import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, OnDestroy, ChangeDetectorRef, } from '@angular/core'; import { IonSlides, ModalController, NavParams, PopoverController, Platform } from '@ionic/angular'; import { AlertService } from 'src/app/services/alert.service'; import { AuthService } from 'src/app/services/auth.service'; import { ChatService } from 'src/app/services/chat.service'; import { ChatOptionsPopoverPage } from 'src/app/shared/popover/chat-options-popover/chat-options-popover.page'; import { ChatPopoverPage } from 'src/app/shared/popover/chat-popover/chat-popover.page'; import { GroupContactsPage } from './group-contacts/group-contacts.page'; import { Router } from '@angular/router' import { EditGroupPage } from '../edit-group/edit-group.page'; import { TimeService } from 'src/app/services/functions/time.service'; import { FileService } from 'src/app/services/functions/file.service'; import { ToastService } from 'src/app/services/toast.service'; import { environment } from 'src/environments/environment'; import { NewEventPage } from '../../agenda/new-event/new-event.page'; 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 { SqliteService } from 'src/app/services/sqlite.service'; import { WsChatMethodsService } from 'src/app/services/chat/ws-chat-methods.service'; import { FileType } from 'src/app/models/fileType'; import { Storage } from '@ionic/storage'; import { CameraService } from 'src/app/services/camera.service'; import { SearchPage } from 'src/app/pages/search/search.page'; import { VoiceRecorder, RecordingData, GenericResponse } from 'capacitor-voice-recorder'; import { Filesystem, Directory } from '@capacitor/filesystem'; import { DomSanitizer } from '@angular/platform-browser'; import { MessageService } from 'src/app/services/chat/message.service'; import { File } from '@awesome-cordova-plugins/file/ngx'; import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; import { SessionStore } from 'src/app/store/session.service'; import { ViewMediaPage } from 'src/app/modals/view-media/view-media.page'; @Component({ selector: 'app-group-messages', templateUrl: './group-messages.page.html', styleUrls: ['./group-messages.page.scss'], }) export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { showLoader: boolean; isGroupCreated: boolean; loggedUser: any; room: any; roomName: any; members: any; contacts: string[] = [" Ana M.", "Andre F.", "Bruno G.", "Catarina T", "Tiago"]; allUsers: any[] = []; roomId: string; loggedUserChat: any; eventSelectedDate: Date = new Date(); scrollingOnce: boolean = true; private scrollChangeCallback: () => void; currentPosition: any; startPosition: number; capturedImage: any; capturedImageTitle: any; attendees: EventPerson[] = []; scrollToBottomBtn = false; longPressActive = false; showMessageOptions = false; selectedMsgId: string; roomCountDownDate: any; downloadFile: any; groupNameFormart = ""; @ViewChild('scrollMe') private myScrollContainer: ElementRef; recording = false; allowTyping = true; storedFileNames = []; lastAudioRecorded = ''; audioRecorded: any = ""; audioDownloaded: any = ""; durationDisplay = ''; duration = 0; showAvatar = true; audioPermissionStatus: 'granted'| 'denied' | 'prompt' | null = null sessionStore = SessionStore isAdmin = false; constructor( private modalController: ModalController, public popoverController: PopoverController, private chatService: ChatService, private navParams: NavParams, private authService: AuthService, private alertService: AlertService, private route: Router, private timeService: TimeService, private fileService: FileService, private toastService: ToastService, public ThemeService: ThemeService, private changeDetectorRef: ChangeDetectorRef, private sqlservice: SqliteService, private platform: Platform, public wsChatMethodsService: WsChatMethodsService, private storage: Storage, private CameraService: CameraService, private sanitiser: DomSanitizer, private file: File, private fileOpener: FileOpener, ) { this.loggedUserChat = authService.ValidatedUserChat['data']; this.isGroupCreated = true; this.roomId = this.navParams.get('roomId'); window.onresize = (event) => { if (window.innerWidth > 701) { this.modalController.dismiss(); } }; this.wsChatMethodsService.getGroupRoom(this.roomId).loadHistory({}); this.wsChatMethodsService.getGroupRoom(this.roomId).scrollDown = this.scrollToBottomClicked; this.wsChatMethodsService.openRoom(this.roomId) this.groupNameFormart = this.wsChatMethodsService.getGroupRoom(this.roomId).name.split('-').join(' ') setTimeout(() => { this.scrollToBottomClicked() }, 50) this.showAvatar = false setTimeout(() => { this.scrollToBottomClicked() this.showAvatar = true }, 150) } ngOnInit() { this.chatService.refreshtoken(); this.loggedUser = this.loggedUserChat; this.getRoomInfo(); this.scrollToBottom(); this.serverLongPull(); this.setStatus('online'); this.getChatMembers(); this.getRoomMessageDB(this.roomId); this.wsChatMethodsService.getUserOfRoom(this.roomId).then((value) => { }) } setStatus(status: string) { let body = { message: '', status: status, } // this.chatService.setUserStatus(body).subscribe(res => { // // }) } deleteMessage(msgId: string) { const room = this.wsChatMethodsService.getGroupRoom(this.roomId) this.alertService.confirmDeleteMessage(msgId, room); } ngAfterViewInit() { this.scrollChangeCallback = () => this.onContentScrolled(event); window.addEventListener('scroll', this.scrollChangeCallback, true); if(this.room?.customFields?.countDownDate) { this.roomCountDownDate = this.timeService.countDownDate(this.room.customFields.countDownDate, this.room._id); } } handlePress(id?: string) { this.selectedMsgId = id; this.showMessageOptions = true; } handleClick() { this.showMessageOptions = false; this.selectedMsgId = ""; } onContentScrolled(e) { this.startPosition = e.srcElement.scrollTop; let scroll = e.srcElement.scrollTop; let windowHeight = e.srcElement.scrollHeight; let containerHeight = windowHeight - e.srcElement.clientHeight; if (scroll > this.currentPosition) { //alert('BOTTOM'); } else { //alert('UP'); this.scrollingOnce = false; } if ((containerHeight - 100) > scroll) { this.scrollToBottomBtn = true; } else { this.scrollToBottomBtn = false; } this.currentPosition = scroll; } calculateDuration() { if (!this.recording) { this.duration = 0; this.durationDisplay = ''; return; } this.duration += 1; const minutes = Math.floor(this.duration / 60); const seconds = (this.duration % 60).toString().padStart(2, '0'); this.durationDisplay = `${minutes}:${seconds}`; setTimeout(() => { this.calculateDuration(); }, 1000) } async getFile(fileName?: any) { const audioFile = await Filesystem.readFile({ path: fileName, directory: Directory.Data }) // const base64sound = audioFile.data; //Converting base64 to blob const base64 = await fetch(base64sound); // const base64Response = await fetch(`data:audio/ogg;base64,${base64sound}`); // this.audioRecorded = base64Response.url; } async loadFiles() { this.storage.get('fileName').then((fileName) => { this.lastAudioRecorded = fileName; }) try { this.storage.get('recordData').then((recordData) => { if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64); } else if(recordData?.value?.mimeType && recordData?.value?.recordDataBase64) { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`); } }); } catch (error) { } } stopRecording() { this.deleteRecording(); this.allowTyping = false; if (!this.recording) { return; } this.recording = false; VoiceRecorder.stopRecording().then(async (result: RecordingData) => { this.recording = false; if (result.value && result.value.recordDataBase64) { const recordData = result.value.recordDataBase64; // const fileName = new Date().getTime() + ".mp3"; //Save file await this.storage.set('fileName', fileName) this.storage.set('recordData', result).then(() => { setTimeout(async () => { this.loadFiles(); }, 1000); }) } }) } async startRecording() { VoiceRecorder.requestAudioRecordingPermission(); if(await VoiceRecorder.canDeviceVoiceRecord().then((result: GenericResponse) =>{return result.value})){ if(await VoiceRecorder.requestAudioRecordingPermission().then((result: GenericResponse) => {return result.value})){ //if(await this.hasAudioRecordingPermission()){ if (this.recording) { return; } this.recording = true; VoiceRecorder.startRecording(); this.calculateDuration(); //} } else{ this.toastService._badRequest('Para gravar uma mensagem de voz, permita o acesso do Gabinete Digital ao seu microfone.'); } } else{ this.toastService._badRequest('Este dispositivo não tem capacidade para gravação de áudio!'); } } async deleteRecording() { this.storage.remove('fileName'); this.storage.remove('recordData'); this.allowTyping = true; this.lastAudioRecorded = ''; this.loadFiles(); } async goToEvent(eventId: any) { let classs; if (window.innerWidth < 701) { classs = 'modal modal-desktop' } else { classs = 'modal modal-desktop showAsideOptions' } const modal = await this.modalController.create({ component: ViewEventPage, componentProps: { eventId: eventId, }, cssClass: classs, }); await modal.present(); modal.onDidDismiss().then((res) => { }); } ngOnDestroy() { window.removeEventListener('scroll', this.scrollChangeCallback, true); } scrollToBottom(): void { try { if (this.scrollingOnce) { this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight; //this.scrollingOnce = false; } } catch (err) { } } scrollToBottomClicked = () => { try { this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight; } catch (err) { } } async getRoomInfo() { this.showLoader = true; // this.chatService.getRoomInfo(this.roomId).subscribe(room => { // this.room = room['room']; // this.roomName = this.room.name.split('-').join(' '); // if (this.room.customFields.countDownDate) { // this.roomCountDownDate = this.timeService.countDownDateTimer(this.room.customFields.countDownDate, this.room._id); // } // this.getGroupContacts(this.room); // this.showLoader = false; // }); this.wsChatMethodsService.getGroupRoom(this.roomId).loadHistory({}); let room = await this.chatService.getRoomInfo(this.roomId).toPromise(); // console.log('ROOM',room) this.room = room['room']; if (this.room.name) { this.roomName = this.room.name.split('-').join(' '); } if(SessionStore.user.ChatData.data.userId == this.room.u._id){ this.isAdmin = true } else { this.isAdmin = false } if (this.room.customFields.countDownDate) { this.roomCountDownDate = this.room.customFields.countDownDate; } } async getChatMembers() { this.chatService.getAllUsers().subscribe(res => { this.allUsers = res['users'].filter(data => data.username != SessionStore.user.UserName); }); } /* load(){ this.getGroupContacts(); this.loadGroupMessages(); } */ close() { this.modalController.dismiss(); this.deleteRecording(); } doRefresh(ev: any) { this.getRoomInfo(); ev.target.complete(); } getGroupContacts(room: any) { this.showLoader = true; //If group is private call getGroupMembers if (this.room.t === 'p') { this.chatService.getGroupMembers(this.roomId).subscribe(res => { this.members = res['members']; this.showLoader = false; }); } //Otherwise call getChannelMembers for públic groups else { this.chatService.getChannelMembers(this.roomId).subscribe(res => { this.members = res['members']; this.showLoader = false; }); } } showDateDuration(start: any) { return this.timeService.showDateDuration(start); } countDownDate(date: any, roomId: string) { this.roomCountDownDate = this.timeService.countDownDate(date, roomId); return this.timeService.countDownDateTimer(date, roomId); } addZero(i) { if (i < 10) { i = "0" + i; } return i; } sendMessage() { 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) => { audioFile = recordData; if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = recordData?.value?.recordDataBase64; } else if(recordData?.value?.mimeType && recordData?.value?.recordDataBase64){ this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`; } //Converting base64 to blob const encodedData = btoa(this.audioRecorded); const blob = this.base64toBlob(encodedData, recordData.value.mimeType) const formData = new FormData(); formData.append("blobFile", blob); this.wsChatMethodsService.getGroupRoom(roomId).send({ file: { "type": "application/audio", "msDuration": audioFile.value.msDuration, "mimeType": audioFile.value.mimeType, }, attachments: [{ "title": fileName, "title_link_download": true, "type": "audio" }], temporaryData: formData }) }); this.deleteRecording(); } async openOptions() { const modal = await this.popoverController.create({ component: ChatPopoverPage, cssClass: 'chat-popover', componentProps: { roomId: this.roomId, members: this.members, isAdmin: this.isAdmin, }, }); await modal.present(); modal.onDidDismiss().then(res => { if (res.data == 'leave') { //this.wsChatMethodsService.subscribeToRoomUpdate(this.roomId, this.room); } else if (res.data == 'cancel') { } else if (res.data == 'edit') { this.editGroup(this.roomId); } }); } viewDocument(file: any, url?: string) { if (file.type == "application/webtrix") { this.openViewDocumentModal(file); } else { let fullUrl = "https://www.tabularium.pt" + url; this.fileService.viewDocumentByUrl(fullUrl); } } async openViewDocumentModal(file: any) { let task = { serialNumber: '', taskStartDate: '', isEvent: true, workflowInstanceDataFields: { FolderID: '', Subject: file.Assunto, SourceSecFsID: file.ApplicationId, SourceType: 'DOC', SourceID: file.DocId, DispatchNumber: '' } } let doc = { "Id": "", "ParentId": "", "Source": 1, "ApplicationId": file.ApplicationId, "CreateDate": "", "Data": null, "Description": "", "Link": null, "SourceId": file.DocId, "SourceName": file.Assunto, "Stakeholders": "", } const modal = await this.modalController.create({ component: ViewDocumentPage, componentProps: { trustedUrl: '', file: { title: file.Assunto, url: '', title_link: '', }, Document: doc, applicationId: file.ApplicationId, docId: file.DocId, folderId: '', task: task }, cssClass: 'modal modal-desktop' }); await modal.present(); } async bookMeeting() { this.attendees = this.members.map((val) => { return { Name: val.name, EmailAddress: val.username + "@" + environment.domain, IsRequired: "true", } }); this.popoverController.dismiss(); if (window.innerWidth <= 1024) { const modal = await this.modalController.create({ component: NewEventPage, componentProps: { attendees: this.attendees, }, cssClass: 'modal modal-desktop', backdropDismiss: false }); await modal.present(); modal.onDidDismiss().then((data) => { if (data) { } }); } } async takePicture() { const roomId = this.roomId const image = await this.CameraService.takePicture(); await this.fileService.saveImage(image) const lastphoto: any = await this.fileService.loadFiles(); const { capturedImage, capturedImageTitle } = await this.fileService.loadFileData(lastphoto); const base64 = await fetch(capturedImage); const blob = await base64.blob(); const formData = new FormData(); formData.append("blobFile", blob); this.wsChatMethodsService.getGroupRoom(roomId).send({ file: { "type": "application/img", "guid": '' }, temporaryData: formData, attachments: [{ "title": capturedImageTitle, "text": "description", "title_link_download": false, }] }) } async addImage() { this.addFileToChat(['image/apng', 'image/jpeg', 'image/png']) } async addFile() { this.addFileToChat(['.doc', '.docx', '.pdf']) } async addFileWebtrix() { const modal = await this.modalController.create({ component: SearchPage, cssClass: 'group-messages modal-desktop search-modal search-modal-to-desktop', componentProps: { type: 'AccoesPresidenciais & ArquivoDespachoElect', select: true, showSearchInput: true, } }); await modal.present(); modal.onDidDismiss().then(async res => { const data = res.data; if (data.selected) { this.wsChatMethodsService.getGroupRoom(this.roomId).send({ file: { "name": res.data.selected.Assunto, "type": "application/webtrix", "ApplicationId": res.data.selected.ApplicationType, "DocId": res.data.selected.Id, "Assunto": res.data.selected.Assunto, }, temporaryData: res, attachments: [{ "title": res.data.selected.Assunto, "description": res.data.selected.DocTypeDesc, // "title_link": url_no_options, "title_link_download": true, //"thumb_url": "assets/images/webtrix-logo.png", // "message_link": url_no_options, "type": "webtrix", //"thumb_url": "assets/images/webtrix-logo.png", "text": res.data.selected.DocTypeDesc, "thumb_url": "https://static.ichimura.ed.jp/uploads/2017/10/pdf-icon.png", }] }) } }); } async addFileToChat(types: typeof FileType[]) { const roomId = this.roomId const file: any = await this.fileService.getFileFromDevice(types); if (file.type != "application/img" && file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/gif") { const encodedData = btoa(JSON.stringify(await this.getBase64(file))); const blob = this.base64toBlob(encodedData, file.type) const formData = new FormData(); formData.append('blobFile', blob); this.wsChatMethodsService.getGroupRoom(roomId).send({ file: { "type": file.type, "guid": '', }, attachments: [{ "title": file.name, "name": file.name, // "text": "description", "title_link_download": false, }], temporaryData: formData }); } else { } } getFileReader(): FileReader { const fileReader = new FileReader(); const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"]; return zoneOriginalInstance || fileReader; } 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; const popover = await this.popoverController.create({ component: ChatOptionsPopoverPage, cssClass: 'chat-options-popover', event: ev, componentProps: { room: this.room, members: this.members, eventSelectedDate: new Date(), }, translucent: true }); await popover.present(); await popover.onDidDismiss().then(async (res) => { if (res['data'] == 'meeting') { this.bookMeeting(); } else if (res['data'] == 'take-picture') { this.takePicture() } else if (res['data'] == 'add-picture') { this.addImage() } else if (res['data'] == 'add-document') { this.addFile() } else if (res['data'] == 'documentoGestaoDocumental') { this.addFileWebtrix() } }); } async addContacts() { const modal = await this.modalController.create({ component: GroupContactsPage, componentProps: { isCreated: this.isGroupCreated, room: this.room, members: this.members, name: this.room.name, }, cssClass: 'contacts', backdropDismiss: false }); await modal.present(); modal.onDidDismiss().then(() => { this.getRoomInfo(); }); } async editGroup(roomId) { const modal = await this.modalController.create({ component: EditGroupPage, cssClass: 'modal modal-desktop', componentProps: { roomId: roomId, }, }); await modal.present(); modal.onDidDismiss().then((res) => { this.getRoomInfo(); //this.modalController.dismiss(res.data); }); } /* async actionSheet() { const actionSheet = await this.actionSheetController.create({ cssClass: 'my-custom-class', buttons: [{ text: 'Sair do grupo', handler: () => { } }, { text: 'Alterar nome do grupo1', handler: () => { this.openChangeGroupName() } }, { text: 'Apagar o grupo', handler: () => { } }, ] }); await actionSheet.present(); } */ getRoomMessageDB(roomId) { if (this.platform.is('desktop') || this.platform.is('mobileweb')) { } else { this.sqlservice.getAllChatMSG(roomId).then((msg: any) => { let chatmsgArray = []; let array = [] msg.forEach(element => { let msgChat = { _id: element.Id, attachments: this.isJson(element.Attachments), channels: this.isJson(element.Channels), file: this.isJson(element.File), mentions: this.isJson(element.Mentions), msg: element.Msg, rid: element.Rid, ts: element.Ts, u: this.isJson(element.U), _updatedAt: element.UpdatedAt, image_url: this.isJson(element.image_url) } chatmsgArray.push(msgChat) }); // this.messages = chatmsgArray; }) } } isJson(str) { try { JSON.parse(str); } catch (e) { return ""; } return JSON.parse(str); } transformDataMSG(res) { if (this.platform.is('desktop') || this.platform.is('mobileweb')) { } else { res.forEach(element => { 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, /* image_url: { name: name, path: `${IMAGE_DIR}/${name}`, data: `data:image/jpeg;base64,${readFile.data}`, }, */ } this.sqlservice.addChatMSG(chatmsg) }); } } 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)); await this.serverLongPull(); } } } else { // Got message //let message = await response.text(); //this.loadMessages() await this.serverLongPull(); } }); } sliderOpts = { zoom: false, slidesPerView: 1.5, spaceBetween: 20, centeredSlides: true }; zoomActive = false; zoomScale = 1; sliderZoomOpts = { allowSlidePrev: false, allowSlideNext: false, zoom: { maxRatio: 5 }, on: { zoomChange: (scale, imageEl, slideEl) => { this.zoomActive = true; this.zoomScale = scale / 5; this.changeDetectorRef.detectChanges(); } } } async touchEnd(zoomslides: IonSlides, card) { // Zoom back to normal const slider = await zoomslides.getSwiper(); const zoom = slider.zoom; zoom.out(); // Card back to normal card.el.style['z-index'] = 9; this.zoomActive = false; this.changeDetectorRef.detectChanges(); } touchStart(card) { // Make card appear above backdrop card.el.style['z-index'] = 11; } 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; } openFile(pdfString, filename, type) { const blob = this.b64toBlob(pdfString, 'application/pdf') let pathFile = '' const fileName = filename const contentFile = blob if (this.platform.is('ios')) { pathFile = this.file.documentsDirectory } else { pathFile = this.file.externalRootDirectory } this.file .writeFile(pathFile, fileName, contentFile, { replace: true }) .then(success => { this.fileOpener .open(pathFile + fileName, 'application/pdf') .then(() => console.log()) .catch(e => console.error(e)) }) .catch(e => console.error(e)) } downloadFileMsg(msg: MessageService) { msg.downloadFileMsg() } downloadFileFromBrowser(fileName: string, data: any): void { const linkSource = data; const downloadLink = document.createElement("a"); downloadLink.href = linkSource; downloadLink.download = fileName; downloadLink.click(); } async openPreview(msg: MessageService) { if(msg?.file?.type === "application/webtrix") { this.viewDocument(msg.file, msg.attachments.image_url) } else { if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { this.downloadFileMsg(msg) } else { var str = msg.attachments[0].image_url; str = str.substring(1, ((str.length) - 1)); if (this.platform.is('desktop') || this.platform.is('mobileweb')) { if (msg?.file?.type == "application/img") { const modal = await this.modalController.create({ component: ViewMediaPage, cssClass: 'modal modal-desktop', componentProps: { image: msg.attachments[0].image_url, type: msg.file.type, username: msg.u.name, _updatedAt: msg._updatedAt } }); modal.present(); } else { this.downloadFileFromBrowser(msg.attachments[0].name, str) } } else { if (msg.file.type == "application/img") { const modal = await this.modalController.create({ component: ViewMediaPage, cssClass: 'modal modal-desktop', componentProps: { image: msg.attachments[0].image_url, type: msg.file.type, username: msg.u.name, _updatedAt: msg._updatedAt } }); modal.present(); } else { this.openFile(str, msg.attachments[0].name, msg.file.type); } } } } } async audioPreview(msg) { if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') { this.downloadFileMsg(msg) } else { } } }