Merge branch 'feature/downloadFile' of bitbucket.org:equilibriumito/gabinete-digital into tempFile

This commit is contained in:
tiago.kayaya
2022-03-21 17:39:52 +01:00
32 changed files with 1335 additions and 833 deletions
+1
View File
@@ -52,3 +52,4 @@ node_modules_
node_modules__
plugins_
ios
src/plugin/beast-orm
@@ -0,0 +1,5 @@
package com.capacitorjs.app.testapp;
import com.getcapacitor.BridgeActivity;
public class MainActivity extends BridgeActivity {}
+54 -5
View File
@@ -2202,6 +2202,21 @@
"integrity": "sha512-HCFwOxmK7igEgNm20y+zYi+XQ0OlZYnE4oCaI82TGmA7sehlDpBBKbjmI2Bd8aM09+BXFbAAtq7JCxkEfY8nIg=="
},
"@capacitor/filesystem": {
<<<<<<< HEAD
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-1.0.6.tgz",
"integrity": "sha512-8xqUbDZFGBMhgqoBSn9wEd9OBPdHIRegQ9zCCZcpHNf3FFAIby1ck+aDFnoq+Da49xhD6ks1SKCBSxz/26qWTw=="
},
"@capacitor/haptics": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-1.1.3.tgz",
"integrity": "sha512-ui2mY/riK1Y4bxnJKJfclWO61obZ0RHmtErPhpmt4wIEVjG1segYdFop45R2PxyEwoUJgzEsAxnviM/T6k8seQ=="
},
"@capacitor/ios": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-3.3.0.tgz",
"integrity": "sha512-KImT4hVoQJuAfe01wUYiMLnutMu7PxVCv4c8HVWiW+OuyyOua3lC8wQ5gAauGDugAo6mdM7fVva5a0Vtyhnbdg=="
=======
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-1.1.0.tgz",
"integrity": "sha512-8O3UuvL8HNUEJvZnmn8yUmvgB1evtXfcF0oxIo3YbSlylqywJwS3JTiuhKmsvSxCdpbTy8IaTsutVh3gZgWbKg=="
@@ -2215,6 +2230,7 @@
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-3.4.1.tgz",
"integrity": "sha512-ycFCyKI8DsgedVg7PW5MpCVgqFuD0PMHQGVfC5ichXc2C/jAATX32EVdEMCB0N3guKoH2k6T3Efwg59+Fcdx2w=="
>>>>>>> 0b14c4c0c63a6d55c9945163d7afb971a7375994
},
"@capacitor/keyboard": {
"version": "1.1.3",
@@ -2997,6 +3013,16 @@
"integrity": "sha512-68hdPn0hA7yn4YNTgmLF32x/l7arFulboGhNiyFQ35/QxqrOmppf77p4xaPOyJtNyICKHLaiStC6w1eEAtl9MA==",
"requires": {
"@types/cordova": "^0.0.34"
<<<<<<< HEAD
},
"dependencies": {
"@types/cordova": {
"version": "0.0.34",
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
}
=======
>>>>>>> 0b14c4c0c63a6d55c9945163d7afb971a7375994
}
},
"@ionic-native/core": {
@@ -4917,11 +4943,6 @@
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
"dev": true
},
"@types/cordova": {
"version": "0.0.34",
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
},
"@types/cors": {
"version": "2.8.12",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
@@ -6229,6 +6250,11 @@
"tweetnacl": "^0.14.3"
}
},
"beast-orm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/beast-orm/-/beast-orm-1.0.0.tgz",
"integrity": "sha512-wSholUbFMteq50U3QM0o4H3xY9IpevpG9MPlq0ZK8yRtRkIuKf/YoZW4QUwFOfY72PJbNzp68z7Ln/iFhpOxDg=="
},
"big-integer": {
"version": "1.6.49",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz",
@@ -16542,6 +16568,29 @@
"tslib": "^2.3.0"
}
},
<<<<<<< HEAD
"ng2-pdf-viewer": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-3.0.8.tgz",
"integrity": "sha512-p2qndFu1wQW4y+xXXw7yk1BhpRo5PGHKWD3PTc7pUULujx9d2vT26lhXR3p9WHitySadGqdCQpkA7W3v1dBlSg==",
"requires": {
"@types/pdfjs-dist": "^0.1.1",
"pdfjs-dist": "1.9.489"
},
"dependencies": {
"pdfjs-dist": {
"version": "1.9.489",
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-1.9.489.tgz",
"integrity": "sha1-yuWf7d0WouXRlappUnlVz+QALB0=",
"requires": {
"node-ensure": "^0.0.0",
"worker-loader": "^0.8.0"
}
}
}
},
=======
>>>>>>> 0b14c4c0c63a6d55c9945163d7afb971a7375994
"ngx-cookie-service": {
"version": "12.0.3",
"resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-12.0.3.tgz",
+1
View File
@@ -99,6 +99,7 @@
"angular-svg-icon": "^12.0.0",
"angular-tag-cloud-module": "^5.2.2",
"base64-js": "^1.5.1",
"beast-orm": "^1.0.0",
"bootstrap": "^4.5.0",
"build": "0.1.4",
"capacitor-voice-recorder": "^2.1.0",
+1 -1
View File
@@ -12,7 +12,7 @@ import { SqliteService } from 'src/app/services/sqlite.service';
import { BackgroundService } from 'src/app/services/background.service';
import { ScreenOrientation } from '@ionic-native/screen-orientation/ngx';
import { StorageService } from 'src/app/services/storage.service';
import { MessageModel } from './models/beast-orm'
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
@@ -120,7 +120,7 @@ export class ChatOptionsFeaturesPage implements OnInit {
}
this.chatService.sendMessage(body).subscribe(res=> {
console.log(res);
// console.log(res);
},(error) => {
});
+44
View File
@@ -0,0 +1,44 @@
import { models } from 'beast-orm'
import { AESEncrypt } from '../services/aesencrypt.service'
const _AESEncrypt = new AESEncrypt()
const { ArrayField, JsonField} = models.indexedDB.fields
export class MessageModel extends models.Model {
channels = ArrayField()
mentions = ArrayField()
msg = models.CharField()
rid = models.CharField()
ts = models.CharField()
u = JsonField()
_id = models.CharField({unique:true})
_updatedAt = models.CharField()
messageSend = models.BooleanField()
offline = models.BooleanField()
viewed = ArrayField()
received = ArrayField()
localReference = models.CharField({blank:true})
attachments = ArrayField()
file = ArrayField()
}
export class DeleteMessageModel extends models.Model {
messageId = models.IntegerField()
rid = models.CharField()
ts = models.CharField()
u = JsonField()
needToReceiveBy = ArrayField()
}
models.register({
databaseName: 'chat-storage',
type: 'indexedDB',
version: 1,
models: [MessageModel, DeleteMessageModel]
})
+126 -121
View File
@@ -67,6 +67,7 @@ interface FirstUnread {
export interface Message {
customFields:any;
_id: string;
id: null | string;
rid: string;
msg: string;
ts: Ts;
@@ -81,7 +82,11 @@ export interface Message {
editedBy: EditedBy;
urls: any[];
temporaryData: object
localReference?: string
localReference?: string,
viewed: string[],
received: string[],
delate: boolean,
delateRequest: boolean
}
@@ -174,159 +179,159 @@ export interface chatHistory {
interface Ts {
$date: any;
$date: any;
}
interface U {
_id: string;
username: string;
name: string;
_id: string;
username: string;
name: string;
}
interface UpdatedAt {
$date: any;
$date: any;
}
interface Attachment {
ts: Date;
title_link_download: boolean;
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;
type: string;
guid: string;
image_url: string;
subject: string;
start_date?: Date;
end_date?: Date;
venue: string;
id: string;
}
interface EditedAt {
$date: number;
$date: number;
}
interface EditedBy {
_id: string;
username: string;
_id: string;
username: string;
}
interface Ts2 {
$date: number;
$date: number;
}
interface U2 {
_id: string;
username: string;
name: string;
_id: string;
username: string;
name: string;
}
interface UpdatedAt2 {
$date: number;
$date: number;
}
interface FirstUnread {
_id: string;
rid: string;
msg: string;
ts: Ts2;
u: U2;
_updatedAt: string;
mentions: any[];
channels: any[];
_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[];
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;
$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[];
_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;
_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;
$date: any;
}
export interface Remove {
_id: string;
_deletedAt: DeletedAt;
_id: string;
_deletedAt: DeletedAt;
}
export interface Result {
update: Update[];
remove: Remove[];
update: Update[];
remove: Remove[];
}
export interface Rooms {
msg: string;
id: string;
result: Result;
msg: string;
id: string;
result: Result;
}
export interface ChatMessage {
msg: string;
id: string;
result: Message
msg: string;
id: string;
result: Message
}
@@ -334,44 +339,44 @@ export interface ChatMessage {
export interface chatHistory {
msg: string;
id: string;
result: {
messages: Message[];
firstUnread: FirstUnread;
unreadNotLoaded: number;
};
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: string;
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;
_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;
}
+54 -4
View File
@@ -1,4 +1,54 @@
export interface Message {
author: string;
message: string;
}
export interface IncomingChatMessage {
msg: string;
collection: string;
id: string;
fields: {
args: {
_id: string;
rid: string;
localReference: string;
msg: string;
file?: any;
ts: {
$date: number;
};
u: {
_id: string;
username: string;
name: string;
};
_updatedAt: {
$date: number;
};
mentions: any[];
channels: any[];
} [];
}
eventName: string;
};
export interface ChatMessageInterface {
_id: string;
rid: string;
localReference: string;
msg: string;
file?: any;
ts: number;
u: {
_id: string;
username: string;
name: string;
};
_updatedAt: number;
mentions: any[];
channels: any[];
};
export interface falseTypingMethod{
method: 'viewMessage' | 'deleteMessage'
params: object
}
-5
View File
@@ -20,7 +20,6 @@ import { NewGroupPage } from './new-group/new-group.page';
import { Storage } from '@ionic/storage';
import { EditGroupPage } from 'src/app/shared/chat/edit-group/edit-group.page';
import * as Rx from "rxjs/Rx";
import { Message } from 'src/app/models/message.model';
import { Observable, Subject } from "rxjs/Rx";
import { NavigationStart, NavigationEnd, Router } from '@angular/router';
import { EventPerson } from 'src/app/models/eventperson.model';
@@ -143,10 +142,6 @@ export class ChatPage implements OnInit {
ngOnInit() {
console.log('Rooms INDIVIDUAIS',this.wsChatMethodsService._dm);
console.log(' ROOMS GROUP',this.wsChatMethodsService._group);
this.segment = "Contactos";
this.authService.userData$.subscribe((res: any) => {
@@ -190,8 +190,9 @@
</ion-content>
<ion-footer>
<div class="typing" >
<ngx-letters-avatar
<div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true">
<ngx-letters-avatar *ngIf="showAvatar"
[avatarName]= "wsChatMethodsService.getGroupRoom(roomId).name"
[width]="30"
[circular]="true"
@@ -85,6 +85,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
audioDownloaded:any = "";
durationDisplay = '';
duration = 0;
showAvatar = true;
constructor(
private menu: MenuController,
@@ -129,6 +130,14 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.scrollToBottomClicked()
}, 50)
this.showAvatar = false
setTimeout(() => {
this.scrollToBottomClicked()
this.showAvatar = true
}, 150)
}
ngOnInit() {
@@ -195,7 +195,7 @@
</ion-toolbar>
</ion-footer> -->
<ion-footer>
<ion-footer >
<div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true">
@@ -517,8 +517,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.chatService.getMembers(this.roomId).subscribe(res => {
this.members = res['members'];
this.dmUsers = res['members'].filter(data => data.username != this.loggedUser.me.username)
console.log(res);
console.log(this.dmUsers);
this.showLoader = false;
});
}
@@ -39,7 +39,6 @@
<div class="content-location">
<p>
<span class="location">{{loadedEvent.workflowInstanceDataFields.Location}}</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Oficial MDGPR' " style="background-color: #ffb703;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
@@ -54,7 +53,6 @@
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Pessoal PR' " style="background-color: #958bfc;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
</p>
</div>
<div class="content-details">
@@ -68,7 +66,6 @@
</div>
</div>
<div class="line"></div>
<div class="overflow-y-auto">
<div class="middle-content">
<div *ngIf="loadedEvent.workflowInstanceDataFields.ParticipantsList">
@@ -86,7 +83,6 @@
<div class="line"></div>
</div>
</div>
<div *ngIf="loadedEvent.Documents" class="bottom-content width-100">
<ion-list>
<h5>Documentos Anexados</h5>
-1
View File
@@ -44,7 +44,6 @@ export class AESEncrypt {
//Decrypting the string contained in cipherParams using the PBKDF2 key
var decrypted = CryptoJS.AES.decrypt(cipherParams, key128Bits1000Iterations, { mode: CryptoJS.mode.CBC, iv: iv, padding: CryptoJS.pad.Pkcs7 });
console.log('AES decrypt',decrypted.toString(CryptoJS.enc.Utf8));
return decrypted.toString(CryptoJS.enc.Utf8);
}
+2
View File
@@ -19,6 +19,7 @@ export class AttachmentsService {
constructor(private http: HttpClient, private platform: Platform, private file: File) {
this.loggeduser = SessionStore.user
this.headers = new HttpHeaders();
this.headers = this.headers.set('Authorization', SessionStore.user.BasicAuthKey);
}
@@ -96,6 +97,7 @@ export class AttachmentsService {
headers: this.headers,
params: params
};
return this.http.get<Attachment[]>(`${geturl}`, options);
}
+15 -12
View File
@@ -51,7 +51,7 @@ export class AuthService {
if (SessionStore.exist) {
this.ValidatedUser = SessionStore.user
console.log('login', SessionStore.user.RochetChatUser, SessionStore.user.Password)
// console.log('login', SessionStore.user.RochetChatUser, SessionStore.user.Password)
this.loginToChatWs()
}
@@ -138,7 +138,7 @@ export class AuthService {
this.autoLoginChat(expirationDate.getTime() - date);
}
async autoLoginChat(expirationDate:number){
async autoLoginChat(expirationDate:number) {
setTimeout(()=>{
this.loginChat();
}, expirationDate)
@@ -148,14 +148,18 @@ export class AuthService {
setTimeout(()=>{
this.WsChatService.connect();
this.WsChatService.login().then((message) => {
console.log('rocket chat login successfully', message)
this.WsChatService.login().then((message: any) => {
SessionStore.user.RochetChatUserId = message.result.id
SessionStore.save()
this.WsChatService.setStatus('online')
}).catch((message)=>{
}).catch((message) => {
console.log('rocket chat login failed', message)
})
// before sending a message with a attachment
this.NfService.beforeSendAttachment = async (message: MessageService, room?: RoomService) => {
if(message.hasFile) {
@@ -165,16 +169,14 @@ export class AuthService {
try {
let guid: any = await this.AttachmentsService.uploadFile(formData).toPromise()
message.file.guid = guid.path
await this.storage.set(guid.path, message.file.image_url).then(() => {
console.log('add picture to chat IMAGE SAVED')
console.log(message.attachments);
message.getFileFromDb()
});
// await this.storage.set(guid.path, message.file.image_url).then(() => {
// console.log('add picture to chat IMAGE SAVED')
// // message.getFileFromDb()
// });
return true
} catch(e) {
console.log(e)
console.log('failed to upload to server', e)
return false
}
@@ -227,6 +229,7 @@ export class AuthService {
return false
}
};
}, 1)
}
+2 -3
View File
@@ -6,8 +6,7 @@ import { StorageService } from './storage.service';
import { HttpClient, HttpHeaderResponse } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { Storage } from '@ionic/storage';
import { Message } from 'src/app/models/message.model';
import { Observable, Subject } from "rxjs/Rx";
@Injectable({
providedIn: 'root'
@@ -120,7 +119,7 @@ export class ChatService {
return this.http.get(environment.apiChatUrl+'im.history', opts);
}
sendMessage(body:any){
sendMessage(body:any) {
let opts = {
headers: this.headers,
}
+29 -2
View File
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { ChatService } from '../chat.service';
import { v4 as uuidv4 } from 'uuid'
@Injectable({
providedIn: 'root'
@@ -17,7 +18,7 @@ export class ChatMethodsService {
{
"rid": roomId,
"msg":"",
"file":{
"file": {
"type": "application/meeting",
"subject": data.subject,
"start_date": data.start,
@@ -29,4 +30,30 @@ export class ChatMethodsService {
}
this.chatService.sendMessage(body).subscribe(res=> {});
}
}
send({roomId, msg, attachments = null, file = null, localReference = null}) {
let body = {
"message":
{
rid: roomId,
localReference: localReference,
msg: msg,
attachments,
file
}
}
return this.chatService.sendMessage(body)
}
deleteMessage(body) {
return this.chatService.deleteMessage(body)
}
}
+153 -131
View File
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
@@ -10,161 +11,182 @@ export class ChatStorageService {
private storage: Storage,
) { }
/**
/**
* @description delete message in the DB. get all messages, delete then corresponding message and update the store
* @param id message ID
*/
private deleteMessageFromDb(messageId, roomId) {
this.storage.get('chatmsg' + roomId).then((messages: any = []) => {
async deleteMessageFromDb(messageId, roomId) {
if (environment.chatOffline) {
await this.storage.get('chatmsg' + roomId).then(async(messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
}
messages.forEach((message, index) => {
await messages.forEach( async (message, index) => {
if(message._id == messageId) {
messages.splice(index, 1)
}
})
this.storage.set('chatmsg' + roomId, messages).then((value) => {
console.log('MSG SAVED ON STORAGE', value)
// console.log('MSG SAVED ON STORAGE', value)
});
})
}
}
async updateMessageDB(ChatMessage, roomId, identificator) {
if (environment.chatOffline) {
await this.storage.get('chatmsg' + roomId).then(async(messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
}
let index;
const find = messages.find((message, _index)=> {
if(message?.localReference == ChatMessage?.localReference ||
message?._id == ChatMessage?._id) {
index = _index
return true
}
return false
})
if(find) {
messages[index] = Object.assign(messages[index], ChatMessage)
await this.storage.set('chatmsg' + roomId, messages)
} else {
// console.log('failed to update', identificator, ':',ChatMessage)
}
})
}
}
getMsgFromDB() {
async updateChat(history, roomId, identificator = '_id') {
if (environment.chatOffline) {
await this.storage.get('chatmsg' + roomId).then(async(messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
}
/* this.storage.get('chatmsg' + this.id).then((message) => {
console.log('ALL MESSAGE WEB', message)
message.forEach(message => {
if (message.file) {
if (message.file.guid) {
this.storage.get(message.file.guid).then((image) => {
//console.log('IMAGE FROM STORAGE', image)
message.file.image_url = image
});
}
}
let mmessage = this.fix_updatedAt(message)
console.log('FROM DB WEB', mmessage)
const wewMessage = new MessageService(this.storage)
wewMessage.setData(mmessage)
this.messages.push(wewMessage)
console.log('loadHistory 222', this.messages)
});
}) */
}
history.forEach( async(ChatMessage)=>{
let index;
const find = messages.find((message, _index)=> {
if(message[identificator]) {
if(message[identificator] == ChatMessage[identificator]) {
index = _index
return true
}
}
return false
})
if(find) {
messages[index] = Object.assign(messages[index], ChatMessage)
// if(messages[index].msg.includes('***********')) {
// console.log('storage update')
// console.log(JSON.stringify(messages[index]))
// console.log(JSON.stringify(ChatMessage))
// }
await this.storage.set('chatmsg' + roomId, messages)
} else {
console.log('failed to update', identificator)
}
})
async transformData(res) {
// this.mgsArray = [];
// res.forEach(async element => {
// if (element.file) {
// if (element.file.guid) {
// await this.storage.get(element.file.guid).then((image) => {
// let chatmsg = {
// _id: element._id,
// attachments: element.attachments,
// channels: element.channels,
// file: {
// guid: element.file.guid,
// image_url: image,
// type: element.file.type
// },
// mentions: element.mentions,
// msg: element.msg,
// rid: element.rid,
// ts: element.ts,
// u: element.u,
// _updatedAt: element._updatedAt,
// }
// this.mgsArray.push(chatmsg);
// })
// } else {
// let chatmsg = {
// _id: element._id,
// attachments: element.attachments,
// channels: element.channels,
// file: element.file,
// mentions: element.mentions,
// msg: element.msg,
// rid: element.rid,
// ts: element.ts,
// u: element.u,
// _updatedAt: element._updatedAt,
// }
// this.mgsArray.push(chatmsg)
// }
// } else {
// let chatmsg = {
// _id: element._id,
// attachments: element.attachments,
// channels: element.channels,
// mentions: element.mentions,
// msg: element.msg,
// rid: element.rid,
// ts: element.ts,
// u: element.u,
// _updatedAt: element._updatedAt,
// }
// this.mgsArray.push(chatmsg)
// }
// });
// await this.storage.remove('chatmsg').then(() => {
// console.log('MSG REMOVE FROM STORAGE')
// });
// await this.storage.set('chatmsg', this.mgsArray).then((value) => {
// console.log('MSG SAVED ON STORAGE', value)
// });
})
}
}
async addMessageDB(ChatMessage, roomId) {
if (environment.chatOffline) {
await this.storage.get('chatmsg' + roomId).then(async(messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
}
if(!ChatMessage._id && environment.chatOffline) {
getMsgFromDBMobile() {
// console.log('ALL MSG DBBB', this.id)
// this.sqlservice.getAllChatMSG(this.id).then((msg: any = []) => {
// let ad = [];
// ad = msg
// console.log('ALL MSG DBBB', ad.length)
// msg.map(element => {
// console.log('CHANNEL ELEMENT', element)
// let msgChat = {
// _id: element.Id,
// attachments: this.isJson(element.Attachments),
// channels: this.isJson(element.Channels),
// file: {
// guid: this.isJson(element.File).guid,
// image_url: this.isJson(element.image_url),
// type: this.isJson(element.File).type
// },
// mentions: this.isJson(element.Mentions),
// msg: element.Msg,
// rid: element.Rid,
// ts: element.Ts,
// u: this.isJson(element.U),
// _updatedAt: this.isJson(element.UpdatedAt),
// }
// let mmessage = this.fix_updatedAt(msgChat)
// console.log('FROM DB WEB', mmessage)
// const wewMessage = new MessageService(this.storage)
// wewMessage.setData(mmessage)
// this.messages.push(wewMessage)
// console.log('loadHistory 222', this.messages)
// });
// });
delete ChatMessage.temporaryData
messages.push(ChatMessage)
console.log('no ID')
await this.storage.set('chatmsg' + roomId, messages)
// console.log('add to DB', ChatMessage)
} else {
const find = messages.find((message)=> {
return message._id == ChatMessage._id
})
if(!find) {
delete ChatMessage.temporaryData
messages.push(ChatMessage)
await this.storage.set('chatmsg' + roomId, messages)
// console.log('add to DB', ChatMessage)
} else {
console.log('duplicate')
}
}
})
}
}
async addManyMessageDB(_ChatMessage: any[], roomId) {
if (environment.chatOffline) {
await this.storage.get('chatmsg' + roomId).then(async(messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
}
await _ChatMessage.forEach(async(ChatMessage)=>{
if(!ChatMessage._id && environment.chatOffline) {
delete ChatMessage.temporaryData
messages.push(ChatMessage)
// console.log('add to DB')
} else {
const find = messages.find((message)=> {
return message._id == ChatMessage._id
})
if(!find) {
delete ChatMessage.temporaryData
messages.push(ChatMessage)
// console.log('add to DB')
}
}
})
await this.storage.set('chatmsg' + roomId, messages)
})
}
}
}
+140 -82
View File
@@ -5,8 +5,12 @@ import { SessionStore } from 'src/app/store/session.service';
import { capitalizeTxt } from 'src/plugin/text'
import { NfService } from 'src/app/services/chat/nf.service'
import { WsChatService } from 'src/app/services/chat/ws-chat.service';
import { environment } from 'src/environments/environment';
import { showDateDuration } from 'src/plugin/showDateDuration';
import { ChatStorageService } from './chat-storage.service'
import { ChatMethodsService } from './chat-methods.service'
import { MessageModel, DeleteMessageModel } from '../../models/beast-orm'
import { AESEncrypt } from '../aesencrypt.service'
@Injectable({
providedIn: 'root'
})
@@ -26,7 +30,8 @@ export class MessageService {
}
t = ''
_id =''
_id = ''
id = '' // table id
_updatedAt
file
attachments
@@ -43,14 +48,22 @@ export class MessageService {
localReference = null
viewed = []
received = []
addToDb = false
messageSend = false
delate = false
delateRequest = false
constructor(private storage: Storage,
private NfService: NfService,
private WsChatService: WsChatService) {
private WsChatService: WsChatService,
private ChatStorageService: ChatStorageService,
private ChatMethodsService: ChatMethodsService,
private AESEncrypt: AESEncrypt) {
}
setData({customFields = {}, channels, mentions, msg ,rid ,ts, u, t, _id, _updatedAt, file, attachments, temporaryData, localReference}:Message) {
this.customFields = customFields
setData({customFields = {}, channels, mentions, msg ,rid ,ts, u, t, _id, id, _updatedAt, file, attachments, temporaryData, localReference , viewed = [], received = [], delate = false, delateRequest =false, }:Message) {
this.channels = channels || []
this.mentions = mentions || []
this.msg = msg || ""
@@ -64,10 +77,19 @@ export class MessageService {
this.attachments = attachments
this.temporaryData = temporaryData
this.localReference = localReference || null
this.id = id
this.delate = delate
this.delateRequest = delateRequest
this.viewed = [...new Set([...viewed,...this.viewed])];
this.received = [...new Set([...received,...this.received])];
if(!this.ts) {
this.offline = true
this.messageSend = false
} else {
this.messageSend = true
this.offline = false
}
@@ -79,18 +101,13 @@ export class MessageService {
}
}
// if(typeof(this.file?.type)) {
// this.hasFile = true
// }
if(this.hasFile) {
this.getFileFromDb()
// this.getFileFromDb()
if(this.file.type != 'application/webtrix') {
this.displayType = this.file.type.replace('application/','').toUpperCase()
}
}
this.calDateDuration()
}
@@ -101,37 +118,29 @@ export class MessageService {
return firstName + ' ' + lastName
}
getFileFromDb() {
// getFileFromDb() {
if(this.hasFile) {
if (this.file.guid) {
this.storage.get(this.file.guid).then((image) => {
if(image != null) {
this.file.image_url = image
}
});
}
}
}
// if(this.hasFile) {
// if (this.file.guid) {
// this.storage.get(this.file.guid).then((image) => {
// if(image != null) {
// this.file.image_url = image
// }
// });
// }
// }
// }
async send(): Promise<any> {
this.sendAttempt++;
if(!this.hasFile) {
this.WsChatService.send({roomId:this.rid, msg:this.msg, localReference: this.localReference}).then(({message, requestId}) => {
let ChatMessage = message.result
if (environment.chatOffline) {
// this.redefinedMessage(ChatMessage)
this.offline = false
}
const params = {roomId:this.rid, msg:this.msg, localReference: this.localReference}
await this.sendRequest(params)
return new Promise((resolve, reject)=>{
resolve(ChatMessage)
})
})
} else {
this.uploadingFile = true
@@ -149,26 +158,17 @@ export class MessageService {
this.temporaryData = {}
this.WsChatService.send({roomId:this.rid, msg: this.msg, attachments: this.attachments, file: this.file, localReference: this.localReference}).then(({message, requestId}) => {
const params = {roomId:this.rid, msg: this.msg, attachments: this.attachments, file: this.file, localReference: this.localReference}
await this.sendRequest(params)
console.log('message', message)
let ChatMessage = message.result
if (environment.chatOffline) {
// this.redefinedMessage(ChatMessage)
this.offline = false
}
return new Promise((resolve, reject)=>{
resolve(ChatMessage)
})
})
} else if(this.WsChatService.isLogin == false) {
this.WsChatService.registerCallback({
type: 'reConnect',
funx: async ()=> {
return await this.send()
this.send()
return true
}
})
@@ -185,11 +185,42 @@ export class MessageService {
}
redefinedMessage(ChatMessage) {
ChatMessage = this.NfService.fix_updatedAt(ChatMessage)
this.setData(ChatMessage)
async sendRequest(params) {
this.ChatMethodsService.send(params).subscribe(
(response: any) => {
const ChatMessage = response.message
this.messageSend = true
this.redefinedMessage(ChatMessage)
},
(error) => {
this.WsChatService.registerCallback({
type: 'reConnect',
funx: async ()=> {
this.WsChatService.send(params).then(({message, requestId}) => {
let ChatMessage = message.result
this.messageSend = true
this.redefinedMessage(ChatMessage)
})
return true
}
})
}
)
}
async redefinedMessage(ChatMessage , update = true) {
ChatMessage = this.NfService.fix_updatedAt(ChatMessage)
const message = this.getChatObj()
ChatMessage = Object.assign(message, ChatMessage)
this.setData(ChatMessage)
await this.save()
}
async downloadFileMsg() {
const result = await this.NfService.beforeSendAttachment(this)
@@ -203,47 +234,74 @@ export class MessageService {
this.duration = showDateDuration(date || this._updatedAt);
}
private messageReceptor() {
return this.u.username != SessionStore.user.RochetChatUser
async delateStatusFalse() {
this.delate = true
this.save()
}
receptorReceive() {
async delateDB() {
const message = await MessageModel.get({_id: this._id})
await message.delete()
if(this.messageReceptor()) {
let newMessage = {
rid: this._id,
msg: this.msg,
attachments: this.attachments,
file: this.file,
localReference: this.localReference,
viewed: this.viewed.push('123'),
received: this.viewed.push('123'),
}
this.WsChatService.updateMessage(newMessage).then(()=>{
console.log('newMessage', newMessage)
})
}
isSenderIsNotMe(ChatMessage) {
return SessionStore.user.RochetChatUser != ChatMessage.u.username
}
messageOwnerById(id) {
return SessionStore.user.RochetChatUser != this.u.username
}
private getChatObj() {
return {
channels: this.channels,
mentions: this.mentions,
//msg: this.AESEncrypt.encrypt(this.msg, SessionStore.user.RochetChatUser),
msg:this.msg,
rid: this.rid,
ts: this.ts,
u: this.u,
_id: this._id,
id: this.id,
_updatedAt: this._updatedAt,
messageSend: this.messageSend,
offline: this.offline,
viewed: this.viewed,
received: this.received,
localReference: this.localReference,
attachments: this.attachments,
file: this.file,
delate: this.delate
}
}
receptorView() {
if(this.messageReceptor()) {
let newMessage = {
rid: this._id,
msg: this.msg,
attachments: this.attachments,
file: this.file,
localReference: this.localReference,
viewed: this.viewed.push('123'),
received: this.viewed.push('123'),
}
this.WsChatService.updateMessage(newMessage).then(()=>{
console.log('newMessage', newMessage)
})
async addMessageDB() {
if(!this.addToDb) {
this.addToDb= true
const message = this.getChatObj()
delete message.id
const createdMessage = await MessageModel.create(message)
this.id = createdMessage.id
}
}
async save() {
const message = this.getChatObj()
await MessageModel.update(message)
}
decryptMessage() {
try {
// this.msg = this.AESEncrypt.decrypt(this.msg, SessionStore.user.RochetChatUser)
} catch (error) {}
}
}
+443 -216
View File
@@ -16,6 +16,11 @@ import { environment } from 'src/environments/environment';
import { ChatService } from 'src/app/services/chat.service';
import { NfService } from 'src/app/services/chat/nf.service';
import { v4 as uuidv4 } from 'uuid'
import { ChatStorageService } from './chat-storage.service'
import { ChatMethodsService } from './chat-methods.service'
import { DeleteMessageModel, MessageModel } from '../../models/beast-orm'
import { AESEncrypt } from '../aesencrypt.service'
import { IncomingChatMessage, ChatMessageInterface, falseTypingMethod } from 'src/app/models/message.model';
@Injectable({
providedIn: 'root'
@@ -32,6 +37,7 @@ export class RoomService {
name = ''
_updatedAt = {}
hasLoadHistory = false
restoreFromOffline = false
duration = ''
isTyping = false
otherUserType = false
@@ -39,10 +45,10 @@ export class RoomService {
message = ''
lastMessageTxt = ''
userThatIsTyping = ''
private ToastService = ToastsService
mgsArray = [];
messagesLocalReference = []
members = []
u
scrollDown = () => { }
@@ -66,21 +72,88 @@ export class RoomService {
private NativeNotificationService: NativeNotificationService,
private sortService: SortService,
private chatService: ChatService,
private NfService: NfService
private NfService: NfService,
private ChatStorageService: ChatStorageService,
private ChatMethodsService: ChatMethodsService,
private AESEncrypt: AESEncrypt
) {
this.NativeNotificationService.askForPermission()
// this.restoreMessageFromDB()
this.WsChatService.getUserStatus((d) => {
const userId = d.fields.args[0][0]
const statusNum = d.fields.args[0][2]
const statusText = this.statusNumberToText(statusNum)
//
if(this.members?.map) {
const membersIds = this.members.map((user)=> user._id)
if(membersIds.includes(userId)) {
if(statusText != 'offline') {
this.deleteMessageToReceive(userId)
}
this.messages.forEach((message, index) => {
if(!message.messageOwnerById(userId)) {
if(!this.messages[index]?.received?.includes(userId)) {
if(this.messages[index]._id) {
try {
if(!this.messages[index].received.includes(userId)) {
this.messages[index].received.push(userId)
}
} catch(e) {
this.messages[index].received = [userId]
}
this.messages[index].save()
}
}
}
})
}
}
})
}
setData({ customFields = {}, id, name, t, lastMessage = new MessageService(this.storage, this.NfService, this.WsChatService), _updatedAt }) {
/**
* @description convert rocketchat statues num to readable string
* @param text
* @returns
*/
statusNumberToText(text) {
if(text == '0') {
return "offline"
}
else if(text == '1') {
return "online"
}
else if(text == '2') {
return "away"
}
else if(text == '3') {
return "busy"
}
}
setData({members, u, customFields = {}, id, name, t, lastMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt), _updatedAt }) {
this.customFields = customFields
this.id = id
this.name = name
this.t = t
this.lastMessage = lastMessage
this._updatedAt = _updatedAt
this.u = u
this.members = members
this.calDateDuration()
this.restoreMessageFromDB()
}
@@ -89,181 +162,183 @@ export class RoomService {
return SessionStore.user.RochetChatUser != ChatMessage.u.username
}
senderId(ChatMessage) {
return ChatMessage.u._id
}
receiveMessage() {
this.WsChatService.updateRoomEventss(
this.id,
"stream-room-messages",
(_ChatMessage) => {
console.log('recivemessage', _ChatMessage)
let ChatMessage = _ChatMessage.fields.args[0]
ChatMessage = this.fix_updatedAt(ChatMessage)
async (IncomingChatMessage:IncomingChatMessage) => {
let IncomingChatMessageArgs = IncomingChatMessage.fields.args[0]
let ChatMessage : ChatMessageInterface = this.fix_updatedAt(IncomingChatMessageArgs)
if(!this.messagesLocalReference.includes(ChatMessage.localReference)) {
const message = this.prepareMessage(ChatMessage)
const message = await this.prepareCreate({message: ChatMessage, save: true})
message.messageSend = true
this.lastMessage = message
this.calDateDuration(ChatMessage._updatedAt)
if (message.t == 'r') {
this.name = message.msg
}
if(this.isSenderIsNotMe(ChatMessage)) {
this.NativeNotificationService.sendNotificationChat({
message: message.msg,
title: this.name
});
}
this.addMessageDB(ChatMessage)
message.addMessageDB()
setTimeout(()=>{
this.scrollDown()
}, 50)
//Sort list of messages from recent to old
this.sortRoomList()
}
}, 50)
} else {
this.messages.forEach((message, index)=> {
if(message.localReference == ChatMessage.localReference) {
const membersIds = this.members.map((user)=> user._id)
this.getAllUsers().forEach( async (users) => {
if(membersIds.includes(users._id)) {
if(users.status != 'offline') {
this.messages[index].received.push(users._id)
setTimeout(() => {
message.save()
}, 150)
}
}
});
}
})
}
}
)
this.WsChatService.receiveStreamNotifyRoom((message) => {
if(message.fields.eventName == this.id+'/'+'typing') {
this.userThatIsTyping = this.usernameToDisplayName(message.fields.args[0])
console.log(this.userThatIsTyping, 'this.userThatIsTyping')
this.isTyping = message.fields.args[1]
this.otherUserType = message.fields.args[1]
const args = message.fields.args
// alert(JSON.stringify(args))
if (typeof args[1] != 'object') {
this.userThatIsTyping = this.usernameToDisplayName(args[0])
console.log(this.userThatIsTyping, 'this.userThatIsTyping')
this.isTyping = args[1]
this.otherUserType = args[1]
this.readAllMessage()
// console.log(JSON.stringify(args))
// alert(JSON.stringify(args))
} else if(args[0]?.method == 'viewMessage' || args[1]?.method == 'viewMessage') {
this.readAllMessage()
} else if(args[0]?.method == 'deleteMessage' || args[1]?.method == 'deleteMessage') {
// alert('delete')
// console.log(args[0], 'receive delete message::()')
this.deleteMessage(args[1]?.method?._id)
} else {
// alert('miss')
}
} else if (message.fields.eventName == this.id+'/'+'deleteMessage') {}
})
}
async addMessageDB(ChatMessage) {
if (environment.chatOffline) {
this.storage.get('chatmsg' + this.id).then((messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
getRoomMembersIds(): string[] {
return this.members.map((user)=> user._id)
}
getAllMemberThatIsNotOffline(): string[] {
const membersIds = this.getRoomMembersIds()
const allChatUsers = this.getAllUsers()
const AllMemberThatIsNotOffline = []
for(let user of allChatUsers) {
if(membersIds.includes(user._id)) {
if(user.status != 'offline') {
AllMemberThatIsNotOffline.push(user._id)
}
}
}
return AllMemberThatIsNotOffline
}
getAllMemberThatIsOffline(): string[] {
const membersIds = this.getRoomMembersIds()
const allChatUsers = this.getAllUsers()
const AllMemberThatIsNotOffline = []
for(let user of allChatUsers) {
if(membersIds.includes(user._id)) {
if(user.status == 'offline') {
AllMemberThatIsNotOffline.push(user._id)
}
}
}
return AllMemberThatIsNotOffline
}
if(!ChatMessage._id && environment.chatOffline) {
async deleteMessageToReceive(userId) {
delete ChatMessage.temporaryData
messages.push(ChatMessage)
this.storage.set('chatmsg' + this.id, messages)
const allDeleteMessages = await DeleteMessageModel.filter({rid: this.id}).execute()
for(let message_ of allDeleteMessages) {
if(message_.needToReceiveBy.includes(userId)) {
message_.needToReceiveBy = message_.needToReceiveBy.filter((e)=> e != userId)
this.sendFalseTypingReadMessage('deleteMessage',{_id:message_.messageId})
if(message_.needToReceiveBy.length == 0) {
const deleteMessage = await DeleteMessageModel.get({messageId: message_.messageId})
await deleteMessage.delete()
} else {
const find = messages.find((message)=> {
return message._id == ChatMessage._id
})
if(!find) {
delete ChatMessage.temporaryData
messages.push(ChatMessage)
this.storage.set('chatmsg' + this.id, messages)
}
}
})
}
}
async updateMessageDB(ChatMessage, localReference) {
if (environment.chatOffline) {
this.storage.get('chatmsg' + this.id).then((messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
await DeleteMessageModel.update(message_)
}
let index;
const find = messages.find((message, _index)=> {
if(message.localReference) {
if(message?.localReference == ChatMessage?.localReference) {
index = _index
return true
}
}
return false
})
if(find) {
messages[index] = ChatMessage
this.storage.set('chatmsg' + this.id, messages)
}
})
}
}
}
}
async updateViewedMessage(id, userId) {
if (environment.chatOffline) {
this.storage.get('chatmsg' + this.id).then((messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
}
let index;
const find = messages.find((message, _index)=> {
if(message._id == id) {
index = _index
return true
}
return false
})
if(find) {
if(!messages[index].hasOwnProperty('viewed') || !Array.isArray(messages[index].viewed)) {
messages.viewed = []
}
messages.viewed.push(userId)
this.storage.set('chatmsg' + this.id, messages)
}
})
}
}
/**
* @description delete message in the DB. get all messages, delete then corresponding message and update the store
* @param id message ID
*/
private deleteMessageFromDb(id) {
if (environment.chatOffline) {
this.storage.get('chatmsg' + this.id).then((messages: any = []) => {
if(!Array.isArray(messages)) {
messages = []
}
messages.forEach((message, index) => {
if(message._id == id) {
messages.splice(index, 1)
}
})
this.storage.set('chatmsg' + this.id, messages).then((value) => {
console.log('MSG SAVED ON STORAGE', value)
});
})
}
}
async receiveMessageDelete() {
@@ -273,7 +348,6 @@ export class RoomService {
async (ChatMessage) => {
const DeletedMessageId = ChatMessage.fields.args[0]._id;
console.log(DeletedMessageId);
this.deleteMessage(DeletedMessageId)
}
@@ -285,12 +359,27 @@ export class RoomService {
* @description delete message in the view
* @param id message ID
*/
deleteMessage(id) {
this.messages.forEach((message, index) => {
async deleteMessage(id) {
await this.messages.forEach(async(message, index) => {
if(message._id == id) {
this.messages.splice(index, 1)
this.deleteMessageFromDb(id)
if (SessionStore.user.RochetChatUser == message.u.username) {
const allMemberThatIsOffline = this.getAllMemberThatIsOffline()
await DeleteMessageModel.create({
messageId: message._id,
rid: message.rid,
ts: message.ts,
u: message.u,
needToReceiveBy: allMemberThatIsOffline
})
}
message.delateStatusFalse()
message.delateDB()
//Get previous last message from room
const previousLastMessage = this.messages.slice(-1)[0];
@@ -300,8 +389,49 @@ export class RoomService {
}
})
}
async delateMessageToSendToOthers(userId) {
const deleteMessage = await DeleteMessageModel.all()
const toSend = deleteMessage.filter((DeleteMessage:string[])=> ! DeleteMessage.includes(userId))
}
async sendDeleteRequest(msgId) {
const message = this.messages.find((e)=>e._id = msgId)
message.delateStatusFalse()
this.ChatMethodsService.deleteMessage({_id:msgId, msgId:msgId, roomId:message.rid}).subscribe(
(response: any) => {
message.delateRequest = true
message.save()
},
(response) => {
if (response.error.error.startsWith('No message found with the id of')) {
this.deleteMessage(msgId)
} else {
// this.deleteMessage(DeletedMessageId)
this.WsChatService.registerCallback({
type: 'reConnect',
funx: async ()=> {
this.sendDeleteRequest(msgId)
return true
}
})
}
}
)
}
/**
* @description sen text message
@@ -316,25 +446,20 @@ export class RoomService {
attachments,
file,
temporaryData,
localReference,
viewed: [],
received: []
localReference
}
const message: MessageService = this.prepareMessage(offlineChatMessage, environment.chatOffline)
/**
* @description redefine message offline data "offlineChatMessage" with live ChatMessage
*/
message.send().then((ChatMessage) => {
this.updateMessageDB(ChatMessage, localReference)
})
this.message= ''
const message: MessageService = await this.prepareCreate({message:offlineChatMessage, save: environment.chatOffline})
this.messagesLocalReference.push(localReference)
await message.addMessageDB()
message.send()
if (environment.chatOffline) {
this.messagesLocalReference.push(localReference)
this.addMessageDB(offlineChatMessage)
setTimeout(() => {
this.scrollDown()
}, 150)
@@ -344,29 +469,10 @@ export class RoomService {
this.sortRoomList()
}
this.message= ''
}
/**
*
* @param message
* @param ChatMessage
* @description when creating message we use offline data, then we need redefined with live data
*/
redefinedMessage (message: MessageService, ChatMessage) {
ChatMessage = this.fix_updatedAt(ChatMessage)
message.setData(ChatMessage)
if( new Date(this.lastMessage._updatedAt).getTime() < new Date(message._updatedAt).getTime()) {
this.lastMessage = message
this.calDateDuration(message._updatedAt)
}
this.sortRoomList()
}
sendTyping(text:string = this.message) {
@@ -389,6 +495,10 @@ export class RoomService {
this.typingWatch()
}
sendFalseTypingReadMessage(method,param: object) {
this.WsChatService.sendStreamNotifyRoom(this.id, SessionStore.user.RochetChatUser, 'typing', {method:method, params: param} as falseTypingMethod)
this.setTypingOff()
}
private typingWatch() {
setTimeout(()=>{
@@ -401,7 +511,7 @@ export class RoomService {
this.WsChatService.sendStreamNotifyRoom(this.id, SessionStore.user.RochetChatUser, 'typing', this.isTyping)
}
} else {
//console.log(now - this.lastTimeType)
}
}, 3000)
@@ -433,43 +543,48 @@ export class RoomService {
return JSON.parse(str);
}
async restoreMessageFromDB() {
if(environment.chatOffline) {
await this.storage.get('chatmsg' + this.id).then( async (messages = []) => {
if(!Array.isArray(messages)) {
messages = []
}
const messages = await MessageModel.filter({rid:this.id}).execute()
await messages.forEach( async (ChatMessage, index) => {
const wewMessage = this.prepareMessage(ChatMessage, false)
await messages.forEach( async (ChatMessage, index) => {
if(wewMessage.offline == false) {
this.prepareMessage(ChatMessage)
} else {
const offlineMessage = this.prepareMessage(ChatMessage)
const wewMessage = await this.simplePrepareMessage(ChatMessage)
if(wewMessage.offline == false) {
const message = await this.prepareMessageCreateIfNotExist({message:ChatMessage})
message?.decryptMessage()
} else {
const offlineMessage = await this.prepareMessageCreateIfNotExist({message:ChatMessage})
if(offlineMessage) {
this.messagesLocalReference.push(offlineMessage.localReference)
offlineMessage.send().then((newChatMessage) => {
this.updateMessageDB(newChatMessage, ChatMessage.localReference)
})
offlineMessage?.decryptMessage()
offlineMessage.send()
}
});
}
setTimeout(()=> {
this.scrollDown()
}, 50)
if(wewMessage.delate && !wewMessage.offline && !wewMessage.delateRequest) {
this.sendDeleteRequest(wewMessage._id)
}
})
});
setTimeout(()=> {
this.scrollDown()
}, 50)
}
}
// runs onces only
async loadHistory({limit = 50, forceUpdate = false }) {
async loadHistory({limit = 10000000, forceUpdate = false }) {
if(forceUpdate == false) {
if (this.hasLoadHistory) {
@@ -477,16 +592,28 @@ export class RoomService {
}
}
if(this.restoreFromOffline == false) {
this.restoreFromOffline = true
await this.restoreMessageFromDB()
}
await this.WsChatService.loadHistory(this.id, limit).then( async (chatHistory:chatHistory) => {
await chatHistory.result.messages.reverse().forEach( async (message) => {
const messagesId = this.messages.map((message)=> message._id)
this.prepareMessage(message)
// this.messages = this.sortService.sortDate(this.messages, '_updatedAt')
chatHistory.result.messages.reverse().forEach(async(message: any) => {
if (!messagesId.includes(message._id)) {
const messagesToSave = await this.prepareMessageCreateIfNotExist({message: message});
if(messagesToSave) {
await messagesToSave.addMessageDB()
}
}
})
this.storage.set('chatmsg' + this.id, chatHistory.result.messages)
// console.log('load chatHistory', chatHistory)
})
setTimeout(() => {
@@ -497,38 +624,135 @@ export class RoomService {
}
async readAllMessage() {
const membersIds = this.members.map((user)=> user._id)
await this.messages.forEach( async (message, index) => {
if(message._id) {
if(message.viewed.length == 0) {
this.messages[index].viewed = membersIds
this.messages[index].received = membersIds
await this.messages[index].save()
}
}
})
}
/**
* @description find or create message
* @param message
* @param save
* @returns
* @param message
* @param save
* @returns
*/
prepareMessage(message, save = true): MessageService {
async prepareMessage({message, save = true, redefined = false}): Promise<MessageService> {
message = this.fix_updatedAt(message)
const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService)
const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt)
wewMessage.setData(message)
wewMessage.loadHistory = this.hasLoadHistory
if(!message._id && environment.chatOffline && save) {
let foundIndex;
this.messages.push(wewMessage)
return wewMessage
}
const found = this.messages.find((MessageService) => {
const found = this.messages.find((MessageService, index) => {
if (MessageService._id == message._id) {
if(this.hasLoadHistory) /* console.log(`${MessageService._id} == ${message._id}`) */
foundIndex = index
return true
} else {
return false
}
})
if (save && !found) {
this.messages.push(wewMessage)
if(save) {
if (!found) {
this.messages.push(wewMessage)
return wewMessage
}
} else if(foundIndex) {
return this.messages[foundIndex]
} else {
return wewMessage
}
}
async ChatMessageIsPresentInTheView(ChatMessage:ChatMessageInterface) {
let foundIndex;
const found = this.messages.find((MessageService, index) => {
if (MessageService._id == ChatMessage._id) {
foundIndex = index
return true
} else {
return false
}
})
if (foundIndex) {
return { found, foundIndex}
} else {
return false
}
}
/**
* @description find or create message
* @param message
* @param save
* @returns
*/
async prepareCreate({message, save = true}): Promise<MessageService> {
message = this.fix_updatedAt(message)
const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt)
wewMessage.setData(message)
wewMessage.loadHistory = this.hasLoadHistory
this.messages.push(wewMessage)
return wewMessage
}
simplePrepareMessage(message) {
message = this.fix_updatedAt(message)
const wewMessage = new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt)
wewMessage.setData(message)
wewMessage.loadHistory = this.hasLoadHistory
return wewMessage
}
async prepareMessageCreateIfNotExist({message}) {
message = this.fix_updatedAt(message)
let foundIndex;
const found = this.messages.find((MessageService, index) => {
if (MessageService._id == message._id ||
MessageService.localReference == message.localReference ) {
foundIndex = index
return true
} else {
return false
}
})
if (!found) {
const wewMessage = this.simplePrepareMessage(message)
this.messages.push(wewMessage)
return wewMessage
} else {
return null
}
}
private calDateDuration(date = null) {
@@ -536,11 +760,10 @@ export class RoomService {
this._updatedAt = date || this._updatedAt
}
private fix_updatedAt(message) {
if (message.result) {
private fix_updatedAt(message): ChatMessageInterface {
if (message?.result) {
message.result._updatedAt = message.result._updatedAt['$date']
} else if(message._updatedAt) {
} else if(message?._updatedAt) {
if(message._updatedAt.hasOwnProperty('$date')) {
message._updatedAt = message._updatedAt['$date']
}
@@ -548,7 +771,6 @@ export class RoomService {
return message
}
usernameToDisplayName(username) {
const firstName = capitalizeTxt(username.split('.')[0])
@@ -556,4 +778,9 @@ export class RoomService {
return firstName + ' ' + lastName
}
sendReadMessage() {
this.WsChatService.readMessage(this.id)
this.sendFalseTypingReadMessage('viewMessage', {})
}
}
@@ -14,6 +14,12 @@ import { SortService } from '../functions/sort.service';
import { chatUser } from 'src/app/models/chatMethod';
import { NfService } from 'src/app/services/chat/nf.service'
import { ChangeProfileService } from '../change-profile.service';
import { UserSession } from 'src/app/models/user.model';
import { AuthService } from '../auth.service';
import { ChatStorageService } from './chat-storage.service'
import { ChatMethodsService } from './chat-methods.service'
import { AESEncrypt } from '../aesencrypt.service'
@Injectable({
providedIn: 'root'
})
@@ -33,6 +39,8 @@ export class WsChatMethodsService {
currentRoom: RoomService = null
users: chatUser[] = []
loggedUser: any;
constructor(
private WsChatService: WsChatService,
private storage: Storage,
@@ -43,8 +51,15 @@ export class WsChatMethodsService {
private ChatService: ChatService,
private NfService: NfService,
private changeProfileService: ChangeProfileService,
private chatService: ChatService,
private authService: AuthService,
private ChatStorageService: ChatStorageService,
private ChatMethodsService:ChatMethodsService,
private AESEncrypt: AESEncrypt
) {
this.loggedUser = authService.ValidatedUserChat['data'];
this.loadChat()
this.WsChatService.registerCallback({
@@ -79,39 +94,6 @@ export class WsChatMethodsService {
this.storage.remove('Rooms');
})
// this.WsChatService.registerCallback({
// type:'Onmessage',
// funx:(message) => {
// if(message.msg =='changed' && message.collection == "stream-room-messages") {
// if(message.fields.args[0].rid) {
// // new message
// const ChatMessage = message.fields.args[0]
// const messageId = ChatMessage.rid
// setTimeout(()=>{
// this.sortRoomList()
// }, 100)
// }
// } else if(message.msg =='changed' && message.collection == "stream-notify-room") {
// if(message.fields.eventName.includes('deleteMessage')) {
// // delete message
// const DeletedMessageId = message.fields.args[0]._id;
// setTimeout(()=>{
// this.sortRoomList()
// }, 100)
// } else if(message.fields.eventName.includes('typing')) {
// }
// }
// }
// })
}
private loadChat() {
@@ -144,7 +126,6 @@ export class WsChatMethodsService {
this.users = []
}
openRoom(roomId) {
if(this.currentRoom) {
@@ -161,12 +142,13 @@ export class WsChatMethodsService {
}
async restoreRooms() {
try {
const rooms = await this.storage.get('Rooms');
console.log('restore',rooms)
if(rooms) {
await rooms.result.update.forEach( async (roomData: room) => {
await this.prepareRoom(roomData);
@@ -183,14 +165,43 @@ export class WsChatMethodsService {
this.loadingWholeList = true
const rooms = await this.WsChatService.getRooms();
await this.storage.remove('Rooms');
await this.storage.set('Rooms', rooms);
console.log('rooms', rooms)
await rooms.result.update.forEach( async (roomData: room, index) => {
const roomId = this.getRoomId(roomData);
if(roomData.t == 'd') {
const res = await this.chatService.getMembers(roomId).toPromise();
const members = res['members'];
const users = members.filter(data => data.username != this.loggedUser.me.username);
rooms.result.update[index]['members'] = users
await this.prepareRoom(roomData);
} else {
if (roomData.t === 'p') {
const res = await this.chatService.getGroupMembers(roomId).toPromise()
const members = res['members'];
const users = members.filter(data => data.username != this.loggedUser.me.username);
rooms.result.update[index]['members'] = users
}
else {
const res = await this.chatService.getChannelMembers(roomId).toPromise()
const members = res['members'];
const users = members.filter(data => data.username != this.loggedUser.me.username);
rooms.result.update[index]['members'] = users
}
}
await rooms.result.update.forEach( async (roomData: room) => {
await this.prepareRoom(roomData);
});
console.log('save rooms', rooms)
await this.storage.set('Rooms', rooms);
this.sortRoomList()
this.loadingWholeList = false
}
@@ -248,6 +259,8 @@ export class WsChatMethodsService {
})
this.WsChatService.subStreamNotifyRoom(id, 'typing', false)
this.WsChatService.subStreamNotifyRoom(id, 'readMessage', false)
this.WsChatService.streamNotifyRoomDeleteMessage(id).then((subscription)=>{
//console.log('streamNotifyRoomDeleteMessage', subscription);
})
@@ -276,21 +289,23 @@ export class WsChatMethodsService {
*/
roomData = this.fix_updatedAt(roomData)
roomData = this.fix_updatedAt(roomData)
const setData = {
customFields: roomData.customFields,
id: this.getRoomId(roomData),
name: this.getRoomName(roomData),
t: roomData.t,
lastMessage: this.getRoomLastMessage(roomData),
_updatedAt: roomData._updatedAt
_updatedAt: new Date( roomData._updatedAt || roomData._updatedAt['$date']),
u : roomData.u || {},
members: roomData.members
}
let roomId = this.getRoomId(roomData)
// create room
if(!this.roomExist(roomId)) {
let room:RoomService = new RoomService(this.WsChatService, new MessageService(this.storage, this.NfService, this.WsChatService), this.storage, this.platform, this.sqlservice, this.NativeNotificationService, this.sortService, this.ChatService, this.NfService)
let room:RoomService = new RoomService(this.WsChatService, new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt), this.storage, this.platform, this.sqlservice, this.NativeNotificationService, this.sortService, this.ChatService, this.NfService , this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt)
room.setData(setData)
room.receiveMessage()
room.getAllUsers = this.getUsers
@@ -314,7 +329,6 @@ export class WsChatMethodsService {
}
} else {
console.log('have!!!')
// in this case room is already present, therefor it will only be necessary,
// to redefine
@@ -350,16 +364,16 @@ export class WsChatMethodsService {
const username = d.fields.args[0][1]
const statusNum = d.fields.args[0][2]
const statusText = this.statusNumberToText(statusNum)
const user = this.getUserByName(username)
if(user) {
user.status = statusText
}
this.users.forEach((user, index) => {
if(user.username == username) {
this.users[index].status = statusText
}
})
})
}
getUserByName(username) {
@@ -474,9 +488,9 @@ export class WsChatMethodsService {
let _res = await this.ChatService.getAllUsers().toPromise()
let user = _res['users'].filter(data => data.username != SessionStore.user.RochetChatUser);
let users = _res['users'].filter(data => data.username != SessionStore.user.RochetChatUser);
user = user.sort((a,b) => {
users = users.sort((a,b) => {
if(a.name < b.name) {
return -1;
}
@@ -486,7 +500,11 @@ export class WsChatMethodsService {
return 0;
});
this.users = user
users.forEach((user, index) => {
// user[index].status = this.statusNumberToText(user[index].status)
})
this.users = users
}
getUserOfRoom(roomId){
+29 -4
View File
@@ -123,6 +123,30 @@ export class WsChatService {
});
}
readMessage(roomId) {
const requestId = uuidv4()
const message = {
"msg":"method",
"method":"readMessages",
"params": [roomId, []],
"id": requestId
}
this.ws.send({message, requestId})
return new Promise<Rooms>((resolve, reject) => {
this.ws.registerCallback({type:'Onmessage', funx:(message)=>{
if(message.id == requestId) { // same request send
resolve(message)
return true
}
}})
});
}
getUserOfRoom(roomId) {
const requestId = uuidv4()
@@ -174,6 +198,8 @@ export class WsChatService {
}]
}
console.log('send message to rocketchat ', message)
this.ws.send({message, requestId});
return new Promise((resolve, reject) => {
@@ -285,7 +311,7 @@ export class WsChatService {
});
}
joinRoom(){}
joinRoom() {}
deleteMessage(msgId) {
const requestId = uuidv4();
@@ -369,7 +395,7 @@ export class WsChatService {
}
subStreamNotifyRoom(roomId : string , event: 'typing' | 'deleteMessage', param: any) {
subStreamNotifyRoom(roomId : string , event: 'typing' | 'deleteMessage' | 'readMessage', param: any) {
const requestId = uuidv4()
@@ -496,7 +522,7 @@ export class WsChatService {
}
updateRoomEventss(roomId, collection:string, funx: Function, ) {
updateRoomEventss(roomId, collection:string, funx: Function, ) {
this.ws.registerCallback({
type:'Onmessage',
@@ -515,7 +541,6 @@ updateRoomEventss(roomId, collection:string, funx: Function, ) {
})
}
streamRoomMessages(roomId : string) {
const requestId = uuidv4()
@@ -27,114 +27,118 @@
</div>
</div>
<div class="content d-flex flex-column">
<div class="header-content width-100 d-flex justify-space-between">
<div (click)="close()" class="header-icon-left cursor-pointer">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-arrow-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-calendar-arrow-left.svg"></ion-icon>
</div>
<div class="header-title flex-grow-1 cursor-pointer">
<label>{{loadedEvent.workflowInstanceDataFields.Subject}}</label>
</div>
<div class="main-content d-flex height-100 width-100">
<div class="content d-flex flex-column">
<div (click)="editar(loadedEvent.serialNumber)" class="header-icon-right display-none-{{showAside}}">
<button class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-edit.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-edit.svg"></ion-icon>
</button>
</div>
<div (click)="rejectTask(loadedEvent.serialNumber)" class="header-icon-right display-none-{{showAside}}">
<button class="btn-no-color" >
<ion-icon class="delete" name="trash-sharp"></ion-icon>
</button>
</div>
</div>
<div class="upper-content d-flex flex-column">
<div class="content-location">
<p>
<span class="location">{{loadedEvent.workflowInstanceDataFields.Location}}</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Oficial MDGPR' " style="background-color: #ffb703;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Pessoal MDGPR' " style="background-color: #f05d5e;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Oficial PR' " style="background-color: #99e47b;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Pessoal PR' " style="background-color: #958bfc;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
</p>
</div>
<div class="content-details">
<ion-label>
<p>{{customDate}}</p>
<p *ngIf="toDateString(loadedEvent.workflowInstanceDataFields.StartDate) == toDateString(loadedEvent.workflowInstanceDataFields.EndDate)">das {{loadedEvent.workflowInstanceDataFields.StartDate | date: 'HH:mm'}} às {{loadedEvent.workflowInstanceDataFields.EndDate | date: 'HH:mm'}}</p>
<p *ngIf="toDateString(loadedEvent.workflowInstanceDataFields.StartDate) != toDateString(loadedEvent.workflowInstanceDataFields.EndDate)">{{loadedEvent.workflowInstanceDataFields.StartDate | date: 'd/M/yy' }} - {{ loadedEvent.workflowInstanceDataFields.StartDate | date: 'dd/M/yy'}} </p>
<p *ngIf="!loadedEvent.workflowInstanceDataFields.IsRecurring">(Não se repete)</p>
<p *ngIf="loadedEvent.workflowInstanceDataFields.IsRecurring">Repete</p>
</ion-label>
</div>
</div>
<div class="line"></div>
<div class="overflow-y-auto">
<div class="middle-content">
<div *ngIf="loadedEvent.workflowInstanceDataFields.ParticipantsList">
<h5>Intervenientes</h5>
<div *ngFor="let att of loadedEvent.workflowInstanceDataFields.ParticipantsList">
<ion-label>{{att.Name}}</ion-label>
</div>
<div class="line"></div>
<div class="header-content width-100 d-flex justify-space-between">
<div (click)="close()" class="header-icon-left cursor-pointer">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-arrow-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-calendar-arrow-left.svg"></ion-icon>
</div>
<div *ngIf="loadedEvent.workflowInstanceDataFields.Body">
<h5>Detalhes</h5>
<ion-item lines="none" class="ion-no-margin ion-no-padding">
<p [innerHTML]="loadedEvent.workflowInstanceDataFields.Body"></p>
</ion-item>
<div class="line"></div>
<div class="header-title flex-grow-1 cursor-pointer">
<label>{{loadedEvent.workflowInstanceDataFields.Subject}}</label>
</div>
<div (click)="editar(loadedEvent.serialNumber)" class="header-icon-right display-none-{{showAside}}">
<button class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-edit.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-edit.svg"></ion-icon>
</button>
</div>
<div (click)="rejectTask(loadedEvent.serialNumber)" class="header-icon-right display-none-{{showAside}}">
<button class="btn-no-color" >
<ion-icon class="delete" name="trash-sharp"></ion-icon>
</button>
</div>
</div>
<div *ngIf="loadedEvent.Documents" class="bottom-content width-100">
<ion-list>
<h5>Documentos Anexados </h5>
<ion-item class="ion-no-margin ion-no-padding cursor-pointer"
*ngFor="let attachment of loadedEvent.Documents"
(click)="viewDocument(attachment.DocId, attachment)">
<div class="upper-content d-flex flex-column">
<div class="content-location">
<p>
<span class="location">{{loadedEvent.workflowInstanceDataFields.Location}}</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Oficial MDGPR' " style="background-color: #ffb703;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Pessoal MDGPR' " style="background-color: #f05d5e;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Oficial PR' " style="background-color: #99e47b;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Pessoal PR' " style="background-color: #958bfc;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
</p>
</div>
<div class="content-details">
<ion-label>
<p class="attach-title-item d-block">{{attachment.Assunto}}</p>
<p><span class="span-left">{{attachment.Sender}}</span><span class="span-right">{{ attachment.DocDate | date: 'dd-MM-yyyy HH:mm' }}</span></p>
<p>{{customDate}}</p>
<p *ngIf="toDateString(loadedEvent.workflowInstanceDataFields.StartDate) == toDateString(loadedEvent.workflowInstanceDataFields.EndDate)">das {{loadedEvent.workflowInstanceDataFields.StartDate | date: 'HH:mm'}} às {{loadedEvent.workflowInstanceDataFields.EndDate | date: 'HH:mm'}}</p>
<p *ngIf="toDateString(loadedEvent.workflowInstanceDataFields.StartDate) != toDateString(loadedEvent.workflowInstanceDataFields.EndDate)">{{loadedEvent.workflowInstanceDataFields.StartDate | date: 'd/M/yy' }} - {{ loadedEvent.workflowInstanceDataFields.StartDate | date: 'dd/M/yy'}} </p>
<p *ngIf="!loadedEvent.workflowInstanceDataFields.IsRecurring">(Não se repete)</p>
<p *ngIf="loadedEvent.workflowInstanceDataFields.IsRecurring">Repete</p>
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
<div class="line"></div>
<div class="overflow-y-auto">
<div class="middle-content">
<div *ngIf="loadedEvent.workflowInstanceDataFields.ParticipantsList">
<h5>Intervenientes</h5>
<div *ngFor="let att of loadedEvent.workflowInstanceDataFields.ParticipantsList">
<ion-label>{{att.Name}}</ion-label>
</div>
<div class="line"></div>
</div>
<div *ngIf="loadedEvent.workflowInstanceDataFields.Body">
<h5>Detalhes</h5>
<ion-item lines="none" class="ion-no-margin ion-no-padding">
<p [innerHTML]="loadedEvent.workflowInstanceDataFields.Body"></p>
</ion-item>
<div class="line"></div>
</div>
</div>
<div *ngIf="loadedEvent.Documents" class="bottom-content width-100">
<ion-list>
<h5>Documentos Anexados </h5>
<ion-item class="ion-no-margin ion-no-padding cursor-pointer"
*ngFor="let attachment of loadedEvent.Documents"
(click)="viewDocument(attachment.DocId, attachment)">
<ion-label>
<p class="attach-title-item d-block">{{attachment.Assunto}}</p>
<p><span class="span-left">{{attachment.Sender}}</span><span class="span-right">{{ attachment.DocDate | date: 'dd-MM-yyyy HH:mm' }}</span></p>
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
</div>
</div>
<div *ngIf="showAside" class="aside-right flex-column height-100 cursor-pointer">
<div class="aside-buttons">
<button hidden full class="btn-ok" shape="round" >Editar evento</button>
<button (click)="approveTask(loadedEvent.serialNumber)" full class="btn-ok" shape="round" >Aprovar</button>
<button (click)="emendTask(loadedEvent.serialNumber)" class="btn-cancel" shape="round" >Rever</button>
<div class="solid"></div>
<button full class="btn-cancel" shape="round" (click)="editar(loadedEvent.serialNumber)" >Editar</button>
<button (click)="rejectTask(loadedEvent.serialNumber)" full class="btn-delete" shape="round" >Rejeitar</button>
<div *ngIf="showAside" class="aside-right flex-column height-100 cursor-pointer">
<div class="aside-buttons">
<button hidden full class="btn-ok" shape="round" >Editar evento</button>
<button (click)="approveTask(loadedEvent.serialNumber)" full class="btn-ok" shape="round" >Aprovar</button>
<button (click)="emendTask(loadedEvent.serialNumber)" class="btn-cancel" shape="round" >Rever</button>
<div class="solid"></div>
<button full class="btn-cancel" shape="round" (click)="editar(loadedEvent.serialNumber)" >Editar</button>
<button (click)="rejectTask(loadedEvent.serialNumber)" full class="btn-delete" shape="round" >Rejeitar</button>
</div>
</div>
</div>
</div>
</ion-content>
@@ -209,14 +209,16 @@
<ion-footer>
<!-- <div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true" >A escrever...</div> -->
<!-- <div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true">
<div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true">
{{ wsChatMethodsService.getGroupRoom(roomId).otherUserType }}
<ngx-letters-avatar *ngIf="showAvatar"
[avatarName]= "wsChatMethodsService.getGroupRoom(roomId).name"
[width]="30"
[circular]="true"
fontFamily="Roboto"></ngx-letters-avatar>
{{ wsChatMethodsService.getGroupRoom(roomId).userThatIsTyping }} está a escrever...
</div> -->
</div>
<div class="width-100 pl-20 pr-20">
<span *ngIf="!lastAudioRecorded">{{durationDisplay}}</span>
+31 -71
View File
@@ -45,20 +45,25 @@
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer">
</fa-icon>
<mat-menu #beforeMenu="matMenu" xPosition="before">
<button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button>
<button (click)="deleteMessage(msg._id, msg)" class="menuButton">Apagar mensagem</button>
</mat-menu>
</div>
<div class="title">
<ion-label (click)="testEditMessage(msg)">{{msg.u.name}}</ion-label>
<ion-label>{{msg.u.name}}</ion-label>
<span class="time">{{msg.duration}}</span>
</div>
<div class="d-flex justify-space-between">
<ion-label class="flex-0">{{msg.msg}}</ion-label>
<!-- <ion-label class="float-status-all float-status" >
<ion-icon *ngIf="!msg.offline && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.offline && msg.viewed.length == 0" src="assets/images/check-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.viewed.length == 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon>
</ion-label> -->
<ion-label *ngIf="msg.delate == false" class="flex-0">{{msg.msg}}</ion-label>
<ion-label *ngIf="msg.delate == true" class="flex-0">Apagou a mensagem</ion-label>
<ion-label class="float-status-all float-status" >
<ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0" src="assets/images/check-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.viewed.length >= 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon>
</ion-label>
{{last ? scrollToBottom() : ''}}
</div>
</div>
@@ -70,11 +75,11 @@
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer">
</fa-icon>
<mat-menu #beforeMenu="matMenu" xPosition="before">
<button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button>
<button (click)="deleteMessage(msg._id, msg)" class="menuButton">Apagar mensagem</button>
</mat-menu>
</div>
<div class="title">
<ion-label>{{msg.u.name}} </ion-label>
<ion-label>{{msg.u.name}}</ion-label>
<span class="time">{{msg.duration}}</span>
</div>
<div>
@@ -82,11 +87,13 @@
<div *ngFor="let file of msg.attachments">
<div *ngIf="msg.file.type == 'application/img'" (click)="openPreview(msg)" dfsdvsvs>
<img src={{msg.attachments[0].image_url}} alt="image">
<!-- <ion-label class="float-status-image float-status-all">
<ion-icon *ngIf="!msg.offline && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.offline && msg.viewed.length == 0" src="assets/images/check-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.viewed.length == 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon>
</ion-label> -->
<ion-label class="float-status-all float-status" >
<ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0" src="assets/images/check-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.viewed.length >= 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon>
</ion-label>
</div>
<div *ngIf="msg.file.type != 'application/img'">
<div *ngIf="msg.file.type != 'application/audio'" class="file add-attachment-bg-color">
@@ -123,11 +130,13 @@
<span *ngIf="file.description && msg.file.type != 'application/webtrix'"></span>
<span *ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span>
</ion-label>
<!-- <ion-label class="float-status-webtrix float-status-all">
<ion-icon *ngIf="!msg.offline && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.offline && msg.viewed.length == 0" src="assets/images/check-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.viewed.length == 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon>
</ion-label> -->
<ion-label class="float-status-all float-status" >
<ion-icon *ngIf="msg.messageSend == false" src="assets/images/clock-regular.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend == true && msg.received.length == 0" src="assets/images/check-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.messageSend && msg.received.length >= 1 && msg.viewed.length == 0" src="assets/images/check-double-solid.svg"></ion-icon>
<ion-icon *ngIf="msg.viewed.length >= 1" src="assets/images/check-double-solid -viewed.svg"></ion-icon>
</ion-label>
</div>
</div>
</div>
@@ -150,55 +159,6 @@
</ion-label><br />
</div>
</div>
<!-- <div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45' *ngIf="msg.msg ==''">
<div *ngIf="msg.file">
<div *ngIf="msg.file.type == 'application/img'">
<div class="message-item-options d-flex justify-content-end">
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer">
</fa-icon>
<mat-menu #beforeMenu="matMenu" xPosition="before">
<button (click)="deleteMessage(msg._id)" class="menuButton">Apagar mensagem</button>
</mat-menu>
</div>
<div class="title">
<ion-label>{{msg.u.name}}</ion-label>
<span class="time">{{msg.duration}}</span>
</div>
<div>
<ion-label>{{msg.msg}}</ion-label>
<div *ngIf="msg.file" class="message-attachments">
<div>
<div (click)="openPreview(msg)">
File
<img *ngIf="msg.attachments[0].image_url" src="{{msg.attachments[0].image_url}}" alt="image">
</div>
</div>
</div>
{{last ? scrollToBottom() : ''}}
</div>
</div>
</div>
</div> -->
<!-- <div *ngIf="msg.file">
<div class="info-meeting" *ngIf="msg.file.type == 'application/meeting'">
<ion-label class="info-meeting-small">{{msg.u.name}} criou esta reunião</ion-label><br />
<button (click)="goToEvent(msg.file.id)" class="btn-no-color info-meeting-normal">
<ion-label class="info-meeting-normal">{{msg.file.subject}}</ion-label>
</button><br />
<ion-label class="info-meeting-medium">
<ion-icon name="calendar-outline"></ion-icon> De {{showDateDuration(msg.file.start_date)}} a
{{showDateDuration(msg.file.end_date)}}
</ion-label><br />
<ion-label class="info-meeting-medium">
<ion-icon></ion-icon>
<ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}
</ion-label><br />
</div>
{{last ? scrollToBottom() : ''}}
</div> -->
</div>
</div>
<ion-fab horizontal="end" vertical="bottom" slot="fixed">
@@ -210,8 +170,8 @@
</ion-content>
<ion-footer>
<ion-footer (click)="wsChatMethodsService.getDmRoom(roomId).sendReadMessage()">
<div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true" >
<ngx-letters-avatar *ngIf="showAvatar"
[avatarName]= "wsChatMethodsService.getDmRoom(roomId).name"
+14 -13
View File
@@ -120,10 +120,9 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
private fileToBase64Service: FileToBase64Service,
private sanitiser: DomSanitizer,
) {
this.loggedUser = authService.ValidatedUserChat['data'];
}
ngOnChanges(changes: SimpleChanges): void {
this.wsChatMethodsService.getDmRoom(this.roomId).loadHistory({})
@@ -192,7 +191,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
}
scrollToBottomClicked = () => {
console.log('scroll')
try {
this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight;
//this.scrollingOnce = false;
@@ -424,9 +422,11 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
}
deleteMessage(msgId: string) {
const room = this.wsChatMethodsService.getDmRoom(this.roomId)
this.alertService.confirmDeleteMessage(msgId, room);
deleteMessage(msgId: string, msg:MessageService) {
msg.delateStatusFalse()
this.wsChatMethodsService.getDmRoom(this.roomId).sendDeleteRequest(msgId)
}
async viewDocument(msg: any, url?: string) {
@@ -507,14 +507,12 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
}
getChatMembers() {
console.log(this.roomId);
// console.log(this.roomId);
//this.showLoader = true;
this.chatService.getMembers(this.roomId).subscribe(res => {
this.members = res['members'];
this.dmUsers = res['members'].filter(data => data.username != this.loggedUser.me.username)
console.log(res);
console.log(this.dmUsers);
this.showLoader = false;
});
}
@@ -645,6 +643,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
temporaryData: formData,
attachments: [{
"title": file.path,
// "image_url": "",
//"image_url": 'data:image/jpeg;base64,' + file.base64String,
"text": "description",
"title_link_download": false,
@@ -774,6 +773,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
const roomId = this.roomId
const file: any = await this.fileService.getFileFromDevice(types);
console.log('Add file', file)
/* const imageData = await this.fileToBase64Service.convert(file).then((filee) => {
console.log('Add file', filee)
@@ -938,9 +938,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
ts: msg.attachments[0].ts
}
await this.storage.set(msg.file.guid, this.downloadFile).then(() => {
console.log('IMAGE SAVED')
});
// save the changes to the storage
msg.save()
}
});
@@ -1007,7 +1008,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
testEditMessage(msg: MessageService) {
msg.receptorReceive()
// msg.receptorReceive()
// alert('cool!')
}
}
+1 -1
View File
@@ -88,7 +88,7 @@ class SessionService {
this.reset(new UserSession())
}
private save() {
save() {
localstoreService.set(this.keyName, {
user: this._user
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M232 120C232 106.7 242.7 96 256 96C269.3 96 280 106.7 280 120V243.2L365.3 300C376.3 307.4 379.3 322.3 371.1 333.3C364.6 344.3 349.7 347.3 338.7 339.1L242.7 275.1C236 271.5 232 264 232 255.1L232 120zM256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512C114.6 512 0 397.4 0 256C0 114.6 114.6 0 256 0zM48 256C48 370.9 141.1 464 256 464C370.9 464 464 370.9 464 256C464 141.1 370.9 48 256 48C141.1 48 48 141.1 48 256z"/></svg>

After

Width:  |  Height:  |  Size: 667 B

+1 -1
View File
@@ -13,7 +13,7 @@ export const environment = {
domain: 'gabinetedigital.local', //gabinetedigital.local
defaultuser: 'paulo.pinto@gabinetedigital.local',//paulo.pinto paulo.pinto@gabinetedigital.local
defaultuserpwd: 'tabteste@006', //tabteste@006,
chatOffline: false
chatOffline: true
};
/*