mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 12:37:53 +00:00
improve chat
This commit is contained in:
@@ -101,3 +101,6 @@ plugin copy
|
||||
pm2.yaml
|
||||
doc/TypeDoc/**
|
||||
doc/TypeDoc
|
||||
|
||||
# Sentry Config File
|
||||
.sentryclirc
|
||||
|
||||
Generated
+198
@@ -108,6 +108,7 @@
|
||||
"@pdftron/pdfjs-express": "^8.0.1",
|
||||
"@sentry/angular": "7.73.0",
|
||||
"@sentry/capacitor": "^0.14.0",
|
||||
"@sentry/cli": "^2.33.1",
|
||||
"@teamhive/capacitor-video-recorder": "^5.0.0",
|
||||
"@tinymce/tinymce-angular": "^4.2.4",
|
||||
"@types/jest-environment-puppeteer": "^5.0.3",
|
||||
@@ -8230,6 +8231,142 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.33.1.tgz",
|
||||
"integrity": "sha512-dUlZ4EFh98VFRPJ+f6OW3JEYQ7VvqGNMa0AMcmvk07ePNeK/GicAWmSQE4ZfJTTl80ul6HZw1kY01fGQOQlVRA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"progress": "^2.0.3",
|
||||
"proxy-from-env": "^1.1.0",
|
||||
"which": "^2.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"sentry-cli": "bin/sentry-cli"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@sentry/cli-darwin": "2.33.1",
|
||||
"@sentry/cli-linux-arm": "2.33.1",
|
||||
"@sentry/cli-linux-arm64": "2.33.1",
|
||||
"@sentry/cli-linux-i686": "2.33.1",
|
||||
"@sentry/cli-linux-x64": "2.33.1",
|
||||
"@sentry/cli-win32-i686": "2.33.1",
|
||||
"@sentry/cli-win32-x64": "2.33.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli-darwin": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.33.1.tgz",
|
||||
"integrity": "sha512-+4/VIx/E1L2hChj5nGf5MHyEPHUNHJ/HoG5RY+B+vyEutGily1c1+DM2bum7RbD0xs6wKLIyup5F02guzSzG8A==",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli-linux-arm": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.33.1.tgz",
|
||||
"integrity": "sha512-zbxEvQju+tgNvzTOt635le4kS/Fbm2XC2RtYbCTs034Vb8xjrAxLnK0z1bQnStUV8BkeBHtsNVrG+NSQDym2wg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux",
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli-linux-arm64": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.33.1.tgz",
|
||||
"integrity": "sha512-DbGV56PRKOLsAZJX27Jt2uZ11QfQEMmWB4cIvxkKcFVE+LJP4MVA+MGGRUL6p+Bs1R9ZUuGbpKGtj0JiG6CoXw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux",
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli-linux-i686": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.33.1.tgz",
|
||||
"integrity": "sha512-g2LS4oPXkPWOfKWukKzYp4FnXVRRSwBxhuQ9eSw2peeb58ZIObr4YKGOA/8HJRGkooBJIKGaAR2mH2Pk1TKaiA==",
|
||||
"cpu": [
|
||||
"x86",
|
||||
"ia32"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux",
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli-linux-x64": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.33.1.tgz",
|
||||
"integrity": "sha512-IV3dcYV/ZcvO+VGu9U6kuxSdbsV2kzxaBwWUQxtzxJ+cOa7J8Hn1t0koKGtU53JVZNBa06qJWIcqgl4/pCuKIg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux",
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli-win32-i686": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.33.1.tgz",
|
||||
"integrity": "sha512-F7cJySvkpzIu7fnLKNHYwBzZYYwlhoDbAUnaFX0UZCN+5DNp/5LwTp37a5TWOsmCaHMZT4i9IO4SIsnNw16/zQ==",
|
||||
"cpu": [
|
||||
"x86",
|
||||
"ia32"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/cli-win32-x64": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.33.1.tgz",
|
||||
"integrity": "sha512-8VyRoJqtb2uQ8/bFRKNuACYZt7r+Xx0k2wXRGTyH05lCjAiVIXn7DiS2BxHFty7M1QEWUCMNsb/UC/x/Cu2wuA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/core": {
|
||||
"version": "7.73.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.73.0.tgz",
|
||||
@@ -50313,6 +50450,67 @@
|
||||
"@sentry/utils": "7.73.0"
|
||||
}
|
||||
},
|
||||
"@sentry/cli": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.33.1.tgz",
|
||||
"integrity": "sha512-dUlZ4EFh98VFRPJ+f6OW3JEYQ7VvqGNMa0AMcmvk07ePNeK/GicAWmSQE4ZfJTTl80ul6HZw1kY01fGQOQlVRA==",
|
||||
"requires": {
|
||||
"@sentry/cli-darwin": "2.33.1",
|
||||
"@sentry/cli-linux-arm": "2.33.1",
|
||||
"@sentry/cli-linux-arm64": "2.33.1",
|
||||
"@sentry/cli-linux-i686": "2.33.1",
|
||||
"@sentry/cli-linux-x64": "2.33.1",
|
||||
"@sentry/cli-win32-i686": "2.33.1",
|
||||
"@sentry/cli-win32-x64": "2.33.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"progress": "^2.0.3",
|
||||
"proxy-from-env": "^1.1.0",
|
||||
"which": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"@sentry/cli-darwin": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.33.1.tgz",
|
||||
"integrity": "sha512-+4/VIx/E1L2hChj5nGf5MHyEPHUNHJ/HoG5RY+B+vyEutGily1c1+DM2bum7RbD0xs6wKLIyup5F02guzSzG8A==",
|
||||
"optional": true
|
||||
},
|
||||
"@sentry/cli-linux-arm": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.33.1.tgz",
|
||||
"integrity": "sha512-zbxEvQju+tgNvzTOt635le4kS/Fbm2XC2RtYbCTs034Vb8xjrAxLnK0z1bQnStUV8BkeBHtsNVrG+NSQDym2wg==",
|
||||
"optional": true
|
||||
},
|
||||
"@sentry/cli-linux-arm64": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.33.1.tgz",
|
||||
"integrity": "sha512-DbGV56PRKOLsAZJX27Jt2uZ11QfQEMmWB4cIvxkKcFVE+LJP4MVA+MGGRUL6p+Bs1R9ZUuGbpKGtj0JiG6CoXw==",
|
||||
"optional": true
|
||||
},
|
||||
"@sentry/cli-linux-i686": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.33.1.tgz",
|
||||
"integrity": "sha512-g2LS4oPXkPWOfKWukKzYp4FnXVRRSwBxhuQ9eSw2peeb58ZIObr4YKGOA/8HJRGkooBJIKGaAR2mH2Pk1TKaiA==",
|
||||
"optional": true
|
||||
},
|
||||
"@sentry/cli-linux-x64": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.33.1.tgz",
|
||||
"integrity": "sha512-IV3dcYV/ZcvO+VGu9U6kuxSdbsV2kzxaBwWUQxtzxJ+cOa7J8Hn1t0koKGtU53JVZNBa06qJWIcqgl4/pCuKIg==",
|
||||
"optional": true
|
||||
},
|
||||
"@sentry/cli-win32-i686": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.33.1.tgz",
|
||||
"integrity": "sha512-F7cJySvkpzIu7fnLKNHYwBzZYYwlhoDbAUnaFX0UZCN+5DNp/5LwTp37a5TWOsmCaHMZT4i9IO4SIsnNw16/zQ==",
|
||||
"optional": true
|
||||
},
|
||||
"@sentry/cli-win32-x64": {
|
||||
"version": "2.33.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.33.1.tgz",
|
||||
"integrity": "sha512-8VyRoJqtb2uQ8/bFRKNuACYZt7r+Xx0k2wXRGTyH05lCjAiVIXn7DiS2BxHFty7M1QEWUCMNsb/UC/x/Cu2wuA==",
|
||||
"optional": true
|
||||
},
|
||||
"@sentry/core": {
|
||||
"version": "7.73.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.73.0.tgz",
|
||||
|
||||
+4
-1
@@ -22,7 +22,9 @@
|
||||
"docker:publish": "docker run -p gabinetedigital:0.0.0.1",
|
||||
"build:oapr": "ionic cap build android --configuration oapr",
|
||||
"build:dev": "ionic cap build android --configuration dev",
|
||||
"doc:generate": "rimraf doc/TypeDoc && typedoc "
|
||||
"doc:generate": "rimraf doc/TypeDoc && typedoc ",
|
||||
"build-and-upload-sourcemaps": "ng build --prod && sentry-cli releases files $(jq -r .version package.json) upload-sourcemaps ./www --url-prefix '~' --rewrite",
|
||||
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org equilibrium-sa --project oapr-gabinetedigital-fo ./www && sentry-cli sourcemaps upload --org equilibrium-sa --project oapr-gabinetedigital-fo ./www"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
@@ -125,6 +127,7 @@
|
||||
"@pdftron/pdfjs-express": "^8.0.1",
|
||||
"@sentry/angular": "7.73.0",
|
||||
"@sentry/capacitor": "^0.14.0",
|
||||
"@sentry/cli": "^2.33.1",
|
||||
"@teamhive/capacitor-video-recorder": "^5.0.0",
|
||||
"@tinymce/tinymce-angular": "^4.2.4",
|
||||
"@types/jest-environment-puppeteer": "^5.0.3",
|
||||
|
||||
@@ -22,7 +22,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CalendarModule, DateAdapter } from 'angular-calendar';
|
||||
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ChatService } from './services/chat.service';
|
||||
import {MatDatepickerModule} from '@angular/material/datepicker';
|
||||
import {MAT_DATE_LOCALE} from '@angular/material/core';
|
||||
import { Network } from '@ionic-native/network/ngx';
|
||||
@@ -238,7 +237,6 @@ export function counterReducer(state, action) {
|
||||
FilePath,
|
||||
/* FCM,
|
||||
FirebaseX, */
|
||||
ChatService,
|
||||
ScreenOrientation,
|
||||
Network,
|
||||
SQLite,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { chatUser } from '../models/chatMethod'
|
||||
|
||||
//import { ChatController } from './chat'
|
||||
export class EventController {
|
||||
static create() {
|
||||
|
||||
@@ -288,37 +288,37 @@ const routes: Routes = [
|
||||
],
|
||||
|
||||
},
|
||||
// {
|
||||
// path: 'publications',
|
||||
// children: [
|
||||
// {
|
||||
// path:'',
|
||||
// loadChildren: ()=> PublicationsPageModule
|
||||
// },
|
||||
// {
|
||||
// path:':folderId',
|
||||
// loadChildren: ()=> import('../pages/publications/view-publications/view-publications.module').then(m => m.ViewPublicationsPageModule)
|
||||
// },
|
||||
// {
|
||||
// path:'view-publications',
|
||||
// children: [
|
||||
// {
|
||||
// path:':folderId/:publicationId',
|
||||
// loadChildren: ()=> import('../pages/publications/view-publications/publication-detail/publication-detail.module').then(m => m.PublicationDetailPageModule)
|
||||
// },
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// path:'new-publication',
|
||||
// loadChildren: ()=> import('../shared/publication/new-publication/new-publication.module').then(m => m.NewPublicationPageModule)
|
||||
// },
|
||||
// {
|
||||
// path: 'request-options',
|
||||
// loadChildren: () => import('../shared/popover/request-options/request-options.module').then( m => m.RequestOptionsPageModule)
|
||||
// },
|
||||
// ],
|
||||
{
|
||||
path: 'publications',
|
||||
children: [
|
||||
{
|
||||
path:'',
|
||||
loadChildren: ()=> PublicationsPageModule
|
||||
},
|
||||
{
|
||||
path:':folderId',
|
||||
loadChildren: ()=> import('../pages/publications/view-publications/view-publications.module').then(m => m.ViewPublicationsPageModule)
|
||||
},
|
||||
{
|
||||
path:'view-publications',
|
||||
children: [
|
||||
{
|
||||
path:':folderId/:publicationId',
|
||||
loadChildren: ()=> import('../pages/publications/view-publications/publication-detail/publication-detail.module').then(m => m.PublicationDetailPageModule)
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path:'new-publication',
|
||||
loadChildren: ()=> import('../shared/publication/new-publication/new-publication.module').then(m => m.NewPublicationPageModule)
|
||||
},
|
||||
{
|
||||
path: 'request-options',
|
||||
loadChildren: () => import('../shared/popover/request-options/request-options.module').then( m => m.RequestOptionsPageModule)
|
||||
},
|
||||
],
|
||||
|
||||
// },
|
||||
},
|
||||
{
|
||||
path: 'chat',
|
||||
children: [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
|
||||
import { err, ok } from 'neverthrow';
|
||||
import { Camera, CameraPhoto, CameraResultType, CameraSource } from '@capacitor/camera';
|
||||
import { err, ok, Result } from 'neverthrow';
|
||||
|
||||
/**
|
||||
* Parameters for picking a picture.
|
||||
@@ -13,6 +13,15 @@ type PickPictureParams = {
|
||||
cameraResultType?: CameraResultType;
|
||||
};
|
||||
|
||||
/**
|
||||
* Error types for the FilePickerService.
|
||||
*/
|
||||
export interface FilePickerError {
|
||||
type: 'PERMISSION_DENIED' | 'CANCELLED' | 'UNKNOWN';
|
||||
message: string;
|
||||
originalError?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service for handling file picking functionality.
|
||||
* This service provides methods to pick a picture from the device's photo library.
|
||||
@@ -22,9 +31,6 @@ type PickPictureParams = {
|
||||
})
|
||||
export class FilePickerService {
|
||||
|
||||
/**
|
||||
* Creates an instance of FilePickerService.
|
||||
*/
|
||||
constructor() { }
|
||||
|
||||
/**
|
||||
@@ -34,7 +40,7 @@ export class FilePickerService {
|
||||
* @param {CameraResultType} [params.cameraResultType=CameraResultType.DataUrl] - The result type of the photo. Defaults to `CameraResultType.DataUrl`.
|
||||
* @returns {Promise<ok<File> | err<any>>} A promise that resolves with an `ok` result containing the file or an `err` result containing the error.
|
||||
*/
|
||||
async getPicture({quality = 90, cameraResultType = CameraResultType.DataUrl }: PickPictureParams) {
|
||||
async getPicture({quality = 90, cameraResultType = CameraResultType.DataUrl }: PickPictureParams): Promise<Result<CameraPhoto, FilePickerError>> {
|
||||
try {
|
||||
const file = await Camera.getPhoto({
|
||||
quality: quality,
|
||||
@@ -44,7 +50,25 @@ export class FilePickerService {
|
||||
|
||||
return ok(file);
|
||||
} catch (e) {
|
||||
return err(e);
|
||||
if (e.message.includes('denied')) {
|
||||
return err({
|
||||
type: 'PERMISSION_DENIED',
|
||||
message: 'Permission to access photos was denied.',
|
||||
originalError: e
|
||||
});
|
||||
} else if (e.message.includes('User cancelled photos app')) {
|
||||
return err({
|
||||
type: 'CANCELLED',
|
||||
message: 'User cancelled the photo selection.',
|
||||
originalError: e
|
||||
});
|
||||
} else {
|
||||
return err({
|
||||
type: 'UNKNOWN',
|
||||
message: 'An unknown error occurred while picking the picture.',
|
||||
originalError: e
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,21 @@ export class FilePickerMobileService {
|
||||
|
||||
constructor() { }
|
||||
|
||||
/**
|
||||
* @example
|
||||
* ```typescript
|
||||
* const types = ['application/pdf', 'application/doc', 'application/docx','application/xls', 'application/xlsx', 'application/ppt','application/pptx', 'application/txt'];
|
||||
* const multiple = false; // Invalid due to commas
|
||||
* const readData = true; // Invalid due to commas
|
||||
* ```
|
||||
*/
|
||||
async getFile({types, multiple, readData}): Promise<Result<PickFilesResult, any>> {
|
||||
try {
|
||||
|
||||
const result = await FilePicker.pickFiles({
|
||||
types: ['application/pdf', 'application/doc', 'application/docx','application/xls', 'application/xlsx', 'application/ppt',
|
||||
'application/pptx', 'application/txt'],
|
||||
multiple: false,
|
||||
readData: true,
|
||||
types: types,
|
||||
multiple: multiple,
|
||||
readData: readData,
|
||||
});
|
||||
|
||||
return ok(result)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Result, ok, err } from 'neverthrow';
|
||||
import { EntityTable } from 'Dexie';
|
||||
import { ZodError, ZodObject, ZodSchema } from 'zod';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
|
||||
// Define a type for the Result of repository operations
|
||||
type RepositoryResult<T, E> = Result<T, Error | ZodError<E>>;
|
||||
@@ -28,6 +29,9 @@ export class DexieRepository<T> {
|
||||
return err(new Error('Failed to insert document: ' + error.message));
|
||||
}
|
||||
} else {
|
||||
Logger.error(`dexie.js failed to insert into ${this.table.name}, invalid data`, {
|
||||
data: document
|
||||
});
|
||||
return err((dataValidation as unknown as ZodError<T>))
|
||||
}
|
||||
}
|
||||
@@ -45,6 +49,9 @@ export class DexieRepository<T> {
|
||||
const ids = await this.table.bulkAdd(documents as any);
|
||||
return ok(ids);
|
||||
} catch (error) {
|
||||
Logger.error(`dexie.js failed to insert many into ${this.table.name}, invalid data`, {
|
||||
data: document
|
||||
});
|
||||
return err(new Error('Failed to insert multiple documents: ' + error.message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { SearchList } from 'src/app/models/search-document';
|
||||
import { NewEventPage } from 'src/app/pages/agenda/new-event/new-event.page';
|
||||
import { SearchPage } from 'src/app/pages/search/search.page';
|
||||
import { AlertService } from 'src/app/services/alert.service';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { FileLoaderService } from 'src/app/services/file/file-loader.service';
|
||||
import { FileToBase64Service } from 'src/app/services/file/file-to-base64.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
@@ -33,7 +32,6 @@ export class ChatOptionsFeaturesPage implements OnInit {
|
||||
private navParams: NavParams,
|
||||
private fileLoaderService: FileLoaderService,
|
||||
private fileToBase64Service: FileToBase64Service,
|
||||
private chatService: ChatService,
|
||||
public ThemeService: ThemeService
|
||||
) {
|
||||
|
||||
@@ -121,9 +119,7 @@ export class ChatOptionsFeaturesPage implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
this.chatService.sendMessage(body).subscribe(res=> {
|
||||
//
|
||||
});
|
||||
|
||||
//
|
||||
};
|
||||
}
|
||||
@@ -145,10 +141,7 @@ export class ChatOptionsFeaturesPage implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
this.chatService.sendMessage(body).subscribe(res=> {
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/* getGroupContacts(room:any){
|
||||
|
||||
@@ -1,390 +0,0 @@
|
||||
interface Ts {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
interface U {
|
||||
_id: string;
|
||||
username: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface UpdatedAt {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
interface Attachment {
|
||||
ts: Date;
|
||||
title_link_download: boolean;
|
||||
}
|
||||
|
||||
export interface File {
|
||||
type: string;
|
||||
guid: string;
|
||||
image_url: string;
|
||||
subject: string;
|
||||
start_date?: Date;
|
||||
end_date?: Date;
|
||||
venue: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface EditedAt {
|
||||
$date: number;
|
||||
}
|
||||
|
||||
interface EditedBy {
|
||||
_id: string;
|
||||
username: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface Ts2 {
|
||||
$date: number;
|
||||
}
|
||||
|
||||
interface U2 {
|
||||
_id: string;
|
||||
username: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface UpdatedAt2 {
|
||||
$date: number;
|
||||
}
|
||||
|
||||
interface FirstUnread {
|
||||
_id: string;
|
||||
rid: string;
|
||||
msg: string;
|
||||
ts: Ts2;
|
||||
u: U2;
|
||||
_updatedAt: string;
|
||||
mentions: any[];
|
||||
channels: any[];
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
customFields:any;
|
||||
_id: string;
|
||||
id: null | string;
|
||||
rid: string;
|
||||
msg: string;
|
||||
ts: Ts;
|
||||
sendAttempt?: number
|
||||
u: U;
|
||||
from: 'Offline'|'History'|'stream'| 'send'
|
||||
t: string;
|
||||
origin: 'history' | 'stream' | 'local'
|
||||
_updatedAt: '';
|
||||
mentions: any[];
|
||||
channels: any[];
|
||||
attachments: Attachment[];
|
||||
file: File;
|
||||
editedAt: EditedAt;
|
||||
editedBy: EditedBy;
|
||||
urls: any[];
|
||||
temporaryData: object
|
||||
localReference?: string,
|
||||
viewed: string[],
|
||||
received: string[],
|
||||
delate: boolean,
|
||||
delateRequest: boolean
|
||||
attachmentsModelData: {
|
||||
fileBase64: string
|
||||
}
|
||||
hasFile: boolean
|
||||
UploadAttachmentsTemp: number
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface Lm {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface LastMessage {
|
||||
_id: string;
|
||||
rid: string;
|
||||
msg: string;
|
||||
ts: Ts;
|
||||
u: U;
|
||||
_updatedAt: UpdatedAt2;
|
||||
mentions: any[];
|
||||
channels: any[];
|
||||
file: File;
|
||||
attachments: Attachment[];
|
||||
}
|
||||
|
||||
export interface CustomFields {
|
||||
}
|
||||
|
||||
export interface Update {
|
||||
_id: string;
|
||||
t: string;
|
||||
usernames: string[];
|
||||
usersCount: number;
|
||||
uids: string[];
|
||||
default: boolean;
|
||||
ro: boolean;
|
||||
sysMes: boolean;
|
||||
_updatedAt: UpdatedAt;
|
||||
lm: Lm;
|
||||
lastMessage: LastMessage;
|
||||
name: string;
|
||||
fname: string;
|
||||
u: U2;
|
||||
customFields: CustomFields;
|
||||
}
|
||||
|
||||
export interface DeletedAt {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
export interface Remove {
|
||||
_id: string;
|
||||
_deletedAt: DeletedAt;
|
||||
}
|
||||
|
||||
export interface Result {
|
||||
update: Update[];
|
||||
remove: Remove[];
|
||||
}
|
||||
|
||||
export interface Rooms {
|
||||
msg: string;
|
||||
id: string;
|
||||
result: Result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface ChatMessage {
|
||||
msg: string;
|
||||
id: string;
|
||||
result: Message
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export interface chatHistory {
|
||||
msg: string;
|
||||
id: string;
|
||||
result: {
|
||||
messages: Message[];
|
||||
firstUnread: FirstUnread;
|
||||
unreadNotLoaded: number;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
interface Ts {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
interface U {
|
||||
_id: string;
|
||||
username: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface UpdatedAt {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
interface Attachment {
|
||||
ts: Date;
|
||||
title_link_download: boolean;
|
||||
}
|
||||
|
||||
export interface File {
|
||||
type: string;
|
||||
guid: string;
|
||||
image_url: string;
|
||||
subject: string;
|
||||
start_date?: Date;
|
||||
end_date?: Date;
|
||||
venue: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface EditedAt {
|
||||
$date: number;
|
||||
}
|
||||
|
||||
interface EditedBy {
|
||||
_id: string;
|
||||
username: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface Ts2 {
|
||||
$date: number;
|
||||
}
|
||||
|
||||
interface U2 {
|
||||
_id: string;
|
||||
username: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface UpdatedAt2 {
|
||||
$date: number;
|
||||
}
|
||||
|
||||
interface FirstUnread {
|
||||
_id: string;
|
||||
rid: string;
|
||||
msg: string;
|
||||
ts: Ts2;
|
||||
u: U2;
|
||||
_updatedAt: string;
|
||||
mentions: any[];
|
||||
channels: any[];
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
customFields:any;
|
||||
_id: string;
|
||||
rid: string;
|
||||
msg: string;
|
||||
ts: Ts;
|
||||
u: U;
|
||||
t: string;
|
||||
_updatedAt: '';
|
||||
mentions: any[];
|
||||
channels: any[];
|
||||
attachments: Attachment[];
|
||||
file: File;
|
||||
editedAt: EditedAt;
|
||||
editedBy: EditedBy;
|
||||
urls: any[];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface Lm {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface LastMessage {
|
||||
_id: string;
|
||||
rid: string;
|
||||
msg: string;
|
||||
ts: Ts;
|
||||
u: U;
|
||||
_updatedAt: UpdatedAt2;
|
||||
mentions: any[];
|
||||
channels: any[];
|
||||
file: File;
|
||||
attachments: Attachment[];
|
||||
}
|
||||
|
||||
export interface CustomFields {
|
||||
}
|
||||
|
||||
export interface Update {
|
||||
_id: string;
|
||||
t: string;
|
||||
usernames: string[];
|
||||
usersCount: number;
|
||||
uids: string[];
|
||||
default: boolean;
|
||||
ro: boolean;
|
||||
sysMes: boolean;
|
||||
_updatedAt: UpdatedAt;
|
||||
lm: Lm;
|
||||
lastMessage: LastMessage;
|
||||
name: string;
|
||||
fname: string;
|
||||
u: U2;
|
||||
customFields: CustomFields;
|
||||
}
|
||||
|
||||
export interface DeletedAt {
|
||||
$date: any;
|
||||
}
|
||||
|
||||
export interface Remove {
|
||||
_id: string;
|
||||
_deletedAt: DeletedAt;
|
||||
}
|
||||
|
||||
export interface Result {
|
||||
update: Update[];
|
||||
remove: Remove[];
|
||||
}
|
||||
|
||||
export interface Rooms {
|
||||
msg: string;
|
||||
id: string;
|
||||
result: Result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface ChatMessage {
|
||||
msg: string;
|
||||
id: string;
|
||||
result: Message
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export interface chatHistory {
|
||||
msg: string;
|
||||
id: string;
|
||||
result: {
|
||||
messages: Message[];
|
||||
firstUnread: FirstUnread;
|
||||
unreadNotLoaded: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface chatUser {
|
||||
_id: string;
|
||||
createdAt: Date;
|
||||
emails: {
|
||||
address: string;
|
||||
verified: boolean;
|
||||
}
|
||||
type: string;
|
||||
status: 'online' | 'offline' | 'away' | 'busy' ;
|
||||
active: boolean;
|
||||
_updatedAt: Date;
|
||||
roles: string[];
|
||||
name: string;
|
||||
lastLogin: Date;
|
||||
statusConnection: string;
|
||||
utcOffset: number;
|
||||
username: string;
|
||||
__rooms: string[];
|
||||
requirePasswordChange?: boolean;
|
||||
settings: {
|
||||
preferences: {
|
||||
language: string;
|
||||
};
|
||||
};
|
||||
nickname: string;
|
||||
statusText: string;
|
||||
banners: any;
|
||||
statusDefault: string;
|
||||
language: string;
|
||||
avatarOrigin: string;
|
||||
avatarETag?: any;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import { ListenMessageDeleteByRoomIdService } from './use-case/listene-message-d
|
||||
import { ListenMessageUpdateByRoomIdUseCase } from './use-case/listen-message-update-by-roomId.service';
|
||||
import { SyncAllRoomMessagesService } from './use-case/sync-all-room-messages.service';
|
||||
import { ListenSendMessageUseCase } from './use-case/listen-send-message.service'
|
||||
import { GetMessageAttachmentLocallyUseCaseService } from 'src/app/module/chat/domain/use-case/get-message-attachment-localy-use-case.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { MessageEntity } from './entity/message';
|
||||
@@ -46,7 +47,8 @@ export class ChatServiceService {
|
||||
private ListenSendMessageUseCase: ListenSendMessageUseCase,
|
||||
private MessageAttachmentByMessageIdService: MessageAttachmentByMessageIdUseCase,
|
||||
private SyncAllRoomMessagesService: SyncAllRoomMessagesService,
|
||||
private DownloadMessageAttachmentUserCaseService: DownloadMessageAttachmentUserCaseService
|
||||
private DownloadMessageAttachmentUserCaseService: DownloadMessageAttachmentUserCaseService,
|
||||
private GetMessageAttachmentLocallyUseCaseService: GetMessageAttachmentLocallyUseCaseService
|
||||
) {
|
||||
this.messageLiveSignalRDataSourceService.getMessageDelete()
|
||||
.pipe()
|
||||
@@ -127,7 +129,7 @@ export class ChatServiceService {
|
||||
return this.SyncAllRoomMessagesService.execute()
|
||||
}
|
||||
|
||||
getMessageAttachmentByMessageId(input: MessageAttachmentByMessageIdInput) {
|
||||
getMessageAttachmentByMessageId(input: MessageEntity) {
|
||||
return this.MessageAttachmentByMessageIdService.execute(input)
|
||||
}
|
||||
|
||||
@@ -135,6 +137,10 @@ export class ChatServiceService {
|
||||
return this.DownloadMessageAttachmentUserCaseService.execute(input)
|
||||
}
|
||||
|
||||
getMessageAttachmentLocallyByMessageId(input: MessageAttachmentByMessageIdInput) {
|
||||
return this.GetMessageAttachmentLocallyUseCaseService.execute(input)
|
||||
}
|
||||
|
||||
|
||||
listenToIncomingMessage(roomId:string) {
|
||||
return this.ListenMessageByRoomIdNewUseCase.execute({roomId})
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageAttachmentByMessageIdInput } from './message-attachment-by-message-id.service';
|
||||
import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/data-source/attachment/attachment-remote-data-source.service'
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/data-source/attachment/attachment-local-data-source.service'
|
||||
import { err, Result } from 'neverthrow';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class GetMessageAttachmentLocallyUseCaseService {
|
||||
|
||||
constructor(
|
||||
private AttachmentRemoteDataSourceService: AttachmentRemoteDataSourceService,
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
|
||||
async execute(input: MessageAttachmentByMessageIdInput): Promise<Result<string, any>> {
|
||||
|
||||
const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({
|
||||
$messageId: input.$messageId
|
||||
})
|
||||
|
||||
if(getLocalAttachment.isOk()) {
|
||||
if(getLocalAttachment.value) {
|
||||
return getLocalAttachment.map(e => e.file)
|
||||
}
|
||||
} else {
|
||||
return err(getLocalAttachment.error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { AttachmentLocalDataSource } from 'src/app/module/chat/data/data-source/
|
||||
import { convertBlobToDataURL } from 'src/app/utils/ToBase64';
|
||||
import { Result } from 'neverthrow';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { MessageEntity } from '../entity/message';
|
||||
|
||||
const MessageAttachmentByMessageIdSchema = z.object({
|
||||
$messageId: z.number(),
|
||||
@@ -23,10 +24,10 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
async execute(input: MessageAttachmentByMessageIdInput): Promise<Result<string, any>> {
|
||||
async execute(input: MessageEntity): Promise<Result<string, any>> {
|
||||
|
||||
const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({
|
||||
$messageId: input.$messageId
|
||||
$messageId: input.$id
|
||||
})
|
||||
|
||||
if(getLocalAttachment.isOk() && getLocalAttachment.value) {
|
||||
@@ -34,18 +35,40 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
return getLocalAttachment.map(e => e.file)
|
||||
}
|
||||
} else {
|
||||
const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.id)
|
||||
const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.attachments[0].id)
|
||||
|
||||
if(result.isErr()) {
|
||||
Logger.error('failed to download message attachment', {
|
||||
error: result.error,
|
||||
data: 'document id '+ input.attachments[0].id,
|
||||
messageId: input.id,
|
||||
$messageId: input.$id
|
||||
})
|
||||
}
|
||||
|
||||
return result.asyncMap(async (e) => {
|
||||
|
||||
const dataUrl = await convertBlobToDataURL(e)
|
||||
Logger.info('downloaded file', {
|
||||
data: dataUrl.slice(0, 100)+'...'
|
||||
})
|
||||
// Logger.info('downloaded file .', {
|
||||
// data: dataUrl.slice(0, 100)+'...'
|
||||
// })
|
||||
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$messageId: input.$messageId,
|
||||
id: input.id,
|
||||
file: dataUrl
|
||||
$messageId: input.$id,
|
||||
file: dataUrl,
|
||||
fileType: input.attachments[0].fileType,
|
||||
source: input.attachments[0].source,
|
||||
fileName: input.attachments[0].fileName,
|
||||
applicationId: input.attachments[0].applicationId,
|
||||
docId: input.attachments[0].docId,
|
||||
mimeType: input.attachments[0].mimeType,
|
||||
}).then((e) => {
|
||||
if(e.isErr()) {
|
||||
Logger.error('failed to create attachment locally on send message', {
|
||||
error: e.error,
|
||||
data: dataUrl.slice(0, 100)+'...'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return dataUrl
|
||||
|
||||
@@ -49,7 +49,13 @@ export class MessageCreateUseCaseService {
|
||||
|
||||
this.AttachmentRepositoryService.create({
|
||||
$messageId: createMessageLocally.value.$id,
|
||||
file: createDataURL(attachment.file, attachment.mimeType)
|
||||
file: createDataURL(attachment.file, attachment.mimeType),
|
||||
fileType: attachment.fileType,
|
||||
source: attachment.source,
|
||||
fileName: attachment.fileName,
|
||||
applicationId: attachment.applicationId,
|
||||
docId: attachment.docId,
|
||||
mimeType: attachment.mimeType,
|
||||
}).then((e) => {
|
||||
if(e.isErr()) {
|
||||
Logger.error('failed to create attachment locally on send message', {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageLocalDataSourceService } from '../../data/data-source/message/message-local-data-source.service';
|
||||
import { MessageOutPutDataDTO } from '../../data/dto/message/messageOutputDTO';
|
||||
import { MessageTable } from '../../infra/database/dexie/schema/message';
|
||||
import { SignalRService } from '../../infra/socket/signal-r.service';
|
||||
import { InstanceId } from '../chat-service.service';
|
||||
import { MessageMapper } from '../mapper/messageMapper';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { AttachmentRepositoryService } from "src/app/module/chat/data/repository/attachment-repository.service";
|
||||
import { AttachmentLocalDataSource } from '../../data/data-source/attachment/attachment-local-data-source.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SendLocalMessagesUseCaseService {
|
||||
|
||||
constructor(
|
||||
private messageLiveSignalRDataSourceService: SignalRService,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private AttachmentRepositoryService: AttachmentLocalDataSource,
|
||||
) { }
|
||||
|
||||
|
||||
async execute() {
|
||||
const messages = await this.messageLocalDataSourceService.getOfflineMessages()
|
||||
|
||||
if(messages.length >= 1) {
|
||||
|
||||
for(const message of messages) {
|
||||
|
||||
const attachments = await this.AttachmentRepositoryService.find({$messageId: message.$id})
|
||||
|
||||
if(attachments.isOk()) {
|
||||
|
||||
message.attachments = attachments.value.map(e => ({
|
||||
fileType: e.fileType,
|
||||
source: e.source,
|
||||
fileName: e.fileName,
|
||||
applicationId: e.applicationId,
|
||||
docId: e.docId,
|
||||
id: e.id,
|
||||
mimeType: e.mimeType,
|
||||
description: e.description,
|
||||
file: e.file.split(',')[0]
|
||||
}))
|
||||
console.log('to upload', messages)
|
||||
const requestId = InstanceId +'@'+ uuidv4();
|
||||
const DTO = MessageMapper.fromDomain(message, requestId)
|
||||
|
||||
await this.messageLocalDataSourceService.update(message.$id, { sending: true })
|
||||
const sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage<MessageOutPutDataDTO>(DTO)
|
||||
|
||||
if(sendMessageResult.isOk()) {
|
||||
|
||||
if(sendMessageResult.value.sender == undefined || sendMessageResult.value.sender == null) {
|
||||
|
||||
delete sendMessageResult.value.sender
|
||||
}
|
||||
|
||||
let clone: MessageTable = {
|
||||
...sendMessageResult.value,
|
||||
id: sendMessageResult.value.id,
|
||||
$id : message.$id
|
||||
}
|
||||
|
||||
console.log('send message local '+ messages.length)
|
||||
|
||||
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId})
|
||||
} else {
|
||||
|
||||
console.log('erro send message')
|
||||
this.messageLocalDataSourceService.update(message.$id, {sending: false})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,22 @@
|
||||
import { z } from "zod";
|
||||
import { EntityTable } from 'Dexie';
|
||||
import { zodDataUrlSchema } from "src/app/utils/zod";
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "src/app/module/chat/data/dto/message/messageOutputDTO";
|
||||
|
||||
export const AttachmentTableSchema = z.object({
|
||||
id: z.string().optional(), // attachment id
|
||||
$id: z.number().optional(), // local id
|
||||
$messageId: z.number(),
|
||||
attachmentId: z.string().optional(),
|
||||
file: zodDataUrlSchema,
|
||||
//
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
fileName: z.string().optional(),
|
||||
applicationId: z.number().optional(),
|
||||
docId: z.string().optional(),
|
||||
mimeType: z.string().optional(),
|
||||
id: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
})
|
||||
|
||||
export type AttachmentTable = z.infer<typeof AttachmentTableSchema>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { nativeEnum, z } from "zod";
|
||||
import { EntityTable } from 'Dexie';
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "src/app/module/chat/data/dto/message/messageOutputDTO";
|
||||
import { z } from 'zod';
|
||||
|
||||
export const MessageTableSchema = z.object({
|
||||
$id: z.number().optional(),
|
||||
@@ -33,6 +33,7 @@ export const MessageTableSchema = z.object({
|
||||
applicationId: z.number().optional(),
|
||||
docId: z.string().optional(),
|
||||
id: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
mimeType: z.string().optional()
|
||||
})).optional()
|
||||
})
|
||||
|
||||
@@ -5,11 +5,16 @@ import { DexieMembersTableSchema, MemberTableColumn } from './schema/members';
|
||||
import { DexieRoomsTable, RoomTableColumn } from './schema/room';
|
||||
import { DexieTypingsTable, TypingTableColumn } from './schema/typing';
|
||||
import { MessageEntity } from '../../../domain/entity/message';
|
||||
import { AttachmentTable, AttachmentTableColumn, DexieAttachmentsTableSchema } from './schema/attachment';
|
||||
// import DexieMemory from 'dexie-in-memory';
|
||||
import { AttachmentTableColumn, DexieAttachmentsTableSchema } from './schema/attachment';
|
||||
// import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
|
||||
// import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
|
||||
|
||||
|
||||
// Database declaration (move this to its own module also)
|
||||
export const chatDatabase = new Dexie('chat-database-infra') as Dexie & {
|
||||
export const chatDatabase = new Dexie('chat-database-infra',{
|
||||
// indexedDB: new FDBFactory,
|
||||
// IDBKeyRange: FDBKeyRange, // Mocking IDBKeyRange
|
||||
}) as Dexie & {
|
||||
message: DexieMessageTable,
|
||||
members: DexieMembersTableSchema,
|
||||
room: DexieRoomsTable,
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController, NavParams, Platform, LoadingController } from '@ionic/angular';
|
||||
import { ModalController, NavParams, Platform } from '@ionic/angular';
|
||||
|
||||
/* import {Plugins, CameraResultType, CameraSource} from '@capacitor/core'; */
|
||||
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
|
||||
import { PublicationsService } from 'src/app/services/publications.service';
|
||||
import { Publication } from 'src/app/models/publication';
|
||||
import { Image } from 'src/app/models/image';
|
||||
import { PhotoService } from 'src/app/services/photo.service';
|
||||
//Capacitor
|
||||
@@ -22,21 +20,16 @@ import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
|
||||
import { PublicationFolderService } from 'src/app/store/publication-folder.service';
|
||||
import { RouteService } from 'src/app/services/route.service';
|
||||
import { FileService } from 'src/app/services/functions/file.service';
|
||||
import { readAndCompressImage } from 'browser-image-resizer';
|
||||
import { FilePicker } from '@capawesome/capacitor-file-picker';
|
||||
import { CapacitorVideoPlayer } from 'capacitor-video-player';
|
||||
import { CaptureError, CaptureImageOptions, MediaCapture, MediaFile } from '@awesome-cordova-plugins/media-capture/ngx';
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { File as IonicFile } from '@ionic-native/file/ngx';
|
||||
|
||||
import { Media } from '@ionic-native/media/ngx';
|
||||
import { checkFileTypeService } from 'src/app/services/checkFileType.service';
|
||||
import { FileValidatorService } from "src/app/services/file/file-validator.service"
|
||||
import { App } from '@capacitor/app';
|
||||
import { NavigationExtras, Router } from '@angular/router';
|
||||
import { VideoconvertService } from 'src/app/services/videoconvert.service'
|
||||
import { PublicationAttachmentEntity } from 'src/app/shared/publication/upload/upload-streaming.service';
|
||||
import { PublicationFromMvService } from "src/app/shared/publication/upload/publication-from-mv.service"
|
||||
import { File } from '../../../models/chatMethod';
|
||||
import { CropImagePage } from 'src/app/modals/crop-image/crop-image.page';
|
||||
|
||||
|
||||
@@ -127,19 +120,15 @@ export class NewPublicationPage implements OnInit {
|
||||
private modalController: ModalController,
|
||||
public photoService: PhotoService,
|
||||
private navParams: NavParams,
|
||||
private publications: PublicationsService,
|
||||
private toastService: ToastService,
|
||||
public ThemeService: ThemeService,
|
||||
private platform: Platform,
|
||||
private loadingCtrl: LoadingController,
|
||||
public imageCompress: NgxImageCompressService,
|
||||
private httpErrorHandle: HttpErrorHandle,
|
||||
public PublicationFolderService: PublicationFolderService,
|
||||
private RouteService: RouteService,
|
||||
public FileService: FileService,
|
||||
private mediaCapture: MediaCapture,
|
||||
public checkFileType: checkFileTypeService,
|
||||
private FileValidatorService: FileValidatorService,
|
||||
private router: Router,
|
||||
private videoconvertService: VideoconvertService,
|
||||
public PublicationFromMvService: PublicationFromMvService,
|
||||
|
||||
@@ -1,436 +0,0 @@
|
||||
import { HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpService } from './http.service';
|
||||
import { StorageService } from './storage.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { Storage } from '@ionic/storage';
|
||||
import { PermissionService } from './permission.service';
|
||||
import { SessionStore } from '../store/session.service';
|
||||
import { ChangeProfileService } from 'src/app/services/change-profile.service';
|
||||
import { NetworkServiceService , ConnectionStatus} from 'src/app/services/network-service.service';
|
||||
// import { RochetChatConnectorService } from 'src/app/services/chat/rochet-chat-connector.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ChatService {
|
||||
headers: HttpHeaders;
|
||||
options: any;
|
||||
options1: any;
|
||||
X_User_Id: any;
|
||||
X_Auth_Token: any;
|
||||
loggedUserChat: any;
|
||||
bindOnMessage: any;
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private httpService: HttpService,
|
||||
private storage: Storage,
|
||||
private storageService: StorageService,
|
||||
public p: PermissionService,
|
||||
private changeProfileService: ChangeProfileService,
|
||||
private NetworkServiceService: NetworkServiceService,
|
||||
// private RochetChatConnectorService: RochetChatConnectorService
|
||||
) {
|
||||
|
||||
this.changeProfileService.registerCallback(() => {
|
||||
this.setheader();
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
getDocumentDetails(url: string) {
|
||||
let headersc = new HttpHeaders();
|
||||
headersc = headersc.set('X-User-Id', SessionStore.user.ChatData.data.userId);
|
||||
headersc = headersc.set('X-Auth-Token', SessionStore.user.ChatData.data.authToken);
|
||||
headersc = headersc.set('Sec-Fetch-Dest', 'attachment');
|
||||
headersc = headersc.set('Sec-Fetch-Mode', 'navigate');
|
||||
headersc = headersc.set('Cookie', 'rc_uid=fsMwcNdufWvdnChj7');
|
||||
headersc = headersc.set('Cookie', 'rc_token=MLbhikLQI4xo9_vL43HqheKPPbxjag7hKfwxe9AjcvY');
|
||||
// headersc = headersc.set("Host", "www.tabularium.pt");
|
||||
// headersc = headersc.set("Origin", "http://localhost:8100");
|
||||
headersc = headersc.set('Referer', 'http://localhost:8100/');
|
||||
let optionsc = {
|
||||
headers: headersc,
|
||||
withCredentials: true
|
||||
};
|
||||
// let fullUrl = "https://www.tabularium.pt/" + url;
|
||||
return this.http.get(url, optionsc).subscribe(() => {
|
||||
// this.fileService.viewDocumentByUrl(url)
|
||||
});
|
||||
}
|
||||
|
||||
getAllChannels() {
|
||||
return this.http.get(environment.apiChatUrl + 'channels.list', this.options);
|
||||
}
|
||||
|
||||
getAllUserChannels() {
|
||||
return this.http.get(environment.apiChatUrl + 'channels.list.joined', this.options);
|
||||
}
|
||||
|
||||
getAllRooms() {
|
||||
return this.http.get(environment.apiChatUrl + 'rooms.get', this.options);
|
||||
}
|
||||
|
||||
getRoomInfo(roomId: any) {
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'rooms.info', opts);
|
||||
}
|
||||
|
||||
|
||||
GetSubscriptionRoomUnreadM(roomId) {
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'subscriptions.getOne', opts);
|
||||
}
|
||||
|
||||
getChannelInfo(roomId: any) {
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
params = params.set("unread", "true");
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'rooms.info', opts);
|
||||
}
|
||||
|
||||
customsRooms(params: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'rooms.get', opts);
|
||||
}
|
||||
getAllPrivateGroups() {
|
||||
return this.http.get(environment.apiChatUrl + 'groups.list', this.options);
|
||||
}
|
||||
|
||||
getAllUsers() {
|
||||
return this.http.get(environment.apiChatUrl + 'users.list', this.options);
|
||||
}
|
||||
getAllConnectedUsers() {
|
||||
return this.http.get(environment.apiChatUrl + 'users.presence', this.options);
|
||||
}
|
||||
|
||||
//Load messages from roomId
|
||||
getAllDirectMessages() {
|
||||
return this.http.get(environment.apiChatUrl + 'im.list', this.options);
|
||||
}
|
||||
//Load messages from roomId
|
||||
getRoomMessages(roomId: any) {
|
||||
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params,
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'im.history', opts);
|
||||
}
|
||||
|
||||
sendMessage(body: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(environment.apiChatUrl + 'chat.sendMessage', body, opts);
|
||||
}
|
||||
|
||||
uploadFile(formData: any, rid: string) {
|
||||
let url = environment.apiChatUrl + 'rooms.upload/' + rid;
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(url, formData, opts);
|
||||
}
|
||||
|
||||
deleteMessage(body: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(environment.apiChatUrl + 'chat.delete', body, opts);
|
||||
}
|
||||
|
||||
leaveRoom(body: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(environment.apiChatUrl + 'rooms.leave', body, opts);
|
||||
}
|
||||
//Load members from a chat
|
||||
getMembers(roomId: any) {
|
||||
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'im.members', opts);
|
||||
}
|
||||
|
||||
getMemberInfo(userId: string) {
|
||||
let params = new HttpParams();
|
||||
params = params.set("userId", userId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'users.info', opts);
|
||||
}
|
||||
|
||||
setUserStatus(body: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(environment.apiChatUrl + 'users.setStatus', body, this.options);
|
||||
}
|
||||
|
||||
removeChatRoom(body: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(environment.apiChatUrl + 'im.delete', body, this.options);
|
||||
}
|
||||
|
||||
createRoom(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'im.create', body, this.options);
|
||||
}
|
||||
getDirectMessage(roomId: string) {
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'im.messages', opts);
|
||||
}
|
||||
|
||||
/* GROUPS */
|
||||
addGroup(body: any) {
|
||||
|
||||
return this.http.post(environment.apiChatUrl + 'groups.create', body, this.options);
|
||||
}
|
||||
setGroupCustomFields(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'groups.setCustomFields', body, this.options);
|
||||
}
|
||||
|
||||
getGroupMembers(roomId: string) {
|
||||
let params = new HttpParams();
|
||||
let url = environment.apiChatUrl + 'groups.members';
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(url, opts);
|
||||
}
|
||||
|
||||
getChannelMembers(roomId: string) {
|
||||
let params = new HttpParams();
|
||||
let url = environment.apiChatUrl + 'channels.members';
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(url, opts);
|
||||
}
|
||||
/* GROUP MESSAGES */
|
||||
getPrivateGroupMessages(roomId: any) {
|
||||
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'groups.history', opts);
|
||||
}
|
||||
getPublicGroupMessages(roomId: any) {
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'channels.history', opts);
|
||||
}
|
||||
closeGroup(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'groups.close', body, this.options);
|
||||
}
|
||||
closeChannel(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'channels.close', body, this.options);
|
||||
}
|
||||
leaveGroup(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'groups.leave', body, this.options);
|
||||
}
|
||||
leaveChannel(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'channels.leave', body, this.options);
|
||||
}
|
||||
removeChannelMember(body: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(environment.apiChatUrl + 'channels.kick', body, opts);
|
||||
}
|
||||
|
||||
addChannelOwner(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'channels.addOwner', body, this.options);
|
||||
}
|
||||
|
||||
addGroupOwner(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'groups.addOwner', body, this.options);
|
||||
}
|
||||
|
||||
deleteGroup(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'groups.delete', body, this.options);
|
||||
}
|
||||
|
||||
deleteChannel(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'channels.delete', body, this.options);
|
||||
}
|
||||
addUserToGroup(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'groups.invite', body, this.options);
|
||||
}
|
||||
getGroupInfo(roomId: any) {
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
return this.http.get(environment.apiChatUrl + 'groups.info', opts);
|
||||
}
|
||||
renameGroup(body: any) {
|
||||
return this.http.post(environment.apiChatUrl + 'groups.rename', body, this.options);
|
||||
}
|
||||
removeGroupMember(body: any) {
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
}
|
||||
return this.http.post(environment.apiChatUrl + 'groups.kick', body, opts);
|
||||
}
|
||||
|
||||
async subscribe(roomId: any) {
|
||||
|
||||
let params = new HttpParams();
|
||||
params = params.set("roomId", roomId);
|
||||
let opts = {
|
||||
headers: this.headers,
|
||||
params: params
|
||||
}
|
||||
|
||||
this.http.get(environment.apiChatUrl + 'im.messages', opts).subscribe(async res => {
|
||||
|
||||
|
||||
if (res == 502) {
|
||||
// Connection timeout
|
||||
// happens when the connection was pending for too long
|
||||
// let's reconnect
|
||||
await this.subscribe(roomId);
|
||||
} else if (res != 200) {
|
||||
// Show Error
|
||||
//showMessage(response.statusText);
|
||||
this.getRoomMessages(roomId)
|
||||
// Reconnect in one second
|
||||
await new Promise(resolve => setTimeout(resolve, 1000)).catch ((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
await this.subscribe(roomId);
|
||||
} else {
|
||||
// Got message
|
||||
//let message = await response.text();
|
||||
this.getRoomMessages(roomId)
|
||||
await this.subscribe(roomId);
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
setheader() {
|
||||
try {
|
||||
|
||||
if (this.p.userPermission(this.p.permissionList.Chat.access) && SessionStore.user.ChatData) {
|
||||
this.headers = new HttpHeaders();;
|
||||
|
||||
if (this.p.userPermission(this.p.permissionList.Chat.access)) {
|
||||
//
|
||||
this.headers = this.headers.set('X-User-Id', SessionStore.user.ChatData.data.userId);
|
||||
this.headers = this.headers.set('X-Auth-Token', SessionStore.user.ChatData.data.authToken);
|
||||
this.options = {
|
||||
headers: this.headers,
|
||||
};
|
||||
|
||||
this.resetTimer();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async refreshtoken() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
lastUpdateIs10sAgo() {
|
||||
const currentTime: any = new Date();
|
||||
|
||||
const diffTime = Math.abs(currentTime - this.timerEventTriggerDateLastUpdate);
|
||||
|
||||
if(this.timerEventTriggerDateLastUpdate == null) {
|
||||
return true
|
||||
}
|
||||
|
||||
if(diffTime >= 5000) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
functionTimer = null;
|
||||
timerEventTriggerDate = null
|
||||
timerEventTriggerDateLastUpdate = null
|
||||
|
||||
resetTimer() {
|
||||
clearTimeout(this.functionTimer);
|
||||
this.timerEventTriggerDate = new Date(+new Date() + 60000*15);
|
||||
|
||||
this.functionTimer = setTimeout(() => {
|
||||
|
||||
if(this.NetworkServiceService.getCurrentNetworkStatus() == ConnectionStatus.Online) {
|
||||
this.refreshtoken();
|
||||
} else {
|
||||
this.resetTimer()
|
||||
}
|
||||
|
||||
}, 60000 * 15); // time is in milliseconds
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ChatService } from '../chat.service';
|
||||
// import { ChatSystemService } from '../chat/chat-system.service';
|
||||
|
||||
@Injectable({
|
||||
|
||||
@@ -14,7 +14,6 @@ import { notificationObject } from '../models/notifications';
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { AngularFireMessaging } from '@angular/fire/messaging';
|
||||
import { NotificationHolderService } from 'src/app/store/notification-holder.service';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { FCM } from '@capacitor-community/fcm';
|
||||
// import { ChatSystemService } from './chat/chat-system.service';
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ import { MiddlewareServiceService } from "src/app/shared/API/middleware/middlewa
|
||||
import { LakefsRepositoryService } from '../../repository/lakefs/lakefs-repository.service';
|
||||
|
||||
import { SocketConnectionMCRService } from "src/app/services/socket-connection-mcr.service"
|
||||
import { CMAPIService } from '../../repository/CMAPI/cmapi.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { CaptureImageOptions, MediaCapture } from '@awesome-cordova-plugins/media-capture/ngx';
|
||||
import { Directory, Filesystem, FilesystemDirectory } from '@capacitor/filesystem';
|
||||
import { ModalController, Platform } from '@ionic/angular';
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ChatMessageService } from './chat-message.service';
|
||||
|
||||
describe('ChatMessageService', () => {
|
||||
let service: ChatMessageService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ChatMessageService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { localstoreService } from '../localstore.service'
|
||||
import { SHA1 } from 'crypto-js'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ChatMessageService {
|
||||
|
||||
private _message = []
|
||||
// local storage keyName
|
||||
private keyName: string;
|
||||
|
||||
constructor() {
|
||||
|
||||
this.keyName = (SHA1('chat'+"ChatMessageService")).toString()
|
||||
|
||||
setTimeout(()=> {
|
||||
let restore = localstoreService.get(this.keyName, {})
|
||||
this._message = restore.message || {}
|
||||
}, 10)
|
||||
|
||||
}
|
||||
|
||||
get message() {
|
||||
return this._message
|
||||
}
|
||||
|
||||
getMessages(roomId) {
|
||||
return this._message[roomId] || []
|
||||
}
|
||||
|
||||
add(roomId:string, message: any[]) {
|
||||
this._message[roomId] = message
|
||||
|
||||
setTimeout(()=> {
|
||||
localstoreService.set(this.keyName, {
|
||||
message: this._message
|
||||
})
|
||||
}, 10)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const ChatMessageStore = new ChatMessageService()
|
||||
@@ -1,16 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ChatUserService } from './chat-user.service';
|
||||
|
||||
describe('ChatUserService', () => {
|
||||
let service: ChatUserService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ChatUserService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,47 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { localstoreService } from '../localstore.service';
|
||||
import { SHA1 } from 'crypto-js';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ChatUserService {
|
||||
|
||||
// main data
|
||||
private _userList = {}
|
||||
// local storage keyName
|
||||
private keyName: string;
|
||||
|
||||
constructor() {
|
||||
|
||||
this.keyName = (SHA1('chat'+"ToDayEventStorageService")).toString()
|
||||
|
||||
setTimeout(()=> {
|
||||
let restore = localstoreService.get(this.keyName, {})
|
||||
this._userList = restore.userList || {}
|
||||
}, 10)
|
||||
|
||||
}
|
||||
|
||||
get userList() {
|
||||
return this._userList
|
||||
}
|
||||
|
||||
add(roomId:string, userList: any[] = []) {
|
||||
|
||||
this._userList[roomId] = userList
|
||||
|
||||
this.save()
|
||||
}
|
||||
|
||||
private save() {
|
||||
setTimeout(()=> {
|
||||
localstoreService.set(this.keyName, {
|
||||
userList: this._userList
|
||||
})
|
||||
}, 10)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const ChatUserStorage = new ChatUserService()
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
import { ModalController } from '@ionic/angular';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { GroupMessagesPage } from './modal/group-messages/group-messages.page';
|
||||
import { ContactsPage } from './modal/./messages/contacts/contacts.page';
|
||||
import { MessagesPage } from './modal/./messages/messages.page';
|
||||
@@ -54,7 +53,6 @@ export class ChatPage implements OnInit {
|
||||
items$!: DexieObservable<RoomListOutPutDTO[]>;
|
||||
|
||||
constructor(
|
||||
private chatService: ChatService,
|
||||
private modalController: ModalController,
|
||||
private timeService: TimeService,
|
||||
public ThemeService: ThemeService,
|
||||
@@ -188,9 +186,7 @@ export class ChatPage implements OnInit {
|
||||
message: '',
|
||||
status: status,
|
||||
}
|
||||
this.chatService.setUserStatus(body).subscribe(res => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
hideRefreshButton() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { ModalController, PickerController } from '@ionic/angular';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { HttpResponse } from '@microsoft/signalr';
|
||||
@@ -33,7 +32,6 @@ export class EditGroupPage implements OnInit {
|
||||
constructor(
|
||||
private modalController: ModalController,
|
||||
private pickerController: PickerController,
|
||||
private chatService: ChatService,
|
||||
public ThemeService: ThemeService,
|
||||
private RoomRepositoryService: RoomRepositoryService,
|
||||
private httpErrorHandle: HttpErrorHandle,
|
||||
@@ -48,16 +46,16 @@ export class EditGroupPage implements OnInit {
|
||||
}
|
||||
|
||||
getRoomInfo(){
|
||||
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
|
||||
this.room = room['room'];
|
||||
// this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
|
||||
// this.room = room['room'];
|
||||
|
||||
try {
|
||||
this.groupName = this.room.name.split('-').join(' ');
|
||||
} catch (error) {
|
||||
this.groupName = this.room.name;
|
||||
}
|
||||
// try {
|
||||
// this.groupName = this.room.name.split('-').join(' ');
|
||||
// } catch (error) {
|
||||
// this.groupName = this.room.name;
|
||||
// }
|
||||
|
||||
});
|
||||
// });
|
||||
}
|
||||
|
||||
close() {
|
||||
@@ -93,11 +91,11 @@ export class EditGroupPage implements OnInit {
|
||||
|
||||
updateGroup() {
|
||||
this.showLoader = true;
|
||||
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
|
||||
this.room = room['room'];
|
||||
this.showLoader = false;
|
||||
this.openGroupMessage.emit(this.room._id);
|
||||
});
|
||||
// this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
|
||||
// this.room = room['room'];
|
||||
// this.showLoader = false;
|
||||
// this.openGroupMessage.emit(this.room._id);
|
||||
// });
|
||||
}
|
||||
|
||||
_ionChange(event){
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Component, OnChanges, OnInit, Input, SimpleChanges, Output, EventEmitter, ViewChild, ElementRef, AfterViewInit, OnDestroy } from '@angular/core';
|
||||
import { AnimationController, ModalController, PopoverController, Platform } from '@ionic/angular';
|
||||
import { AlertService } from 'src/app/services/alert.service';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { GroupContactsPage } from './group-contacts/group-contacts.page';
|
||||
import { ChatOptionsFeaturesPage } from 'src/app/modals/chat-options-features/chat-options-features.page';
|
||||
import { TimeService } from 'src/app/services/functions/time.service';
|
||||
@@ -87,7 +86,6 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
|
||||
// public ChatSystemService: ChatSystemService,
|
||||
private modalController: ModalController,
|
||||
public popoverController: PopoverController,
|
||||
private chatService: ChatService,
|
||||
private animationController: AnimationController,
|
||||
private alertService: AlertService,
|
||||
private timeService: TimeService,
|
||||
@@ -156,9 +154,6 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
|
||||
message: '',
|
||||
status: status,
|
||||
}
|
||||
this.chatService.setUserStatus(body).subscribe(res => {
|
||||
//
|
||||
})
|
||||
}
|
||||
|
||||
scrollToBottom(): void {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<ion-header class="ion-no-border" >
|
||||
<ion-toolbar class="header-toolbar" >
|
||||
<div class="main-header" *ngIf="roomData$ | async as roomData">
|
||||
<div class="main-header">
|
||||
<div class="header-top">
|
||||
<div class="middle" >
|
||||
<ion-label class="title"> {{ roomData.roomName }}</ion-label>
|
||||
<ion-label class="title" *ngIf="roomData$ | async as roomData"> {{ roomData.roomName }}</ion-label>
|
||||
<!-- <button (click)="ChatMessageDebuggingPage()">Dev</button> -->
|
||||
<span *ngIf="roomStatus$ | async as roomStatus"><ion-icon *ngIf="roomStatus" class="online" name="ellipse"></ion-icon></span>
|
||||
</div>
|
||||
@@ -44,7 +44,7 @@
|
||||
<div class="messages height-100 width-100 d-flex flex-column" #scrollMe >
|
||||
|
||||
<div
|
||||
*ngFor="let message of messages1[roomId]" class="messages-list-item-wrapper"
|
||||
*ngFor="let message of messages1[roomId]; let messageIndex = index" class="messages-list-item-wrapper"
|
||||
[ngClass]="{'my-message': message.sender.wxUserId === sessionStore.user.UserId, 'other-message': message.sender.wxUserId !== sessionStore.user.UserId}"
|
||||
>
|
||||
<div class="message-container">
|
||||
@@ -67,7 +67,10 @@
|
||||
</div>
|
||||
|
||||
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Image">
|
||||
<img [src]="attachment.safeFile">
|
||||
<img
|
||||
[src]="attachment.safeFile"
|
||||
(load)="onImageLoad(message, messageIndex)"
|
||||
(error)="onImageError()">
|
||||
</div>
|
||||
|
||||
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Audio">
|
||||
|
||||
@@ -3,8 +3,6 @@ import { AnimationController, GestureController, IonRange, ModalController, Popo
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { ContactsPage } from '../new-group/contacts/contacts.page';
|
||||
import { ChatOptionsFeaturesPage } from 'src/app/modals/chat-options-features/chat-options-features.page';
|
||||
import { ChatMessageStore } from 'src/app/store/chat/chat-message.service';
|
||||
import { ChatUserStorage } from 'src/app/store/chat/chat-user.service';
|
||||
import { TimeService } from 'src/app/services/functions/time.service';
|
||||
import { FileService } from 'src/app/services/functions/file.service';
|
||||
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
|
||||
@@ -43,6 +41,7 @@ import { allowedDocExtension } from 'src/app/utils/allowedDocExtension';
|
||||
import { SpeakerService, StartRecordingResultError, StopRecordingResultError } from 'src/app/infra/speaker/speaker.service'
|
||||
import { compressImageBase64 } from 'src/app/utils/imageCompressore';
|
||||
import { ChatPopoverPage } from '../../modal/chat-popover/chat-popover.page';
|
||||
import { LastMessage } from '../../utils/lastMessage';
|
||||
|
||||
@Component({
|
||||
selector: 'app-messages',
|
||||
@@ -72,10 +71,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
@Output() getGroups: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
|
||||
|
||||
chatMessageStore = ChatMessageStore
|
||||
chatUserStorage = ChatUserStorage
|
||||
|
||||
scrollingOnce: boolean = true;
|
||||
private scrollChangeCallback: () => void;
|
||||
currentPosition: any;
|
||||
@@ -176,13 +171,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
this.listenToUpdateMessage();
|
||||
this.listenToSendMessage()
|
||||
|
||||
this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
|
||||
// this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
|
||||
this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) as any
|
||||
this.roomStatus$ = this.roomRepositoryService.getRoomStatus(this.roomId)
|
||||
this.roomRepositoryService.getRoomById(this.roomId)
|
||||
this.messageRepositoryService.listAllMessagesByRoomId(this.roomId).then(()=> {
|
||||
// this.getMessages();
|
||||
})
|
||||
|
||||
this.userTypingServiceRepository.getUserTypingLive().subscribe((e) => {
|
||||
const arrayNames = e.map(e => e.userName)
|
||||
@@ -202,11 +194,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
|
||||
this.messages1[this.roomId] = []
|
||||
this.messages1[this.roomId] = messages
|
||||
this.loadAttachment()
|
||||
|
||||
setTimeout(() => {
|
||||
this.scrollToBottomClicked()
|
||||
}, 200)
|
||||
this.messages1[this.roomId].push(LastMessage)
|
||||
|
||||
this.loadAttachment()
|
||||
|
||||
}
|
||||
|
||||
@@ -214,33 +205,32 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
for(const message of this.messages1[this.roomId]) {
|
||||
if(message.hasAttachment) {
|
||||
|
||||
const result = await this.chatServiceService.getMessageAttachmentByMessageId({
|
||||
$messageId: message.$id,
|
||||
id: message.attachments[0].id
|
||||
})
|
||||
|
||||
if(result.isOk()){
|
||||
if(message.$id) {
|
||||
console.log('message.$id', message.$id)
|
||||
this.chatServiceService.getMessageAttachmentByMessageId(message).then((result)=> {
|
||||
if(result.isOk()) {
|
||||
message.attachments[0].safeFile = result.value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Sorting function
|
||||
sortBySentAt (arr, order = 'asc') {
|
||||
return arr.sort((a, b) => {
|
||||
// Handle null or undefined sentAt
|
||||
const dateA = a.sentAt ? new Date(a.sentAt).getTime() : Number.MAX_VALUE;
|
||||
const dateB = b.sentAt ? new Date(b.sentAt).getTime() : Number.MAX_VALUE;
|
||||
|
||||
if (order === 'asc') {
|
||||
return dateA - dateB;
|
||||
} else {
|
||||
return dateB - dateA;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async onImageLoad(message: MessageEntity, index:number) {
|
||||
if(message.attachments[0].fileName == LastMessage.attachments[0].fileName) {
|
||||
|
||||
this.scrollToBottom()
|
||||
setTimeout(() => {
|
||||
this.scrollToBottom();
|
||||
}, 100)
|
||||
|
||||
this.messages1[this.roomId].splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
async onImageError() {}
|
||||
|
||||
|
||||
listenToIncomingMessage() {
|
||||
@@ -404,14 +394,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// this.ChatSystemService.getAllRooms();
|
||||
// this.chatService.refreshtoken();
|
||||
this.scrollToBottom();
|
||||
this.getChatMembers();
|
||||
|
||||
this.deleteRecording();
|
||||
// this.loadFiles();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController, NavParams, PopoverController } from '@ionic/angular';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
import { SetRoomOwnerPage } from 'src/app/modals/set-room-owner/set-room-owner.page';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController, NavParams, PickerController } from '@ionic/angular';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
|
||||
@Component({
|
||||
@@ -21,7 +20,6 @@ export class EditGroupPage implements OnInit {
|
||||
constructor(
|
||||
private modalController: ModalController,
|
||||
private pickerController: PickerController,
|
||||
private chatService: ChatService,
|
||||
private navParams: NavParams,
|
||||
public ThemeService: ThemeService
|
||||
) {
|
||||
@@ -34,16 +32,7 @@ export class EditGroupPage implements OnInit {
|
||||
}
|
||||
|
||||
getRoomInfo(){
|
||||
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
|
||||
this.room = room['room'];
|
||||
|
||||
try {
|
||||
this.groupName = this.room.name.split('-').join(' ');
|
||||
} catch(error) {
|
||||
this.groupName = this.room.name;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
close(){
|
||||
@@ -57,9 +46,6 @@ export class EditGroupPage implements OnInit {
|
||||
"roomId": this.room._id,
|
||||
"name": name,
|
||||
}
|
||||
this.chatService.renameGroup(body).subscribe(res=>{
|
||||
this.modalController.dismiss(res['group']);
|
||||
});
|
||||
}
|
||||
else{
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController, NavParams } from '@ionic/angular';
|
||||
import * as _ from 'lodash';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { GroupMessagesPage } from '../group-messages.page';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
@@ -39,10 +38,6 @@ export class GroupContactsPage implements OnInit {
|
||||
|
||||
constructor(
|
||||
private modalController: ModalController,
|
||||
private http: HttpClient,
|
||||
private chatService: ChatService,
|
||||
private authService: AuthService,
|
||||
private navParams: NavParams,
|
||||
public ThemeService: ThemeService,
|
||||
// public ChatSystemService: ChatSystemService,
|
||||
)
|
||||
@@ -122,18 +117,7 @@ export class GroupContactsPage implements OnInit {
|
||||
}
|
||||
|
||||
getMembers(){
|
||||
if(this.room.t == "p"){
|
||||
this.chatService.getGroupMembers(this.room._id).subscribe(res=>{
|
||||
this.members = res['members'];
|
||||
this.loadUsers();
|
||||
});
|
||||
}
|
||||
else if(this.room.t == "c"){
|
||||
this.chatService.getChannelMembers(this.room._id).subscribe(res=>{
|
||||
this.members = res['members'];
|
||||
this.loadUsers();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
separateLetter(record, recordIndex, records){
|
||||
@@ -157,16 +141,10 @@ export class GroupContactsPage implements OnInit {
|
||||
}
|
||||
|
||||
if(this.room.t == "p"){
|
||||
this.chatService.removeGroupMember(body).subscribe(res=>{
|
||||
|
||||
this.getMembers();
|
||||
});
|
||||
}
|
||||
else if(this.room.t == "c"){
|
||||
this.chatService.removeChannelMember(body).subscribe(res=>{
|
||||
|
||||
this.getMembers();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,10 +240,8 @@ export class GroupContactsPage implements OnInit {
|
||||
"userId":user._id,
|
||||
|
||||
}
|
||||
this.chatService.addUserToGroup(body).subscribe(res=>{
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loading = false
|
||||
@@ -277,14 +253,7 @@ export class GroupContactsPage implements OnInit {
|
||||
this.loading = true
|
||||
console.log('this.room', this.room)
|
||||
|
||||
this.chatService.getRoomInfo(this.room._id).subscribe(room=>{
|
||||
this.room = room['room'];
|
||||
this.addContacts(this.room);
|
||||
this.openGroupMessages(room['room']._id);
|
||||
this.loading = false
|
||||
}, ()=> {
|
||||
this.loading = false
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async openGroupMessages(roomId:any){
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, OnDestroy, ChangeDetectorRef, } from '@angular/core';
|
||||
import { ModalController, NavParams, PopoverController, Platform } from '@ionic/angular';
|
||||
import { AlertService } from 'src/app/services/alert.service';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { GroupContactsPage } from './group-contacts/group-contacts.page';
|
||||
import { Router } from '@angular/router'
|
||||
import { EditGroupPage } from '../edit-group/edit-group.page';
|
||||
@@ -13,7 +12,6 @@ import { EventPerson } from 'src/app/models/eventperson.model';
|
||||
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
import { ViewEventPage } from 'src/app/modals/view-event/view-event.page';
|
||||
//import { ChatSystemService } from 'src/app/services/chat/chat-system.service';
|
||||
import { FileType } from 'src/app/models/fileType';
|
||||
import { Storage } from '@ionic/storage';
|
||||
|
||||
@@ -32,7 +30,6 @@ import { RouteService } from 'src/app/services/route.service';
|
||||
import { FileValidatorService } from "src/app/services/file/file-validator.service"
|
||||
import { sanitize } from "sanitize-filename-ts";
|
||||
import { FilePicker } from '@capawesome/capacitor-file-picker';
|
||||
import { ViewDocumentSecondOptionsPage } from 'src/app/modals/view-document-second-options/view-document-second-options.page';
|
||||
import { NewEventPage } from 'src/app/pages/agenda/new-event/new-event.page';
|
||||
import { ChatPopoverPage } from '../chat-popover/chat-popover.page';
|
||||
import { ChatOptionsPopoverPage } from '../chat-options-popover/chat-options-popover.page';
|
||||
@@ -91,10 +88,6 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
constructor(
|
||||
private modalController: ModalController,
|
||||
public popoverController: PopoverController,
|
||||
private chatService: ChatService,
|
||||
private navParams: NavParams,
|
||||
private alertService: AlertService,
|
||||
private route: Router,
|
||||
private timeService: TimeService,
|
||||
private fileService: FileService,
|
||||
private toastService: ToastService,
|
||||
@@ -103,7 +96,6 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
private platform: Platform,
|
||||
//public ChatSystemService: ChatSystemService,
|
||||
private storage: Storage,
|
||||
private CameraService: CameraService,
|
||||
private sanitiser: DomSanitizer,
|
||||
private file: File,
|
||||
private fileOpener: FileOpener,
|
||||
@@ -1054,43 +1046,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
async serverLongPull() {
|
||||
this.chatService.getPrivateGroupMessages(this.roomId).subscribe(async res => {
|
||||
|
||||
if (res == 502) {
|
||||
// Connection timeout
|
||||
// happens when the connection was pending for too long
|
||||
// let's reconnect
|
||||
await this.serverLongPull();
|
||||
} else if (res != 200) {
|
||||
// Show Error
|
||||
//showMessage(response.statusText);
|
||||
//this.loadMessages()
|
||||
let msgOnly = res['messages'].filter(data => data.t != 'au');
|
||||
//this.messages = msgOnly.reverse();
|
||||
//
|
||||
this.transformDataMSG(msgOnly.reverse());
|
||||
// this.getRoomMessageDB(this.roomId);
|
||||
// Reconnect in one second
|
||||
if (this.route.url != "/home/chat") {
|
||||
|
||||
} else {
|
||||
//Check if modal is opened
|
||||
if (document.querySelector('.isGroupChatOpened')) {
|
||||
await new Promise(resolve => setTimeout(resolve, 5000)).catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
await this.serverLongPull();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Got message
|
||||
//let message = await response.text();
|
||||
//this.loadMessages()
|
||||
await this.serverLongPull();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sliderOpts = {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController, NavParams, PopoverController } from '@ionic/angular';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { ThemeService } from 'src/app/services/theme.service';
|
||||
|
||||
@Component({
|
||||
@@ -15,7 +14,6 @@ export class MessagesOptionsPage implements OnInit {
|
||||
constructor(
|
||||
private popoverController: PopoverController,
|
||||
private modalController: ModalController,
|
||||
private chatService: ChatService,
|
||||
private navParams: NavParams,
|
||||
public ThemeService: ThemeService,
|
||||
)
|
||||
@@ -40,9 +38,6 @@ export class MessagesOptionsPage implements OnInit {
|
||||
|
||||
closeChatRoom(){
|
||||
let body = { "roomId": this.roomId }
|
||||
this.chatService.removeChatRoom(body).subscribe(res=>{
|
||||
|
||||
});
|
||||
this.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController } from '@ionic/angular';
|
||||
import { ChatService } from 'src/app/services/chat.service';
|
||||
import { MessagesPage } from '../messages.page';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
|
||||
@@ -9,8 +7,7 @@ import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-
|
||||
import { UserContacts } from 'src/app/services/Repositorys/contacts/data-source/contacts-data-source.service';
|
||||
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { HttpRequest, HttpResponse } from '@angular/common/http';
|
||||
import { ZodError } from 'zod';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-contacts',
|
||||
@@ -38,7 +35,6 @@ export class ContactsPage implements OnInit {
|
||||
|
||||
constructor(
|
||||
private modalController: ModalController,
|
||||
private chatService: ChatService,
|
||||
public ThemeService: ThemeService,
|
||||
private contactsRepositoryService: ContactRepositoryService,
|
||||
private RoomRepositoryService: RoomRepositoryService,
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="middle-container" *ngIf="!showMessageOptions">
|
||||
<div class="middle" *ngIf="roomData$ | async as roomData">
|
||||
<ion-label class="title">{{ roomData.roomName }}</ion-label>
|
||||
<div class="middle" >
|
||||
<ion-label *ngIf="roomData$ | async as roomData" class="title">{{ roomData.roomName }}</ion-label>
|
||||
<span *ngIf="roomStatus$ | async as roomStatus"><ion-icon *ngIf="roomStatus"
|
||||
class="online" name="ellipse"></ion-icon></span>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { GestureController, ModalController, NavParams, PopoverController, Platform } from '@ionic/angular';
|
||||
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
|
||||
import { EventPerson } from 'src/app/models/eventperson.model';
|
||||
import { ExpedientTaskModalPageNavParamsTask } from 'src/app/models/ExpedientTaskModalPage';
|
||||
import { ContactsPage } from 'src/app/ui/chat/modal/messages/contacts/contacts.page';
|
||||
import { AlertService } from 'src/app/services/alert.service';
|
||||
import { FileService } from 'src/app/services/functions/file.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { ChatMessageStore } from 'src/app/store/chat/chat-message.service';
|
||||
import { ChatUserStorage } from 'src/app/store/chat/chat-user.service';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
|
||||
import { VoiceRecorder, GenericResponse } from 'capacitor-voice-recorder';
|
||||
@@ -16,15 +13,11 @@ import { Haptics, ImpactStyle } from '@capacitor/haptics';
|
||||
import { ViewEventPage } from 'src/app/modals/view-event/view-event.page';
|
||||
import { SearchPage } from 'src/app/pages/search/search.page';
|
||||
import { Storage } from '@ionic/storage';
|
||||
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
|
||||
import { CameraResultType } from '@capacitor/camera';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { ViewMediaPage } from 'src/app/modals/view-media/view-media.page';
|
||||
import { File } from '@awesome-cordova-plugins/file/ngx';
|
||||
import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx';
|
||||
import { Filesystem, Directory } from '@capacitor/filesystem';
|
||||
import { FileValidatorService } from "src/app/services/file/file-validator.service"
|
||||
import { FilePicker } from '@capawesome/capacitor-file-picker';
|
||||
|
||||
//======
|
||||
import { Observable as DexieObservable } from 'Dexie';
|
||||
import { Subscription } from 'rxjs';
|
||||
@@ -45,7 +38,11 @@ import { RecordingData } from 'capacitor-voice-recorder';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { MessagesOptionsPage } from '../messages-options/messages-options.page';
|
||||
import { ChatOptionsPopoverPage } from '../chat-options-popover/chat-options-popover.page';
|
||||
|
||||
import { CameraService } from 'src/app/infra/camera/camera.service'
|
||||
import { FilePickerMobileService } from 'src/app/infra/file-picker/mobile/file-picker-mobile.service'
|
||||
import { FilePickerWebService } from 'src/app/infra/file-picker/web/file-picker-web.service'
|
||||
import { allowedDocExtension } from 'src/app/utils/allowedDocExtension';
|
||||
import { JSFileToDataUrl } from 'src/app/utils/ToBase64';
|
||||
const IMAGE_DIR = 'stored-images';
|
||||
|
||||
@Component({
|
||||
@@ -57,7 +54,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
showLoader: boolean;
|
||||
|
||||
@ViewChild('scrollMe') private myScrollContainer: ElementRef;
|
||||
/* @ViewChild('messageContainer') messageContainer: ElementRef; */
|
||||
@ViewChild('rectangle') private rectangle: ElementRef;
|
||||
|
||||
canvas: any
|
||||
@@ -70,15 +66,10 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
members: any;
|
||||
scrollingOnce: boolean = true;
|
||||
|
||||
chatMessageStore = ChatMessageStore;
|
||||
chatUserStorage = ChatUserStorage;
|
||||
|
||||
private scrollChangeCallback: () => void;
|
||||
currentPosition: any;
|
||||
startPosition: number;
|
||||
scrollToBottomBtn = false;
|
||||
attendees: EventPerson[] = [];
|
||||
longPressActive = false;
|
||||
showMessageOptions = false;
|
||||
selectedMsgId: string;
|
||||
|
||||
@@ -146,14 +137,14 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
private platform: Platform,
|
||||
private storage: Storage,
|
||||
private sanitiser: DomSanitizer,
|
||||
private file: File,
|
||||
private fileOpener: FileOpener,
|
||||
private FileValidatorService: FileValidatorService,
|
||||
private roomRepositoryService: RoomRepositoryService,
|
||||
private messageRepositoryService: MessageRepositoryService,
|
||||
private userTypingServiceRepository: UserTypingServiceRepository,
|
||||
private chatServiceService: ChatServiceService,
|
||||
private FilePickerService: FilePickerService,
|
||||
private CameraService: CameraService,
|
||||
private FilePickerMobileService: FilePickerMobileService,
|
||||
private FilePickerWebService: FilePickerWebService
|
||||
) {
|
||||
|
||||
|
||||
@@ -169,23 +160,10 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.listenToSendMessage()
|
||||
|
||||
|
||||
this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
|
||||
// this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
|
||||
this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) as any
|
||||
this.roomStatus$ = this.roomRepositoryService.getRoomStatus(this.roomId)
|
||||
this.roomRepositoryService.getRoomById(this.roomId)
|
||||
|
||||
this.newMessagesStream?.unsubscribe()
|
||||
this.newMessagesStream = this.messageRepositoryService.subscribeToNewMessages(this.roomId).subscribe((e) => {
|
||||
|
||||
setTimeout(() => {
|
||||
this.scrollToBottomClicked()
|
||||
}, 200)
|
||||
|
||||
setTimeout(() => {
|
||||
this.scrollToBottomClicked()
|
||||
}, 500)
|
||||
|
||||
})
|
||||
// this.roomRepositoryService.getRoomById(this.roomId)
|
||||
|
||||
this.userTypingServiceRepository.getUserTypingLive().subscribe((e) => {
|
||||
const arrayNames = e.map(e => e.userName)
|
||||
@@ -218,10 +196,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
for(const message of this.messages1[this.roomId]) {
|
||||
if(message.hasAttachment) {
|
||||
|
||||
const result = await this.chatServiceService.getMessageAttachmentByMessageId({
|
||||
$messageId: message.$id,
|
||||
id: message.attachments[0].id
|
||||
})
|
||||
|
||||
const result = await this.chatServiceService.getMessageAttachmentByMessageId(message)
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
@@ -282,14 +258,11 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
listenToIncomingMessage() {
|
||||
this.messageReceiveSubject?.unsubscribe();
|
||||
this.messageReceiveSubject = this.chatServiceService.listenToIncomingMessage(this.roomId).subscribe(async (message) => {
|
||||
this.messages1[this.roomId].push(message as MessageEntity)
|
||||
this.messages1[this.roomId].unshift(message as MessageEntity)
|
||||
|
||||
if(message.hasAttachment) {
|
||||
|
||||
const result = await this.chatServiceService.getMessageAttachmentByMessageId({
|
||||
$messageId: message.$id,
|
||||
id: message.attachments[0].id
|
||||
})
|
||||
const result = await this.chatServiceService.getMessageAttachmentByMessageId(message)
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
@@ -734,33 +707,48 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
async takePictureMobile() {
|
||||
|
||||
this.addFileToChatMobile()
|
||||
const picture = await this.CameraService.takePicture({
|
||||
cameraResultType: CameraResultType.DataUrl,
|
||||
quality: 90
|
||||
})
|
||||
|
||||
if(picture.isOk()) {
|
||||
const file = picture.value
|
||||
|
||||
const compressedImage = await compressImageBase64(
|
||||
file.dataUrl,
|
||||
800, // maxWidth
|
||||
800, // maxHeight
|
||||
0.9 // quality
|
||||
)
|
||||
|
||||
if(compressedImage.isOk()) {
|
||||
|
||||
const message = new MessageEntity();
|
||||
message.roomId = this.roomId
|
||||
|
||||
message.sender = {
|
||||
userPhoto: '',
|
||||
wxeMail: SessionStore.user.Email,
|
||||
wxFullName: SessionStore.user.FullName,
|
||||
wxUserId: SessionStore.user.UserId
|
||||
}
|
||||
|
||||
message.attachments = [{
|
||||
file: compressedImage.value.split(',')[1],
|
||||
fileName: "foto",
|
||||
source: MessageAttachmentSource.Device,
|
||||
fileType: MessageAttachmentFileType.Image,
|
||||
mimeType: 'image/'+picture.value.format
|
||||
}]
|
||||
|
||||
this.messages1[this.roomId].push(message)
|
||||
this.chatServiceService.sendMessage(message)
|
||||
|
||||
}
|
||||
|
||||
dataURItoBlob(dataURI) {
|
||||
// convert base64 to raw binary data held in a string
|
||||
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
|
||||
var byteString = atob(dataURI.split(',')[1]);
|
||||
|
||||
// separate out the mime component
|
||||
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
|
||||
|
||||
// write the bytes of the string to an ArrayBuffer
|
||||
var ab = new ArrayBuffer(byteString.length);
|
||||
|
||||
// create a view into the buffer
|
||||
var ia = new Uint8Array(ab);
|
||||
|
||||
// set the bytes of the buffer to the correct values
|
||||
for (var i = 0; i < byteString.length; i++) {
|
||||
ia[i] = byteString.charCodeAt(i);
|
||||
}
|
||||
|
||||
// write the ArrayBuffer to a blob, and you're done
|
||||
var blob = new Blob([ab], { type: mimeString });
|
||||
return blob;
|
||||
|
||||
}
|
||||
|
||||
@@ -856,6 +844,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
} else {
|
||||
if(file.error.type == 'PERMISSION_DENIED') {
|
||||
this.toastService._badRequest("Sem acesso a camera")
|
||||
}
|
||||
Logger.error('failed to pick picture from the device', {
|
||||
error: file.error
|
||||
})
|
||||
@@ -863,79 +854,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
}
|
||||
|
||||
async addFileToChatMobile() {
|
||||
const roomId = this.roomId
|
||||
|
||||
const file = await Camera.getPhoto({
|
||||
quality: 90,
|
||||
// allowEditing: true,
|
||||
resultType: CameraResultType.Base64,
|
||||
source: CameraSource.Photos
|
||||
});
|
||||
|
||||
//const imageData = await this.fileToBase64Service.convert(file)
|
||||
//
|
||||
|
||||
var imageBase64 = 'data:image/jpeg;base64,' + file.base64String
|
||||
|
||||
|
||||
const compressedImage = await this.compressImageBase64(
|
||||
imageBase64,
|
||||
800, // maxWidth
|
||||
800, // maxHeight
|
||||
0.9 // quality
|
||||
).then((picture) => {
|
||||
console.log('Selected: ', picture)
|
||||
imageBase64 = picture
|
||||
});
|
||||
|
||||
//console.log(imageBase64)
|
||||
|
||||
const response = await fetch(imageBase64);
|
||||
const blob = await response.blob();
|
||||
|
||||
const formData = new FormData();
|
||||
//console.log('add file', formData)
|
||||
formData.append("blobFile", blob);
|
||||
//console.log('add file', formData)
|
||||
|
||||
// this.ChatSystemService.getDmRoom(roomId).send({
|
||||
// file: {
|
||||
// "type": "application/img",
|
||||
// "guid": ''
|
||||
// },
|
||||
// temporaryData: formData,
|
||||
// attachments: [{
|
||||
// "title": file.path,
|
||||
// "text": "description",
|
||||
// "title_link_download": false,
|
||||
// }],
|
||||
// attachmentsModelData: {
|
||||
// fileBase64: imageBase64,
|
||||
// }
|
||||
// })
|
||||
|
||||
}
|
||||
|
||||
getFileReader(): FileReader {
|
||||
const fileReader = new FileReader();
|
||||
const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"];
|
||||
return zoneOriginalInstance || fileReader;
|
||||
}
|
||||
|
||||
|
||||
_getBase64(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = function () {
|
||||
resolve(reader.result)
|
||||
};
|
||||
reader.onerror = function (error) {
|
||||
console.log('Error: ', error);
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
async addFileToChat(types) {
|
||||
console.log('add file ')
|
||||
@@ -944,14 +862,15 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
if (this.platform.is('ios')) {
|
||||
console.log('ios add file ')
|
||||
|
||||
const resultt = await FilePicker.pickFiles({
|
||||
const result = await this.FilePickerMobileService.getFile({
|
||||
types: ['application/pdf', 'application/doc', 'application/docx','application/xls', 'application/xlsx', 'application/ppt',
|
||||
'application/pptx', 'application/txt'],
|
||||
multiple: false,
|
||||
readData: true,
|
||||
});
|
||||
})
|
||||
|
||||
console.log('RESULT', resultt.files[0].data)
|
||||
if(result.isOk()) {
|
||||
console.log('RESULT', result.value.files[0].data)
|
||||
|
||||
const message = new MessageEntity();
|
||||
message.roomId = this.roomId
|
||||
@@ -964,8 +883,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
message.attachments = [{
|
||||
file: resultt.files[0].data,
|
||||
fileName: resultt.files[0].name,
|
||||
file: result.value.files[0].data,
|
||||
fileName: result.value.files[0].name,
|
||||
source: MessageAttachmentSource.Device,
|
||||
fileType: MessageAttachmentFileType.Doc
|
||||
}]
|
||||
@@ -974,28 +893,27 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.chatServiceService.sendMessage(message)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const file = await this.fileService.getFileFromDevice(types);
|
||||
const file = await this.FilePickerWebService.getFileFromDevice(types)
|
||||
|
||||
if(file.isOk()) {
|
||||
|
||||
console.log(file)
|
||||
|
||||
|
||||
const fileName = file.name
|
||||
const fileName = file.value.name
|
||||
|
||||
const validation = this.FileValidatorService.fileNameValidation(fileName)
|
||||
const validation = await allowedDocExtension(fileName)
|
||||
|
||||
if (validation.isOk) {
|
||||
if (validation.isOk()) {
|
||||
|
||||
const encodedData = btoa(JSON.stringify(await this.getBase64(file).catch((error) => {
|
||||
console.error(error);
|
||||
})));
|
||||
console.log(encodedData)
|
||||
const blob = this.fileService.base64toBlob(encodedData, file.type)
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('blobFile', blob);
|
||||
let fileBase64 = await JSFileToDataUrl(file.value);
|
||||
|
||||
if(fileBase64.isOk()) {
|
||||
|
||||
const message = new MessageEntity();
|
||||
message.roomId = this.roomId
|
||||
@@ -1008,34 +926,24 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
message.attachments = [{
|
||||
file: encodedData,
|
||||
fileName: file.name,
|
||||
file: fileBase64.value.split(',')[1],
|
||||
fileName: file.value.name,
|
||||
source: MessageAttachmentSource.Device,
|
||||
fileType: MessageAttachmentFileType.Doc,
|
||||
mimeType: file.type
|
||||
mimeType: file.value.type
|
||||
}]
|
||||
|
||||
this.messages1[this.roomId].push(message)
|
||||
this.chatServiceService.sendMessage(message)
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
this.toastService._badRequest("Ficheiro inválido")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getBase64(file) {
|
||||
var reader = this.getFileReader();
|
||||
reader.readAsDataURL(file);
|
||||
return new Promise(resolve => {
|
||||
reader.onload = function () {
|
||||
resolve(reader.result)
|
||||
};
|
||||
reader.onerror = function (error) {
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async openChatOptions(ev?: any) {
|
||||
@@ -1085,40 +993,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
|
||||
|
||||
b64toBlob(b64Data, contentType) {
|
||||
contentType = contentType || '';
|
||||
var sliceSize = 512;
|
||||
b64Data = b64Data.replace(/^[^,]+,/, '');
|
||||
b64Data = b64Data.replace(/\s/g, '');
|
||||
var byteCharacters = window.atob(b64Data);
|
||||
var byteArrays = [];
|
||||
|
||||
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
||||
var slice = byteCharacters.slice(offset, offset + sliceSize);
|
||||
|
||||
var byteNumbers = new Array(slice.length);
|
||||
for (var i = 0; i < slice.length; i++) {
|
||||
byteNumbers[i] = slice.charCodeAt(i);
|
||||
}
|
||||
|
||||
var byteArray = new Uint8Array(byteNumbers);
|
||||
|
||||
byteArrays.push(byteArray);
|
||||
}
|
||||
|
||||
var blob = new Blob(byteArrays, { type: contentType });
|
||||
return blob;
|
||||
}
|
||||
|
||||
blobToBase64(blob) {
|
||||
return new Promise((resolve, _) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => resolve(reader.result);
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
async openFile(pdfString, filename, type) {
|
||||
|
||||
console.log('url while open ',pdfString)
|
||||
@@ -1135,43 +1009,43 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
/*
|
||||
await modal.present(); */
|
||||
|
||||
var blob = new Blob([pdfString], { type: 'application/pdf' });
|
||||
// var blob = new Blob([pdfString], { type: 'application/pdf' });
|
||||
|
||||
console.log('blob blob', blob)
|
||||
// console.log('blob blob', blob)
|
||||
|
||||
this.blobToBase64(blob).then((value) => {
|
||||
console.log(value)
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
// this.blobToBase64(blob).then((value) => {
|
||||
// console.log(value)
|
||||
// }).catch((error) => {
|
||||
// console.log(error)
|
||||
// })
|
||||
|
||||
let pathFile = ''
|
||||
const fileName = filename
|
||||
if (this.platform.is('ios')) {
|
||||
pathFile = this.file.documentsDirectory
|
||||
} else {
|
||||
pathFile = this.file.externalRootDirectory
|
||||
}
|
||||
// let pathFile = ''
|
||||
// const fileName = filename
|
||||
// if (this.platform.is('ios')) {
|
||||
// pathFile = this.file.documentsDirectory
|
||||
// } else {
|
||||
// pathFile = this.file.externalRootDirectory
|
||||
// }
|
||||
|
||||
console.log('file data', pdfString)
|
||||
console.log(pathFile)
|
||||
// console.log('file data', pdfString)
|
||||
// console.log(pathFile)
|
||||
|
||||
let removePre = this.removeTextBeforeSlash(pdfString,',')
|
||||
console.log('file data remove ', removePre)
|
||||
// let removePre = this.removeTextBeforeSlash(pdfString,',')
|
||||
// console.log('file data remove ', removePre)
|
||||
|
||||
await Filesystem.writeFile({
|
||||
path: fileName,
|
||||
data: removePre,
|
||||
directory: Directory.Cache,
|
||||
}).then((dir) => {
|
||||
console.log('DIR ', dir)
|
||||
this.fileOpener
|
||||
.open(dir.uri, type)
|
||||
.then(() => console.log())
|
||||
.catch(e => console.error(e))
|
||||
}).catch((error) => {
|
||||
console.log('error writing the file', error)
|
||||
});
|
||||
// await Filesystem.writeFile({
|
||||
// path: fileName,
|
||||
// data: removePre,
|
||||
// directory: Directory.Cache,
|
||||
// }).then((dir) => {
|
||||
// console.log('DIR ', dir)
|
||||
// this.fileOpener
|
||||
// .open(dir.uri, type)
|
||||
// .then(() => console.log())
|
||||
// .catch(e => console.error(e))
|
||||
// }).catch((error) => {
|
||||
// console.log('error writing the file', error)
|
||||
// });
|
||||
}
|
||||
|
||||
removeTextBeforeSlash(inputString, controlString) {
|
||||
@@ -1273,52 +1147,16 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
}
|
||||
|
||||
async compressImageBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new (window as any).Image();
|
||||
image.src = base64String;
|
||||
|
||||
image.onload = async () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
let newWidth = image.width;
|
||||
let newHeight = image.height;
|
||||
|
||||
if (newWidth > maxWidth) {
|
||||
newHeight *= maxWidth / newWidth;
|
||||
newWidth = maxWidth;
|
||||
}
|
||||
|
||||
if (newHeight > maxHeight) {
|
||||
newWidth *= maxHeight / newHeight;
|
||||
newHeight = maxHeight;
|
||||
}
|
||||
|
||||
canvas.width = newWidth;
|
||||
canvas.height = newHeight;
|
||||
|
||||
const context = canvas.getContext('2d');
|
||||
context?.drawImage(image, 0, 0, newWidth, newHeight);
|
||||
|
||||
const compressedBase64 = canvas.toDataURL('image/jpeg', quality);
|
||||
resolve(compressedBase64);
|
||||
};
|
||||
|
||||
image.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
dataURItoBlobIso(dataURI: any) {
|
||||
const byteString = window.atob(dataURI);
|
||||
const arrayBuffer = new ArrayBuffer(byteString.length);
|
||||
const int8Array = new Uint8Array(arrayBuffer);
|
||||
for (let i = 0; i < byteString.length; i++) {
|
||||
int8Array[i] = byteString.charCodeAt(i);
|
||||
}
|
||||
const blob = new Blob([int8Array], { type: 'application/pdf' });
|
||||
return blob;
|
||||
}
|
||||
// dataURItoBlobIso(dataURI: any) {
|
||||
// const byteString = window.atob(dataURI);
|
||||
// const arrayBuffer = new ArrayBuffer(byteString.length);
|
||||
// const int8Array = new Uint8Array(arrayBuffer);
|
||||
// for (let i = 0; i < byteString.length; i++) {
|
||||
// int8Array[i] = byteString.charCodeAt(i);
|
||||
// }
|
||||
// const blob = new Blob([int8Array], { type: 'application/pdf' });
|
||||
// return blob;
|
||||
// }
|
||||
|
||||
|
||||
messageDelete(message: MessageEntity) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "src/app/module/chat/data/dto/message/messageOutputDTO";
|
||||
import { MessageEntity } from "src/app/module/chat/domain/entity/message";
|
||||
import { SessionStore } from "src/app/store/session.service";
|
||||
|
||||
export const LastMessage = new MessageEntity()
|
||||
|
||||
LastMessage.sentAt = new Date().toISOString()
|
||||
|
||||
LastMessage.message = 'last'
|
||||
LastMessage.sender = {
|
||||
userPhoto: '',
|
||||
wxeMail: SessionStore.user.Email,
|
||||
wxFullName: SessionStore.user.FullName,
|
||||
wxUserId: SessionStore.user.UserId
|
||||
}
|
||||
|
||||
LastMessage.attachments = [{
|
||||
safeFile: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/wcAAwAB/BO5RfQAAAAASUVORK5CYII=',
|
||||
fileName: "lastMessageUUID",
|
||||
source: MessageAttachmentSource.Device,
|
||||
fileType: MessageAttachmentFileType.Image,
|
||||
mimeType: 'image/png',
|
||||
}]
|
||||
@@ -70,6 +70,7 @@ export function createDataURL(base64String: string, mimeType: string): string {
|
||||
* Converts a `Blob` to a Data URL.
|
||||
* @param {Blob} blob - The `Blob` to be converted.
|
||||
* @returns {Promise<string>} A promise that resolves with the Data URL representation of the `Blob`.
|
||||
* @example const result = 'data:audio/aac;base64,ZGF0YTphdWRpby9hYWM7YmFzZTY0…RnNRQmxmL0FGQUl'
|
||||
*/
|
||||
export function convertBlobToDataURL(blob: Blob): Promise<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
|
||||
Reference in New Issue
Block a user