Added new audio controler on chat

This commit is contained in:
Eudes Inácio
2022-06-29 11:42:31 +01:00
parent e3df1e7de1
commit 528d3be338
5 changed files with 1010 additions and 33131 deletions
+706 -32935
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -133,6 +133,7 @@
"g": "^2.0.1", "g": "^2.0.1",
"global": "^4.4.0", "global": "^4.4.0",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"howler": "^2.2.3",
"http-server": "^0.12.3", "http-server": "^0.12.3",
"i": "^0.3.7", "i": "^0.3.7",
"ionic-angular": "^3.9.10", "ionic-angular": "^3.9.10",
@@ -213,7 +213,15 @@
</div> </div>
<div class="width-100 pl-20 pr-20"> <div class="width-100 pl-20 pr-20">
<span *ngIf="!lastAudioRecorded">{{durationDisplay}}</span> <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 class=" audioDiv d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded">
<!-- <button class="audioButtonPlay" fill="clear" (click)="start(audioRecorded)" *ngIf="!isPlaying"> <ion-icon slot="icon-only" name="play"></ion-icon> </button>
<button class="audioButtonPlay" fill="clear" (click)="togglePlayer(true)" *ngIf="isPlaying"> <ion-icon slot="icon-only" name="pause"></ion-icon> </button> -->
<div (click)="start(audioRecorded)" *ngIf="!isPlaying" > <ion-icon slot="icon-only" name="play"></ion-icon> </div>
<div (click)="togglePlayer(isPlaying)" *ngIf="isPlaying"> <ion-icon slot="icon-only" name="pause"></ion-icon> </div>
<!-- <label>{{audioDuration}}</label> -->
<ion-range #range [(ngModel)]="audioProgress" max="100" (mouseup)="seek()"></ion-range>
</div>
<!-- <audio [src]="audioRecorded" class="d-flex width-100 mt-10 mb-10" *ngIf="lastAudioRecorded" controls controlsList="nodownload noplaybackrate"></audio> -->
</div> </div>
<div class="container width-100 d-flex"> <div class="container width-100 d-flex">
@@ -1,10 +1,12 @@
@import '~src/function.scss'; @import '~src/function.scss';
.header-toolbar { .header-toolbar {
--background: transparent; --background: transparent;
--opacity: 1; --opacity: 1;
.main-header { .main-header {
width: 100%; /* 400px */ width: 100%;
/* 400px */
height: 100%; height: 100%;
font-family: Roboto; font-family: Roboto;
background-color: #fff; background-color: #fff;
@@ -19,6 +21,7 @@
overflow: auto; overflow: auto;
//padding: 0 !important; //padding: 0 !important;
background: #fff; background: #fff;
.middle { .middle {
//padding: 0!important; //padding: 0!important;
float: left; float: left;
@@ -28,6 +31,7 @@
align-items: center; align-items: center;
} }
.right { .right {
padding: 0 !important; padding: 0 !important;
float: right; float: right;
@@ -36,6 +40,7 @@
margin: 5px 0 0 0; margin: 5px 0 0 0;
} }
} }
.header-bottom { .header-bottom {
width: 95%; width: 95%;
overflow: auto; overflow: auto;
@@ -48,6 +53,7 @@
padding: 2px; padding: 2px;
} }
.header-bottom-contacts { .header-bottom-contacts {
width: 275px; width: 275px;
font-size: 15px; font-size: 15px;
@@ -68,6 +74,7 @@
text-overflow: ellipsis !important; text-overflow: ellipsis !important;
float: left; float: left;
} }
.div-icon { .div-icon {
width: 40px; width: 40px;
float: right; float: right;
@@ -75,16 +82,19 @@
overflow: auto; overflow: auto;
padding: 1px; padding: 1px;
} }
.div-icon ion-icon { .div-icon ion-icon {
float: right; float: right;
padding-left: 20px; padding-left: 20px;
} }
} }
} }
ion-content { ion-content {
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 30px 20px 0 20px !important; padding: 30px 20px 0 20px !important;
.welcome-text { .welcome-text {
/* width: 322px; */ /* width: 322px; */
/* width: em(422px); */ /* width: em(422px); */
@@ -100,6 +110,7 @@
border-radius: 8px; border-radius: 8px;
border: 1px solid red; border: 1px solid red;
} }
.info-meeting { .info-meeting {
/* width: 322px; */ /* width: 322px; */
width: em(422px); width: em(422px);
@@ -117,12 +128,15 @@
font-size: 10px; font-size: 10px;
font-style: italic; font-style: italic;
} }
.info-meeting-medium { .info-meeting-medium {
font-size: 12px; font-size: 12px;
} }
.info-meeting-normal { .info-meeting-normal {
font-weight: 700; font-weight: 700;
} }
.info-meeting-normal:hover { .info-meeting-normal:hover {
text-decoration: underline; text-decoration: underline;
color: #0782c9; color: #0782c9;
@@ -151,7 +165,8 @@
} }
.incoming-true, .incoming-false{ .incoming-true,
.incoming-false {
padding: 15px 20px; padding: 15px 20px;
border-radius: 10px; border-radius: 10px;
} }
@@ -162,11 +177,13 @@
float: left; float: left;
} }
} }
.incoming-false { .incoming-false {
margin: 10px 20px 10px 75px; margin: 10px 20px 10px 75px;
background: var(--chat-incoming-msg-color); background: var(--chat-incoming-msg-color);
float: right; float: right;
} }
.title { .title {
display: inline; display: inline;
color: var(--title-text-color); color: var(--title-text-color);
@@ -180,6 +197,7 @@
float: right; float: right;
} }
} }
.message { .message {
.message-attachments { .message-attachments {
.file { .file {
@@ -195,6 +213,7 @@
overflow: hidden !important; overflow: hidden !important;
text-overflow: ellipsis !important; text-overflow: ellipsis !important;
} }
.file-title:hover { .file-title:hover {
color: #0782c9; color: #0782c9;
} }
@@ -257,36 +276,42 @@
font-weight: 500; font-weight: 500;
letter-spacing: normal; letter-spacing: normal;
} }
.user-status-online { .user-status-online {
display: block; display: block;
float: left; float: left;
color: #99e47b; color: #99e47b;
padding-left: 10px; padding-left: 10px;
} }
.online { .online {
display: block; display: block;
float: left; float: left;
color: #99e47b; color: #99e47b;
padding-left: 10px; padding-left: 10px;
} }
.offline { .offline {
color: #cbced1; color: #cbced1;
display: block; display: block;
float: left; float: left;
padding-left: 10px; padding-left: 10px;
} }
.away { .away {
color: #ffd21f; color: #ffd21f;
display: block; display: block;
float: left; float: left;
padding-left: 10px; padding-left: 10px;
} }
.invisible { .invisible {
color: #cbced1; color: #cbced1;
display: block; display: block;
float: left; float: left;
padding-left: 10px; padding-left: 10px;
} }
.busy { .busy {
color: #f5455c; color: #f5455c;
display: block; display: block;
@@ -346,3 +371,21 @@ display: block;
flex: auto; flex: auto;
margin-right: 9px; margin-right: 9px;
} }
.divColor {
color: #000;
width: 10ch;
height: 10ch;
}
.audioDiv {
border-radius: 25px;
background: #cbced1;
padding: 20px;
height: 50px;
}
.audioButtonPlay {
margin-bottom: 100%;
right: 50%;
}
+57 -1
View File
@@ -1,5 +1,5 @@
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import { AnimationController, GestureController, ModalController, PopoverController } from '@ionic/angular'; import { AnimationController, GestureController, IonRange, ModalController, PopoverController } from '@ionic/angular';
import { AuthService } from 'src/app/services/auth.service'; import { AuthService } from 'src/app/services/auth.service';
import { ChatService } from 'src/app/services/chat.service'; import { ChatService } from 'src/app/services/chat.service';
import { ToastService } from 'src/app/services/toast.service'; import { ToastService } from 'src/app/services/toast.service';
@@ -32,6 +32,8 @@ import { File } from '@awesome-cordova-plugins/file/ngx';
import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx';
import { SessionStore } from 'src/app/store/session.service'; import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { Howl } from 'howler';
import { runInThisContext } from 'vm';
const IMAGE_DIR = 'stored-images'; const IMAGE_DIR = 'stored-images';
@@ -90,6 +92,12 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
audioPermissionStatus: 'granted'| 'denied' | 'prompt' | null = null audioPermissionStatus: 'granted'| 'denied' | 'prompt' | null = null
sessionStore = SessionStore sessionStore = SessionStore
audioPlay: Howl = null;
isPlaying = false;
audioProgress = 0;
audioDuration = 0;
audioTimer:any;
@ViewChild('range', {static: false}) range: IonRange;
constructor( constructor(
public popoverController: PopoverController, public popoverController: PopoverController,
@@ -1061,6 +1069,54 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
// msg.receptorReceive() // msg.receptorReceive()
// alert('cool!') // alert('cool!')
} }
start(track) {
if(this.audioPlay){
this.audioPlay.stop();
}
this.audioPlay = new Howl({
src: [track.changingThisBreaksApplicationSecurity],
onplay: () => {
console.log('audio play')
this.isPlaying = true;
this.updateProgress()
},
onend: () => {
console.log('audio end')
this.isPlaying = false;
clearTimeout(this.audioTimer)
this.audioProgress = 0
},
})
this.audioPlay.play();
}
togglePlayer(pause) {
this.isPlaying = !pause;
if(pause) {
this.audioPlay.pause();
} else {
this.audioPlay.play();
}
}
seek() {
let newValue = +this.range.value;
let duration = this.audioPlay.duration();
this.audioPlay.seek(duration * (newValue / 100));
}
updateProgress() {
let seek = this.audioPlay.seek();
this.audioProgress = (seek / this.audioPlay.duration()) * 100 || 0;
console.log(this.audioDuration)
this.audioTimer = setTimeout(() => {
this.updateProgress()
},1000)
}
} }