From 7dcec1aaad1229dc73ae0589749419e166c9c9c5 Mon Sep 17 00:00:00 2001 From: Park Byung Eun Date: Tue, 9 Jun 2020 09:12:32 +0900 Subject: [PATCH] sync --- .../2째주/backup/binary-viewer.component.html | 117 ++++++++++++ .../2째주/backup/binary-viewer.component.scss | 67 +++++++ .../2째주/backup/binary-viewer.component.spec.ts | 27 +++ .../6월/2째주/backup/binary-viewer.component.ts | 41 ++++ .../2째주/backup/document-viewer.component.html | 29 +++ .../2째주/backup/document-viewer.component.scss | 13 ++ .../backup/document-viewer.component.spec.ts | 27 +++ .../2째주/backup/document-viewer.component.ts | 39 ++++ .../6월/2째주/backup/file-viewer.component.html | 20 ++ .../6월/2째주/backup/file-viewer.component.scss | 4 + .../2째주/backup/file-viewer.component.spec.ts | 27 +++ .../6월/2째주/backup/file-viewer.component.ts | 77 ++++++++ .../backup/file-viewer.dialog.component.html | 17 ++ .../backup/file-viewer.dialog.component.scss | 0 .../backup/file-viewer.dialog.component.spec.ts | 27 +++ .../2째주/backup/file-viewer.dialog.component.ts | 178 +++++++++++++++++ .../2째주/backup/image-viewer.component.html | 179 ++++++++++++++++++ .../2째주/backup/image-viewer.component.scss | 73 +++++++ .../2째주/backup/image-viewer.component.spec.ts | 27 +++ .../6월/2째주/backup/image-viewer.component.ts | 149 +++++++++++++++ .../2째주/backup/sound-viewer.component.html | 144 ++++++++++++++ .../2째주/backup/sound-viewer.component.scss | 163 ++++++++++++++++ .../2째주/backup/sound-viewer.component.spec.ts | 27 +++ .../6월/2째주/backup/sound-viewer.component.ts | 104 ++++++++++ .../2째주/backup/video-viewer.component.html | 169 +++++++++++++++++ .../2째주/backup/video-viewer.component.scss | 100 ++++++++++ .../2째주/backup/video-viewer.component.spec.ts | 27 +++ .../6월/2째주/backup/video-viewer.component.ts | 125 ++++++++++++ 28 files changed, 1997 insertions(+) create mode 100644 documents/업무/6월/2째주/backup/binary-viewer.component.html create mode 100644 documents/업무/6월/2째주/backup/binary-viewer.component.scss create mode 100644 documents/업무/6월/2째주/backup/binary-viewer.component.spec.ts create mode 100644 documents/업무/6월/2째주/backup/binary-viewer.component.ts create mode 100644 documents/업무/6월/2째주/backup/document-viewer.component.html create mode 100644 documents/업무/6월/2째주/backup/document-viewer.component.scss create mode 100644 documents/업무/6월/2째주/backup/document-viewer.component.spec.ts create mode 100644 documents/업무/6월/2째주/backup/document-viewer.component.ts create mode 100644 documents/업무/6월/2째주/backup/file-viewer.component.html create mode 100644 documents/업무/6월/2째주/backup/file-viewer.component.scss create mode 100644 documents/업무/6월/2째주/backup/file-viewer.component.spec.ts create mode 100644 documents/업무/6월/2째주/backup/file-viewer.component.ts create mode 100644 documents/업무/6월/2째주/backup/file-viewer.dialog.component.html create mode 100644 documents/업무/6월/2째주/backup/file-viewer.dialog.component.scss create mode 100644 documents/업무/6월/2째주/backup/file-viewer.dialog.component.spec.ts create mode 100644 documents/업무/6월/2째주/backup/file-viewer.dialog.component.ts create mode 100644 documents/업무/6월/2째주/backup/image-viewer.component.html create mode 100644 documents/업무/6월/2째주/backup/image-viewer.component.scss create mode 100644 documents/업무/6월/2째주/backup/image-viewer.component.spec.ts create mode 100644 documents/업무/6월/2째주/backup/image-viewer.component.ts create mode 100644 documents/업무/6월/2째주/backup/sound-viewer.component.html create mode 100644 documents/업무/6월/2째주/backup/sound-viewer.component.scss create mode 100644 documents/업무/6월/2째주/backup/sound-viewer.component.spec.ts create mode 100644 documents/업무/6월/2째주/backup/sound-viewer.component.ts create mode 100644 documents/업무/6월/2째주/backup/video-viewer.component.html create mode 100644 documents/업무/6월/2째주/backup/video-viewer.component.scss create mode 100644 documents/업무/6월/2째주/backup/video-viewer.component.spec.ts create mode 100644 documents/업무/6월/2째주/backup/video-viewer.component.ts diff --git a/documents/업무/6월/2째주/backup/binary-viewer.component.html b/documents/업무/6월/2째주/backup/binary-viewer.component.html new file mode 100644 index 0000000..1cc01de --- /dev/null +++ b/documents/업무/6월/2째주/backup/binary-viewer.component.html @@ -0,0 +1,117 @@ +
+ + + + + + {{ + fileInfo.sentMessageJson.fileName + }} + + + + + + +
+
+ +
+
+
+
+
+
+
+
+
+
+ {{ 'common.file.errors.noPreview' | translate }} +
+
+ +
+
+
+
diff --git a/documents/업무/6월/2째주/backup/binary-viewer.component.scss b/documents/업무/6월/2째주/backup/binary-viewer.component.scss new file mode 100644 index 0000000..8b0bd9a --- /dev/null +++ b/documents/업무/6월/2째주/backup/binary-viewer.component.scss @@ -0,0 +1,67 @@ +.ucap-binary-viewer-container { + width: 100%; + height: 100%; + + .ucap-binary-viewer-header { + width: 100%; + height: 60px; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.6); + background-color: #333333; + color: #ffffff; + + .ucap-binary-viewer-icon { + margin-right: 10px; + } + + .ucap-binary-viewer-title { + font-size: 16px; + } + + .ucap-binary-viewer-spacer { + flex: 1 1 auto; + } + + .stroke-bar { + width: 1px; + height: 30px; + background-color: rgba(256, 256, 256, 0.3); + margin: 0 10px; + } + .ucap-binary-viewer-action { + margin-left: auto; + width: 24px; + height: 24px; + margin-left: 10px; + &:hover { + opacity: 0.7; + } + } + } + + .ucap-binary-viewer-body { + position: relative; + width: 100%; + height: calc(100% - 60px); + + .ucap-image-viewer-image-wrapper { + height: 100%; + padding: 20px; + background-color: rgba(0, 0, 0, 0.9); + } + .circle-box { + display: flex; + width: 140px; + height: 140px; + border-radius: 50%; + justify-content: center; + align-items: center; + border: 2px solid #ffffff; + background-color: rgba(256, 256, 256, 0.7); + } + .guide-msg { + font-size: 16px; + margin: 30px; + color: #ffffff; + } + } +} diff --git a/documents/업무/6월/2째주/backup/binary-viewer.component.spec.ts b/documents/업무/6월/2째주/backup/binary-viewer.component.spec.ts new file mode 100644 index 0000000..b5932b4 --- /dev/null +++ b/documents/업무/6월/2째주/backup/binary-viewer.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { BinaryViewerComponent } from './binary-viewer.component'; + +describe('BinaryViewerComponent', () => { + let component: BinaryViewerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [BinaryViewerComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BinaryViewerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/documents/업무/6월/2째주/backup/binary-viewer.component.ts b/documents/업무/6월/2째주/backup/binary-viewer.component.ts new file mode 100644 index 0000000..5b39192 --- /dev/null +++ b/documents/업무/6월/2째주/backup/binary-viewer.component.ts @@ -0,0 +1,41 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { ucapAnimations } from '../../animations'; + +import { FileDownloadItem } from '@ucap-webmessenger/api'; +import { FileInfo } from '@ucap-webmessenger/protocol-file'; +import { NGXLogger } from 'ngx-logger'; + +@Component({ + selector: 'ucap-binary-viewer', + templateUrl: './binary-viewer.component.html', + styleUrls: ['./binary-viewer.component.scss'], + animations: ucapAnimations +}) +export class BinaryViewerComponent implements OnInit { + @Input() + fileInfo: FileInfo; + + @Input() + fileDownloadUrl: string; + + @Output() + download = new EventEmitter(); + + @Output() + closed = new EventEmitter(); + + fileDownloadItem: FileDownloadItem; + + constructor() {} + + ngOnInit() {} + + onClickDownload(): void { + this.fileDownloadItem = new FileDownloadItem(); + this.download.emit(this.fileDownloadItem); + } + + onClickClose(): void { + this.closed.emit(); + } +} diff --git a/documents/업무/6월/2째주/backup/document-viewer.component.html b/documents/업무/6월/2째주/backup/document-viewer.component.html new file mode 100644 index 0000000..1590190 --- /dev/null +++ b/documents/업무/6월/2째주/backup/document-viewer.component.html @@ -0,0 +1,29 @@ +
+ + Third Line + + favorite + delete + +
+
+ +
+
+
diff --git a/documents/업무/6월/2째주/backup/document-viewer.component.scss b/documents/업무/6월/2째주/backup/document-viewer.component.scss new file mode 100644 index 0000000..9c406ef --- /dev/null +++ b/documents/업무/6월/2째주/backup/document-viewer.component.scss @@ -0,0 +1,13 @@ +.ucap-document-viewer-container { + width: 100%; + height: 100%; + + .ucap-document-viewer-header { + width: 100%; + height: 50px; + + .ucap-document-viewer-spacer { + flex: 1 1 auto; + } + } +} diff --git a/documents/업무/6월/2째주/backup/document-viewer.component.spec.ts b/documents/업무/6월/2째주/backup/document-viewer.component.spec.ts new file mode 100644 index 0000000..3ec0ca9 --- /dev/null +++ b/documents/업무/6월/2째주/backup/document-viewer.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { DocumentViewerComponent } from './document-viewer.component'; + +describe('DocumentViewerComponent', () => { + let component: DocumentViewerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [DocumentViewerComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DocumentViewerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/documents/업무/6월/2째주/backup/document-viewer.component.ts b/documents/업무/6월/2째주/backup/document-viewer.component.ts new file mode 100644 index 0000000..8feafe8 --- /dev/null +++ b/documents/업무/6월/2째주/backup/document-viewer.component.ts @@ -0,0 +1,39 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { ucapAnimations } from '../../animations'; +import { FileInfo } from '@ucap-webmessenger/protocol-file'; +import { FileDownloadItem } from '@ucap-webmessenger/api'; + +@Component({ + selector: 'ucap-document-viewer', + templateUrl: './document-viewer.component.html', + styleUrls: ['./document-viewer.component.scss'], + animations: ucapAnimations +}) +export class DocumentViewerComponent implements OnInit { + @Input() + fileInfo: FileInfo; + + @Input() + fileDownloadUrl: string; + + @Output() + download = new EventEmitter(); + + @Output() + closed = new EventEmitter(); + + fileDownloadItem: FileDownloadItem; + + constructor() {} + + ngOnInit() {} + + onClickDownload(): void { + this.fileDownloadItem = new FileDownloadItem(); + this.download.emit(this.fileDownloadItem); + } + + onClickClose(): void { + this.closed.emit(); + } +} diff --git a/documents/업무/6월/2째주/backup/file-viewer.component.html b/documents/업무/6월/2째주/backup/file-viewer.component.html new file mode 100644 index 0000000..7918958 --- /dev/null +++ b/documents/업무/6월/2째주/backup/file-viewer.component.html @@ -0,0 +1,20 @@ +
+ + + +
diff --git a/documents/업무/6월/2째주/backup/file-viewer.component.scss b/documents/업무/6월/2째주/backup/file-viewer.component.scss new file mode 100644 index 0000000..9e8bf81 --- /dev/null +++ b/documents/업무/6월/2째주/backup/file-viewer.component.scss @@ -0,0 +1,4 @@ +.ucap-file-viewer-container { + width: 100%; + height: 100%; +} diff --git a/documents/업무/6월/2째주/backup/file-viewer.component.spec.ts b/documents/업무/6월/2째주/backup/file-viewer.component.spec.ts new file mode 100644 index 0000000..71f25cd --- /dev/null +++ b/documents/업무/6월/2째주/backup/file-viewer.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { FileViewerComponent } from './file-viewer.component'; + +describe('FileViewerComponent', () => { + let component: FileViewerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [FileViewerComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FileViewerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/documents/업무/6월/2째주/backup/file-viewer.component.ts b/documents/업무/6월/2째주/backup/file-viewer.component.ts new file mode 100644 index 0000000..ed8a5ed --- /dev/null +++ b/documents/업무/6월/2째주/backup/file-viewer.component.ts @@ -0,0 +1,77 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { ucapAnimations } from '../animations'; + +import { FileViewerType } from '../types/file-viewer.type'; +import { FileType, FileInfo, isSound } from '@ucap-webmessenger/protocol-file'; +import { FileDownloadItem } from '@ucap-webmessenger/api'; +import { SelectFileInfo } from '../models/select-file-info'; + +@Component({ + selector: 'ucap-file-viewer', + templateUrl: './file-viewer.component.html', + styleUrls: ['./file-viewer.component.scss'], + animations: ucapAnimations +}) +export class FileViewerComponent implements OnInit { + @Input() + set fileInfo(v: { fileInfos: FileInfo[]; selectFileInfo: SelectFileInfo }) { + this._fileInfo = v; + + this.currentFileInfo = v.fileInfos.find( + f => f.sentMessageJson.attachmentSeq === v.selectFileInfo.attachmentSeq + ); + } + // tslint:disable-next-line: variable-name + _fileInfo: { + fileInfos: FileInfo[]; + selectFileInfo: SelectFileInfo; + }; + + @Input() + fileDownloadUrl: (attachmentSeq: number) => string; + + @Output() + download = new EventEmitter<{ + attachmentSeq?: number; + downloadUrl?: string; + fileName: string; + fileDownloadItem: FileDownloadItem; + }>(); + + @Output() + closed = new EventEmitter(); + + currentFileInfo: FileInfo; + FileViewerType = FileViewerType; + + constructor() {} + + ngOnInit() {} + + detectFileViewerType(fileInfo: FileInfo): FileViewerType { + switch (fileInfo.type) { + case FileType.Image: + return FileViewerType.Image; + case FileType.Sound: + return FileViewerType.Sound; + case FileType.Video: + return FileViewerType.Video; + default: + if (isSound(fileInfo)) { + return FileViewerType.Sound; + } + return FileViewerType.Binary; + } + } + onDownload(fileDownloadItem: FileDownloadItem): void { + this.download.emit({ + attachmentSeq: this.currentFileInfo.sentMessageJson.attachmentSeq, + fileName: this.currentFileInfo.sentMessageJson.fileName, + fileDownloadItem + }); + } + + onClosedViewer(): void { + this.closed.emit(); + } +} diff --git a/documents/업무/6월/2째주/backup/file-viewer.dialog.component.html b/documents/업무/6월/2째주/backup/file-viewer.dialog.component.html new file mode 100644 index 0000000..9185158 --- /dev/null +++ b/documents/업무/6월/2째주/backup/file-viewer.dialog.component.html @@ -0,0 +1,17 @@ + + + + + diff --git a/documents/업무/6월/2째주/backup/file-viewer.dialog.component.scss b/documents/업무/6월/2째주/backup/file-viewer.dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/documents/업무/6월/2째주/backup/file-viewer.dialog.component.spec.ts b/documents/업무/6월/2째주/backup/file-viewer.dialog.component.spec.ts new file mode 100644 index 0000000..099a2d4 --- /dev/null +++ b/documents/업무/6월/2째주/backup/file-viewer.dialog.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { FileViewerDialogComponent } from './file-viewer.dialog.component'; + +describe('FileViewerDialogComponent', () => { + let component: FileViewerDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [FileViewerDialogComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FileViewerDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/documents/업무/6월/2째주/backup/file-viewer.dialog.component.ts b/documents/업무/6월/2째주/backup/file-viewer.dialog.component.ts new file mode 100644 index 0000000..a908cfa --- /dev/null +++ b/documents/업무/6월/2째주/backup/file-viewer.dialog.component.ts @@ -0,0 +1,178 @@ +import { Component, OnInit, OnDestroy, Inject } from '@angular/core'; + +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { NGXLogger } from 'ngx-logger'; + +import { DeviceType } from '@ucap-webmessenger/core'; +import { FileDownloadItem } from '@ucap-webmessenger/api'; +import { CommonApiService } from '@ucap-webmessenger/api-common'; +import { AppFileService } from '@app/services/file.service'; +import { FileInfo, isMedia } from '@ucap-webmessenger/protocol-file'; +import { SelectFileInfo, SnackBarService } from '@ucap-webmessenger/ui'; +import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; +import { TranslateService } from '@ngx-translate/core'; + +export interface FileViewerDialogData { + fileInfos: FileInfo[]; + selectFileInfo: SelectFileInfo; + downloadUrl: string; + userSeq: number; + deviceType: DeviceType; + token: string; +} + +export interface FileViewerDialogResult {} + +@Component({ + selector: 'app-layout-common-file-viewer', + templateUrl: './file-viewer.dialog.component.html', + styleUrls: ['./file-viewer.dialog.component.scss'] +}) +export class FileViewerDialogComponent implements OnInit, OnDestroy { + isMediaType: boolean; + fileInfo: { + fileInfos: FileInfo[]; + selectFileInfo: SelectFileInfo; + }; + currentFileInfo: FileInfo; + + constructor( + public dialogRef: MatDialogRef< + FileViewerDialogData, + FileViewerDialogResult + >, + @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, + @Inject(MAT_DIALOG_DATA) public data: FileViewerDialogData, + private snackBarService: SnackBarService, + private commonApiService: CommonApiService, + private appFileService: AppFileService, + private translateService: TranslateService, + private logger: NGXLogger + ) { + this.currentFileInfo = this.data.fileInfos.find( + (f) => f.seq === this.data.selectFileInfo.attachmentSeq + ); + + if (!this.currentFileInfo) { + this.logger.warn( + 'file info is exist', + this.data.fileInfos, + this.data.selectFileInfo + ); + this.dialogRef.close(); + return; + } + + this.isMediaType = isMedia(this.currentFileInfo); + + this.fileInfo = { + fileInfos: this.data.fileInfos.filter((f) => { + const i = isMedia(f); + return this.isMediaType ? i : !i; + }), + selectFileInfo: this.data.selectFileInfo + }; + } + + ngOnInit() {} + + ngOnDestroy(): void {} + + onDownload(info: { + attachmentSeq?: number; + fileName: string; + fileDownloadItem: FileDownloadItem; + roomSeq?: number; + eventSeq?: number; + }): void { + let fileName; + + const startIdx = info.fileName.indexOf('.thumb'); + + if (startIdx < 0) { + fileName = info.fileName; + } else { + const endIdx = info.fileName.lastIndexOf('.'); + const startFileName = info.fileName.substring(0, startIdx - 4); + const endFileName = info.fileName.substring(endIdx, info.fileName.length); + + fileName = startFileName.concat(endFileName); + } + + this.nativeService + .selectSaveFilePath(fileName) + .then((result) => { + if (!result) { + return; + } + + if (result.canceled) { + } else { + this.saveFile(info, result.filePath); + } + }) + .catch((reason) => { + this.snackBarService.open( + this.translateService.instant('common.file.errors.failToSpecifyPath'), + this.translateService.instant('common.file.errors.label') + ); + }); + } + + saveFile( + info: { + attachmentSeq?: number; + downloadUrl?: string; + fileName: string; + fileDownloadItem: FileDownloadItem; + roomSeq?: number; + eventSeq?: number; + }, + savePath: string + ) { + if (!!info.roomSeq && !!info.eventSeq) { + this.appFileService.fileTalkDownloadMulti({ + req: { + userSeq: this.data.userSeq, + deviceType: this.data.deviceType, + token: this.data.token, + roomSeq: info.roomSeq, + eventSeq: info.eventSeq, + thumbUrl: info.fileName, + fileDownloadItem: info.fileDownloadItem + }, + fileName: info.fileName, + savePath + }); + } else { + this.appFileService.fileTalkDownlod({ + req: { + userSeq: this.data.userSeq, + deviceType: this.data.deviceType, + token: this.data.token, + attachmentsSeq: info.attachmentSeq, + fileDownloadItem: info.fileDownloadItem + }, + fileName: info.fileName, + fileDownloadUrl: this.data.downloadUrl, + savePath + }); + } + } + + onClosedViewer(): void { + this.dialogRef.close(); + } + + fileDownloadUrl = (attachmentSeq: number) => { + return this.commonApiService.urlForFileTalkDownload( + { + userSeq: this.data.userSeq, + deviceType: this.data.deviceType, + token: this.data.token, + attachmentsSeq: attachmentSeq + }, + this.data.downloadUrl + ); + }; +} diff --git a/documents/업무/6월/2째주/backup/image-viewer.component.html b/documents/업무/6월/2째주/backup/image-viewer.component.html new file mode 100644 index 0000000..35f881d --- /dev/null +++ b/documents/업무/6월/2째주/backup/image-viewer.component.html @@ -0,0 +1,179 @@ +
+ + + + + + + + {{ fileName }} + + + + + + + + + +
+
+ +
+
+
+
+ +
+
+
diff --git a/documents/업무/6월/2째주/backup/image-viewer.component.scss b/documents/업무/6월/2째주/backup/image-viewer.component.scss new file mode 100644 index 0000000..a946307 --- /dev/null +++ b/documents/업무/6월/2째주/backup/image-viewer.component.scss @@ -0,0 +1,73 @@ +.ucap-image-viewer-container { + width: 100%; + height: 100%; + + .ucap-image-viewer-header { + width: 100%; + height: 60px; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.6); + background-color: #333333; + + .ucap-image-viewer-icon { + margin-right: 10px; + } + + .ucap-image-viewer-title { + font-size: 16px; + } + + .ucap-image-viewer-spacer { + flex: 1 1 auto; + } + + .stroke-bar { + width: 1px; + height: 30px; + background-color: rgba(256, 256, 256, 0.3); + margin: 0 10px; + } + .ucap-image-viewer-action { + width: 24px; + height: 24px; + margin-left: 10px; + &:hover { + opacity: 0.7; + } + } + } + + .ucap-image-viewer-body { + position: relative; + width: 100%; + height: calc(100% - 60px); + + .ucap-image-viewer-image-wrapper { + position: relative; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + overflow: auto; + + img { + position: absolute; + max-width: none !important; + } + + &::-webkit-scrollbar { + background-color: rgba(0, 0, 0, 0.7); + } + &::-webkit-scrollbar-corner { + background-color: rgba(0, 0, 0, 0.7); + } + &::-webkit-scrollbar:hover { + background-color: rgba(255, 255, 255, 0.12); + } + &::-webkit-scrollbar-thumb { + box-shadow: inset 0 0 0 12px rgba(255, 255, 255, 0.37); + } + &::-webkit-scrollbar-thumb:active { + box-shadow: inset 0 0 0 12px rgba(255, 255, 255, 0.54); + } + } + } +} diff --git a/documents/업무/6월/2째주/backup/image-viewer.component.spec.ts b/documents/업무/6월/2째주/backup/image-viewer.component.spec.ts new file mode 100644 index 0000000..9306526 --- /dev/null +++ b/documents/업무/6월/2째주/backup/image-viewer.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { ImageViewerComponent } from './image-viewer.component'; + +describe('ImageViewerComponent', () => { + let component: ImageViewerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ImageViewerComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ImageViewerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/documents/업무/6월/2째주/backup/image-viewer.component.ts b/documents/업무/6월/2째주/backup/image-viewer.component.ts new file mode 100644 index 0000000..bc61826 --- /dev/null +++ b/documents/업무/6월/2째주/backup/image-viewer.component.ts @@ -0,0 +1,149 @@ +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + ChangeDetectorRef, + ChangeDetectionStrategy, + ViewChild, + ElementRef, + HostListener +} from '@angular/core'; +import { ucapAnimations } from '../../animations'; +import { FileDownloadItem } from '@ucap-webmessenger/api'; +import { FileInfo } from '@ucap-webmessenger/protocol-file'; +@Component({ + selector: 'ucap-image-viewer', + templateUrl: './image-viewer.component.html', + styleUrls: ['./image-viewer.component.scss'], + animations: ucapAnimations, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ImageViewerComponent implements OnInit { + @Input() + fileInfo: FileInfo; + + @Input() + fileName: string; + + @Input() + fileDownloadUrl: string; + + @Output() + closed = new EventEmitter(); + + @Output() + download = new EventEmitter(); + + @ViewChild('imageContainer', { static: false }) + imageContainer: ElementRef; + + @ViewChild('downloadImage', { static: false }) + downloadImage: ElementRef; + + fileDownloadItem: FileDownloadItem; + + naturalWidth = 0; + naturalHeight = 0; + imageHeight = 0; + + zoomRatio = 100; + + constructor(private changeDetectorRef: ChangeDetectorRef) {} + + ngOnInit() { + this.naturalWidth = this.fileInfo.sentMessageJson.imageWidth; + this.naturalHeight = this.fileInfo.sentMessageJson.imageHeight; + } + + @HostListener('window:resize', ['$event']) + onResize(event: Event) { + this.setImageHeight(); + + this.changeDetectorRef.detectChanges(); + } + + onClickDownload(): void { + this.fileDownloadItem = new FileDownloadItem(); + this.download.emit(this.fileDownloadItem); + } + + onClickClose(): void { + this.closed.emit(); + } + + onLoadFileDownloadUrl(img: HTMLImageElement) { + this.naturalWidth = img.naturalWidth; + this.naturalHeight = img.naturalHeight; + + this.setImageHeight(); + + this.changeDetectorRef.detectChanges(); + } + + onClickZoomOut() { + if (60 >= this.zoomRatio) { + return; + } + this.zoomRatio -= 10; + + this.setImageHeight(); + + this.changeDetectorRef.detectChanges(); + } + onClickZoomIn() { + if (180 <= this.zoomRatio) { + return; + } + this.zoomRatio += 10; + + this.setImageHeight(); + + this.changeDetectorRef.detectChanges(); + } + onClickZoomReset() { + this.zoomRatio = 100; + + this.setImageHeight(); + + this.changeDetectorRef.detectChanges(); + } + + setImageHeight() { + const realContainerHeight = + this.imageContainer.nativeElement.clientHeight - 20; + const oriHeight = + this.naturalHeight > realContainerHeight + ? realContainerHeight + : this.naturalHeight; + + const oriWidth = (oriHeight * this.naturalWidth) / this.naturalHeight; + + const imageHeight = oriHeight * (this.zoomRatio / 100); + const imageWidth = oriWidth * (this.zoomRatio / 100); + let imageTop = + (this.imageContainer.nativeElement.clientHeight - imageHeight) / 2; + let imageLeft = + (this.imageContainer.nativeElement.clientWidth - imageWidth) / 2; + + let scrollTop = 0; + if (0 > imageTop) { + scrollTop = Math.abs(imageTop); + imageTop = 0; + } + + let scrollLeft = 0; + if (0 > imageLeft) { + scrollLeft = Math.abs(imageLeft); + imageLeft = 0; + } + + this.downloadImage.nativeElement.style.top = `${imageTop}px`; + this.downloadImage.nativeElement.style.left = `${imageLeft}px`; + this.imageContainer.nativeElement.scrollTop = scrollTop; + this.imageContainer.nativeElement.scrollLeft = scrollLeft; + + this.imageHeight = imageHeight; + } +} diff --git a/documents/업무/6월/2째주/backup/sound-viewer.component.html b/documents/업무/6월/2째주/backup/sound-viewer.component.html new file mode 100644 index 0000000..2c3ec2d --- /dev/null +++ b/documents/업무/6월/2째주/backup/sound-viewer.component.html @@ -0,0 +1,144 @@ +
+ + music_note + {{ fileName }} + + + + + +
+
+ +
+
+
+
+ +
+ + music_note + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+ {{ currentTime | ucapSecondsToMinutes }} +
+ + + +
+ {{ duration | ucapSecondsToMinutes }} +
+
+
+
+
diff --git a/documents/업무/6월/2째주/backup/sound-viewer.component.scss b/documents/업무/6월/2째주/backup/sound-viewer.component.scss new file mode 100644 index 0000000..db26337 --- /dev/null +++ b/documents/업무/6월/2째주/backup/sound-viewer.component.scss @@ -0,0 +1,163 @@ +.ucap-sound-viewer-container { + width: 100%; + height: 100%; + + .ucap-sound-viewer-header { + width: 100%; + height: 60px; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.6); + background-color: #333333; + + .ucap-sound-viewer-icon { + margin-right: 10px; + } + + .ucap-sound-viewer-title { + font-size: 16px; + } + .stroke-bar { + width: 1px; + height: 30px; + background-color: rgba(256, 256, 256, 0.3); + margin: 0 10px; + } + .ucap-sound-viewer-action { + width: 24px; + height: 24px; + margin-left: 10px; + &:hover { + opacity: 0.7; + } + } + } + + .ucap-sound-viewer-body { + position: relative; + width: 100%; + height: calc(100% - 60px); + + .circle-box { + position: relative; + display: flex; + width: 140px; + height: 140px; + border-radius: 50%; + justify-content: center; + align-items: center; + border: 2px solid #ffffff; + background-color: rgba(256, 256, 256, 0.7); + .mat-icon { + font-size: 100px; + height: 100px; + width: 100px; + } + .sound-wave { + height: 80px; + left: 50%; + margin: -35px 0 0 -35px; + position: absolute; + bottom: 30px; + width: 70px; + } + } + + .ucap-sound-viewer-sound-icon { + width: 100%; + height: calc(100% - 80px); + } + .viewer-bottom { + background-color: #212121; + color: #ffffff; + .ucap-sound-viewer-sound-time { + width: 100%; + height: 30px; + } + .ucap-sound-viewer-sound-controls { + width: 100%; + height: 50px; + + .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-icon { + font-size: 40px; + width: 100%; + height: 100%; + line-height: 50px; + } + } +} + +.sound-bar { + bottom: 1px; + height: 10px; + position: absolute; + width: 5px; + animation: sound-play 0ms -800ms linear infinite alternate; +} +.sound-bar:nth-child(1) { + left: 0px; + animation-duration: 474ms; +} +.sound-bar:nth-child(2) { + left: 7px; + animation-duration: 433ms; +} +.sound-bar { + left: 14px; + animation-duration: 407ms; +} +.sound-bar:nth-child(4) { + left: 21px; + animation-duration: 458ms; +} +.sound-bar:nth-child(5) { + left: 28px; + animation-duration: 400ms; +} +.sound-bar:nth-child(6) { + left: 35px; + animation-duration: 427ms; +} +.sound-bar:nth-child(7) { + left: 42px; + animation-duration: 441ms; +} +.sound-bar:nth-child(8) { + left: 49px; + animation-duration: 419ms; +} +.sound-bar:nth-child(9) { + left: 56px; + animation-duration: 487ms; +} +.sound-bar:nth-child(10) { + left: 63px; + animation-duration: 442ms; +} + +@keyframes sound-play { + 0% { + opacity: 0.35; + height: 10px; + } + 100% { + opacity: 1; + height: 60px; + } +} + +mat-slider { + width: 94%; +} diff --git a/documents/업무/6월/2째주/backup/sound-viewer.component.spec.ts b/documents/업무/6월/2째주/backup/sound-viewer.component.spec.ts new file mode 100644 index 0000000..722d6ae --- /dev/null +++ b/documents/업무/6월/2째주/backup/sound-viewer.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { SoundViewerComponent } from './sound-viewer.component'; + +describe('SoundViewerComponent', () => { + let component: SoundViewerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SoundViewerComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SoundViewerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/documents/업무/6월/2째주/backup/sound-viewer.component.ts b/documents/업무/6월/2째주/backup/sound-viewer.component.ts new file mode 100644 index 0000000..026cd50 --- /dev/null +++ b/documents/업무/6월/2째주/backup/sound-viewer.component.ts @@ -0,0 +1,104 @@ +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + ViewChild, + ElementRef +} from '@angular/core'; +import { ucapAnimations } from '../../animations'; +import { FileInfo } from '@ucap-webmessenger/protocol-file'; +import { MatSlider, MatSliderChange } from '@angular/material/slider'; +import { FileDownloadItem } from '@ucap-webmessenger/api'; + +@Component({ + selector: 'ucap-sound-viewer', + templateUrl: './sound-viewer.component.html', + styleUrls: ['./sound-viewer.component.scss'], + animations: ucapAnimations +}) +export class SoundViewerComponent implements OnInit { + @Input() + fileInfo: FileInfo; + + @Input() + fileName: string; + + @Input() + fileDownloadUrl: string; + + @Output() + download = new EventEmitter(); + + @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; + fileDownloadItem: FileDownloadItem; + + constructor() {} + + ngOnInit() {} + + 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 { + 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.fileDownloadItem = new FileDownloadItem(); + this.download.emit(this.fileDownloadItem); + } + + onClickClose(): void { + this.closed.emit(); + } +} diff --git a/documents/업무/6월/2째주/backup/video-viewer.component.html b/documents/업무/6월/2째주/backup/video-viewer.component.html new file mode 100644 index 0000000..4101910 --- /dev/null +++ b/documents/업무/6월/2째주/backup/video-viewer.component.html @@ -0,0 +1,169 @@ +
+ + + + + + + + + + + + + {{ fileName }} + + + + + +
+
+ +
+
+
+
+ +
+ {{ 'common.file.errors.cantPlay' | translate }} +
+
+
+
+ + +
+
+
+ {{ Math.floor(currentTime) | ucapSecondsToMinutes }} +
+ + + +
+ {{ Math.floor(duration) | ucapSecondsToMinutes }} +
+
+
+
+
diff --git a/documents/업무/6월/2째주/backup/video-viewer.component.scss b/documents/업무/6월/2째주/backup/video-viewer.component.scss new file mode 100644 index 0000000..95b0f3b --- /dev/null +++ b/documents/업무/6월/2째주/backup/video-viewer.component.scss @@ -0,0 +1,100 @@ +.ucap-video-viewer-container { + width: 100%; + height: 100%; + + .ucap-video-viewer-header { + width: 100%; + height: 60px; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.6); + background-color: #333333; + color: #ffffff; + .ucap-video-viewer-icon { + margin-right: 10px; + } + + .ucap-video-viewer-title { + font-size: 16px; + } + .stroke-bar { + width: 1px; + height: 30px; + background-color: rgba(256, 256, 256, 0.3); + margin: 0 10px; + } + .ucap-image-viewer-action { + width: 24px; + height: 24px; + margin-left: 10px; + &:hover { + opacity: 0.7; + } + } + } + + .ucap-video-viewer-body { + position: relative; + width: 100%; + height: calc(100% - 60px); + + .ucap-video-viewer-video-icon { + width: 100%; + height: calc(100% - 80px); + + .guide-msg { + font-size: 16px; + margin: 30px; + color: #ffffff; + } + } + .viewer-bottom { + background-color: #212121; + color: #ffffff; + .ucap-video-viewer-video-time { + width: 100%; + height: 30px; + .mat-slider { + width: 94%; + } + } + .ucap-video-viewer-video-controls { + width: 100%; + height: 50px; + + .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-icon { + font-size: 40px; + width: 100%; + height: 100%; + line-height: 40px; + } + } +} + +//viewr 플레이어 공통 +::ng-deep .viewer-bottom { + .mat-slider-horizontal { + .mat-slider-track-background { + background-color: #999999 !important; + } + &.mat-slider-min-value { + &:not(.mat-slider-thumb-label-showing) { + .mat-slider-thumb { + border-color: #999999 !important; + } + } + } + } +} diff --git a/documents/업무/6월/2째주/backup/video-viewer.component.spec.ts b/documents/업무/6월/2째주/backup/video-viewer.component.spec.ts new file mode 100644 index 0000000..9306526 --- /dev/null +++ b/documents/업무/6월/2째주/backup/video-viewer.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { ImageViewerComponent } from './image-viewer.component'; + +describe('ImageViewerComponent', () => { + let component: ImageViewerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ImageViewerComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ImageViewerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/documents/업무/6월/2째주/backup/video-viewer.component.ts b/documents/업무/6월/2째주/backup/video-viewer.component.ts new file mode 100644 index 0000000..c142f72 --- /dev/null +++ b/documents/업무/6월/2째주/backup/video-viewer.component.ts @@ -0,0 +1,125 @@ +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + ViewChild, + ElementRef, + ChangeDetectorRef +} from '@angular/core'; +import { MatSlider, MatSliderChange } from '@angular/material/slider'; +import { NGXLogger } from 'ngx-logger'; +import { FileInfo } from '@ucap-webmessenger/protocol-file'; +import { FileDownloadItem } from '@ucap-webmessenger/api'; + +import { ucapAnimations } from '../../animations'; + +@Component({ + selector: 'ucap-video-viewer', + templateUrl: './video-viewer.component.html', + styleUrls: ['./video-viewer.component.scss'], + animations: ucapAnimations +}) +export class VideoViewerComponent implements OnInit { + @Input() + fileInfo: FileInfo; + + @Input() + fileName: string; + + @Input() + fileDownloadUrl: string; + + @Output() + download = new EventEmitter(); + + @Output() + closed = new EventEmitter(); + + @ViewChild('audioPlayer', { static: false }) + audioPlayer: ElementRef; + + @ViewChild('timeSlider', { static: true }) + timeSlider: MatSlider; + + playing = false; + duration = 0.0; + currentTime = 0.0; + volume = 0.1; + loading = false; + fileDownloadItem: FileDownloadItem; + + videoWidth = 0; + videoHeight = 0; + + playable = true; + + Math = Math; + + constructor( + private changeDetectorRef: ChangeDetectorRef, + private logger: NGXLogger + ) {} + + ngOnInit() {} + + 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 { + 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 = this.audioPlayer.nativeElement.currentTime; + } + + onVolumeChangeVideo(): void { + this.volume = this.audioPlayer.nativeElement.volume; + } + + onLoadStartVideo(): void { + this.loading = true; + } + + onLoadedDataVideo(): void { + this.loading = false; + this.duration = this.audioPlayer.nativeElement.duration; + + this.videoWidth = this.audioPlayer.nativeElement.videoWidth; + this.videoHeight = this.audioPlayer.nativeElement.videoHeight; + + if (0 === this.videoHeight || 0 === this.videoWidth) { + this.playable = false; + this.duration = 0; + } + } + + onClickDownload(): void { + this.fileDownloadItem = new FileDownloadItem(); + this.download.emit(this.fileDownloadItem); + } + + onClickClose(): void { + this.closed.emit(); + } +}