improve chat

This commit is contained in:
Peter Maquiran
2024-08-17 22:05:57 +01:00
parent eb615d4335
commit 650c772084
43 changed files with 712 additions and 1540 deletions
-4
View File
@@ -3,7 +3,6 @@ import {
OnInit,
} from '@angular/core';
import { ModalController } from '@ionic/angular';
import { ChatService } from 'src/app/services/chat.service';
import { GroupMessagesPage } from './modal/group-messages/group-messages.page';
import { ContactsPage } from './modal/./messages/contacts/contacts.page';
import { MessagesPage } from './modal/./messages/messages.page';
@@ -54,7 +53,6 @@ export class ChatPage implements OnInit {
items$!: DexieObservable<RoomListOutPutDTO[]>;
constructor(
private chatService: ChatService,
private modalController: ModalController,
private timeService: TimeService,
public ThemeService: ThemeService,
@@ -188,9 +186,7 @@ export class ChatPage implements OnInit {
message: '',
status: status,
}
this.chatService.setUserStatus(body).subscribe(res => {
})
}
hideRefreshButton() {
@@ -1,7 +1,6 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ModalController, PickerController } from '@ionic/angular';
import { ChatService } from 'src/app/services/chat.service';
import { ThemeService } from 'src/app/services/theme.service'
import { SessionStore } from 'src/app/store/session.service';
import { HttpResponse } from '@microsoft/signalr';
@@ -33,7 +32,6 @@ export class EditGroupPage implements OnInit {
constructor(
private modalController: ModalController,
private pickerController: PickerController,
private chatService: ChatService,
public ThemeService: ThemeService,
private RoomRepositoryService: RoomRepositoryService,
private httpErrorHandle: HttpErrorHandle,
@@ -48,16 +46,16 @@ export class EditGroupPage implements OnInit {
}
getRoomInfo(){
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
this.room = room['room'];
// this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
// this.room = room['room'];
try {
this.groupName = this.room.name.split('-').join(' ');
} catch (error) {
this.groupName = this.room.name;
}
// try {
// this.groupName = this.room.name.split('-').join(' ');
// } catch (error) {
// this.groupName = this.room.name;
// }
});
// });
}
close() {
@@ -93,11 +91,11 @@ export class EditGroupPage implements OnInit {
updateGroup() {
this.showLoader = true;
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
this.room = room['room'];
this.showLoader = false;
this.openGroupMessage.emit(this.room._id);
});
// this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
// this.room = room['room'];
// this.showLoader = false;
// this.openGroupMessage.emit(this.room._id);
// });
}
_ionChange(event){
@@ -1,7 +1,6 @@
import { Component, OnChanges, OnInit, Input, SimpleChanges, Output, EventEmitter, ViewChild, ElementRef, AfterViewInit, OnDestroy } from '@angular/core';
import { AnimationController, ModalController, PopoverController, Platform } from '@ionic/angular';
import { AlertService } from 'src/app/services/alert.service';
import { ChatService } from 'src/app/services/chat.service';
import { GroupContactsPage } from './group-contacts/group-contacts.page';
import { ChatOptionsFeaturesPage } from 'src/app/modals/chat-options-features/chat-options-features.page';
import { TimeService } from 'src/app/services/functions/time.service';
@@ -87,7 +86,6 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
// public ChatSystemService: ChatSystemService,
private modalController: ModalController,
public popoverController: PopoverController,
private chatService: ChatService,
private animationController: AnimationController,
private alertService: AlertService,
private timeService: TimeService,
@@ -156,9 +154,6 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
message: '',
status: status,
}
this.chatService.setUserStatus(body).subscribe(res => {
//
})
}
scrollToBottom(): void {
@@ -1,9 +1,9 @@
<ion-header class="ion-no-border" >
<ion-toolbar class="header-toolbar" >
<div class="main-header" *ngIf="roomData$ | async as roomData">
<div class="main-header">
<div class="header-top">
<div class="middle" >
<ion-label class="title"> {{ roomData.roomName }}</ion-label>
<ion-label class="title" *ngIf="roomData$ | async as roomData"> {{ roomData.roomName }}</ion-label>
<!-- <button (click)="ChatMessageDebuggingPage()">Dev</button> -->
<span *ngIf="roomStatus$ | async as roomStatus"><ion-icon *ngIf="roomStatus" class="online" name="ellipse"></ion-icon></span>
</div>
@@ -44,7 +44,7 @@
<div class="messages height-100 width-100 d-flex flex-column" #scrollMe >
<div
*ngFor="let message of messages1[roomId]" class="messages-list-item-wrapper"
*ngFor="let message of messages1[roomId]; let messageIndex = index" class="messages-list-item-wrapper"
[ngClass]="{'my-message': message.sender.wxUserId === sessionStore.user.UserId, 'other-message': message.sender.wxUserId !== sessionStore.user.UserId}"
>
<div class="message-container">
@@ -67,7 +67,10 @@
</div>
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Image">
<img [src]="attachment.safeFile">
<img
[src]="attachment.safeFile"
(load)="onImageLoad(message, messageIndex)"
(error)="onImageError()">
</div>
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Audio">
@@ -3,8 +3,6 @@ import { AnimationController, GestureController, IonRange, ModalController, Popo
import { ToastService } from 'src/app/services/toast.service';
import { ContactsPage } from '../new-group/contacts/contacts.page';
import { ChatOptionsFeaturesPage } from 'src/app/modals/chat-options-features/chat-options-features.page';
import { ChatMessageStore } from 'src/app/store/chat/chat-message.service';
import { ChatUserStorage } from 'src/app/store/chat/chat-user.service';
import { TimeService } from 'src/app/services/functions/time.service';
import { FileService } from 'src/app/services/functions/file.service';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
@@ -43,6 +41,7 @@ import { allowedDocExtension } from 'src/app/utils/allowedDocExtension';
import { SpeakerService, StartRecordingResultError, StopRecordingResultError } from 'src/app/infra/speaker/speaker.service'
import { compressImageBase64 } from 'src/app/utils/imageCompressore';
import { ChatPopoverPage } from '../../modal/chat-popover/chat-popover.page';
import { LastMessage } from '../../utils/lastMessage';
@Component({
selector: 'app-messages',
@@ -72,10 +71,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
@Output() getGroups: EventEmitter<any> = new EventEmitter<any>();
chatMessageStore = ChatMessageStore
chatUserStorage = ChatUserStorage
scrollingOnce: boolean = true;
private scrollChangeCallback: () => void;
currentPosition: any;
@@ -176,13 +171,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.listenToUpdateMessage();
this.listenToSendMessage()
this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
// this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) as any
this.roomStatus$ = this.roomRepositoryService.getRoomStatus(this.roomId)
this.roomRepositoryService.getRoomById(this.roomId)
this.messageRepositoryService.listAllMessagesByRoomId(this.roomId).then(()=> {
// this.getMessages();
})
this.userTypingServiceRepository.getUserTypingLive().subscribe((e) => {
const arrayNames = e.map(e => e.userName)
@@ -202,11 +194,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.messages1[this.roomId] = []
this.messages1[this.roomId] = messages
this.loadAttachment()
this.messages1[this.roomId].push(LastMessage)
setTimeout(() => {
this.scrollToBottomClicked()
}, 200)
this.loadAttachment()
}
@@ -214,33 +205,32 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
for(const message of this.messages1[this.roomId]) {
if(message.hasAttachment) {
const result = await this.chatServiceService.getMessageAttachmentByMessageId({
$messageId: message.$id,
id: message.attachments[0].id
})
if(result.isOk()){
message.attachments[0].safeFile = result.value
}
if(message.$id) {
console.log('message.$id', message.$id)
this.chatServiceService.getMessageAttachmentByMessageId(message).then((result)=> {
if(result.isOk()) {
message.attachments[0].safeFile = result.value
}
})
}
}
}
}
// Sorting function
sortBySentAt (arr, order = 'asc') {
return arr.sort((a, b) => {
// Handle null or undefined sentAt
const dateA = a.sentAt ? new Date(a.sentAt).getTime() : Number.MAX_VALUE;
const dateB = b.sentAt ? new Date(b.sentAt).getTime() : Number.MAX_VALUE;
async onImageLoad(message: MessageEntity, index:number) {
if(message.attachments[0].fileName == LastMessage.attachments[0].fileName) {
if (order === 'asc') {
return dateA - dateB;
} else {
return dateB - dateA;
}
});
};
this.scrollToBottom()
setTimeout(() => {
this.scrollToBottom();
}, 100)
this.messages1[this.roomId].splice(index, 1);
}
}
async onImageError() {}
listenToIncomingMessage() {
@@ -404,14 +394,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
}
ngOnInit() {
// this.ChatSystemService.getAllRooms();
// this.chatService.refreshtoken();
this.scrollToBottom();
this.getChatMembers();
this.deleteRecording();
// this.loadFiles();
}
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams, PopoverController } from '@ionic/angular';
import { ChatService } from 'src/app/services/chat.service';
import { ToastService } from 'src/app/services/toast.service';
import { ThemeService } from 'src/app/services/theme.service'
import { SetRoomOwnerPage } from 'src/app/modals/set-room-owner/set-room-owner.page';
@@ -1,7 +1,6 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams, PickerController } from '@ionic/angular';
import { ChatService } from 'src/app/services/chat.service';
import { ThemeService } from 'src/app/services/theme.service'
@Component({
@@ -21,7 +20,6 @@ export class EditGroupPage implements OnInit {
constructor(
private modalController: ModalController,
private pickerController: PickerController,
private chatService: ChatService,
private navParams: NavParams,
public ThemeService: ThemeService
) {
@@ -34,16 +32,7 @@ export class EditGroupPage implements OnInit {
}
getRoomInfo(){
this.chatService.getRoomInfo(this.roomId).subscribe(room=>{
this.room = room['room'];
try {
this.groupName = this.room.name.split('-').join(' ');
} catch(error) {
this.groupName = this.room.name;
}
});
}
close(){
@@ -57,13 +46,10 @@ export class EditGroupPage implements OnInit {
"roomId": this.room._id,
"name": name,
}
this.chatService.renameGroup(body).subscribe(res=>{
this.modalController.dismiss(res['group']);
});
}
else{
}
}
}
_ionChange(event){
this.showDuration = event.detail.checked;
@@ -72,42 +58,42 @@ export class EditGroupPage implements OnInit {
const picker = await this.pickerController.create({
cssClass: '',
buttons: [
{
{
text: 'Cancelar', role: 'cancel', cssClass: 'btn-cancel'
},
{
text: 'Ok',
{
text: 'Ok',
cssClass: 'btn-cancel',
handler:(value:any)=>{
this.selectedDuration = [
value.days.value,
value.hours.value,
value.minutes.value,
]
if(value.days.value != null && value.hours.value != null && value.minutes.value != null){
if(value.days.value > 0){
if(value.days.value == 1){
if(value.hours.value == 1){
this.displayDuration = value.days.value + " day " +
this.displayDuration = value.days.value + " day " +
value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.days.value + " days " +
this.displayDuration = value.days.value + " days " +
value.hours.value + " horas " +
value.minutes.value + " minutos";
}
}
else{
if(value.hours.value == 1){
this.displayDuration = value.days.value + " days " +
this.displayDuration = value.days.value + " days " +
value.hours.value + " hora " +
value.minutes.value + " minutos";
}
else{
this.displayDuration = value.days.value + " days " +
this.displayDuration = value.days.value + " days " +
value.hours.value + " horas " +
value.minutes.value + " minutos";
}
@@ -123,7 +109,7 @@ export class EditGroupPage implements OnInit {
value.minutes.value + " minutos";
}
}
}
}
},
},
],
@@ -176,7 +162,7 @@ export class EditGroupPage implements OnInit {
await picker.present();
picker.onDidDismiss().then(async data =>{
let day = await picker.getColumn('days');
let hour = await picker.getColumn('hours');
let hour = await picker.getColumn('hours');
let minutes = await picker.getColumn('minutes');
});
@@ -3,7 +3,6 @@ import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams } from '@ionic/angular';
import * as _ from 'lodash';
import { AuthService } from 'src/app/services/auth.service';
import { ChatService } from 'src/app/services/chat.service';
import { GroupMessagesPage } from '../group-messages.page';
import { ThemeService } from 'src/app/services/theme.service'
import { SessionStore } from 'src/app/store/session.service';
@@ -39,10 +38,6 @@ export class GroupContactsPage implements OnInit {
constructor(
private modalController: ModalController,
private http: HttpClient,
private chatService: ChatService,
private authService: AuthService,
private navParams: NavParams,
public ThemeService: ThemeService,
// public ChatSystemService: ChatSystemService,
)
@@ -122,18 +117,7 @@ export class GroupContactsPage implements OnInit {
}
getMembers(){
if(this.room.t == "p"){
this.chatService.getGroupMembers(this.room._id).subscribe(res=>{
this.members = res['members'];
this.loadUsers();
});
}
else if(this.room.t == "c"){
this.chatService.getChannelMembers(this.room._id).subscribe(res=>{
this.members = res['members'];
this.loadUsers();
});
}
}
separateLetter(record, recordIndex, records){
@@ -157,16 +141,10 @@ export class GroupContactsPage implements OnInit {
}
if(this.room.t == "p"){
this.chatService.removeGroupMember(body).subscribe(res=>{
this.getMembers();
});
}
else if(this.room.t == "c"){
this.chatService.removeChannelMember(body).subscribe(res=>{
this.getMembers();
});
}
}
@@ -262,9 +240,7 @@ export class GroupContactsPage implements OnInit {
"userId":user._id,
}
this.chatService.addUserToGroup(body).subscribe(res=>{
});
});
}
@@ -277,14 +253,7 @@ export class GroupContactsPage implements OnInit {
this.loading = true
console.log('this.room', this.room)
this.chatService.getRoomInfo(this.room._id).subscribe(room=>{
this.room = room['room'];
this.addContacts(this.room);
this.openGroupMessages(room['room']._id);
this.loading = false
}, ()=> {
this.loading = false
});
}
async openGroupMessages(roomId:any){
@@ -1,7 +1,6 @@
import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, OnDestroy, ChangeDetectorRef, } from '@angular/core';
import { ModalController, NavParams, PopoverController, Platform } from '@ionic/angular';
import { AlertService } from 'src/app/services/alert.service';
import { ChatService } from 'src/app/services/chat.service';
import { GroupContactsPage } from './group-contacts/group-contacts.page';
import { Router } from '@angular/router'
import { EditGroupPage } from '../edit-group/edit-group.page';
@@ -13,7 +12,6 @@ import { EventPerson } from 'src/app/models/eventperson.model';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { ThemeService } from 'src/app/services/theme.service'
import { ViewEventPage } from 'src/app/modals/view-event/view-event.page';
//import { ChatSystemService } from 'src/app/services/chat/chat-system.service';
import { FileType } from 'src/app/models/fileType';
import { Storage } from '@ionic/storage';
@@ -32,7 +30,6 @@ import { RouteService } from 'src/app/services/route.service';
import { FileValidatorService } from "src/app/services/file/file-validator.service"
import { sanitize } from "sanitize-filename-ts";
import { FilePicker } from '@capawesome/capacitor-file-picker';
import { ViewDocumentSecondOptionsPage } from 'src/app/modals/view-document-second-options/view-document-second-options.page';
import { NewEventPage } from 'src/app/pages/agenda/new-event/new-event.page';
import { ChatPopoverPage } from '../chat-popover/chat-popover.page';
import { ChatOptionsPopoverPage } from '../chat-options-popover/chat-options-popover.page';
@@ -91,10 +88,6 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
constructor(
private modalController: ModalController,
public popoverController: PopoverController,
private chatService: ChatService,
private navParams: NavParams,
private alertService: AlertService,
private route: Router,
private timeService: TimeService,
private fileService: FileService,
private toastService: ToastService,
@@ -103,7 +96,6 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
private platform: Platform,
//public ChatSystemService: ChatSystemService,
private storage: Storage,
private CameraService: CameraService,
private sanitiser: DomSanitizer,
private file: File,
private fileOpener: FileOpener,
@@ -1054,43 +1046,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy {
}
async serverLongPull() {
this.chatService.getPrivateGroupMessages(this.roomId).subscribe(async res => {
if (res == 502) {
// Connection timeout
// happens when the connection was pending for too long
// let's reconnect
await this.serverLongPull();
} else if (res != 200) {
// Show Error
//showMessage(response.statusText);
//this.loadMessages()
let msgOnly = res['messages'].filter(data => data.t != 'au');
//this.messages = msgOnly.reverse();
//
this.transformDataMSG(msgOnly.reverse());
// this.getRoomMessageDB(this.roomId);
// Reconnect in one second
if (this.route.url != "/home/chat") {
} else {
//Check if modal is opened
if (document.querySelector('.isGroupChatOpened')) {
await new Promise(resolve => setTimeout(resolve, 5000)).catch((error) => {
console.error(error);
});
await this.serverLongPull();
}
}
} else {
// Got message
//let message = await response.text();
//this.loadMessages()
await this.serverLongPull();
}
});
}
sliderOpts = {
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams, PopoverController } from '@ionic/angular';
import { ChatService } from 'src/app/services/chat.service';
import { ThemeService } from 'src/app/services/theme.service';
@Component({
@@ -15,7 +14,6 @@ export class MessagesOptionsPage implements OnInit {
constructor(
private popoverController: PopoverController,
private modalController: ModalController,
private chatService: ChatService,
private navParams: NavParams,
public ThemeService: ThemeService,
)
@@ -40,9 +38,6 @@ export class MessagesOptionsPage implements OnInit {
closeChatRoom(){
let body = { "roomId": this.roomId }
this.chatService.removeChatRoom(body).subscribe(res=>{
});
this.close();
}
@@ -1,7 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { ChatService } from 'src/app/services/chat.service';
import { MessagesPage } from '../messages.page';
import { ThemeService } from 'src/app/services/theme.service'
import { SessionStore } from 'src/app/store/session.service';
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
@@ -9,8 +7,7 @@ import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-
import { UserContacts } from 'src/app/services/Repositorys/contacts/data-source/contacts-data-source.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { ToastService } from 'src/app/services/toast.service';
import { HttpRequest, HttpResponse } from '@angular/common/http';
import { ZodError } from 'zod';
@Component({
selector: 'app-contacts',
@@ -38,7 +35,6 @@ export class ContactsPage implements OnInit {
constructor(
private modalController: ModalController,
private chatService: ChatService,
public ThemeService: ThemeService,
private contactsRepositoryService: ContactRepositoryService,
private RoomRepositoryService: RoomRepositoryService,
@@ -9,8 +9,8 @@
</button>
</div>
<div class="middle-container" *ngIf="!showMessageOptions">
<div class="middle" *ngIf="roomData$ | async as roomData">
<ion-label class="title">{{ roomData.roomName }}</ion-label>
<div class="middle" >
<ion-label *ngIf="roomData$ | async as roomData" class="title">{{ roomData.roomName }}</ion-label>
<span *ngIf="roomStatus$ | async as roomStatus"><ion-icon *ngIf="roomStatus"
class="online" name="ellipse"></ion-icon></span>
</div>
+152 -314
View File
@@ -1,14 +1,11 @@
import { AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { GestureController, ModalController, NavParams, PopoverController, Platform } from '@ionic/angular';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { EventPerson } from 'src/app/models/eventperson.model';
import { ExpedientTaskModalPageNavParamsTask } from 'src/app/models/ExpedientTaskModalPage';
import { ContactsPage } from 'src/app/ui/chat/modal/messages/contacts/contacts.page';
import { AlertService } from 'src/app/services/alert.service';
import { FileService } from 'src/app/services/functions/file.service';
import { ToastService } from 'src/app/services/toast.service';
import { ChatMessageStore } from 'src/app/store/chat/chat-message.service';
import { ChatUserStorage } from 'src/app/store/chat/chat-user.service';
import { ThemeService } from 'src/app/services/theme.service'
import { VoiceRecorder, GenericResponse } from 'capacitor-voice-recorder';
@@ -16,15 +13,11 @@ import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { ViewEventPage } from 'src/app/modals/view-event/view-event.page';
import { SearchPage } from 'src/app/pages/search/search.page';
import { Storage } from '@ionic/storage';
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
import { CameraResultType } from '@capacitor/camera';
import { DomSanitizer } from '@angular/platform-browser';
import { SessionStore } from 'src/app/store/session.service';
import { ViewMediaPage } from 'src/app/modals/view-media/view-media.page';
import { File } from '@awesome-cordova-plugins/file/ngx';
import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx';
import { Filesystem, Directory } from '@capacitor/filesystem';
import { FileValidatorService } from "src/app/services/file/file-validator.service"
import { FilePicker } from '@capawesome/capacitor-file-picker';
//======
import { Observable as DexieObservable } from 'Dexie';
import { Subscription } from 'rxjs';
@@ -45,7 +38,11 @@ import { RecordingData } from 'capacitor-voice-recorder';
import { Logger } from 'src/app/services/logger/main/service';
import { MessagesOptionsPage } from '../messages-options/messages-options.page';
import { ChatOptionsPopoverPage } from '../chat-options-popover/chat-options-popover.page';
import { CameraService } from 'src/app/infra/camera/camera.service'
import { FilePickerMobileService } from 'src/app/infra/file-picker/mobile/file-picker-mobile.service'
import { FilePickerWebService } from 'src/app/infra/file-picker/web/file-picker-web.service'
import { allowedDocExtension } from 'src/app/utils/allowedDocExtension';
import { JSFileToDataUrl } from 'src/app/utils/ToBase64';
const IMAGE_DIR = 'stored-images';
@Component({
@@ -57,7 +54,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
showLoader: boolean;
@ViewChild('scrollMe') private myScrollContainer: ElementRef;
/* @ViewChild('messageContainer') messageContainer: ElementRef; */
@ViewChild('rectangle') private rectangle: ElementRef;
canvas: any
@@ -70,15 +66,10 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
members: any;
scrollingOnce: boolean = true;
chatMessageStore = ChatMessageStore;
chatUserStorage = ChatUserStorage;
private scrollChangeCallback: () => void;
currentPosition: any;
startPosition: number;
scrollToBottomBtn = false;
attendees: EventPerson[] = [];
longPressActive = false;
showMessageOptions = false;
selectedMsgId: string;
@@ -146,14 +137,14 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
private platform: Platform,
private storage: Storage,
private sanitiser: DomSanitizer,
private file: File,
private fileOpener: FileOpener,
private FileValidatorService: FileValidatorService,
private roomRepositoryService: RoomRepositoryService,
private messageRepositoryService: MessageRepositoryService,
private userTypingServiceRepository: UserTypingServiceRepository,
private chatServiceService: ChatServiceService,
private FilePickerService: FilePickerService,
private CameraService: CameraService,
private FilePickerMobileService: FilePickerMobileService,
private FilePickerWebService: FilePickerWebService
) {
@@ -169,23 +160,10 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.listenToSendMessage()
this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
// this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) as any
this.roomStatus$ = this.roomRepositoryService.getRoomStatus(this.roomId)
this.roomRepositoryService.getRoomById(this.roomId)
this.newMessagesStream?.unsubscribe()
this.newMessagesStream = this.messageRepositoryService.subscribeToNewMessages(this.roomId).subscribe((e) => {
setTimeout(() => {
this.scrollToBottomClicked()
}, 200)
setTimeout(() => {
this.scrollToBottomClicked()
}, 500)
})
// this.roomRepositoryService.getRoomById(this.roomId)
this.userTypingServiceRepository.getUserTypingLive().subscribe((e) => {
const arrayNames = e.map(e => e.userName)
@@ -218,10 +196,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
for(const message of this.messages1[this.roomId]) {
if(message.hasAttachment) {
const result = await this.chatServiceService.getMessageAttachmentByMessageId({
$messageId: message.$id,
id: message.attachments[0].id
})
const result = await this.chatServiceService.getMessageAttachmentByMessageId(message)
if(result.isOk()) {
@@ -282,14 +258,11 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
listenToIncomingMessage() {
this.messageReceiveSubject?.unsubscribe();
this.messageReceiveSubject = this.chatServiceService.listenToIncomingMessage(this.roomId).subscribe(async (message) => {
this.messages1[this.roomId].push(message as MessageEntity)
this.messages1[this.roomId].unshift(message as MessageEntity)
if(message.hasAttachment) {
const result = await this.chatServiceService.getMessageAttachmentByMessageId({
$messageId: message.$id,
id: message.attachments[0].id
})
const result = await this.chatServiceService.getMessageAttachmentByMessageId(message)
if(result.isOk()) {
@@ -734,33 +707,48 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
async takePictureMobile() {
this.addFileToChatMobile()
const picture = await this.CameraService.takePicture({
cameraResultType: CameraResultType.DataUrl,
quality: 90
})
if(picture.isOk()) {
const file = picture.value
}
const compressedImage = await compressImageBase64(
file.dataUrl,
800, // maxWidth
800, // maxHeight
0.9 // quality
)
dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
if(compressedImage.isOk()) {
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
const message = new MessageEntity();
message.roomId = this.roomId
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
}
// create a view into the buffer
var ia = new Uint8Array(ab);
message.attachments = [{
file: compressedImage.value.split(',')[1],
fileName: "foto",
source: MessageAttachmentSource.Device,
fileType: MessageAttachmentFileType.Image,
mimeType: 'image/'+picture.value.format
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
}
// set the bytes of the buffer to the correct values
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ab], { type: mimeString });
return blob;
}
@@ -856,6 +844,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}
} else {
if(file.error.type == 'PERMISSION_DENIED') {
this.toastService._badRequest("Sem acesso a camera")
}
Logger.error('failed to pick picture from the device', {
error: file.error
})
@@ -863,79 +854,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}
async addFileToChatMobile() {
const roomId = this.roomId
const file = await Camera.getPhoto({
quality: 90,
// allowEditing: true,
resultType: CameraResultType.Base64,
source: CameraSource.Photos
});
//const imageData = await this.fileToBase64Service.convert(file)
//
var imageBase64 = 'data:image/jpeg;base64,' + file.base64String
const compressedImage = await this.compressImageBase64(
imageBase64,
800, // maxWidth
800, // maxHeight
0.9 // quality
).then((picture) => {
console.log('Selected: ', picture)
imageBase64 = picture
});
//console.log(imageBase64)
const response = await fetch(imageBase64);
const blob = await response.blob();
const formData = new FormData();
//console.log('add file', formData)
formData.append("blobFile", blob);
//console.log('add file', formData)
// this.ChatSystemService.getDmRoom(roomId).send({
// file: {
// "type": "application/img",
// "guid": ''
// },
// temporaryData: formData,
// attachments: [{
// "title": file.path,
// "text": "description",
// "title_link_download": false,
// }],
// attachmentsModelData: {
// fileBase64: imageBase64,
// }
// })
}
getFileReader(): FileReader {
const fileReader = new FileReader();
const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"];
return zoneOriginalInstance || fileReader;
}
_getBase64(file) {
return new Promise((resolve, reject) => {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
resolve(reader.result)
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
})
}
async addFileToChat(types) {
console.log('add file ')
@@ -944,100 +862,90 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
if (this.platform.is('ios')) {
console.log('ios add file ')
const resultt = await FilePicker.pickFiles({
const result = await this.FilePickerMobileService.getFile({
types: ['application/pdf', 'application/doc', 'application/docx','application/xls', 'application/xlsx', 'application/ppt',
'application/pptx', 'application/txt'],
multiple: false,
readData: true,
});
})
console.log('RESULT', resultt.files[0].data)
if(result.isOk()) {
console.log('RESULT', result.value.files[0].data)
const message = new MessageEntity();
message.roomId = this.roomId
const message = new MessageEntity();
message.roomId = this.roomId
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
}
message.attachments = [{
file: result.value.files[0].data,
fileName: result.value.files[0].name,
source: MessageAttachmentSource.Device,
fileType: MessageAttachmentFileType.Doc
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
return
}
message.attachments = [{
file: resultt.files[0].data,
fileName: resultt.files[0].name,
source: MessageAttachmentSource.Device,
fileType: MessageAttachmentFileType.Doc
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
return
}
const file = await this.fileService.getFileFromDevice(types);
console.log(file)
const file = await this.FilePickerWebService.getFileFromDevice(types)
if(file.isOk()) {
console.log(file)
const fileName = file.name
const fileName = file.value.name
const validation = this.FileValidatorService.fileNameValidation(fileName)
const validation = await allowedDocExtension(fileName)
if (validation.isOk) {
if (validation.isOk()) {
const encodedData = btoa(JSON.stringify(await this.getBase64(file).catch((error) => {
console.error(error);
})));
console.log(encodedData)
const blob = this.fileService.base64toBlob(encodedData, file.type)
let fileBase64 = await JSFileToDataUrl(file.value);
const formData = new FormData();
formData.append('blobFile', blob);
if(fileBase64.isOk()) {
const message = new MessageEntity();
message.roomId = this.roomId
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
}
message.attachments = [{
file: fileBase64.value.split(',')[1],
fileName: file.value.name,
source: MessageAttachmentSource.Device,
fileType: MessageAttachmentFileType.Doc,
mimeType: file.value.type
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
}
const message = new MessageEntity();
message.roomId = this.roomId
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
} else {
this.toastService._badRequest("Ficheiro inválido")
}
message.attachments = [{
file: encodedData,
fileName: file.name,
source: MessageAttachmentSource.Device,
fileType: MessageAttachmentFileType.Doc,
mimeType: file.type
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
} else {
this.toastService._badRequest("Ficheiro inválido")
}
}
getBase64(file) {
var reader = this.getFileReader();
reader.readAsDataURL(file);
return new Promise(resolve => {
reader.onload = function () {
resolve(reader.result)
};
reader.onerror = function (error) {
};
});
}
async openChatOptions(ev?: any) {
const roomId = this.roomId
@@ -1085,40 +993,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}
b64toBlob(b64Data, contentType) {
contentType = contentType || '';
var sliceSize = 512;
b64Data = b64Data.replace(/^[^,]+,/, '');
b64Data = b64Data.replace(/\s/g, '');
var byteCharacters = window.atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, { type: contentType });
return blob;
}
blobToBase64(blob) {
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
async openFile(pdfString, filename, type) {
console.log('url while open ',pdfString)
@@ -1135,43 +1009,43 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
/*
await modal.present(); */
var blob = new Blob([pdfString], { type: 'application/pdf' });
// var blob = new Blob([pdfString], { type: 'application/pdf' });
console.log('blob blob', blob)
// console.log('blob blob', blob)
this.blobToBase64(blob).then((value) => {
console.log(value)
}).catch((error) => {
console.log(error)
})
// this.blobToBase64(blob).then((value) => {
// console.log(value)
// }).catch((error) => {
// console.log(error)
// })
let pathFile = ''
const fileName = filename
if (this.platform.is('ios')) {
pathFile = this.file.documentsDirectory
} else {
pathFile = this.file.externalRootDirectory
}
// let pathFile = ''
// const fileName = filename
// if (this.platform.is('ios')) {
// pathFile = this.file.documentsDirectory
// } else {
// pathFile = this.file.externalRootDirectory
// }
console.log('file data', pdfString)
console.log(pathFile)
// console.log('file data', pdfString)
// console.log(pathFile)
let removePre = this.removeTextBeforeSlash(pdfString,',')
console.log('file data remove ', removePre)
// let removePre = this.removeTextBeforeSlash(pdfString,',')
// console.log('file data remove ', removePre)
await Filesystem.writeFile({
path: fileName,
data: removePre,
directory: Directory.Cache,
}).then((dir) => {
console.log('DIR ', dir)
this.fileOpener
.open(dir.uri, type)
.then(() => console.log())
.catch(e => console.error(e))
}).catch((error) => {
console.log('error writing the file', error)
});
// await Filesystem.writeFile({
// path: fileName,
// data: removePre,
// directory: Directory.Cache,
// }).then((dir) => {
// console.log('DIR ', dir)
// this.fileOpener
// .open(dir.uri, type)
// .then(() => console.log())
// .catch(e => console.error(e))
// }).catch((error) => {
// console.log('error writing the file', error)
// });
}
removeTextBeforeSlash(inputString, controlString) {
@@ -1273,52 +1147,16 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}
async compressImageBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise<string> {
return new Promise((resolve, reject) => {
const image = new (window as any).Image();
image.src = base64String;
image.onload = async () => {
const canvas = document.createElement('canvas');
let newWidth = image.width;
let newHeight = image.height;
if (newWidth > maxWidth) {
newHeight *= maxWidth / newWidth;
newWidth = maxWidth;
}
if (newHeight > maxHeight) {
newWidth *= maxHeight / newHeight;
newHeight = maxHeight;
}
canvas.width = newWidth;
canvas.height = newHeight;
const context = canvas.getContext('2d');
context?.drawImage(image, 0, 0, newWidth, newHeight);
const compressedBase64 = canvas.toDataURL('image/jpeg', quality);
resolve(compressedBase64);
};
image.onerror = (error) => {
reject(error);
};
});
}
dataURItoBlobIso(dataURI: any) {
const byteString = window.atob(dataURI);
const arrayBuffer = new ArrayBuffer(byteString.length);
const int8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteString.length; i++) {
int8Array[i] = byteString.charCodeAt(i);
}
const blob = new Blob([int8Array], { type: 'application/pdf' });
return blob;
}
// dataURItoBlobIso(dataURI: any) {
// const byteString = window.atob(dataURI);
// const arrayBuffer = new ArrayBuffer(byteString.length);
// const int8Array = new Uint8Array(arrayBuffer);
// for (let i = 0; i < byteString.length; i++) {
// int8Array[i] = byteString.charCodeAt(i);
// }
// const blob = new Blob([int8Array], { type: 'application/pdf' });
// return blob;
// }
messageDelete(message: MessageEntity) {
+23
View File
@@ -0,0 +1,23 @@
import { MessageAttachmentFileType, MessageAttachmentSource } from "src/app/module/chat/data/dto/message/messageOutputDTO";
import { MessageEntity } from "src/app/module/chat/domain/entity/message";
import { SessionStore } from "src/app/store/session.service";
export const LastMessage = new MessageEntity()
LastMessage.sentAt = new Date().toISOString()
LastMessage.message = 'last'
LastMessage.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
}
LastMessage.attachments = [{
safeFile: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/wcAAwAB/BO5RfQAAAAASUVORK5CYII=',
fileName: "lastMessageUUID",
source: MessageAttachmentSource.Device,
fileType: MessageAttachmentFileType.Image,
mimeType: 'image/png',
}]