sync
This commit is contained in:
parent
8f5410f725
commit
7dcec1aaad
117
documents/업무/6월/2째주/backup/binary-viewer.component.html
Normal file
117
documents/업무/6월/2째주/backup/binary-viewer.component.html
Normal file
|
@ -0,0 +1,117 @@
|
|||
<div class="ucap-binary-viewer-container">
|
||||
<mat-toolbar class="ucap-binary-viewer-header">
|
||||
<!--<mat-icon class="ucap-binary-viewer-icon">attachment</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
class="ucap-binary-viewer-icon"
|
||||
>
|
||||
<path
|
||||
d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"
|
||||
></path>
|
||||
</svg>
|
||||
<span class="ucap-binary-viewer-title">{{
|
||||
fileInfo.sentMessageJson.fileName
|
||||
}}</span>
|
||||
<span class="ucap-binary-viewer-spacer"></span>
|
||||
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-binary-viewer-action"
|
||||
matTooltip="{{ 'common.file.download' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
aria-label=""
|
||||
(click)="onClickDownload()"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="stroke-bar"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
class="ucap-binary-viewer-action"
|
||||
(click)="onClickClose()"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
<div style="position: relative;">
|
||||
<div
|
||||
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||
style="position: absolute; width: 100%;"
|
||||
>
|
||||
<mat-progress-bar
|
||||
mode="determinate"
|
||||
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||
></mat-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ucap-binary-viewer-body">
|
||||
<div
|
||||
class="ucap-binary-viewer-content-wrapper"
|
||||
fxLayout="column"
|
||||
fxLayout.xs="row"
|
||||
fxFlexFill
|
||||
fxLayoutAlign="center center"
|
||||
>
|
||||
<div class="circle-box">
|
||||
<div
|
||||
[ngClass]="[
|
||||
'mime-icon',
|
||||
'light',
|
||||
'ico-' + fileInfo.sentMessageJson.fileExt
|
||||
]"
|
||||
>
|
||||
<div class="ico"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="guide-msg">
|
||||
{{ 'common.file.errors.noPreview' | translate }}
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
colori
|
||||
mat-raised-button
|
||||
aria-label=""
|
||||
(click)="onClickDownload()"
|
||||
>
|
||||
{{ 'common.file.download' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
67
documents/업무/6월/2째주/backup/binary-viewer.component.scss
Normal file
67
documents/업무/6월/2째주/backup/binary-viewer.component.scss
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
27
documents/업무/6월/2째주/backup/binary-viewer.component.spec.ts
Normal file
27
documents/업무/6월/2째주/backup/binary-viewer.component.spec.ts
Normal file
|
@ -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<BinaryViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [BinaryViewerComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BinaryViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
41
documents/업무/6월/2째주/backup/binary-viewer.component.ts
Normal file
41
documents/업무/6월/2째주/backup/binary-viewer.component.ts
Normal file
|
@ -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<FileDownloadItem>();
|
||||
|
||||
@Output()
|
||||
closed = new EventEmitter<void>();
|
||||
|
||||
fileDownloadItem: FileDownloadItem;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
onClickDownload(): void {
|
||||
this.fileDownloadItem = new FileDownloadItem();
|
||||
this.download.emit(this.fileDownloadItem);
|
||||
}
|
||||
|
||||
onClickClose(): void {
|
||||
this.closed.emit();
|
||||
}
|
||||
}
|
29
documents/업무/6월/2째주/backup/document-viewer.component.html
Normal file
29
documents/업무/6월/2째주/backup/document-viewer.component.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
<div class="ucap-image-viewer-container">
|
||||
<mat-toolbar class="bg-primary-dark">
|
||||
<span>Third Line</span>
|
||||
<span class="ucap-image-viewer-spacer"></span>
|
||||
<mat-icon
|
||||
class="example-icon"
|
||||
aria-hidden="false"
|
||||
aria-label="Example heart icon"
|
||||
>favorite</mat-icon
|
||||
>
|
||||
<mat-icon
|
||||
class="example-icon"
|
||||
aria-hidden="false"
|
||||
aria-label="Example delete icon"
|
||||
>delete</mat-icon
|
||||
>
|
||||
</mat-toolbar>
|
||||
<div style="position: relative;">
|
||||
<div
|
||||
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||
style="position: absolute; width: 100%;"
|
||||
>
|
||||
<mat-progress-bar
|
||||
mode="determinate"
|
||||
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||
></mat-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
13
documents/업무/6월/2째주/backup/document-viewer.component.scss
Normal file
13
documents/업무/6월/2째주/backup/document-viewer.component.scss
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
27
documents/업무/6월/2째주/backup/document-viewer.component.spec.ts
Normal file
27
documents/업무/6월/2째주/backup/document-viewer.component.spec.ts
Normal file
|
@ -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<DocumentViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DocumentViewerComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DocumentViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
39
documents/업무/6월/2째주/backup/document-viewer.component.ts
Normal file
39
documents/업무/6월/2째주/backup/document-viewer.component.ts
Normal file
|
@ -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<FileDownloadItem>();
|
||||
|
||||
@Output()
|
||||
closed = new EventEmitter<void>();
|
||||
|
||||
fileDownloadItem: FileDownloadItem;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
onClickDownload(): void {
|
||||
this.fileDownloadItem = new FileDownloadItem();
|
||||
this.download.emit(this.fileDownloadItem);
|
||||
}
|
||||
|
||||
onClickClose(): void {
|
||||
this.closed.emit();
|
||||
}
|
||||
}
|
20
documents/업무/6월/2째주/backup/file-viewer.component.html
Normal file
20
documents/업무/6월/2째주/backup/file-viewer.component.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<div
|
||||
class="ucap-file-viewer-container"
|
||||
[ngSwitch]="detectFileViewerType(currentFileInfo)"
|
||||
>
|
||||
<ucap-document-viewer
|
||||
*ngSwitchCase="FileViewerType.Document"
|
||||
[fileInfo]="currentFileInfo"
|
||||
[fileDownloadUrl]="fileDownloadUrl"
|
||||
(download)="onDownload($event)"
|
||||
(closed)="onClosedViewer()"
|
||||
>
|
||||
</ucap-document-viewer>
|
||||
<ucap-binary-viewer
|
||||
*ngSwitchDefault
|
||||
[fileInfo]="currentFileInfo"
|
||||
[fileDownloadUrl]="fileDownloadUrl"
|
||||
(download)="onDownload($event)"
|
||||
(closed)="onClosedViewer()"
|
||||
></ucap-binary-viewer>
|
||||
</div>
|
4
documents/업무/6월/2째주/backup/file-viewer.component.scss
Normal file
4
documents/업무/6월/2째주/backup/file-viewer.component.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
.ucap-file-viewer-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
27
documents/업무/6월/2째주/backup/file-viewer.component.spec.ts
Normal file
27
documents/업무/6월/2째주/backup/file-viewer.component.spec.ts
Normal file
|
@ -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<FileViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [FileViewerComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FileViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
77
documents/업무/6월/2째주/backup/file-viewer.component.ts
Normal file
77
documents/업무/6월/2째주/backup/file-viewer.component.ts
Normal file
|
@ -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<void>();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
17
documents/업무/6월/2째주/backup/file-viewer.dialog.component.html
Normal file
17
documents/업무/6월/2째주/backup/file-viewer.dialog.component.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<ng-container *ngIf="!!currentFileInfo">
|
||||
<ucap-file-viewer
|
||||
*ngIf="!isMediaType"
|
||||
[fileInfo]="fileInfo"
|
||||
[fileDownloadUrl]="fileDownloadUrl"
|
||||
(download)="onDownload($event)"
|
||||
(closed)="onClosedViewer()"
|
||||
></ucap-file-viewer>
|
||||
|
||||
<ucap-media-viewer
|
||||
*ngIf="isMediaType"
|
||||
[fileInfo]="fileInfo"
|
||||
[fileDownloadUrl]="fileDownloadUrl"
|
||||
(download)="onDownload($event)"
|
||||
(closed)="onClosedViewer()"
|
||||
></ucap-media-viewer>
|
||||
</ng-container>
|
|
@ -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<FileViewerDialogComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [FileViewerDialogComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FileViewerDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
178
documents/업무/6월/2째주/backup/file-viewer.dialog.component.ts
Normal file
178
documents/업무/6월/2째주/backup/file-viewer.dialog.component.ts
Normal file
|
@ -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
|
||||
);
|
||||
};
|
||||
}
|
179
documents/업무/6월/2째주/backup/image-viewer.component.html
Normal file
179
documents/업무/6월/2째주/backup/image-viewer.component.html
Normal file
|
@ -0,0 +1,179 @@
|
|||
<div class="ucap-image-viewer-container">
|
||||
<mat-toolbar class="ucap-image-viewer-header bg-primary-dark">
|
||||
<!--<mat-icon class="ucap-image-viewer-icon">image</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
class="ucap-image-viewer-icon"
|
||||
>
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" />
|
||||
<circle cx="8.5" cy="8.5" r="1.5" />
|
||||
<path d="M20.4 14.5L16 10 4 20" />
|
||||
</svg>
|
||||
<span class="ucap-image-viewer-title">{{ fileName }}</span>
|
||||
<span class="ucap-image-viewer-spacer"></span>
|
||||
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-image-viewer-action"
|
||||
matTooltip="{{ 'common.messages.zoomReset' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
aria-label=""
|
||||
(click)="onClickZoomReset()"
|
||||
>
|
||||
<!--<mat-icon>settings_overscan</mat-icon>-->
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M3.8 3.8l16.4 16.4M20.2 3.8L3.8 20.2M15 3h6v6M9 3H3v6M15 21h6v-6M9 21H3v-6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-image-viewer-action"
|
||||
matTooltip="{{ 'common.messages.zoomOut' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
aria-label=""
|
||||
(click)="onClickZoomOut()"
|
||||
>
|
||||
<!--<mat-icon>zoom_out</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle cx="11" cy="11" r="8"></circle>
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||
<line x1="8" y1="11" x2="14" y2="11"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-image-viewer-action"
|
||||
matTooltip="{{ 'common.messages.zoomIn' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
aria-label=""
|
||||
(click)="onClickZoomIn()"
|
||||
>
|
||||
<!--<mat-icon>zoom_in</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle cx="11" cy="11" r="8"></circle>
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||
<line x1="11" y1="8" x2="11" y2="14"></line>
|
||||
<line x1="8" y1="11" x2="14" y2="11"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-image-viewer-action"
|
||||
matTooltip="{{ 'common.file.download' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
aria-label=""
|
||||
(click)="onClickDownload()"
|
||||
>
|
||||
<!--<mat-icon>get_app</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="stroke-bar"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
class="ucap-image-viewer-action btn-close"
|
||||
matTooltip="{{ 'common.messages.close' | translate }}"
|
||||
(click)="onClickClose()"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
<div style="position: relative;">
|
||||
<div
|
||||
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||
style="position: absolute; width: 100%;"
|
||||
>
|
||||
<mat-progress-bar
|
||||
mode="determinate"
|
||||
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||
></mat-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ucap-image-viewer-body">
|
||||
<div
|
||||
#imageContainer
|
||||
class="ucap-image-viewer-image-wrapper"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
fxFlexFill
|
||||
fxLayoutAlign="center center"
|
||||
>
|
||||
<img
|
||||
#downloadImage
|
||||
*ngIf="fileDownloadUrl"
|
||||
[src]="fileDownloadUrl"
|
||||
[style.width]="'auto'"
|
||||
[style.height]="imageHeight + 'px'"
|
||||
(load)="onLoadFileDownloadUrl(downloadImage)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
73
documents/업무/6월/2째주/backup/image-viewer.component.scss
Normal file
73
documents/업무/6월/2째주/backup/image-viewer.component.scss
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
documents/업무/6월/2째주/backup/image-viewer.component.spec.ts
Normal file
27
documents/업무/6월/2째주/backup/image-viewer.component.spec.ts
Normal file
|
@ -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<ImageViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ImageViewerComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ImageViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
149
documents/업무/6월/2째주/backup/image-viewer.component.ts
Normal file
149
documents/업무/6월/2째주/backup/image-viewer.component.ts
Normal file
|
@ -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<void>();
|
||||
|
||||
@Output()
|
||||
download = new EventEmitter<FileDownloadItem>();
|
||||
|
||||
@ViewChild('imageContainer', { static: false })
|
||||
imageContainer: ElementRef<HTMLElement>;
|
||||
|
||||
@ViewChild('downloadImage', { static: false })
|
||||
downloadImage: ElementRef<HTMLElement>;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
144
documents/업무/6월/2째주/backup/sound-viewer.component.html
Normal file
144
documents/업무/6월/2째주/backup/sound-viewer.component.html
Normal file
|
@ -0,0 +1,144 @@
|
|||
<div class="ucap-sound-viewer-container">
|
||||
<mat-toolbar color="accent" class="ucap-sound-viewer-header">
|
||||
<mat-icon class="ucap-sound-viewer-icon">music_note</mat-icon>
|
||||
<span class="ucap-sound-viewer-title">{{ fileName }}</span>
|
||||
<span class="ucap-sound-viewer-spacer"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-image-viewer-action"
|
||||
matTooltip="{{ 'common.file.download' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
aria-label=""
|
||||
(click)="onClickDownload()"
|
||||
>
|
||||
<!--<mat-icon>get_app</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="stroke-bar"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
class="ucap-image-viewer-action btn-close"
|
||||
matTooltip="{{ 'common.messages.close' | translate }}"
|
||||
(click)="onClickClose()"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
<div style="position: relative;">
|
||||
<div
|
||||
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||
style="position: absolute; width: 100%;"
|
||||
>
|
||||
<mat-progress-bar
|
||||
mode="determinate"
|
||||
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||
></mat-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ucap-sound-viewer-body">
|
||||
<div
|
||||
class="ucap-sound-viewer-sound-icon"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="center center"
|
||||
>
|
||||
<audio
|
||||
[src]="fileDownloadUrl"
|
||||
#audioPlayer
|
||||
(playing)="onPlayingAudio()"
|
||||
(pause)="onPauseAudio()"
|
||||
(timeupdate)="onTimeUpdateAudio()"
|
||||
(volumechange)="onVolumeChangeAudio()"
|
||||
(loadstart)="onLoadStartAudio()"
|
||||
(loadeddata)="onLoadedDataAudio()"
|
||||
></audio>
|
||||
<div class="circle-box">
|
||||
<mat-icon class="ucap-sound-viewer-icon" *ngIf="!playing">
|
||||
music_note
|
||||
</mat-icon>
|
||||
<div class="sound-wave" *ngIf="playing">
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
<div class="sound-bar bg-accent-dark"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="viewer-bottom">
|
||||
<div
|
||||
class="ucap-sound-viewer-sound-time"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="center center"
|
||||
>
|
||||
<mat-slider
|
||||
#timeSlider
|
||||
min="0"
|
||||
[max]="duration"
|
||||
[value]="currentTime"
|
||||
(change)="onChangeTimeSlider($event)"
|
||||
>
|
||||
</mat-slider>
|
||||
</div>
|
||||
<div
|
||||
class="ucap-sound-viewer-sound-controls"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
>
|
||||
<div class="ucap-sound-viewer-sound-time-current">
|
||||
{{ currentTime | ucapSecondsToMinutes }}
|
||||
</div>
|
||||
<span class="ucap-sound-viewer-spacer"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-sound-viewer-action"
|
||||
matTooltip="{{
|
||||
(playing ? 'common.player.stop' : 'common.player.play') | translate
|
||||
}}"
|
||||
aria-label=""
|
||||
(click)="onClickPlayOrPause()"
|
||||
>
|
||||
<mat-icon>{{ playing ? 'pause' : 'play_arrow' }}</mat-icon>
|
||||
</button>
|
||||
<span class="ucap-sound-viewer-spacer"></span>
|
||||
<div class="ucap-sound-viewer-sound-time-total">
|
||||
{{ duration | ucapSecondsToMinutes }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
163
documents/업무/6월/2째주/backup/sound-viewer.component.scss
Normal file
163
documents/업무/6월/2째주/backup/sound-viewer.component.scss
Normal file
|
@ -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%;
|
||||
}
|
27
documents/업무/6월/2째주/backup/sound-viewer.component.spec.ts
Normal file
27
documents/업무/6월/2째주/backup/sound-viewer.component.spec.ts
Normal file
|
@ -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<SoundViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SoundViewerComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SoundViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
104
documents/업무/6월/2째주/backup/sound-viewer.component.ts
Normal file
104
documents/업무/6월/2째주/backup/sound-viewer.component.ts
Normal file
|
@ -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<FileDownloadItem>();
|
||||
|
||||
@Output()
|
||||
closed = new EventEmitter<void>();
|
||||
|
||||
@ViewChild('audioPlayer', { static: true })
|
||||
audioPlayer: ElementRef<HTMLAudioElement>;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
169
documents/업무/6월/2째주/backup/video-viewer.component.html
Normal file
169
documents/업무/6월/2째주/backup/video-viewer.component.html
Normal file
|
@ -0,0 +1,169 @@
|
|||
<div class="ucap-video-viewer-container">
|
||||
<mat-toolbar color="accent" class="ucap-video-viewer-header">
|
||||
<!--<mat-icon class="ucap-video-viewer-icon">video_label</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
class="ucap-video-viewer-icon"
|
||||
>
|
||||
<rect x="2" y="2" width="20" height="20" rx="2.18" ry="2.18"></rect>
|
||||
<line x1="7" y1="2" x2="7" y2="22"></line>
|
||||
<line x1="17" y1="2" x2="17" y2="22"></line>
|
||||
<line x1="2" y1="12" x2="22" y2="12"></line>
|
||||
<line x1="2" y1="7" x2="7" y2="7"></line>
|
||||
<line x1="2" y1="17" x2="7" y2="17"></line>
|
||||
<line x1="17" y1="17" x2="22" y2="17"></line>
|
||||
<line x1="17" y1="7" x2="22" y2="7"></line>
|
||||
</svg>
|
||||
<span class="ucap-video-viewer-title">{{ fileName }}</span>
|
||||
<span class="ucap-video-viewer-spacer"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-video-viewer-action"
|
||||
matTooltip="{{ 'common.file.download' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
aria-label=""
|
||||
(click)="onClickDownload()"
|
||||
>
|
||||
<!--<mat-icon>get_app</mat-icon>-->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="stroke-bar"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
class="ucap-image-viewer-action btn-close"
|
||||
matTooltip="{{ 'common.messages.close' | translate }}"
|
||||
(click)="onClickClose()"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="butt"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
<div style="position: relative;">
|
||||
<div
|
||||
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||
style="position: absolute; width: 100%;"
|
||||
>
|
||||
<mat-progress-bar
|
||||
mode="determinate"
|
||||
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||
></mat-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ucap-video-viewer-body">
|
||||
<div
|
||||
#videoContainer
|
||||
class="ucap-video-viewer-video-icon"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="center center"
|
||||
>
|
||||
<video
|
||||
*ngIf="playable"
|
||||
#audioPlayer
|
||||
[src]="fileDownloadUrl"
|
||||
[style.width]="'auto'"
|
||||
[style.height]="
|
||||
videoHeight > videoContainer.clientHeight
|
||||
? ((videoContainer.clientHeight - 20) / videoHeight) * videoHeight +
|
||||
'px'
|
||||
: videoHeight + 'px'
|
||||
"
|
||||
(playing)="onPlayingVideo()"
|
||||
(pause)="onPauseVideo()"
|
||||
(timeupdate)="onTimeUpdateVideo()"
|
||||
(volumechange)="onVolumeChangeVideo()"
|
||||
(loadstart)="onLoadStartVideo()"
|
||||
(loadeddata)="onLoadedDataVideo()"
|
||||
></video>
|
||||
<div *ngIf="!playable" class="guide-msg">
|
||||
{{ 'common.file.errors.cantPlay' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="viewer-bottom">
|
||||
<div
|
||||
class="ucap-video-viewer-video-time"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="center center"
|
||||
>
|
||||
<mat-slider
|
||||
#timeSlider
|
||||
min="0"
|
||||
[max]="duration"
|
||||
[value]="currentTime"
|
||||
(change)="onChangeTimeSlider($event)"
|
||||
>
|
||||
</mat-slider>
|
||||
</div>
|
||||
<div
|
||||
class="ucap-video-viewer-video-controls"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
>
|
||||
<div class="ucap-video-viewer-video-time-current">
|
||||
{{ Math.floor(currentTime) | ucapSecondsToMinutes }}
|
||||
</div>
|
||||
<span class="ucap-video-viewer-spacer"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="ucap-video-viewer-action"
|
||||
matTooltip="{{
|
||||
(playing ? 'common.player.stop' : 'common.player.play') | translate
|
||||
}}"
|
||||
aria-label=""
|
||||
[disabled]="!playable"
|
||||
(click)="onClickPlayOrPause()"
|
||||
>
|
||||
<mat-icon>{{ playing ? 'pause' : 'play_arrow' }}</mat-icon>
|
||||
<!--{{ playing ? '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
||||
<rect x="6" y="4" width="4" height="16"></rect>
|
||||
<rect x="14" y="4" width="4" height="16"></rect>
|
||||
</svg>' : '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
||||
<polygon points="5 3 19 12 5 21 5 3"></polygon>
|
||||
</svg>'}}-->
|
||||
</button>
|
||||
<span class="ucap-video-viewer-spacer"></span>
|
||||
<div class="ucap-video-viewer-video-time-total">
|
||||
{{ Math.floor(duration) | ucapSecondsToMinutes }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
100
documents/업무/6월/2째주/backup/video-viewer.component.scss
Normal file
100
documents/업무/6월/2째주/backup/video-viewer.component.scss
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
documents/업무/6월/2째주/backup/video-viewer.component.spec.ts
Normal file
27
documents/업무/6월/2째주/backup/video-viewer.component.spec.ts
Normal file
|
@ -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<ImageViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ImageViewerComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ImageViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
125
documents/업무/6월/2째주/backup/video-viewer.component.ts
Normal file
125
documents/업무/6월/2째주/backup/video-viewer.component.ts
Normal file
|
@ -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<FileDownloadItem>();
|
||||
|
||||
@Output()
|
||||
closed = new EventEmitter<void>();
|
||||
|
||||
@ViewChild('audioPlayer', { static: false })
|
||||
audioPlayer: ElementRef<HTMLVideoElement>;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user