From 8066acc2bd7b293f53ecca551d70176a1f4c9bde Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 7 Nov 2019 15:46:02 +0900 Subject: [PATCH] audio & video viewer are added --- .../components/messages.component.html | 2 +- .../components/messages.component.ts | 4 +- .../message-box/file.component.html | 6 +- .../components/message-box/file.component.ts | 6 +- .../lib/components/messages.component.html | 2 +- .../src/lib/components/messages.component.ts | 6 +- .../lib/components/file-viewer.component.ts | 7 ++ .../file-viewer/sound-viewer.component.html | 94 ++++++++++++++++--- .../file-viewer/sound-viewer.component.scss | 44 ++++++++- .../file-viewer/sound-viewer.component.ts | 71 +++++++++++++- .../file-viewer/video-viewer.component.html | 94 ++++++++++++++++--- .../file-viewer/video-viewer.component.scss | 44 ++++++++- .../file-viewer/video-viewer.component.ts | 71 +++++++++++++- .../src/lib/pipes/seconds-to-minutes.pipe.ts | 10 ++ .../src/lib/ucap-ui.module.ts | 6 +- 15 files changed, 416 insertions(+), 51 deletions(-) create mode 100644 projects/ucap-webmessenger-ui/src/lib/pipes/seconds-to-minutes.pipe.ts diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html index 1b7c2279..d48498bc 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html @@ -109,7 +109,7 @@ (moreEvent)="onMoreEvent($event)" (massDetail)="onMassDetail($event)" (save)="onSave($event)" - (imageViewer)="onImageViewer($event)" + (fileViewer)="onFileViewer($event)" (contextMenu)="onContextMenuMessage($event)" > diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.ts index c01f45a3..60f7dfd6 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.ts @@ -470,8 +470,8 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit { ); } - async onImageViewer(fileInfo: FileEventJson) { - this.logger.debug('imageViewer', fileInfo); + async onFileViewer(fileInfo: FileEventJson) { + this.logger.debug('onFileViewer', fileInfo); const result = await this.dialogService.open< FileViewerDialogComponent, FileViewerDialogData, diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html index 1db0af0c..1bd22a2b 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html @@ -6,6 +6,7 @@ *ngSwitchCase="FileType.File" [fileInfo]="fileInfo" [expired]="getExpiredFile()" + (click)="onClickFileViewer(fileInfo)" (save)="onSave($event)" > @@ -13,6 +14,7 @@ *ngSwitchCase="FileType.Sound" [fileInfo]="fileInfo" [expired]="getExpiredFile()" + (click)="onClickFileViewer(fileInfo)" (save)="onSave($event)" > @@ -20,13 +22,13 @@ *ngSwitchCase="FileType.Image" [fileInfo]="fileInfo" [expired]="getExpiredFile()" - (click)="onClickImageViewer(fileInfo)" + (click)="onClickFileViewer(fileInfo)" > (); @Output() - imageViewer = new EventEmitter(); + fileViewer = new EventEmitter(); fileInfo?: FileEventJson; errorMessage?: string; @@ -50,8 +50,8 @@ export class FileComponent implements OnInit { } } - onClickImageViewer(fileInfo: FileEventJson) { - this.imageViewer.emit(fileInfo); + onClickFileViewer(fileInfo: FileEventJson) { + this.fileViewer.emit(fileInfo); } onSave(value: string) { diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html index 178cffb2..2bed0581 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html @@ -111,7 +111,7 @@ [eventInfoStatus]="eventInfoStatus" [message]="message" (save)="onSave($event)" - (imageViewer)="onImageViewer($event)" + (fileViewer)="onFileViewer($event)" (contextmenu)="onContextMenuMessage($event, message)" > diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.ts b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.ts index 28c2ed48..970bff89 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.ts +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.ts @@ -46,7 +46,7 @@ export class MessagesComponent implements OnInit { @Output() massDetail = new EventEmitter(); @Output() - imageViewer = new EventEmitter(); + fileViewer = new EventEmitter(); @Output() save = new EventEmitter<{ fileInfo: FileInfo; type: string }>(); @Output() @@ -158,8 +158,8 @@ export class MessagesComponent implements OnInit { } /** [Event] Image Viewer */ - onImageViewer(fileInfo: FileEventJson) { - this.imageViewer.emit(fileInfo); + onFileViewer(fileInfo: FileEventJson) { + this.fileViewer.emit(fileInfo); } /** [Event] Attach File Save & Save As */ diff --git a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer.component.ts b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer.component.ts index 20fdbbb4..54c0140a 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer.component.ts +++ b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer.component.ts @@ -38,6 +38,9 @@ export class FileViewerComponent implements OnInit { case FileType.Video: return FileViewerType.Video; default: + if (this.isSoundFile(fileInfo.fileExt)) { + return FileViewerType.Sound; + } return FileViewerType.Binary; } } @@ -48,4 +51,8 @@ export class FileViewerComponent implements OnInit { onClosedViewer(): void { this.closed.emit(); } + + private isSoundFile(fileExt: string): boolean { + return -1 !== ['mp3'].indexOf(fileExt); + } } diff --git a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.html b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.html index 25607b58..6d3a0430 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.html +++ b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.html @@ -1,18 +1,84 @@ -
- - Third Line - - favorite + + music_note + {{ fileInfo.fileName }} + + + +
+
+ + music_note +
+
+ + +
+
+
+ {{ currentTime | ucapSecondsToMinutes }} +
+ + + +
+ {{ duration | ucapSecondsToMinutes }} +
+
+
diff --git a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.scss b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.scss index acffcbee..d2d0bfbf 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.scss +++ b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.scss @@ -6,8 +6,48 @@ width: 100%; height: 50px; - .ucap-sound-viewer-spacer { - flex: 1 1 auto; + .ucap-sound-viewer-icon { + } + + .ucap-sound-viewer-title { } } + + .ucap-sound-viewer-body { + position: relative; + background-color: white; + width: 100%; + height: 100%; + padding-bottom: 70px; + + .ucap-sound-viewer-sound-icon { + width: 100%; + height: calc(100% - 60px); + } + .ucap-sound-viewer-sound-time { + width: 100%; + height: 30px; + } + .ucap-sound-viewer-sound-controls { + width: 100%; + height: 30px; + + .ucap-sound-viewer-sound-time-current { + padding-left: 30px; + } + + .ucap-sound-viewer-sound-time-total { + padding-right: 30px; + } + } + } + .ucap-sound-viewer-spacer { + flex: 1 1 auto; + } + .ucap-sound-viewer-action { + } +} + +mat-slider { + width: 95%; } diff --git a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.ts b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.ts index de030392..d3b39457 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.ts +++ b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/sound-viewer.component.ts @@ -1,7 +1,15 @@ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + ViewChild, + ElementRef +} from '@angular/core'; import { ucapAnimations } from '../../animations'; import { FileEventJson } from '@ucap-webmessenger/protocol-event'; -import { DeviceType } from '@ucap-webmessenger/core'; +import { MatSlider, MatSliderChange } from '@angular/material'; @Component({ selector: 'ucap-sound-viewer', @@ -22,11 +30,68 @@ export class SoundViewerComponent implements OnInit { @Output() closed = new EventEmitter(); + @ViewChild('audioPlayer', { static: true }) + audioPlayer: ElementRef; + + @ViewChild('timeSlider', { static: true }) + timeSlider: MatSlider; + + playing = false; + duration = 0.01; + currentTime = 0; + volume = 0.1; + loading = false; + constructor() {} ngOnInit() {} - onClickDownload(): void {} + onClickPlayOrPause(): void { + if (this.loading) { + return; + } + if (this.audioPlayer.nativeElement.paused) { + this.audioPlayer.nativeElement.play(); + } else { + this.currentTime = this.audioPlayer.nativeElement.currentTime; + this.audioPlayer.nativeElement.pause(); + } + } + + onChangeTimeSlider(e: MatSliderChange): void { + console.log('onChangeTimeSlider', e.value); + this.audioPlayer.nativeElement.currentTime = e.value; + } + + onPlayingAudio(): void { + this.playing = true; + // this.duration = Math.floor(this.audioPlayer.nativeElement.duration); + } + + onPauseAudio(): void { + this.playing = false; + } + + onTimeUpdateAudio(): void { + this.currentTime = Math.floor(this.audioPlayer.nativeElement.currentTime); + } + + onVolumeChangeAudio(): void { + this.volume = Math.floor(this.audioPlayer.nativeElement.volume); + } + + onLoadStartAudio(): void { + this.loading = true; + } + + onLoadedDataAudio(): void { + this.loading = false; + this.duration = Math.floor(this.audioPlayer.nativeElement.duration); + } + + onClickDownload(): void { + this.download.emit(); + } onClickClose(): void { this.closed.emit(); diff --git a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.html b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.html index 25607b58..d945dac5 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.html +++ b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.html @@ -1,18 +1,84 @@ -
- - Third Line - - favorite + + video_label + {{ fileInfo.fileName }} + + + + +
+
+ +
+
+ + +
+
+
+ {{ currentTime | ucapSecondsToMinutes }} +
+ + + +
+ {{ duration | ucapSecondsToMinutes }} +
+
+
diff --git a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.scss b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.scss index d5420d73..7ad92977 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.scss +++ b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.scss @@ -6,8 +6,48 @@ width: 100%; height: 50px; - .ucap-video-viewer-spacer { - flex: 1 1 auto; + .ucap-video-viewer-icon { + } + + .ucap-video-viewer-title { } } + + .ucap-video-viewer-body { + position: relative; + background-color: white; + width: 100%; + height: 100%; + padding-bottom: 70px; + + .ucap-video-viewer-video-icon { + width: 100%; + height: calc(100% - 60px); + } + .ucap-video-viewer-video-time { + width: 100%; + height: 30px; + } + .ucap-video-viewer-video-controls { + width: 100%; + height: 30px; + + .ucap-video-viewer-video-time-current { + padding-left: 30px; + } + + .ucap-video-viewer-video-time-total { + padding-right: 30px; + } + } + } + .ucap-video-viewer-spacer { + flex: 1 1 auto; + } + .ucap-video-viewer-action { + } +} + +mat-slider { + width: 95%; } diff --git a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.ts b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.ts index 2effdefd..c58efc2c 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.ts +++ b/projects/ucap-webmessenger-ui/src/lib/components/file-viewer/video-viewer.component.ts @@ -1,7 +1,15 @@ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + ViewChild, + ElementRef +} from '@angular/core'; import { ucapAnimations } from '../../animations'; import { FileEventJson } from '@ucap-webmessenger/protocol-event'; -import { DeviceType } from '@ucap-webmessenger/core'; +import { MatSlider, MatSliderChange } from '@angular/material'; @Component({ selector: 'ucap-video-viewer', @@ -22,11 +30,68 @@ export class VideoViewerComponent implements OnInit { @Output() closed = new EventEmitter(); + @ViewChild('audioPlayer', { static: true }) + audioPlayer: ElementRef; + + @ViewChild('timeSlider', { static: true }) + timeSlider: MatSlider; + + playing = false; + duration = 0.01; + currentTime = 0; + volume = 0.1; + loading = false; + constructor() {} ngOnInit() {} - onClickDownload(): void {} + onClickPlayOrPause(): void { + if (this.loading) { + return; + } + if (this.audioPlayer.nativeElement.paused) { + this.audioPlayer.nativeElement.play(); + } else { + this.currentTime = this.audioPlayer.nativeElement.currentTime; + this.audioPlayer.nativeElement.pause(); + } + } + + onChangeTimeSlider(e: MatSliderChange): void { + console.log('onChangeTimeSlider', e.value); + this.audioPlayer.nativeElement.currentTime = e.value; + } + + onPlayingVideo(): void { + this.playing = true; + // this.duration = Math.floor(this.audioPlayer.nativeElement.duration); + } + + onPauseVideo(): void { + this.playing = false; + } + + onTimeUpdateVideo(): void { + this.currentTime = Math.floor(this.audioPlayer.nativeElement.currentTime); + } + + onVolumeChangeVideo(): void { + this.volume = Math.floor(this.audioPlayer.nativeElement.volume); + } + + onLoadStartVideo(): void { + this.loading = true; + } + + onLoadedDataVideo(): void { + this.loading = false; + this.duration = Math.floor(this.audioPlayer.nativeElement.duration); + } + + onClickDownload(): void { + this.download.emit(); + } onClickClose(): void { this.closed.emit(); diff --git a/projects/ucap-webmessenger-ui/src/lib/pipes/seconds-to-minutes.pipe.ts b/projects/ucap-webmessenger-ui/src/lib/pipes/seconds-to-minutes.pipe.ts new file mode 100644 index 00000000..af9cd703 --- /dev/null +++ b/projects/ucap-webmessenger-ui/src/lib/pipes/seconds-to-minutes.pipe.ts @@ -0,0 +1,10 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ name: 'ucapSecondsToMinutes' }) +export class SecondsToMinutesPipe implements PipeTransform { + public transform(time: number): string { + const minutes = ('0' + Math.floor(time / 60)).slice(-2); + const seconds = ('0' + (time % 60)).slice(-2); + return `${minutes}:${seconds}`; + } +} diff --git a/projects/ucap-webmessenger-ui/src/lib/ucap-ui.module.ts b/projects/ucap-webmessenger-ui/src/lib/ucap-ui.module.ts index 7eaa1e55..fb3aebea 100644 --- a/projects/ucap-webmessenger-ui/src/lib/ucap-ui.module.ts +++ b/projects/ucap-webmessenger-ui/src/lib/ucap-ui.module.ts @@ -9,6 +9,7 @@ import { MatCardModule } from '@angular/material/card'; import { MatDialogModule } from '@angular/material/dialog'; import { MatIconModule } from '@angular/material/icon'; import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatSliderModule } from '@angular/material/slider'; import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatToolbarModule } from '@angular/material/toolbar'; @@ -39,6 +40,7 @@ import { ConfirmDialogComponent } from './dialogs/confirm.dialog.component'; import { BytesPipe } from './pipes/bytes.pipe'; import { LinefeedToHtmlPipe, HtmlToLinefeedPipe } from './pipes/linefeed.pipe'; import { DateToStringForChatRoomListPipe } from './pipes/dates.pipe'; +import { SecondsToMinutesPipe } from './pipes/seconds-to-minutes.pipe'; const COMPONENTS = [ FileUploadQueueComponent, @@ -61,7 +63,8 @@ const PIPES = [ BytesPipe, LinefeedToHtmlPipe, HtmlToLinefeedPipe, - DateToStringForChatRoomListPipe + DateToStringForChatRoomListPipe, + SecondsToMinutesPipe ]; const SERVICES = [ BottomSheetService, @@ -79,6 +82,7 @@ const SERVICES = [ MatDialogModule, MatIconModule, MatProgressBarModule, + MatSliderModule, MatSnackBarModule, MatToolbarModule, MatTooltipModule,