Git pull with conflits

This commit is contained in:
Eudes Inácio
2022-03-27 21:03:49 +01:00
80 changed files with 2615 additions and 1341 deletions
@@ -11,10 +11,10 @@ import { SharedModule } from 'src/app/shared/shared.module';
import { ChatPopoverPageModule } from '../../popover/chat-popover/chat-popover.module';
import { NewEventPageModule } from '../../agenda/new-event/new-event.module';
import { PdfViewerModule } from 'ng2-pdf-viewer';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import {MatMenuModule} from '@angular/material/menu';
import { LettersAvatarModule } from "ngx-letters-avatar";
import { PipesModule } from 'src/app/pipes/pipes.module';
@NgModule({
imports: [
@@ -22,11 +22,11 @@ import { LettersAvatarModule } from "ngx-letters-avatar";
FormsModule,
IonicModule,
FontAwesomeModule,
PdfViewerModule,
ChatPopoverPageModule,
GroupMessagesPageRoutingModule,
MatMenuModule,
LettersAvatarModule
LettersAvatarModule,
PipesModule,
//
],
exports: [GroupMessagesPage],
@@ -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">
@@ -72,6 +70,7 @@
</mat-menu>
</div>
<div class="title">
<ion-label>{{msg.u.name}}</ion-label>
<span class="time">{{msg.duration}}</span>
</div>
<div class="message">
@@ -82,7 +81,7 @@
<ion-icon *ngIf="msg.attachments[0].image_url == null" name="download-outline"></ion-icon>
</div>
<div *ngIf="msg.file.type != 'application/img'">
<div class="file">
<div *ngIf="msg.file.type != 'application/audio'" class="file add-attachment-bg-color">
<div (click)="openPreview(msg)" 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>
@@ -93,11 +92,14 @@
<ion-label class="file-title">{{file.title}}</ion-label>
</div>
</div>
<div class="file-details-optional">
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio'">
<audio [src]="file.title_link|safehtml" preload="metadata" controls controlsList="nodownload noplaybackrate"></audio>
</div>
<div class="file-details-optional add-attachment-bg-color">
<ion-label *ngIf="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.displayType}}</span>
<span *ngIf="msg.file.type != 'application/webtrix' && msg.file.type != 'application/audio'">{{msg.displayType}}</span>
</ion-label>
</div>
</div>
@@ -114,35 +116,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 />
@@ -203,14 +180,27 @@
</ion-content>
<ion-footer>
<div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true" >A escrever...</div>
<!-- <div class="typing" *ngIf="wsChatMethodsService.getGroupRoom(roomId).otherUserType == true" >A escrever...</div> -->
<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 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>
</div>
<div class="container width-100 d-flex">
<div>
<!-- <button class="btn-no-color" (click)="openSendGroupMessageOptions()">
<ion-icon class="chat-icon-options" src="assets/images/icons-add.svg"></ion-icon>
</button> -->
<ion-fab horizontal="start" vertical="bottom" slot="fixed">
<ion-fab *ngIf="!recording && !lastAudioRecorded && allowTyping" horizontal="start" vertical="bottom" slot="fixed">
<ion-fab-button color="light" size="small">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
@@ -232,24 +222,34 @@
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<button *ngIf="recording || lastAudioRecorded || !allowTyping" class="btn-delete-recording btn-no-color" (click)="deleteRecording()">
<fa-icon class="icon-size-27" icon="trash"></fa-icon>
</button>
</div>
<div class="width-100">
<ion-item class="ion-no-padding type-message" lines="none">
<div *ngIf="!recording && !lastAudioRecorded" class="type-message">
<ion-textarea autocomplete="on" autocorrect="on" spellcheck="true" (keyup.enter)="sendMessage()" clearOnEdit="true" placeholder="Escrever uma mensagem" class="message-input" rows="1" [(ngModel)]="wsChatMethodsService.getGroupRoom(roomId).message" (ionChange)="wsChatMethodsService.getGroupRoom(roomId).sendTyping()"></ion-textarea>
<button hidden class="btn-no-color">
<ion-icon slot="end" src="assets/icon/icons-chat-mic.svg"></ion-icon>
</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>
</button>
</ion-item>
</div>
</div>
<div class="btn-send">
<button #recordbtn *ngIf="!wsChatMethodsService.getGroupRoom(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.getGroupRoom(roomId).message" class="btn-no-color" (click)="sendMessage()">
<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 title="Enviar Mensagem" *ngIf="!wsChatMethodsService.getGroupRoom(roomId).message" 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.getGroupRoom(roomId).message && lastAudioRecorded" class="btn-no-color" (click)="sendAudio(lastAudioRecorded)">
<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>
@@ -80,6 +80,10 @@
}
}
}
.btn-delete-recording{
margin-left: 20px !important;
}
ion-content{
.welcome-text{
/* width: 322px; */
@@ -287,5 +291,5 @@
.typing ngx-letters-avatar {
padding-left: 10px;
}
padding-right: 5px;
}
@@ -33,6 +33,9 @@ import { element } from 'protractor';
import { FileType } from 'src/app/models/fileType';
import { ToastService } from 'src/app/services/toast.service';
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder';
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
import { DomSanitizer } from '@angular/platform-browser';
/*
import * as pdfjsLib from 'pdfjs-dist';
@@ -85,6 +88,16 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
pdfurl = "http://www.africau.edu/images/default/sample.pdf";
downloadFile: any;
showAvatar = false;
recording = false;
allowTyping = true;
storedFileNames = [];
lastAudioRecorded = '';
audioRecorded:any = "";
audioDownloaded:any = "";
durationDisplay = '';
duration = 0;
constructor(
public wsChatMethodsService: WsChatMethodsService,
@@ -107,6 +120,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
private CameraService: CameraService,
private toastService: ToastService,
private sanitiser: DomSanitizer,
) {
console.log('OnCONSTRUCTOR');
@@ -126,10 +140,15 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
this.wsChatMethodsService.openRoom(this.roomId)
this.wsChatMethodsService.getGroupRoom(this.roomId).scrollDown = this.scrollToBottomClicked
this.showAvatar = false
setTimeout(()=>{
this.scrollToBottomClicked()
this.showAvatar = true
}, 50)
this.deleteRecording();
}
ngOnInit() {
@@ -142,6 +161,9 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
}, 1000);
this.getChatMembers();
//this.getMessageDB();
VoiceRecorder.requestAudioRecordingPermission();
this.deleteRecording();
this.loadFiles();
}
@@ -225,12 +247,100 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
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;
const base64Response = await fetch(`data:audio/ogg;base64,${base64sound}`);
this.audioRecorded = base64Response.url;
}
async loadFiles() {
this.storage.get('fileName').then((fileName) => {
this.lastAudioRecorded = fileName;
})
this.storage.get('recordData').then((recordData) => {
console.log(recordData);
if(recordData.value.recordDataBase64.includes('data:audio')){
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64);
}
else{
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`);
}
});
}
startRecording() {
console.log('Recording');
if (this.recording) {
return;
}
this.recording = true;
VoiceRecorder.startRecording();
this.calculateDuration();
}
stopRecording() {
this.deleteRecording();
this.allowTyping = false;
console.log('Stop');
if (!this.recording) {
return;
}
this.recording = false;
VoiceRecorder.stopRecording().then(async (result: RecordingData) => {
console.log(result);
this.recording = false;
if (result.value && result.value.recordDataBase64) {
const recordData = result.value.recordDataBase64;
//console.log(recordData);
const fileName = new Date().getTime() + ".mp3";
//Save file
this.storage.set('fileName',fileName);
this.storage.set('recordData',result).then(() => {
console.log('Audio recorded saved');
})
}
})
setTimeout(async () => {
this.loadFiles();
}, 1000);
}
async deleteRecording(){
this.storage.remove('fileName');
this.storage.remove('recordData');
this.allowTyping = true;
this.lastAudioRecorded = '';
this.loadFiles();
}
ngOnDestroy() {
window.removeEventListener('scroll', this.scrollChangeCallback, true);
}
async getChatMembers() {
//return await this.chatService.getMembers(roomId).toPromise();
this.chatService.getAllUsers().subscribe(res => {
@@ -307,6 +417,43 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
this.wsChatMethodsService.getGroupRoom(this.roomId).send({})
}
async sendAudio(fileName) {
const roomId = this.roomId
this.storage.get('recordData').then((recordData) => {
console.log(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 formData = new FormData();
formData.append("blobFile", blob);
this.wsChatMethodsService.getGroupRoom(roomId).send({
file: {
"type": "application/audio",
/* "guid": '', */
},
attachments: [{
"title": fileName ,
"title_link": this.audioRecorded,
"title_link_download": true,
"type": "file"
}],
temporaryData: formData
})
this.deleteRecording();
}
deleteMessage(msgId: string) {
const room = this.wsChatMethodsService.getGroupRoom(this.roomId)
this.alertService.confirmDeleteMessage(msgId, room);
@@ -838,10 +985,10 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe
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,
@@ -12,7 +12,7 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { MatButtonModule } from '@angular/material/button';
import {MatMenuModule} from '@angular/material/menu';
import { LettersAvatarModule } from "ngx-letters-avatar";
import { PdfViewerModule } from 'ng2-pdf-viewer';
import { PipesModule } from 'src/app/pipes/pipes.module';
@NgModule({
imports: [
@@ -24,7 +24,7 @@ import { PdfViewerModule } from 'ng2-pdf-viewer';
MatButtonModule,
MatMenuModule,
LettersAvatarModule,
PdfViewerModule
PipesModule,
],
exports: [MessagesPage],
+73 -108
View File
@@ -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,37 +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 *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>
@@ -83,17 +83,16 @@
<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 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 class="file">
<div *ngIf="msg.file.type != 'application/audio'" class="file add-attachment-bg-color">
<div (click)="openPreview(msg)" 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>
@@ -110,19 +109,21 @@
<ion-label class="file-title">{{file.title}}</ion-label>
</div>
</div>
<div class="file-details-optional">
<div class="audio-contentainer" *ngIf="msg.file.type == 'application/audio'">
<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">
<ion-label *ngIf="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.displayType}}</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 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>
@@ -147,56 +148,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>
@@ -206,21 +164,24 @@
</ion-content>
<ion-footer>
<div class="typing">
<ngx-letters-avatar *ngIf="showAvatar" [avatarName]="wsChatMethodsService.getDmRoom(roomId).name" [width]="30"
[circular]="true" fontFamily="Open Sans"></ngx-letters-avatar>
A escrever...
<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"
[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>
</div>
<div class="container width-100 d-flex">
<div>
<!-- <button class="btn-no-color" (click)="openSendMessageOptions()">
<ion-icon class="chat-icon-options" src="assets/images/icons-add.svg"></ion-icon>
</button> -->
<ion-fab horizontal="start" vertical="bottom" slot="fixed">
<ion-fab *ngIf="!recording && !lastAudioRecorded && allowTyping" horizontal="start" vertical="bottom" slot="fixed">
<ion-fab-button color="light" size="small">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
@@ -242,31 +203,35 @@
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<button *ngIf="recording || lastAudioRecorded || !allowTyping" class="btn-no-color" (click)="deleteRecording()">
<fa-icon class="icon-size-27" icon="trash"></fa-icon>
</button>
</div>
<div class="width-100">
<ion-item class="ion-no-padding type-message" lines="none">
<ion-textarea (keyup.enter)="sendMessage()" clearOnEdit="true" placeholder="Escrever uma mensagem"
class="message-input" rows="1" [(ngModel)]="wsChatMethodsService.getDmRoom(roomId).message"
(ionChange)="wsChatMethodsService.getDmRoom(roomId).sendTyping()"></ion-textarea>
<button hidden class="btn-no-color">
<ion-icon slot="end" src="assets/icon/icons-chat-mic.svg"></ion-icon>
<div *ngIf="!recording && !lastAudioRecorded" class="type-message">
<ion-textarea *ngIf="allowTyping" (keyup.enter)="sendMessage()" clearOnEdit="true" placeholder="Escrever uma mensagem" 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>
</button>
</ion-item>
</div>
</div>
<div>
<button *ngIf="wsChatMethodsService.getDmRoom(roomId).message" class="btn-no-color" (click)="sendMessage()">
<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 #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">
<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()">
<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" class="btn-no-color" (click)="sendAudio(lastAudioRecorded)">
<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>
</ion-footer>
</ion-footer>
@@ -327,5 +327,5 @@ display: block;
.typing ngx-letters-avatar {
padding-left: 10px;
}
padding-right: 5px;
}
+164 -16
View File
@@ -19,7 +19,6 @@ import { ThemeService } from 'src/app/services/theme.service'
import { ViewMediaPage } from 'src/app/modals/view-media/view-media.page';
import { SqliteService } from 'src/app/services/sqlite.service';
import { StorageService } from 'src/app/services/storage.service';
import { Directory, Filesystem } from '@capacitor/filesystem';
import { ViewEventPage } from 'src/app/modals/view-event/view-event.page';
import { Storage } from '@ionic/storage';
import { WsChatMethodsService } from 'src/app/services/chat/ws-chat-methods.service'
@@ -34,6 +33,9 @@ import { ProcessesService } from 'src/app/services/processes.service';
import { FileToBase64Service } from 'src/app/services/file/file-to-base64.service';
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
import { DocumentViewer, DocumentViewerOptions } from '@ionic-native/document-viewer';
import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder';
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
import { DomSanitizer } from '@angular/platform-browser';
const IMAGE_DIR = 'stored-images';
@Component({
@@ -78,7 +80,16 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
downloadFile: string;
massages: MessageService[] = []
showAvatar = true
showAvatar = true;
recording = false;
allowTyping = true;
storedFileNames = [];
lastAudioRecorded = '';
audioRecorded:any = "";
audioDownloaded:any = "";
durationDisplay = '';
duration = 0;
constructor(
public popoverController: PopoverController,
@@ -107,11 +118,11 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
private CameraService: CameraService,
private processesService: ProcessesService,
private fileToBase64Service: FileToBase64Service,
private sanitiser: DomSanitizer,
) {
this.loggedUser = authService.ValidatedUserChat['data'];
}
ngOnChanges(changes: SimpleChanges): void {
this.wsChatMethodsService.getDmRoom(this.roomId).loadHistory({})
@@ -130,13 +141,17 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.showAvatar = true
}, 150)
this.deleteRecording()
}
ngOnInit() {
this.scrollToBottom();
this.getChatMembers();
VoiceRecorder.requestAudioRecordingPermission();
this.deleteRecording();
this.loadFiles();
}
@@ -176,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;
@@ -209,6 +223,96 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
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;
const base64Response = await fetch(`data:audio/ogg;base64,${base64sound}`);
this.audioRecorded = base64Response.url;
}
async loadFiles() {
this.storage.get('fileName').then((fileName) => {
this.lastAudioRecorded = fileName;
})
this.storage.get('recordData').then((recordData) => {
console.log(recordData);
if(recordData.value.recordDataBase64.includes('data:audio')){
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64);
}
else{
this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`);
}
});
}
startRecording() {
console.log('Recording');
if (this.recording) {
return;
}
this.recording = true;
VoiceRecorder.startRecording();
this.calculateDuration();
}
stopRecording() {
this.deleteRecording();
this.allowTyping = false;
console.log('Stop');
if (!this.recording) {
return;
}
this.recording = false;
VoiceRecorder.stopRecording().then(async (result: RecordingData) => {
console.log(result);
this.recording = false;
if (result.value && result.value.recordDataBase64) {
const recordData = result.value.recordDataBase64;
//console.log(recordData);
const fileName = new Date().getTime() + ".mp3";
//Save file
this.storage.set('fileName',fileName);
this.storage.set('recordData',result).then(() => {
console.log('Audio recorded saved');
})
}
})
setTimeout(async () => {
this.loadFiles();
}, 1000);
}
async deleteRecording(){
this.storage.remove('fileName');
this.storage.remove('recordData');
this.allowTyping = true;
this.lastAudioRecorded = '';
this.loadFiles();
}
ngOnDestroy() {
this.checktimeOut = false;
window.removeEventListener('scroll', this.scrollChangeCallback, true);
@@ -250,9 +354,52 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.wsChatMethodsService.getDmRoom(this.roomId).send({})
}
deleteMessage(msgId: string) {
const room = this.wsChatMethodsService.getDmRoom(this.roomId)
this.alertService.confirmDeleteMessage(msgId, room);
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 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();
}
deleteMessage(msgId: string, msg:MessageService) {
/* msg.delateStatusFalse()
this.wsChatMethodsService.getDmRoom(this.roomId).sendDeleteRequest(msgId) */
}
async viewDocument(msg: any, url?: string) {
@@ -333,14 +480,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;
});
}
@@ -471,6 +616,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,
@@ -600,6 +746,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)
@@ -763,9 +910,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
ts: msg.attachments[0].ts
}
await this.storage.set(msg.file.guid, this.downloadFile).then(() => {
console.log('IMAGE SAVED')
});
// save the changes to the storage
//msg.save()
}
});
@@ -821,7 +969,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
testEditMessage(msg: MessageService) {
msg.receptorReceive()
// msg.receptorReceive()
// alert('cool!')
}
}