mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 12:37:53 +00:00
Merge branch 'tempFile' of bitbucket.org:equilibriumito/gabinete-digital into developer
This commit is contained in:
+2
-2
@@ -35,7 +35,7 @@ npm-debug.log*
|
||||
# Custom
|
||||
/package-lock.json
|
||||
|
||||
|
||||
|
||||
src/app/architect/
|
||||
src/environments/environment.e2e.ts
|
||||
.env
|
||||
@@ -52,4 +52,4 @@ node_modules_
|
||||
node_modules__
|
||||
plugins_
|
||||
ios
|
||||
src/plugin/beast-orm/
|
||||
src/plugin/beast-orm
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest package="com.gpr.gabinetedigital" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:name=".App" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
|
||||
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="@string/title_activity_main" android:launchMode="singleTask" android:name="com.gpr.gabinetedigital.MainActivity" android:theme="@style/AppTheme.NoActionBarLaunch">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<provider android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider">
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
</manifest>
|
||||
@@ -16,5 +16,8 @@
|
||||
"sound"
|
||||
]
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"url": "http://192.168.1.8:8100"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.capacitorjs.app.testapp;
|
||||
|
||||
import com.getcapacitor.BridgeActivity;
|
||||
|
||||
public class MainActivity extends BridgeActivity {}
|
||||
Generated
+5
@@ -6229,6 +6229,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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
});
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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) => {
|
||||
|
||||
@@ -63,7 +63,8 @@
|
||||
<span class="time">{{msg.duration}}</span>
|
||||
</div>
|
||||
<div class="message">
|
||||
<ion-label>{{msg.msg}}</ion-label>
|
||||
<ion-label *ngIf="msg.delate == false">{{msg.msg}}</ion-label>
|
||||
<ion-label *ngIf="msg.delate == true">{{msg.msg}}</ion-label>
|
||||
{{last ? scrollToBottom() : ''}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,7 +93,7 @@
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div *ngIf="msg.file">
|
||||
<div *ngIf="msg.file && msg.delate == false">
|
||||
<div class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}' class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}' *ngIf="msg.t != 'r' && msg.t != 'ul' && msg.t != 'ru' && msg.file.type != 'application/meeting'" (press)="handlePress(msg._id)">
|
||||
<div class="title">
|
||||
<ion-label>{{msg.u.name ?? ""}}</ion-label>
|
||||
@@ -117,7 +118,15 @@
|
||||
<ion-label class="file-title">{{file.title}}</ion-label>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="msg.file.type == 'application/audio'">
|
||||
<div (click)="audioPreview(msg)" class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && !file.title_link">
|
||||
<ion-item class="add-attachment-bg-color" shape="round" lines="none" type="button">
|
||||
<ion-icon name="mic-outline" class="file-icon"></ion-icon>
|
||||
<ion-label>{{file.title}}</ion-label>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></ion-icon>
|
||||
</ion-item>
|
||||
</div>
|
||||
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && file.title_link">
|
||||
<audio [src]="file.title_link|safehtml" preload="metadata" class="d-flex width-100" controls controlsList="nodownload noplaybackrate"></audio>
|
||||
</div>
|
||||
<div class="file-details-optional add-attachment-bg-color">
|
||||
@@ -140,7 +149,9 @@
|
||||
<ion-label class="info-meeting-medium"><ion-icon></ion-icon><ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}</ion-label><br />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="msg.file && msg.delate == true">
|
||||
Apagou a mensagem
|
||||
</div>
|
||||
|
||||
<div *ngIf="msg.t == 'r'" class="info-text">
|
||||
<ion-label>Alterou o nome do grupo para "{{msg.msg.split('-').join(' ')}}"</ion-label><br />
|
||||
@@ -190,8 +201,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() {
|
||||
@@ -419,41 +428,64 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.wsChatMethodsService.getGroupRoom(this.roomId).send({})
|
||||
}
|
||||
|
||||
base64toBlob(base64Data, contentType) {
|
||||
contentType = contentType || '';
|
||||
var sliceSize = 1024;
|
||||
var byteCharacters = atob(base64Data);
|
||||
var bytesLength = byteCharacters.length;
|
||||
var slicesCount = Math.ceil(bytesLength / sliceSize);
|
||||
var byteArrays = new Array(slicesCount);
|
||||
|
||||
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
|
||||
var begin = sliceIndex * sliceSize;
|
||||
var end = Math.min(begin + sliceSize, bytesLength);
|
||||
|
||||
var bytes = new Array(end - begin);
|
||||
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
|
||||
bytes[i] = byteCharacters[offset].charCodeAt(0);
|
||||
}
|
||||
byteArrays[sliceIndex] = new Uint8Array(bytes);
|
||||
}
|
||||
return new Blob(byteArrays, { type: contentType });
|
||||
}
|
||||
|
||||
async sendAudio(fileName) {
|
||||
|
||||
const roomId = this.roomId
|
||||
let audioFile;
|
||||
this.storage.get('recordData').then((recordData) => {
|
||||
console.log(recordData);
|
||||
audioFile = recordData;
|
||||
if(recordData.value.recordDataBase64.includes('data:audio')){
|
||||
this.audioRecorded = recordData.value.recordDataBase64;
|
||||
}
|
||||
else{
|
||||
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`;
|
||||
}
|
||||
});
|
||||
|
||||
//Converting base64 to blob
|
||||
const base64Response = await fetch(this.audioRecorded);
|
||||
const blob = await base64Response.blob();
|
||||
|
||||
const encodedData = btoa(this.audioRecorded);
|
||||
const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
|
||||
console.log(blob)
|
||||
const formData = new FormData();
|
||||
formData.append("blobFile", blob);
|
||||
|
||||
this.wsChatMethodsService.getGroupRoom(roomId).send({
|
||||
file: {
|
||||
"type": "application/audio",
|
||||
/* "guid": '', */
|
||||
"msDuration":audioFile.value.msDuration,
|
||||
"mimeType":audioFile.value.mimeType,
|
||||
},
|
||||
attachments: [{
|
||||
"title": fileName ,
|
||||
"title_link": this.audioRecorded,
|
||||
"title_link_download": true,
|
||||
"type": "file"
|
||||
"type": "audio"
|
||||
}],
|
||||
temporaryData: formData
|
||||
})
|
||||
this.deleteRecording();
|
||||
|
||||
});
|
||||
this.deleteRecording();
|
||||
}
|
||||
|
||||
|
||||
@@ -944,34 +976,35 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
downloadFileMsg(msg) {
|
||||
console.log('FILE TYPE', msg.file.type)
|
||||
this.downloadFile = "";
|
||||
// if (msg.file.type == "application/img") {
|
||||
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
|
||||
console.log('FILE TYPE 22', msg.file.guid)
|
||||
var name = msg.file.guid;
|
||||
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
|
||||
console.log('FILE TYPE 22', msg.file.guid)
|
||||
var name = msg.file.guid;
|
||||
|
||||
if (event.type === HttpEventType.DownloadProgress) {
|
||||
//this.downloadProgess = Math.round((100 * event.loaded) / event.total);
|
||||
console.log('FILE TYPE 33', msg.file.type)
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (msg.file.type == "application/img") {
|
||||
if (event.type === HttpEventType.DownloadProgress) {
|
||||
//this.downloadProgess = Math.round((100 * event.loaded) / event.total);
|
||||
console.log('FILE TYPE 33', msg.file.type)
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (msg.file.type == "application/img") {
|
||||
this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||
} else {
|
||||
} else if (msg.file.type === 'application/pdf') {
|
||||
|
||||
this.downloadFile = event.body;
|
||||
} else if (msg.file.type == 'application/audio') {
|
||||
this.downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '');
|
||||
}
|
||||
|
||||
msg.attachments[0] = {
|
||||
image_url: this.downloadFile,
|
||||
name: msg.attachments[0].name,
|
||||
title: msg.attachments[0].title,
|
||||
title_link: this.downloadFile,
|
||||
title_link_download: msg.attachments[0].title_link_download,
|
||||
ts: msg.attachments[0].ts
|
||||
}
|
||||
this.sqlservice.updateChatMsg(msg._id, this.downloadFile);
|
||||
}
|
||||
});
|
||||
console.log('FILE TYPE 44', this.downloadFile)
|
||||
//}
|
||||
// save the changes to the storage
|
||||
msg.save()
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async openPreview(msg) {
|
||||
@@ -994,5 +1027,12 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async audioPreview(msg) {
|
||||
console.log(msg);
|
||||
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
|
||||
this.downloadFileMsg(msg)
|
||||
} else {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<ion-header class="ion-no-border">
|
||||
<ion-header class="ion-no-border">
|
||||
<ion-toolbar class="header-toolbar">
|
||||
<!-- <div #rectangle class="rectangle" (press)="handlePress()">
|
||||
Double click me to change the color
|
||||
@@ -17,6 +17,8 @@
|
||||
<!-- <span><ion-icon class="{{users.status}}" name="ellipse"></ion-icon></span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div (click)="wsChatMethodsService.getDmRoom(roomId).deleteAll()" >delete all</div> -->
|
||||
<div class="middle-container-options" *ngIf="showMessageOptions">
|
||||
<fa-icon (click)="deleteMessage(selectedMsgId)" icon="trash" class="middle-container-options-icons"></fa-icon>
|
||||
<!-- <ion-icon name="trash"></ion-icon> -->
|
||||
@@ -24,14 +26,15 @@
|
||||
<div hidden class="right">
|
||||
<button class="btn-no-color" (click)="openMessagesOptions()">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-menu.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg">
|
||||
</ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div hidden class="header-bottom" (click)="addContacts()">
|
||||
<div class="header-bottom-icon">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/icon/theme/gov/icons-user.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/icon/theme/gov/icons-user.svg"></ion-icon>
|
||||
</div>
|
||||
<div class="header-bottom-contacts">
|
||||
<ion-label class="text-color-blue">Adicionar contacto</ion-label>
|
||||
@@ -49,31 +52,24 @@
|
||||
</ion-refresher-content>
|
||||
</ion-refresher> -->
|
||||
<div (click)="handleClick()" class="messages" #scrollMe>
|
||||
<div class="messages-list-item-wrapper container-width-100" *ngFor="let msg of wsChatMethodsService.getDmRoom(this.roomId).messages; let last = last" [class.messages-list-item-wrapper-active]="msg._id == selectedMsgId" >
|
||||
<div (press)="handlePress(msg._id)" class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}' (click)="downloadFileMsg(msg)" *ngIf="msg.msg !=''">
|
||||
<div class="messages-list-item-wrapper container-width-100"
|
||||
*ngFor="let msg of wsChatMethodsService.getDmRoom(this.roomId).messages; let last = last"
|
||||
[class.messages-list-item-wrapper-active]="msg._id == selectedMsgId">
|
||||
<div (press)="handlePress(msg._id)" class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}'
|
||||
(click)="downloadFileMsg(msg)" *ngIf="msg.msg !=''">
|
||||
<div class="title">
|
||||
<ion-label (click)="hkellor()">{{msg.u.name}}</ion-label>
|
||||
<span class="time">{{msg.duration}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<ion-label>{{msg.msg}}</ion-label>
|
||||
{{last ? scrollToBottom() : ''}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div (press)="handlePress(msg._id)" class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}' (click)="openPreview(msg)" *ngIf="msg.msg !=''">
|
||||
<div class="title">
|
||||
<ion-label>{{msg.u.name}}</ion-label>
|
||||
<span class="time">{{msg.duration}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<ion-label>{{msg.msg}}</ion-label>
|
||||
<ion-label *ngIf="msg.delate == false">{{msg.msg}}</ion-label>
|
||||
<ion-label *ngIf="msg.delate == true">{{msg.msg}}</ion-label>
|
||||
{{last ? scrollToBottom() : ''}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div *ngIf="msg.file">
|
||||
<div *ngIf="msg.file && msg.delate == false">
|
||||
<div (press)="handlePress(msg._id)" class='message-container incoming-{{msg.u.username!=loggedUser.me.username}}' *ngIf="msg.file.type != 'application/meeting'">
|
||||
<div class="title">
|
||||
<ion-label>{{msg.u.name}}</ion-label>
|
||||
@@ -88,50 +84,85 @@
|
||||
</div>
|
||||
<div *ngIf="msg.file.type != 'application/img'">
|
||||
<div class="file add-attachment-bg-color" *ngIf="msg.file.type != 'application/audio'">
|
||||
<div (click)="docIndex(i); viewDocument(msg, file.title_link)" class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file">
|
||||
<div (click)="docIndex(i); viewDocument(msg, file.title_link)"
|
||||
class="file-details add-ellipsis cursor-pointer" *ngIf="msg.file">
|
||||
<span *ngIf="msg.file.type">
|
||||
<fa-icon *ngIf="msg.file.type == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon>
|
||||
<fa-icon *ngIf="msg.file.type == 'application/word'" icon="file-word" class="word-icon"></fa-icon>
|
||||
<fa-icon *ngIf="msg.file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'" icon="file-word" class="excel-icon"></fa-icon>
|
||||
<ion-icon *ngIf="msg.file.type == 'application/webtrix'" src="assets/icon/webtrix.svg"></ion-icon>
|
||||
<fa-icon *ngIf="msg.file.type == 'application/word'" icon="file-word" class="word-icon">
|
||||
</fa-icon>
|
||||
<fa-icon
|
||||
*ngIf="msg.file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"
|
||||
icon="file-word" class="excel-icon"></fa-icon>
|
||||
<ion-icon *ngIf="msg.file.type == 'application/webtrix'" src="assets/icon/webtrix.svg">
|
||||
</ion-icon>
|
||||
</span>
|
||||
<ion-label class="file-title">{{file.title}}</ion-label>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="msg.file.type == 'application/audio'">
|
||||
<audio [src]="file.title_link|safehtml" preload="metadata" class="d-flex width-100" controls controlsList="nodownload noplaybackrate"></audio>
|
||||
<div (click)="audioPreview(msg)" class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && !file.title_link">
|
||||
<ion-item class="add-attachment-bg-color" shape="round" lines="none" type="button">
|
||||
<ion-icon name="mic-outline" class="file-icon"></ion-icon>
|
||||
<ion-label>{{file.title}}</ion-label>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></ion-icon>
|
||||
</ion-item>
|
||||
</div>
|
||||
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && file.title_link">
|
||||
<audio [src]="file.title_link|safehtml" preload="metadata" class="d-flex width-100" controls
|
||||
controlsList="nodownload noplaybackrate"></audio>
|
||||
</div>
|
||||
<div class="file-details-optional add-attachment-bg-color">
|
||||
<ion-label *ngIf="msg.file && msg.file != ''">
|
||||
<span *ngIf="file.description">{{file.description}}</span>
|
||||
<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>
|
||||
<span
|
||||
*ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span>
|
||||
</ion-label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{last ? scrollToBottom() : ''}}
|
||||
</div>
|
||||
{{last ? scrollToBottom() : ''}}
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="msg.file.type == 'application/meeting'" class="info-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>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="msg.file">
|
||||
<div *ngIf="msg.file.type == 'application/meeting'" class="info-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 />
|
||||
<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>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="msg.file && msg.delate == false">
|
||||
<div *ngIf="msg.file.type == 'application/meeting'" class="info-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 *ngIf="msg.file && msg.delate == true">
|
||||
Apagou a mensagem
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ion-fab horizontal="end" vertical="bottom" slot="fixed">
|
||||
@@ -165,27 +196,27 @@
|
||||
</ion-toolbar>
|
||||
</ion-footer> -->
|
||||
|
||||
<ion-footer>
|
||||
<ion-footer >
|
||||
|
||||
|
||||
<div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true">
|
||||
<ngx-letters-avatar
|
||||
[avatarName]= "wsChatMethodsService.getGroupRoom(roomId).name"
|
||||
[width]="30"
|
||||
[circular]="true"
|
||||
fontFamily="Roboto"></ngx-letters-avatar>
|
||||
<div class="typing" *ngIf="wsChatMethodsService.getDmRoom(roomId).otherUserType == true">
|
||||
<ngx-letters-avatar [avatarName]="wsChatMethodsService.getGroupRoom(roomId).name" [width]="30" [circular]="true"
|
||||
fontFamily="Roboto"></ngx-letters-avatar>
|
||||
está a escrever ...
|
||||
</div>
|
||||
<div class="width-100 pl-20 pr-20">
|
||||
<span *ngIf="!lastAudioRecorded">{{durationDisplay}}</span>
|
||||
<audio [src]="audioRecorded" class="d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded" controls controlsList="nodownload noplaybackrate"></audio>
|
||||
<audio [src]="audioRecorded" class="d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded" controls
|
||||
controlsList="nodownload noplaybackrate"></audio>
|
||||
</div>
|
||||
|
||||
<div class="container width-100 d-flex">
|
||||
<div>
|
||||
<button *ngIf="!recording && !lastAudioRecorded && allowTyping" class="btn-no-color" (click)="openChatOptions()">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-options" src="assets/images/icons-add.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-options" src="assets/images/theme/gov/icons-add.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-options"
|
||||
src="assets/images/icons-add.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-options"
|
||||
src="assets/images/theme/gov/icons-add.svg"></ion-icon>
|
||||
</button>
|
||||
<button *ngIf="recording || lastAudioRecorded || !allowTyping" class="btn-no-color" (click)="deleteRecording()">
|
||||
<fa-icon class="icon-size-27" icon="trash"></fa-icon>
|
||||
@@ -193,26 +224,38 @@
|
||||
</div>
|
||||
<div class="width-70 message-container">
|
||||
<div *ngIf="!recording && !lastAudioRecorded" class="type-message">
|
||||
<ion-textarea *ngIf="allowTyping" autocomplete="on" autocorrect="on" spellcheck="true" clearOnEdit="true" placeholder="Escrever uma mensagem" auto-grow class="message-input" rows="1" [(ngModel)]="wsChatMethodsService.getDmRoom(roomId).message" (ionChange)="wsChatMethodsService.getDmRoom(roomId).sendTyping()"></ion-textarea>
|
||||
<ion-textarea *ngIf="allowTyping" autocomplete="on" autocorrect="on" spellcheck="true" clearOnEdit="true"
|
||||
placeholder="Escrever uma mensagem" auto-grow class="message-input" rows="1"
|
||||
[(ngModel)]="wsChatMethodsService.getDmRoom(roomId).message"
|
||||
(ionChange)="wsChatMethodsService.getDmRoom(roomId).sendTyping()"></ion-textarea>
|
||||
</div>
|
||||
<div *ngIf="recording" class="d-flex align-items-center justify-content-center">
|
||||
<button (click)="stopRecording()" class="btn-no-color d-flex align-items-center justify-content-center">
|
||||
<ion-icon class="icon-size-45" name="stop-circle-outline" color="danger"></ion-icon>
|
||||
<ion-icon class="icon-size-45" name="stop-circle-outline" color="danger"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button #recordbtn *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && !lastAudioRecorded" (click)="startRecording()" class="btn-no-color">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/default/icons-chat-record-audio.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-record-audio.svg"></ion-icon>
|
||||
<button #recordbtn *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && !lastAudioRecorded"
|
||||
(click)="startRecording()" class="btn-no-color">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send"
|
||||
src="assets/icon/theme/default/icons-chat-record-audio.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send"
|
||||
src="assets/icon/theme/gov/icons-chat-record-audio.svg"></ion-icon>
|
||||
</button>
|
||||
<button *ngIf="wsChatMethodsService.getDmRoom(roomId).message" class="btn-no-color" (click)="sendMessage()" class="btn-no-color">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
<button *ngIf="wsChatMethodsService.getDmRoom(roomId).message" class="btn-no-color" (click)="sendMessage()"
|
||||
class="btn-no-color">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send"
|
||||
src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send"
|
||||
src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
</button>
|
||||
<button *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && lastAudioRecorded" (click)="sendAudio(lastAudioRecorded)" class="btn-no-color">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send" src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
<button *ngIf="!wsChatMethodsService.getDmRoom(roomId).message && lastAudioRecorded"
|
||||
(click)="sendAudio(lastAudioRecorded)" class="btn-no-color">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="chat-icon-send"
|
||||
src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="chat-icon-send"
|
||||
src="assets/icon/theme/gov/icons-chat-send.svg"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -366,41 +366,64 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.wsChatMethodsService.getDmRoom(this.roomId).send({})
|
||||
}
|
||||
|
||||
base64toBlob(base64Data, contentType) {
|
||||
contentType = contentType || '';
|
||||
var sliceSize = 1024;
|
||||
var byteCharacters = atob(base64Data);
|
||||
var bytesLength = byteCharacters.length;
|
||||
var slicesCount = Math.ceil(bytesLength / sliceSize);
|
||||
var byteArrays = new Array(slicesCount);
|
||||
|
||||
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
|
||||
var begin = sliceIndex * sliceSize;
|
||||
var end = Math.min(begin + sliceSize, bytesLength);
|
||||
|
||||
var bytes = new Array(end - begin);
|
||||
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
|
||||
bytes[i] = byteCharacters[offset].charCodeAt(0);
|
||||
}
|
||||
byteArrays[sliceIndex] = new Uint8Array(bytes);
|
||||
}
|
||||
return new Blob(byteArrays, { type: contentType });
|
||||
}
|
||||
|
||||
async sendAudio(fileName) {
|
||||
|
||||
const roomId = this.roomId
|
||||
let audioFile;
|
||||
this.storage.get('recordData').then((recordData) => {
|
||||
console.log(recordData);
|
||||
audioFile = recordData;
|
||||
if(recordData.value.recordDataBase64.includes('data:audio')){
|
||||
this.audioRecorded = recordData.value.recordDataBase64;
|
||||
}
|
||||
else{
|
||||
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`;
|
||||
}
|
||||
});
|
||||
|
||||
//Converting base64 to blob
|
||||
const base64Response = await fetch(this.audioRecorded);
|
||||
const blob = await base64Response.blob();
|
||||
|
||||
const encodedData = btoa(this.audioRecorded);
|
||||
const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
|
||||
console.log(blob)
|
||||
const formData = new FormData();
|
||||
formData.append("blobFile", blob);
|
||||
|
||||
this.wsChatMethodsService.getDmRoom(roomId).send({
|
||||
file: {
|
||||
"type": "application/audio",
|
||||
/* "guid": '', */
|
||||
"msDuration":audioFile.value.msDuration,
|
||||
"mimeType":audioFile.value.mimeType,
|
||||
},
|
||||
attachments: [{
|
||||
"title": fileName ,
|
||||
"title_link": this.audioRecorded,
|
||||
"title_link_download": true,
|
||||
"type": "file"
|
||||
"type": "audio"
|
||||
}],
|
||||
temporaryData: formData
|
||||
})
|
||||
this.deleteRecording();
|
||||
|
||||
});
|
||||
this.deleteRecording();
|
||||
}
|
||||
|
||||
blobToBase64 = blob => {
|
||||
@@ -517,8 +540,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;
|
||||
});
|
||||
}
|
||||
@@ -743,14 +764,11 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
/* const imageData = await this.fileToBase64Service.convert(file).then((filee) => {
|
||||
console.log('Add file', filee)
|
||||
}) */
|
||||
const response = await fetch(file);
|
||||
const blob = await response.blob();
|
||||
const blob2 = new Blob([blob])
|
||||
console.log('Add file base64', file)
|
||||
console.log('Add file blob', blob)
|
||||
const blob = new Blob(file, { type: file.type })
|
||||
console.log('Add file', blob)
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("blobFile", blob2);
|
||||
formData.append("blobFile", blob);
|
||||
|
||||
this.wsChatMethodsService.getDmRoom(roomId).send({
|
||||
file: {
|
||||
@@ -892,37 +910,35 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
downloadFileMsg(msg: MessageService) {
|
||||
console.log('FILE TYPE', msg.file.type)
|
||||
this.downloadFile = "";
|
||||
//if (msg.file.type == "application/img") {
|
||||
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
|
||||
console.log('FILE TYPE 22', msg.file.guid)
|
||||
var name = msg.file.guid;
|
||||
|
||||
if (event.type === HttpEventType.DownloadProgress) {
|
||||
this.downloadProgess = Math.round((100 * event.loaded) / event.total);
|
||||
console.log(this.downloadProgess)
|
||||
//this.downloadProgess = Math.round((100 * event.loaded) / event.total);
|
||||
console.log('FILE TYPE 33', msg.file.type)
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (msg.file.type == "application/img") {
|
||||
this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||
} else {
|
||||
//console.log('TRY THIS LIBRARY ',fromByteArray(event.body));
|
||||
this.downloadFile = event.body;
|
||||
}
|
||||
} else if (msg.file.type === 'application/pdf') {
|
||||
|
||||
this.downloadFile = event.body;
|
||||
} else if (msg.file.type == 'application/audio') {
|
||||
this.downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '');
|
||||
}
|
||||
msg.attachments[0] = {
|
||||
image_url: this.downloadFile,
|
||||
name: msg.attachments[0].name,
|
||||
title: msg.attachments[0].title,
|
||||
title_link: this.downloadFile,
|
||||
title_link_download: msg.attachments[0].title_link_download,
|
||||
ts: msg.attachments[0].ts
|
||||
}
|
||||
this.sqlservice.updateChatMsg(msg._id, this.downloadFile);
|
||||
// save the changes to the storage
|
||||
msg.save()
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
testDownlod(msg: MessageService) {
|
||||
@@ -932,7 +948,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
async openPreview(msg) {
|
||||
console.log(msg);
|
||||
|
||||
if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') {
|
||||
if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '' || !msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
|
||||
this.downloadFile(msg)
|
||||
//this.testDownlod(msg)
|
||||
|
||||
@@ -952,6 +968,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
}
|
||||
|
||||
async audioPreview(msg) {
|
||||
console.log(msg);
|
||||
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
|
||||
this.downloadFileMsg(msg)
|
||||
} else {}
|
||||
}
|
||||
|
||||
|
||||
imageSize(img) {
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,75 @@ 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() {
|
||||
|
||||
// alert('delete data')
|
||||
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) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,181 @@ 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) {
|
||||
|
||||
const allDeleteMessages = await DeleteMessageModel.filter({rid: this.id}).execute()
|
||||
|
||||
delete ChatMessage.temporaryData
|
||||
messages.push(ChatMessage)
|
||||
this.storage.set('chatmsg' + this.id, messages)
|
||||
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 +346,6 @@ export class RoomService {
|
||||
async (ChatMessage) => {
|
||||
|
||||
const DeletedMessageId = ChatMessage.fields.args[0]._id;
|
||||
console.log(DeletedMessageId);
|
||||
this.deleteMessage(DeletedMessageId)
|
||||
|
||||
}
|
||||
@@ -285,12 +357,28 @@ 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)
|
||||
|
||||
|
||||
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()
|
||||
|
||||
this.deleteMessageFromDb(id)
|
||||
//Get previous last message from room
|
||||
const previousLastMessage = this.messages.slice(-1)[0];
|
||||
|
||||
@@ -300,9 +388,62 @@ export class RoomService {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
deleteAll() {
|
||||
this.messages.forEach((message)=>{
|
||||
if(message?._id) {
|
||||
this.sendDeleteRequest(message._id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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()
|
||||
this.deleteMessage(msgId)
|
||||
},
|
||||
(response) => {
|
||||
|
||||
if (response.error.error.startsWith('No message found with the id of')) {
|
||||
// alert('not found')
|
||||
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 +457,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 +480,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 +506,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 +522,7 @@ export class RoomService {
|
||||
this.WsChatService.sendStreamNotifyRoom(this.id, SessionStore.user.RochetChatUser, 'typing', this.isTyping)
|
||||
}
|
||||
} else {
|
||||
//console.log(now - this.lastTimeType)
|
||||
|
||||
}
|
||||
|
||||
}, 3000)
|
||||
@@ -433,43 +554,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_iD({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 = 1000, forceUpdate = false }) {
|
||||
|
||||
if(forceUpdate == false) {
|
||||
if (this.hasLoadHistory) {
|
||||
@@ -477,16 +603,29 @@ 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) => {
|
||||
console.log('load chatHistory', JSON.stringify(chatHistory))
|
||||
|
||||
this.prepareMessage(message)
|
||||
// this.messages = this.sortService.sortDate(this.messages, '_updatedAt')
|
||||
const messagesId = this.messages.map((message)=> message._id)
|
||||
|
||||
chatHistory.result.messages.reverse().forEach(async(message: any) => {
|
||||
|
||||
if (!messagesId.includes(message._id)) {
|
||||
const messagesToSave = await this.prepareMessageCreateIfNotExist_iD({message: message});
|
||||
if(messagesToSave) {
|
||||
await messagesToSave.addMessageDB()
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
this.storage.set('chatmsg' + this.id, chatHistory.result.messages)
|
||||
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
@@ -497,38 +636,156 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async prepareMessageCreateIfNotExist_iD({message}) {
|
||||
message = this.fix_updatedAt(message)
|
||||
|
||||
const found = this.messages.find((MessageService, index) => {
|
||||
if (MessageService._id == message._id ) {
|
||||
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 +793,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 +804,6 @@ export class RoomService {
|
||||
return message
|
||||
}
|
||||
|
||||
|
||||
usernameToDisplayName(username) {
|
||||
|
||||
const firstName = capitalizeTxt(username.split('.')[0])
|
||||
@@ -556,4 +811,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){
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -23,10 +23,7 @@
|
||||
</ion-label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div *ngIf="room.customFields.countDownDate" class="d-flex align-items-center yellow-orange pl-10">
|
||||
<i class="far fa-clock font-15" ></i>
|
||||
<ion-label class="font-15 pl-10" color="warning">{{countDownDate()}}</ion-label>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
@@ -57,12 +54,13 @@
|
||||
<span class="time">{{msg.duration}}</span>
|
||||
</div>
|
||||
<div class="message">
|
||||
<ion-label>{{msg.msg}}</ion-label>
|
||||
<ion-label *ngIf="msg.delate == false">{{msg.msg}}</ion-label>
|
||||
<ion-label *ngIf="msg.delate == true">{{msg.msg}}</ion-label>
|
||||
{{last ? scrollToBottom() : ''}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="msg.file">
|
||||
<div *ngIf="msg.file && msg.delate == false">
|
||||
<div class="message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45" *ngIf="msg.t != 'r' && msg.t != 'ul' && msg.t != 'au' && msg.t != 'ru' && msg.file.type != 'application/meeting'" >
|
||||
<div *ngIf="msg.file.type != 'application/meeting'">
|
||||
<div class="message-item-options d-flex justify-content-end">
|
||||
@@ -94,7 +92,15 @@
|
||||
<ion-label class="file-title">{{file.title}}</ion-label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio'">
|
||||
<div (click)="audioPreview(msg)" class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && !file.title_link">
|
||||
<ion-item class="add-attachment-bg-color" shape="round" lines="none" type="button">
|
||||
<ion-icon name="mic-outline" class="file-icon"></ion-icon>
|
||||
<ion-label>{{file.title}}</ion-label>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></ion-icon>
|
||||
</ion-item>
|
||||
</div>
|
||||
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && file.title_link">
|
||||
<audio [src]="file.title_link|safehtml" preload="metadata" controls controlsList="nodownload noplaybackrate"></audio>
|
||||
</div>
|
||||
<div class="file-details-optional add-attachment-bg-color">
|
||||
@@ -118,35 +124,10 @@
|
||||
<ion-label class="info-meeting-medium"><ion-icon></ion-icon><ion-icon name="location-outline"></ion-icon> {{msg.file.venue}}</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.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)">
|
||||
<img *ngIf="msg.attachments[0].image_url" src="{{msg.attachments[0].image_url}}" alt="image">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{last ? scrollToBottom() : ''}}
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="msg.file && msg.delate == true">
|
||||
Apagou a mensagem
|
||||
</div>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<div *ngIf="msg.t == 'r'" class="info-text">
|
||||
<ion-label>Alterou o nome do grupo para "{{msg.msg.split('-').join(' ')}}"</ion-label><br />
|
||||
@@ -209,14 +190,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>
|
||||
|
||||
@@ -417,41 +417,64 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
|
||||
this.wsChatMethodsService.getGroupRoom(this.roomId).send({})
|
||||
}
|
||||
|
||||
base64toBlob(base64Data, contentType) {
|
||||
contentType = contentType || '';
|
||||
var sliceSize = 1024;
|
||||
var byteCharacters = atob(base64Data);
|
||||
var bytesLength = byteCharacters.length;
|
||||
var slicesCount = Math.ceil(bytesLength / sliceSize);
|
||||
var byteArrays = new Array(slicesCount);
|
||||
|
||||
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
|
||||
var begin = sliceIndex * sliceSize;
|
||||
var end = Math.min(begin + sliceSize, bytesLength);
|
||||
|
||||
var bytes = new Array(end - begin);
|
||||
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
|
||||
bytes[i] = byteCharacters[offset].charCodeAt(0);
|
||||
}
|
||||
byteArrays[sliceIndex] = new Uint8Array(bytes);
|
||||
}
|
||||
return new Blob(byteArrays, { type: contentType });
|
||||
}
|
||||
|
||||
async sendAudio(fileName) {
|
||||
|
||||
const roomId = this.roomId
|
||||
let audioFile;
|
||||
this.storage.get('recordData').then((recordData) => {
|
||||
console.log(recordData);
|
||||
audioFile = recordData;
|
||||
if(recordData.value.recordDataBase64.includes('data:audio')){
|
||||
this.audioRecorded = recordData.value.recordDataBase64;
|
||||
}
|
||||
else{
|
||||
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`;
|
||||
}
|
||||
});
|
||||
|
||||
//Converting base64 to blob
|
||||
const base64Response = await fetch(this.audioRecorded);
|
||||
const blob = await base64Response.blob();
|
||||
|
||||
const encodedData = btoa(this.audioRecorded);
|
||||
const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
|
||||
console.log(blob)
|
||||
const formData = new FormData();
|
||||
formData.append("blobFile", blob);
|
||||
|
||||
this.wsChatMethodsService.getGroupRoom(roomId).send({
|
||||
file: {
|
||||
"type": "application/audio",
|
||||
/* "guid": '', */
|
||||
"msDuration":audioFile.value.msDuration,
|
||||
"mimeType":audioFile.value.mimeType,
|
||||
},
|
||||
attachments: [{
|
||||
"title": fileName ,
|
||||
"title_link": this.audioRecorded,
|
||||
"title_link_download": true,
|
||||
"type": "file"
|
||||
"type": "audio"
|
||||
}],
|
||||
temporaryData: formData
|
||||
})
|
||||
this.deleteRecording();
|
||||
|
||||
});
|
||||
this.deleteRecording();
|
||||
}
|
||||
|
||||
deleteMessage(msgId: string) {
|
||||
@@ -973,38 +996,34 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
|
||||
downloadFileMsg(msg: MessageService) {
|
||||
console.log('FILE TYPE', msg.file.type)
|
||||
this.downloadFile = "";
|
||||
if (msg.file.type == "application/img") {
|
||||
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
|
||||
console.log('FILE TYPE 22', msg.file.guid)
|
||||
var name = msg.file.guid;
|
||||
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
|
||||
console.log('FILE TYPE 22', msg.file.guid)
|
||||
var name = msg.file.guid;
|
||||
|
||||
if (event.type === HttpEventType.DownloadProgress) {
|
||||
//this.downloadProgess = Math.round((100 * event.loaded) / event.total);
|
||||
console.log('FILE TYPE 33', msg.file.type)
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (msg.file.type == "application/img") {
|
||||
this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||
} else if (msg.file.type === 'application/pdf') {
|
||||
if (event.type === HttpEventType.DownloadProgress) {
|
||||
//this.downloadProgess = Math.round((100 * event.loaded) / event.total);
|
||||
console.log('FILE TYPE 33', msg.file.type)
|
||||
} else if (event.type === HttpEventType.Response) {
|
||||
if (msg.file.type == "application/img") {
|
||||
this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||
} else if (msg.file.type === 'application/pdf') {
|
||||
|
||||
this.downloadFile = event.body;
|
||||
}
|
||||
|
||||
msg.attachments[0] = {
|
||||
image_url: this.downloadFile,
|
||||
name: msg.attachments[0].name,
|
||||
title: msg.attachments[0].title,
|
||||
title_link_download: msg.attachments[0].title_link_download,
|
||||
ts: msg.attachments[0].ts
|
||||
}
|
||||
|
||||
await this.storage.set(msg.file.guid, this.downloadFile).then(() => {
|
||||
console.log('IMAGE SAVED')
|
||||
});
|
||||
this.downloadFile = event.body;
|
||||
} else if (msg.file.type == 'application/audio') {
|
||||
this.downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
msg.attachments[0] = {
|
||||
image_url: this.downloadFile,
|
||||
name: msg.attachments[0].name,
|
||||
title: msg.attachments[0].title,
|
||||
title_link: this.downloadFile,
|
||||
title_link_download: msg.attachments[0].title_link_download,
|
||||
ts: msg.attachments[0].ts
|
||||
}
|
||||
// save the changes to the storage
|
||||
msg.save()
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -1029,5 +1048,12 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
|
||||
|
||||
}
|
||||
|
||||
async audioPreview(msg) {
|
||||
console.log(msg);
|
||||
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
|
||||
this.downloadFileMsg(msg)
|
||||
} else {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div *ngIf="frameUrl" class="width-100">
|
||||
<iframe id="iframe" [src]="frameUrl" height="20%" width="100%" title="Iframe Example">
|
||||
</iframe>
|
||||
</div> -->
|
||||
<div hidden class="header-bottom" (click)="addContacts()">
|
||||
<div class="header-bottom-icon">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-icon>
|
||||
@@ -45,36 +41,41 @@
|
||||
<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>
|
||||
|
||||
<div *ngIf="msg.file">
|
||||
<div *ngIf="msg.file && msg.delate == false">
|
||||
<div class='message-item incoming-{{msg.u.username!=loggedUser.me.username}} max-width-45'
|
||||
*ngIf="msg.file.type != 'application/meeting'">
|
||||
<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>
|
||||
<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 +83,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">
|
||||
@@ -106,7 +109,15 @@
|
||||
<ion-label class="file-title">{{file.title}}</ion-label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio'">
|
||||
<div (click)="audioPreview(msg)" class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && !file.title_link">
|
||||
<ion-item class="add-attachment-bg-color" shape="round" lines="none" type="button">
|
||||
<ion-icon name="mic-outline" class="file-icon"></ion-icon>
|
||||
<ion-label>{{file.title}}</ion-label>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon-download" src="assets/icon/theme/default/icons-download.svg" slot="end"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon-download" src="assets/icon/theme/gov/icons-download.svg" slot="end"></ion-icon>
|
||||
</ion-item>
|
||||
</div>
|
||||
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio' && file.title_link">
|
||||
<audio [src]="file.title_link|safehtml" preload="metadata" class="flex-grow-1" controls controlsList="nodownload noplaybackrate"></audio>
|
||||
</div>
|
||||
<div class="file-details-optional add-attachment-bg-color">
|
||||
@@ -115,11 +126,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>
|
||||
@@ -143,56 +156,13 @@
|
||||
</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 && msg.delate == true">
|
||||
Apagou a mensagem
|
||||
</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">
|
||||
<ion-fab-button *ngIf="scrollToBottomBtn" (click)="scrollToBottomClicked()" color="light" size="small">
|
||||
<ion-icon name="chevron-down"></ion-icon>
|
||||
@@ -202,8 +172,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"
|
||||
|
||||
@@ -227,6 +227,13 @@
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.chat-icon-download{
|
||||
font-size: 95px;
|
||||
margin: 0 auto;
|
||||
margin-top: 4px;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.type-message{
|
||||
display: flex;
|
||||
border: 1px solid #ebebeb;
|
||||
@@ -329,3 +336,8 @@ display: block;
|
||||
.typing ngx-letters-avatar {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.div-do-audio{
|
||||
border: 1px solid red !important;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -356,6 +354,27 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
this.wsChatMethodsService.getDmRoom(this.roomId).send({})
|
||||
}
|
||||
|
||||
base64toBlob(base64Data, contentType) {
|
||||
contentType = contentType || '';
|
||||
var sliceSize = 1024;
|
||||
var byteCharacters = atob(base64Data);
|
||||
var bytesLength = byteCharacters.length;
|
||||
var slicesCount = Math.ceil(bytesLength / sliceSize);
|
||||
var byteArrays = new Array(slicesCount);
|
||||
|
||||
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
|
||||
var begin = sliceIndex * sliceSize;
|
||||
var end = Math.min(begin + sliceSize, bytesLength);
|
||||
|
||||
var bytes = new Array(end - begin);
|
||||
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
|
||||
bytes[i] = byteCharacters[offset].charCodeAt(0);
|
||||
}
|
||||
byteArrays[sliceIndex] = new Uint8Array(bytes);
|
||||
}
|
||||
return new Blob(byteArrays, { type: contentType });
|
||||
}
|
||||
|
||||
async sendAudio(fileName) {
|
||||
|
||||
const roomId = this.roomId
|
||||
@@ -369,37 +388,36 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
else{
|
||||
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`;
|
||||
}
|
||||
});
|
||||
|
||||
//Converting base64 to blob
|
||||
const base64Response = await fetch(this.audioRecorded);
|
||||
const blob = await base64Response.blob();
|
||||
|
||||
const encodedData = btoa(this.audioRecorded);
|
||||
const blob = this.base64toBlob(encodedData, recordData.value.mimeType)
|
||||
console.log(blob)
|
||||
const formData = new FormData();
|
||||
formData.append("blobFile", blob);
|
||||
|
||||
this.wsChatMethodsService.getDmRoom(roomId).send({
|
||||
file: {
|
||||
"type": "application/audio",
|
||||
/* "guid": '', */
|
||||
"msDuration":audioFile.value.msDuration,
|
||||
"mimeType":audioFile.value.mimeType,
|
||||
},
|
||||
attachments: [{
|
||||
"title": fileName ,
|
||||
"title_link": this.audioRecorded,
|
||||
"title_link_download": true,
|
||||
"type": "audio"
|
||||
}],
|
||||
temporaryData: formData
|
||||
})
|
||||
this.deleteRecording();
|
||||
|
||||
});
|
||||
this.deleteRecording();
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -480,14 +498,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;
|
||||
});
|
||||
}
|
||||
@@ -618,6 +634,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,
|
||||
@@ -747,6 +764,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)
|
||||
@@ -884,7 +902,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
downloadFileMsg(msg: MessageService) {
|
||||
console.log('FILE TYPE', msg.file.type)
|
||||
this.downloadFile = "";
|
||||
//if (msg.file.type == "application/img") {
|
||||
this.AttachmentsService.downloadFile(msg.file.guid).subscribe(async (event) => {
|
||||
console.log('FILE TYPE 22', msg.file.guid)
|
||||
var name = msg.file.guid;
|
||||
@@ -898,25 +915,22 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
} else if (msg.file.type === 'application/pdf') {
|
||||
|
||||
this.downloadFile = event.body;
|
||||
} else if (msg.file.type == 'application/audio') {
|
||||
this.downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '');
|
||||
}
|
||||
|
||||
msg.attachments[0] = {
|
||||
image_url: this.downloadFile,
|
||||
name: msg.attachments[0].name,
|
||||
title: msg.attachments[0].title,
|
||||
title_link: this.downloadFile,
|
||||
title_link_download: msg.attachments[0].title_link_download,
|
||||
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()
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
_arrayBufferToBase64( buffer ) {
|
||||
@@ -936,6 +950,13 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
DocumentViewer.viewDocument
|
||||
}
|
||||
|
||||
async audioPreview(msg) {
|
||||
console.log(msg);
|
||||
if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') {
|
||||
this.downloadFileMsg(msg)
|
||||
} else {}
|
||||
}
|
||||
|
||||
async openPreview(msg) {
|
||||
console.log(msg);
|
||||
|
||||
@@ -966,7 +987,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
|
||||
|
||||
testEditMessage(msg: MessageService) {
|
||||
msg.receptorReceive()
|
||||
// msg.receptorReceive()
|
||||
// alert('cool!')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class SessionService {
|
||||
this.reset(new UserSession())
|
||||
}
|
||||
|
||||
private save() {
|
||||
save() {
|
||||
|
||||
localstoreService.set(this.keyName, {
|
||||
user: this._user
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<svg width="55" height="55" viewBox="0 0 55 55" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_223_29)">
|
||||
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
|
||||
</g>
|
||||
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4327 31.208H20.3764C20.6649 31.208 20.9402 31.3245 21.1401 31.532L23.3285 33.7963C23.5285 34.0028 23.8037 34.1198 24.0923 34.1198H31.0456C31.3336 34.1198 31.6094 34.0033 31.8094 33.7963L33.9972 31.532C34.1972 31.325 34.473 31.208 34.7609 31.208H37.5879C38.1734 31.208 38.6487 31.6818 38.6487 32.2668V35.9727C38.6487 36.5577 38.1734 37.0315 37.5879 37.0315H17.4333C16.8472 37.0315 16.3725 36.5577 16.3725 35.9727V32.2668C16.3725 31.6818 16.8472 31.208 17.4333 31.208H17.4327ZM29.6316 19.0358V26.1214L30.8186 26.087C31.1114 26.0785 31.3559 26.3094 31.3644 26.6011C31.3686 26.7609 31.3007 26.9134 31.1798 27.0177L27.5329 30.1471L23.8859 27.0834C23.6621 26.8949 23.6335 26.5608 23.8223 26.3369C23.9231 26.2172 24.0726 26.1484 24.2296 26.1489L25.3811 26.1526V19.0321C25.3811 18.4471 25.8563 17.9732 26.4419 17.9732H26.4445L28.5735 17.9769C29.1585 17.9785 29.6316 18.4518 29.6316 19.0358V19.0358Z" stroke="#797979" stroke-linejoin="round"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_223_29" x="0" y="0" width="55" height="55" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="2.5"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_223_29"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_223_29" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg width="55" height="55" viewBox="0 0 55 55" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_223_29)">
|
||||
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
|
||||
</g>
|
||||
<path d="M49.5 27.5C49.5 39.6503 39.6503 49.5 27.5 49.5C15.3497 49.5 5.5 39.6503 5.5 27.5C5.5 15.3497 15.3497 5.5 27.5 5.5C39.6503 5.5 49.5 15.3497 49.5 27.5Z" stroke="#797979"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4327 31.208H20.3764C20.6649 31.208 20.9402 31.3245 21.1401 31.532L23.3285 33.7963C23.5285 34.0028 23.8037 34.1198 24.0923 34.1198H31.0456C31.3336 34.1198 31.6094 34.0033 31.8094 33.7963L33.9972 31.532C34.1972 31.325 34.473 31.208 34.7609 31.208H37.5879C38.1734 31.208 38.6487 31.6818 38.6487 32.2668V35.9727C38.6487 36.5577 38.1734 37.0315 37.5879 37.0315H17.4333C16.8472 37.0315 16.3725 36.5577 16.3725 35.9727V32.2668C16.3725 31.6818 16.8472 31.208 17.4333 31.208H17.4327ZM29.6316 19.0358V26.1214L30.8186 26.087C31.1114 26.0785 31.3559 26.3094 31.3644 26.6011C31.3686 26.7609 31.3007 26.9134 31.1798 27.0177L27.5329 30.1471L23.8859 27.0834C23.6621 26.8949 23.6335 26.5608 23.8223 26.3369C23.9231 26.2172 24.0726 26.1484 24.2296 26.1489L25.3811 26.1526V19.0321C25.3811 18.4471 25.8563 17.9732 26.4419 17.9732H26.4445L28.5735 17.9769C29.1585 17.9785 29.6316 18.4518 29.6316 19.0358V19.0358Z" stroke="#797979" stroke-linejoin="round"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_223_29" x="0" y="0" width="55" height="55" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="2.5"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_223_29"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_223_29" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -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 |
@@ -0,0 +1,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="173" height="178" viewBox="0 0 173 178">
|
||||
<defs>
|
||||
<ellipse id="37ng76i1qb" cx="42.422" cy="42.5" rx="42.422" ry="42.5"/>
|
||||
<filter id="7z30ci9zua" width="117.7%" height="117.6%" x="-8.8%" y="-8.8%" filterUnits="objectBoundingBox">
|
||||
<feOffset in="SourceAlpha" result="shadowOffsetOuter1"/>
|
||||
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="2.5"/>
|
||||
<feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#42B9FE" fill-opacity=".3" d="M78.031 168c48.523 0 113.902-43.009 86.32-95.233C136.77 20.542 136.033 7 93.437 7 50.841 7 .905 28.222.905 90.687.905 153.152 29.508 168 78.03 168z" transform="translate(-661 -387) translate(661 387)"/>
|
||||
<g>
|
||||
<g transform="translate(-661 -387) translate(661 387) translate(1.905) rotate(-15 97.339 11.047)">
|
||||
<rect width="89.361" height="112.826" x=".165" y="5.209" fill="#0782C9" fill-opacity=".5" rx="2"/>
|
||||
<rect width="89.361" height="112.826" x="4.716" y=".233" fill="#FFF" stroke="#0782C9" stroke-linejoin="round" stroke-width="2" rx="2"/>
|
||||
<rect width="52.804" height="4.964" x="24.04" y="32.43" fill="#0782C9" rx="2.482"/>
|
||||
<rect width="52.804" height="4.964" x="26.63" y="53.977" fill="#0782C9" rx="2.482"/>
|
||||
<rect width="36.557" height="4.964" x="24.523" y="76.287" fill="#0782C9" rx="2.482"/>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="translate(-661 -387) translate(661 387) translate(1.905) translate(80.654 88.496)">
|
||||
<use fill="#000" filter="url(#7z30ci9zua)" xlink:href="#37ng76i1qb"/>
|
||||
<use fill="#42B9FE" xlink:href="#37ng76i1qb"/>
|
||||
</g>
|
||||
<path stroke="#FFF" stroke-linejoin="round" stroke-width="2" d="M23.441 49.504h5.55c.544 0 1.063.22 1.44.612l4.126 4.277c.377.39.896.611 1.44.611h13.11c.543 0 1.063-.22 1.44-.611l4.125-4.277c.377-.391.897-.612 1.44-.612h5.33c1.104 0 2 .895 2 2v7c0 1.105-.896 2-2 2h-38c-1.105 0-2-.895-2-2v-7c0-1.105.895-2 2-2zM46.441 26.512v13.384h0l2.238-.065c.552-.016 1.013.42 1.029.971.008.302-.12.59-.348.787L42.484 47.5h0l-6.876-5.787c-.422-.356-.476-.987-.12-1.41.19-.226.472-.356.768-.355l2.171.007h0v-13.45c0-1.105.896-2 2-2h.005l4.014.007c1.103.003 1.995.897 1.995 2z" transform="translate(-661 -387) translate(661 387) translate(1.905) translate(80.654 88.496)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -6,5 +6,5 @@ export const environment = {
|
||||
domain: 'gabinetedigital.local',
|
||||
defaultuser: '',//paulo.pinto paulo.pinto@gabinetedigital.local
|
||||
defaultuserpwd: '', //tabteste@006,
|
||||
chatOffline: false
|
||||
chatOffline: true
|
||||
};
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+10
-2
@@ -1148,9 +1148,16 @@ ngx-mat-datetime-content{
|
||||
}
|
||||
}
|
||||
.audio-contentainer{
|
||||
width: 200px !important;
|
||||
min-width: 200px !important;
|
||||
display: flex;
|
||||
overflow: auto !important;
|
||||
.icon-download{
|
||||
font-size:35px !important;
|
||||
}
|
||||
.item-prior-download{
|
||||
--background:#000000e7;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.title{
|
||||
@@ -1190,7 +1197,8 @@ ngx-mat-datetime-content{
|
||||
}
|
||||
|
||||
.add-attachment-bg-color{
|
||||
background-color: #42b9fe13;
|
||||
background-color: #42b9fe13 !important;
|
||||
--background: #42b9fe0a !important;
|
||||
}
|
||||
|
||||
.message-attachments{
|
||||
|
||||
Reference in New Issue
Block a user