progress bar of file down is modified
This commit is contained in:
parent
a33ee7c2ff
commit
568ff48268
|
@ -241,8 +241,9 @@ ipcMain.on(
|
||||||
try {
|
try {
|
||||||
const buffer: Buffer = args[0];
|
const buffer: Buffer = args[0];
|
||||||
const fileName: string = args[1];
|
const fileName: string = args[1];
|
||||||
|
const mimeType: string = args[2];
|
||||||
let savePath: string = path.join(
|
let savePath: string = path.join(
|
||||||
!!args[2] ? args[2] : DefaultFolder.downloads(),
|
!!args[3] ? args[3] : DefaultFolder.downloads(),
|
||||||
fileName
|
fileName
|
||||||
);
|
);
|
||||||
savePath = await FileUtil.uniqueFileName(savePath);
|
savePath = await FileUtil.uniqueFileName(savePath);
|
||||||
|
|
9
package-lock.json
generated
9
package-lock.json
generated
|
@ -2789,6 +2789,15 @@
|
||||||
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"angular-split": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/angular-split/-/angular-split-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-km59k1kEgVlplo2t4t5Ob43Vx16qVXWXsl5gbsdQtqrOW7341So4CFUmCjcZgfk1swu9RBaCdSQEqzNWOe/89w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ansi-align": {
|
"ansi-align": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
<mat-progress-bar
|
|
||||||
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
|
||||||
mode="determinate"
|
|
||||||
[value]="fileDownloadItem.downloadingProgress$ | async"
|
|
||||||
></mat-progress-bar>
|
|
||||||
<ucap-file-viewer
|
<ucap-file-viewer
|
||||||
[fileInfo]="fileInfo"
|
[fileInfo]="fileInfo"
|
||||||
[fileDownloadUrl]="fileDownloadUrl"
|
[fileDownloadUrl]="fileDownloadUrl"
|
||||||
(download)="onDownload()"
|
(download)="onDownload($event)"
|
||||||
(closed)="onClosedViewer()"
|
(closed)="onClosedViewer()"
|
||||||
></ucap-file-viewer>
|
></ucap-file-viewer>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
OnInit,
|
OnInit,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
Inject,
|
Inject,
|
||||||
EventEmitter
|
EventEmitter,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
|
@ -15,7 +15,7 @@ import { take, map, finalize, tap } from 'rxjs/operators';
|
||||||
import { SnackBarService } from '@ucap-webmessenger/ui';
|
import { SnackBarService } from '@ucap-webmessenger/ui';
|
||||||
import {
|
import {
|
||||||
FileDownloadItem,
|
FileDownloadItem,
|
||||||
CommonApiService
|
CommonApiService,
|
||||||
} from '@ucap-webmessenger/api-common';
|
} from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
export interface FileViewerDialogData {
|
export interface FileViewerDialogData {
|
||||||
|
@ -31,7 +31,7 @@ export interface FileViewerDialogResult {}
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-layout-common-file-viewer',
|
selector: 'app-layout-common-file-viewer',
|
||||||
templateUrl: './file-viewer.dialog.component.html',
|
templateUrl: './file-viewer.dialog.component.html',
|
||||||
styleUrls: ['./file-viewer.dialog.component.scss']
|
styleUrls: ['./file-viewer.dialog.component.scss'],
|
||||||
})
|
})
|
||||||
export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
||||||
fileInfo: FileEventJson;
|
fileInfo: FileEventJson;
|
||||||
|
@ -40,8 +40,6 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
||||||
deviceType: DeviceType;
|
deviceType: DeviceType;
|
||||||
token: string;
|
token: string;
|
||||||
|
|
||||||
fileDownloadItem: FileDownloadItem;
|
|
||||||
|
|
||||||
fileDownloadUrl: string;
|
fileDownloadUrl: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -66,7 +64,7 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
||||||
userSeq: this.userSeq,
|
userSeq: this.userSeq,
|
||||||
deviceType: this.deviceType,
|
deviceType: this.deviceType,
|
||||||
token: this.token,
|
token: this.token,
|
||||||
attachmentsSeq: this.fileInfo.attachmentSeq
|
attachmentsSeq: this.fileInfo.attachmentSeq,
|
||||||
},
|
},
|
||||||
this.downloadUrl
|
this.downloadUrl
|
||||||
);
|
);
|
||||||
|
@ -76,8 +74,7 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
ngOnDestroy(): void {}
|
ngOnDestroy(): void {}
|
||||||
|
|
||||||
onDownload(): void {
|
onDownload(fileDownloadItem: FileDownloadItem): void {
|
||||||
this.fileDownloadItem = new FileDownloadItem();
|
|
||||||
this.commonApiService
|
this.commonApiService
|
||||||
.fileTalkDownload(
|
.fileTalkDownload(
|
||||||
{
|
{
|
||||||
|
@ -85,37 +82,36 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
||||||
deviceType: this.deviceType,
|
deviceType: this.deviceType,
|
||||||
token: this.token,
|
token: this.token,
|
||||||
attachmentsSeq: this.fileInfo.attachmentSeq,
|
attachmentsSeq: this.fileInfo.attachmentSeq,
|
||||||
fileDownloadItem: this.fileDownloadItem
|
fileDownloadItem,
|
||||||
},
|
},
|
||||||
this.downloadUrl
|
this.downloadUrl
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
take(1),
|
take(1),
|
||||||
map(async rawBlob => {
|
map(async rawBlob => {
|
||||||
const blob = rawBlob.slice(
|
const mimeType = MimeUtil.getMimeFromExtension(this.fileInfo.fileExt);
|
||||||
0,
|
const blob = rawBlob.slice(0, rawBlob.size, mimeType);
|
||||||
rawBlob.size,
|
|
||||||
MimeUtil.getMimeFromExtension(this.fileInfo.fileExt)
|
|
||||||
);
|
|
||||||
|
|
||||||
FileUtil.fromBlobToBuffer(blob)
|
FileUtil.fromBlobToBuffer(blob)
|
||||||
.then(buffer => {
|
.then(buffer => {
|
||||||
this.nativeService
|
this.nativeService
|
||||||
.saveFile(buffer, this.fileInfo.fileName)
|
.saveFile(buffer, this.fileInfo.fileName, mimeType)
|
||||||
.pipe(take(1))
|
.then(result => {
|
||||||
.subscribe(result => {
|
|
||||||
if (!!result) {
|
if (!!result) {
|
||||||
this.snackBarService.open(
|
this.snackBarService.open(
|
||||||
`파일이 경로[${result}]에 저장되었습니다.`,
|
`파일이 경로[${result}]에 저장되었습니다.`,
|
||||||
'',
|
'',
|
||||||
{
|
{
|
||||||
duration: 3000,
|
duration: 3000,
|
||||||
verticalPosition: 'bottom'
|
verticalPosition: 'bottom',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.snackBarService.open('파일 저장에 실패하였습니다.');
|
this.snackBarService.open('파일 저장에 실패하였습니다.');
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch(reason => {
|
||||||
|
this.snackBarService.open('파일 저장에 실패하였습니다.');
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(reason => {
|
.catch(reason => {
|
||||||
|
@ -123,7 +119,9 @@ export class FileViewerDialogComponent implements OnInit, OnDestroy {
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.fileDownloadItem = undefined;
|
setTimeout(() => {
|
||||||
|
fileDownloadItem.downloadingProgress$ = undefined;
|
||||||
|
}, 1000);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
|
@ -485,7 +485,6 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
async onFileViewer(fileInfo: FileEventJson) {
|
async onFileViewer(fileInfo: FileEventJson) {
|
||||||
this.logger.debug('onFileViewer', fileInfo);
|
|
||||||
const result = await this.dialogService.open<
|
const result = await this.dialogService.open<
|
||||||
FileViewerDialogComponent,
|
FileViewerDialogComponent,
|
||||||
FileViewerDialogData,
|
FileViewerDialogData,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Injectable, Inject } from '@angular/core';
|
import { Injectable, Inject } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { of } from 'rxjs';
|
import { of, Observable } from 'rxjs';
|
||||||
import { catchError, exhaustMap, map, tap, switchMap } from 'rxjs/operators';
|
import { catchError, exhaustMap, map, tap, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { Actions, ofType, createEffect } from '@ngrx/effects';
|
import { Actions, ofType, createEffect } from '@ngrx/effects';
|
||||||
|
@ -86,9 +86,12 @@ export class Effects {
|
||||||
() =>
|
() =>
|
||||||
this.actions$.pipe(
|
this.actions$.pipe(
|
||||||
ofType(webLoginSuccess),
|
ofType(webLoginSuccess),
|
||||||
switchMap(params =>
|
switchMap(
|
||||||
this.nativeService.checkForUpdates().pipe(
|
params =>
|
||||||
map((update: boolean) => {
|
new Observable<void>(subscriber => {
|
||||||
|
this.nativeService
|
||||||
|
.checkForUpdates()
|
||||||
|
.then((update: boolean) => {
|
||||||
if (!update) {
|
if (!update) {
|
||||||
this.appAuthenticationService.login(
|
this.appAuthenticationService.login(
|
||||||
params.loginInfo,
|
params.loginInfo,
|
||||||
|
@ -96,9 +99,15 @@ export class Effects {
|
||||||
);
|
);
|
||||||
this.router.navigate(['/messenger']);
|
this.router.navigate(['/messenger']);
|
||||||
}
|
}
|
||||||
}),
|
subscriber.next();
|
||||||
catchError(error => of(error))
|
})
|
||||||
)
|
.catch(reason => {
|
||||||
|
subscriber.error(reason);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
})
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
{ dispatch: false }
|
{ dispatch: false }
|
||||||
|
|
|
@ -69,6 +69,113 @@ export class FileUtil {
|
||||||
a.remove();
|
a.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static save(
|
||||||
|
buffer: Buffer,
|
||||||
|
fileName: string,
|
||||||
|
mimeType: string
|
||||||
|
): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
const defaultMime = 'application/octet-stream';
|
||||||
|
const mime = !!mimeType ? mimeType : defaultMime;
|
||||||
|
const blob = new Blob([buffer], { type: mime });
|
||||||
|
|
||||||
|
if (navigator.msSaveBlob) {
|
||||||
|
// IE10+ : (has Blob, but not a[download] or URL)
|
||||||
|
navigator.msSaveBlob(blob, fileName);
|
||||||
|
resolve(fileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const download = (url: string, mode: boolean = false) => {
|
||||||
|
const anchor = document.createElement('a');
|
||||||
|
|
||||||
|
if ('download' in anchor) {
|
||||||
|
// html5 A[download]
|
||||||
|
anchor.href = url;
|
||||||
|
anchor.setAttribute('download', fileName);
|
||||||
|
anchor.className = 'download-js-link';
|
||||||
|
anchor.innerHTML = 'downloading...';
|
||||||
|
anchor.style.display = 'none';
|
||||||
|
document.body.appendChild(anchor);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
anchor.click();
|
||||||
|
document.body.removeChild(anchor);
|
||||||
|
resolve(fileName);
|
||||||
|
if (mode) {
|
||||||
|
setTimeout(() => {
|
||||||
|
window.URL.revokeObjectURL(anchor.href);
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
}, 66);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle non-a[download] safari as best we can:
|
||||||
|
if (
|
||||||
|
/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(
|
||||||
|
navigator.userAgent
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
url = url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
|
||||||
|
if (!window.open(url)) {
|
||||||
|
// popup blocked, offer direct download:
|
||||||
|
if (
|
||||||
|
confirm(
|
||||||
|
'Displaying New Document\n\nUse Save As... to download, then click back to return to this page.'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
location.href = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(fileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do iframe dataURL download (old ch+FF):
|
||||||
|
const f = document.createElement('iframe');
|
||||||
|
document.body.appendChild(f);
|
||||||
|
|
||||||
|
if (!mode) {
|
||||||
|
// force a mime that will download:
|
||||||
|
url = 'data:' + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
|
||||||
|
}
|
||||||
|
f.src = url;
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(f);
|
||||||
|
}, 333);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (window.URL) {
|
||||||
|
download(window.URL.createObjectURL(blob), true);
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
typeof blob === 'string' ||
|
||||||
|
(blob as any).constructor === this.toString
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
download(
|
||||||
|
'data:' + mime + ';base64,' + window.btoa((blob as any) as string)
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
download(
|
||||||
|
'data:' +
|
||||||
|
mime +
|
||||||
|
';base64,' +
|
||||||
|
encodeURIComponent((blob as any) as string)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
fileReader.onload = () => {
|
||||||
|
download(fileReader.result as string);
|
||||||
|
};
|
||||||
|
fileReader.readAsDataURL(blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static thumbnail(file: File): Promise<File> {
|
static thumbnail(file: File): Promise<File> {
|
||||||
return new Promise<File>((resolve, reject) => {
|
return new Promise<File>((resolve, reject) => {
|
||||||
const fileReader = new FileReader();
|
const fileReader = new FileReader();
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { TranslateLoader } from '@ngx-translate/core';
|
||||||
import { TranslateLoaderService } from '../translate/browser-loader';
|
import { TranslateLoaderService } from '../translate/browser-loader';
|
||||||
import { NotificationService } from '../notification/notification.service';
|
import { NotificationService } from '../notification/notification.service';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { FileUtil } from '@ucap-webmessenger/core';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
@ -34,34 +35,35 @@ export class BrowserNativeService extends NativeService {
|
||||||
}
|
}
|
||||||
closeAllNotify(): void {}
|
closeAllNotify(): void {}
|
||||||
|
|
||||||
checkForUpdates(): Observable<boolean> {
|
checkForUpdates(): Promise<boolean> {
|
||||||
return new Observable<boolean>(subscriber => {
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
try {
|
resolve(false);
|
||||||
subscriber.next(false);
|
|
||||||
} catch (error) {
|
|
||||||
subscriber.error(error);
|
|
||||||
} finally {
|
|
||||||
subscriber.complete();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showImageViewer(): void {}
|
showImageViewer(): void {}
|
||||||
|
|
||||||
readFile(path: string): Observable<Buffer> {
|
readFile(path: string): Promise<Buffer> {
|
||||||
return this.httpClient.get(path, { responseType: 'arraybuffer' }).pipe(
|
return new Promise<Buffer>((resolve, reject) => {
|
||||||
map(arrayBuffer => {
|
resolve(null);
|
||||||
return Buffer.from(arrayBuffer);
|
});
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFile(
|
saveFile(
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
fileName: string,
|
fileName: string,
|
||||||
|
mimeType: string,
|
||||||
path?: string
|
path?: string
|
||||||
): Observable<string> {
|
): Promise<string> {
|
||||||
return this.httpClient.post<string>(path, buffer, {});
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
FileUtil.save(buffer, fileName, mimeType).then(fn => {
|
||||||
|
resolve(fn);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
windowStateChanged(): Observable<WindowState> {
|
windowStateChanged(): Observable<WindowState> {
|
||||||
|
@ -85,7 +87,6 @@ export class BrowserNativeService extends NativeService {
|
||||||
idleStateChanged(): Observable<WindowIdle> {
|
idleStateChanged(): Observable<WindowIdle> {
|
||||||
return new Observable<WindowIdle>(subscriber => {
|
return new Observable<WindowIdle>(subscriber => {
|
||||||
try {
|
try {
|
||||||
subscriber.next(WindowIdle.Active);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
subscriber.error(error);
|
subscriber.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { TranslateLoader } from '@ngx-translate/core';
|
import { TranslateLoader } from '@ngx-translate/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { NativeService } from '@ucap-webmessenger/native';
|
import { NativeService } from '@ucap-webmessenger/native';
|
||||||
import { take, map } from 'rxjs/operators';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
|
@ -18,13 +17,18 @@ export class TranslateLoaderService implements TranslateLoader {
|
||||||
* Gets the translations from the server
|
* Gets the translations from the server
|
||||||
*/
|
*/
|
||||||
public getTranslation(lang: string): Observable<any> {
|
public getTranslation(lang: string): Observable<any> {
|
||||||
return this.nativeService
|
return new Observable<any>(subscriber => {
|
||||||
|
this.nativeService
|
||||||
.readFile(`${this.prefix}${lang}.${this.suffix}`)
|
.readFile(`${this.prefix}${lang}.${this.suffix}`)
|
||||||
.pipe(
|
.then(buffer => {
|
||||||
take(1),
|
subscriber.next(JSON.parse(buffer.toString('utf-8')));
|
||||||
map(buffer => {
|
|
||||||
return JSON.parse(buffer.toString('utf-8'));
|
|
||||||
})
|
})
|
||||||
);
|
.catch(reason => {
|
||||||
|
subscriber.error(reason);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,14 +47,12 @@ export class ElectronNativeService implements NativeService {
|
||||||
this.ipcRenderer.send(NotificationChannel.CloseAllNotify);
|
this.ipcRenderer.send(NotificationChannel.CloseAllNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForUpdates(): Observable<boolean> {
|
checkForUpdates(): Promise<boolean> {
|
||||||
return new Observable<boolean>(subscriber => {
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
subscriber.next(this.ipcRenderer.sendSync(UpdaterChannel.Check));
|
resolve(this.ipcRenderer.sendSync(UpdaterChannel.Check));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
subscriber.error(error);
|
reject(error);
|
||||||
} finally {
|
|
||||||
subscriber.complete();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -63,14 +61,12 @@ export class ElectronNativeService implements NativeService {
|
||||||
this.ipcRenderer.send(FileChannel.ShowImageViewer);
|
this.ipcRenderer.send(FileChannel.ShowImageViewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
readFile(path: string): Observable<Buffer> {
|
readFile(path: string): Promise<Buffer> {
|
||||||
return new Observable<Buffer>(subscriber => {
|
return new Promise<Buffer>((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
subscriber.next(this.ipcRenderer.sendSync(FileChannel.ReadFile, path));
|
resolve(this.ipcRenderer.sendSync(FileChannel.ReadFile, path));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
subscriber.error(error);
|
reject(error);
|
||||||
} finally {
|
|
||||||
subscriber.complete();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -78,22 +74,22 @@ export class ElectronNativeService implements NativeService {
|
||||||
saveFile(
|
saveFile(
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
fileName: string,
|
fileName: string,
|
||||||
|
mimeType: string,
|
||||||
path?: string
|
path?: string
|
||||||
): Observable<string> {
|
): Promise<string> {
|
||||||
return new Observable<string>(subscriber => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
subscriber.next(
|
resolve(
|
||||||
this.ipcRenderer.sendSync(
|
this.ipcRenderer.sendSync(
|
||||||
FileChannel.SaveFile,
|
FileChannel.SaveFile,
|
||||||
buffer,
|
buffer,
|
||||||
fileName,
|
fileName,
|
||||||
|
mimeType,
|
||||||
path
|
path
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
subscriber.error(error);
|
reject(error);
|
||||||
} finally {
|
|
||||||
subscriber.complete();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { TranslateLoader } from '@ngx-translate/core';
|
import { TranslateLoader } from '@ngx-translate/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { NativeService } from '@ucap-webmessenger/native';
|
import { NativeService } from '@ucap-webmessenger/native';
|
||||||
import { take, map } from 'rxjs/operators';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
|
@ -18,13 +17,18 @@ export class TranslateLoaderService implements TranslateLoader {
|
||||||
* Gets the translations from the server
|
* Gets the translations from the server
|
||||||
*/
|
*/
|
||||||
public getTranslation(lang: string): Observable<any> {
|
public getTranslation(lang: string): Observable<any> {
|
||||||
return this.nativeService
|
return new Observable<any>(subscriber => {
|
||||||
|
this.nativeService
|
||||||
.readFile(`${this.prefix}${lang}.${this.suffix}`)
|
.readFile(`${this.prefix}${lang}.${this.suffix}`)
|
||||||
.pipe(
|
.then(buffer => {
|
||||||
take(1),
|
subscriber.next(JSON.parse(buffer.toString('utf-8')));
|
||||||
map(buf => {
|
|
||||||
return JSON.parse(buf.toString());
|
|
||||||
})
|
})
|
||||||
);
|
.catch(reason => {
|
||||||
|
subscriber.error(reason);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,17 @@ export abstract class NativeService {
|
||||||
abstract notify(noti: NotificationRequest): void;
|
abstract notify(noti: NotificationRequest): void;
|
||||||
abstract closeAllNotify(): void;
|
abstract closeAllNotify(): void;
|
||||||
|
|
||||||
abstract checkForUpdates(): Observable<boolean>;
|
abstract checkForUpdates(): Promise<boolean>;
|
||||||
|
|
||||||
abstract showImageViewer(): void;
|
abstract showImageViewer(): void;
|
||||||
|
|
||||||
abstract saveFile(
|
abstract saveFile(
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
fileName: string,
|
fileName: string,
|
||||||
|
mimeType: string,
|
||||||
path?: string
|
path?: string
|
||||||
): Observable<string>;
|
): Promise<string>;
|
||||||
abstract readFile(path: string): Observable<Buffer>;
|
abstract readFile(path: string): Promise<Buffer>;
|
||||||
|
|
||||||
abstract windowStateChanged(): Observable<WindowState>;
|
abstract windowStateChanged(): Observable<WindowState>;
|
||||||
abstract windowClose(): void;
|
abstract windowClose(): void;
|
||||||
|
|
|
@ -191,12 +191,18 @@ export class ProtocolService {
|
||||||
|
|
||||||
responseSubject = new Subject<ProtocolMessage>().pipe(
|
responseSubject = new Subject<ProtocolMessage>().pipe(
|
||||||
finalize(() => {
|
finalize(() => {
|
||||||
|
this.logger.debug(
|
||||||
|
'ProtocolService::pendingRequests.finalize',
|
||||||
|
requestId
|
||||||
|
);
|
||||||
|
|
||||||
if (this.pendingRequests.has(requestId)) {
|
if (this.pendingRequests.has(requestId)) {
|
||||||
this.pendingRequests.delete(requestId);
|
this.pendingRequests.delete(requestId);
|
||||||
}
|
}
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'ProtocolService::pendingRequests.size',
|
'ProtocolService::pendingRequests.size',
|
||||||
this.pendingRequests.size
|
this.pendingRequests.size,
|
||||||
|
this.pendingRequests
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
) as Subject<ProtocolMessage>;
|
) as Subject<ProtocolMessage>;
|
||||||
|
|
|
@ -6,35 +6,35 @@
|
||||||
*ngSwitchCase="FileViewerType.Document"
|
*ngSwitchCase="FileViewerType.Document"
|
||||||
[fileInfo]="fileInfo"
|
[fileInfo]="fileInfo"
|
||||||
[fileDownloadUrl]="fileDownloadUrl"
|
[fileDownloadUrl]="fileDownloadUrl"
|
||||||
(download)="onDownload()"
|
(download)="onDownload($event)"
|
||||||
(closed)="onClosedViewer()"
|
(closed)="onClosedViewer()"
|
||||||
></ucap-document-viewer>
|
></ucap-document-viewer>
|
||||||
<ucap-image-viewer
|
<ucap-image-viewer
|
||||||
*ngSwitchCase="FileViewerType.Image"
|
*ngSwitchCase="FileViewerType.Image"
|
||||||
[fileInfo]="fileInfo"
|
[fileInfo]="fileInfo"
|
||||||
[fileDownloadUrl]="fileDownloadUrl"
|
[fileDownloadUrl]="fileDownloadUrl"
|
||||||
(download)="onDownload()"
|
(download)="onDownload($event)"
|
||||||
(closed)="onClosedViewer()"
|
(closed)="onClosedViewer()"
|
||||||
></ucap-image-viewer>
|
></ucap-image-viewer>
|
||||||
<ucap-sound-viewer
|
<ucap-sound-viewer
|
||||||
*ngSwitchCase="FileViewerType.Sound"
|
*ngSwitchCase="FileViewerType.Sound"
|
||||||
[fileInfo]="fileInfo"
|
[fileInfo]="fileInfo"
|
||||||
[fileDownloadUrl]="fileDownloadUrl"
|
[fileDownloadUrl]="fileDownloadUrl"
|
||||||
(download)="onDownload()"
|
(download)="onDownload($event)"
|
||||||
(closed)="onClosedViewer()"
|
(closed)="onClosedViewer()"
|
||||||
></ucap-sound-viewer>
|
></ucap-sound-viewer>
|
||||||
<ucap-video-viewer
|
<ucap-video-viewer
|
||||||
*ngSwitchCase="FileViewerType.Video"
|
*ngSwitchCase="FileViewerType.Video"
|
||||||
[fileInfo]="fileInfo"
|
[fileInfo]="fileInfo"
|
||||||
[fileDownloadUrl]="fileDownloadUrl"
|
[fileDownloadUrl]="fileDownloadUrl"
|
||||||
(download)="onDownload()"
|
(download)="onDownload($event)"
|
||||||
(closed)="onClosedViewer()"
|
(closed)="onClosedViewer()"
|
||||||
></ucap-video-viewer>
|
></ucap-video-viewer>
|
||||||
<ucap-binary-viewer
|
<ucap-binary-viewer
|
||||||
*ngSwitchDefault
|
*ngSwitchDefault
|
||||||
[fileInfo]="fileInfo"
|
[fileInfo]="fileInfo"
|
||||||
[fileDownloadUrl]="fileDownloadUrl"
|
[fileDownloadUrl]="fileDownloadUrl"
|
||||||
(download)="onDownload()"
|
(download)="onDownload($event)"
|
||||||
(closed)="onClosedViewer()"
|
(closed)="onClosedViewer()"
|
||||||
></ucap-binary-viewer>
|
></ucap-binary-viewer>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,12 +3,13 @@ import { ucapAnimations } from '../animations';
|
||||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||||
import { FileViewerType } from '../types/file-viewer.type';
|
import { FileViewerType } from '../types/file-viewer.type';
|
||||||
import { FileType } from '@ucap-webmessenger/protocol-file';
|
import { FileType } from '@ucap-webmessenger/protocol-file';
|
||||||
|
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-file-viewer',
|
selector: 'ucap-file-viewer',
|
||||||
templateUrl: './file-viewer.component.html',
|
templateUrl: './file-viewer.component.html',
|
||||||
styleUrls: ['./file-viewer.component.scss'],
|
styleUrls: ['./file-viewer.component.scss'],
|
||||||
animations: ucapAnimations
|
animations: ucapAnimations,
|
||||||
})
|
})
|
||||||
export class FileViewerComponent implements OnInit {
|
export class FileViewerComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
|
@ -18,7 +19,7 @@ export class FileViewerComponent implements OnInit {
|
||||||
fileDownloadUrl: string;
|
fileDownloadUrl: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
download = new EventEmitter<void>();
|
download = new EventEmitter<FileDownloadItem>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
closed = new EventEmitter<void>();
|
closed = new EventEmitter<void>();
|
||||||
|
@ -44,8 +45,8 @@ export class FileViewerComponent implements OnInit {
|
||||||
return FileViewerType.Binary;
|
return FileViewerType.Binary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onDownload(): void {
|
onDownload(fileDownloadItem: FileDownloadItem): void {
|
||||||
this.download.emit();
|
this.download.emit(fileDownloadItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClosedViewer(): void {
|
onClosedViewer(): void {
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
<mat-progress-bar
|
||||||
|
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||||
|
mode="determinate"
|
||||||
|
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||||
|
></mat-progress-bar>
|
||||||
<div class="ucap-binary-viewer-body">
|
<div class="ucap-binary-viewer-body">
|
||||||
<div
|
<div
|
||||||
class="ucap-binary-viewer-content-wrapper"
|
class="ucap-binary-viewer-content-wrapper"
|
||||||
|
|
|
@ -2,12 +2,13 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
import { ucapAnimations } from '../../animations';
|
import { ucapAnimations } from '../../animations';
|
||||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||||
import { DeviceType } from '@ucap-webmessenger/core';
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
|
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-binary-viewer',
|
selector: 'ucap-binary-viewer',
|
||||||
templateUrl: './binary-viewer.component.html',
|
templateUrl: './binary-viewer.component.html',
|
||||||
styleUrls: ['./binary-viewer.component.scss'],
|
styleUrls: ['./binary-viewer.component.scss'],
|
||||||
animations: ucapAnimations
|
animations: ucapAnimations,
|
||||||
})
|
})
|
||||||
export class BinaryViewerComponent implements OnInit {
|
export class BinaryViewerComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
|
@ -17,17 +18,20 @@ export class BinaryViewerComponent implements OnInit {
|
||||||
fileDownloadUrl: string;
|
fileDownloadUrl: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
download = new EventEmitter<void>();
|
download = new EventEmitter<FileDownloadItem>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
closed = new EventEmitter<void>();
|
closed = new EventEmitter<void>();
|
||||||
|
|
||||||
|
fileDownloadItem: FileDownloadItem;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
onClickDownload(): void {
|
onClickDownload(): void {
|
||||||
this.download.emit();
|
this.fileDownloadItem = new FileDownloadItem();
|
||||||
|
this.download.emit(this.fileDownloadItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickClose(): void {
|
onClickClose(): void {
|
||||||
|
|
|
@ -15,4 +15,9 @@
|
||||||
>delete</mat-icon
|
>delete</mat-icon
|
||||||
>
|
>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
<mat-progress-bar
|
||||||
|
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||||
|
mode="determinate"
|
||||||
|
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||||
|
></mat-progress-bar>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,12 +2,13 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
import { ucapAnimations } from '../../animations';
|
import { ucapAnimations } from '../../animations';
|
||||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||||
import { DeviceType } from '@ucap-webmessenger/core';
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
|
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-document-viewer',
|
selector: 'ucap-document-viewer',
|
||||||
templateUrl: './document-viewer.component.html',
|
templateUrl: './document-viewer.component.html',
|
||||||
styleUrls: ['./document-viewer.component.scss'],
|
styleUrls: ['./document-viewer.component.scss'],
|
||||||
animations: ucapAnimations
|
animations: ucapAnimations,
|
||||||
})
|
})
|
||||||
export class DocumentViewerComponent implements OnInit {
|
export class DocumentViewerComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
|
@ -17,16 +18,21 @@ export class DocumentViewerComponent implements OnInit {
|
||||||
fileDownloadUrl: string;
|
fileDownloadUrl: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
download = new EventEmitter<void>();
|
download = new EventEmitter<FileDownloadItem>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
closed = new EventEmitter<void>();
|
closed = new EventEmitter<void>();
|
||||||
|
|
||||||
|
fileDownloadItem: FileDownloadItem;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
onClickDownload(): void {}
|
onClickDownload(): void {
|
||||||
|
this.fileDownloadItem = new FileDownloadItem();
|
||||||
|
this.download.emit(this.fileDownloadItem);
|
||||||
|
}
|
||||||
|
|
||||||
onClickClose(): void {
|
onClickClose(): void {
|
||||||
this.closed.emit();
|
this.closed.emit();
|
||||||
|
|
|
@ -1,11 +1,22 @@
|
||||||
<div class="ucap-image-viewer-container">
|
<div class="ucap-image-viewer-container">
|
||||||
<mat-toolbar class="ucap-image-viewer-header bg-primary-dark">
|
<mat-toolbar class="ucap-image-viewer-header bg-primary-dark">
|
||||||
<!--<mat-icon class="ucap-image-viewer-icon">image</mat-icon>-->
|
<!--<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"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" class="ucap-image-viewer-icon">
|
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" />
|
<rect x="3" y="3" width="18" height="18" rx="2" />
|
||||||
<circle cx="8.5" cy="8.5" r="1.5" />
|
<circle cx="8.5" cy="8.5" r="1.5" />
|
||||||
<path d="M20.4 14.5L16 10 4 20" /></svg>
|
<path d="M20.4 14.5L16 10 4 20" />
|
||||||
|
</svg>
|
||||||
<span class="ucap-image-viewer-title">{{ fileInfo.fileName }}</span>
|
<span class="ucap-image-viewer-title">{{ fileInfo.fileName }}</span>
|
||||||
<span class="ucap-image-viewer-spacer"></span>
|
<span class="ucap-image-viewer-spacer"></span>
|
||||||
|
|
||||||
|
@ -18,9 +29,20 @@
|
||||||
>
|
>
|
||||||
<!--<mat-icon>settings_overscan</mat-icon>-->
|
<!--<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"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<path d="M3.8 3.8l16.4 16.4M20.2 3.8L3.8 20.2M15 3h6v6M9 3H3v6M15 21h6v-6M9 21H3v-6" />
|
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>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
@ -31,7 +53,21 @@
|
||||||
aria-label=""
|
aria-label=""
|
||||||
>
|
>
|
||||||
<!--<mat-icon>zoom_out</mat-icon>-->
|
<!--<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>
|
<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>
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
|
@ -41,8 +77,17 @@
|
||||||
aria-label=""
|
aria-label=""
|
||||||
>
|
>
|
||||||
<!--<mat-icon>zoom_in</mat-icon>-->
|
<!--<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"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
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>
|
<circle cx="11" cy="11" r="8"></circle>
|
||||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||||
<line x1="11" y1="8" x2="11" y2="14"></line>
|
<line x1="11" y1="8" x2="11" y2="14"></line>
|
||||||
|
@ -58,9 +103,21 @@
|
||||||
(click)="onClickDownload()"
|
(click)="onClickDownload()"
|
||||||
>
|
>
|
||||||
<!--<mat-icon>get_app</mat-icon>-->
|
<!--<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"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<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>
|
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>
|
</button>
|
||||||
<span class="stroke-bar"></span>
|
<span class="stroke-bar"></span>
|
||||||
<button
|
<button
|
||||||
|
@ -70,13 +127,27 @@
|
||||||
matTooltip="뷰어닫기"
|
matTooltip="뷰어닫기"
|
||||||
(click)="onClickClose()"
|
(click)="onClickClose()"
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
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="18" y1="6" x2="6" y2="18"></line>
|
||||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
<mat-progress-bar
|
||||||
|
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||||
|
mode="determinate"
|
||||||
|
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||||
|
></mat-progress-bar>
|
||||||
<div class="ucap-image-viewer-body">
|
<div class="ucap-image-viewer-body">
|
||||||
<div
|
<div
|
||||||
class="ucap-image-viewer-image-wrapper"
|
class="ucap-image-viewer-image-wrapper"
|
||||||
|
|
|
@ -2,13 +2,16 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
import { ucapAnimations } from '../../animations';
|
import { ucapAnimations } from '../../animations';
|
||||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||||
import { DeviceType } from '@ucap-webmessenger/core';
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
import { CommonApiService } from '@ucap-webmessenger/api-common';
|
import {
|
||||||
|
CommonApiService,
|
||||||
|
FileDownloadItem,
|
||||||
|
} from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-image-viewer',
|
selector: 'ucap-image-viewer',
|
||||||
templateUrl: './image-viewer.component.html',
|
templateUrl: './image-viewer.component.html',
|
||||||
styleUrls: ['./image-viewer.component.scss'],
|
styleUrls: ['./image-viewer.component.scss'],
|
||||||
animations: ucapAnimations
|
animations: ucapAnimations,
|
||||||
})
|
})
|
||||||
export class ImageViewerComponent implements OnInit {
|
export class ImageViewerComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
|
@ -21,14 +24,17 @@ export class ImageViewerComponent implements OnInit {
|
||||||
closed = new EventEmitter<void>();
|
closed = new EventEmitter<void>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
download = new EventEmitter<void>();
|
download = new EventEmitter<FileDownloadItem>();
|
||||||
|
|
||||||
|
fileDownloadItem: FileDownloadItem;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
onClickDownload(): void {
|
onClickDownload(): void {
|
||||||
this.download.emit();
|
this.fileDownloadItem = new FileDownloadItem();
|
||||||
|
this.download.emit(this.fileDownloadItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickClose(): void {
|
onClickClose(): void {
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
<mat-progress-bar
|
||||||
|
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||||
|
mode="determinate"
|
||||||
|
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||||
|
></mat-progress-bar>
|
||||||
<div class="ucap-sound-viewer-body">
|
<div class="ucap-sound-viewer-body">
|
||||||
<div
|
<div
|
||||||
class="ucap-sound-viewer-sound-icon"
|
class="ucap-sound-viewer-sound-icon"
|
||||||
|
|
|
@ -5,17 +5,18 @@ import {
|
||||||
Output,
|
Output,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ElementRef
|
ElementRef,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { ucapAnimations } from '../../animations';
|
import { ucapAnimations } from '../../animations';
|
||||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||||
import { MatSlider, MatSliderChange } from '@angular/material';
|
import { MatSlider, MatSliderChange } from '@angular/material';
|
||||||
|
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-sound-viewer',
|
selector: 'ucap-sound-viewer',
|
||||||
templateUrl: './sound-viewer.component.html',
|
templateUrl: './sound-viewer.component.html',
|
||||||
styleUrls: ['./sound-viewer.component.scss'],
|
styleUrls: ['./sound-viewer.component.scss'],
|
||||||
animations: ucapAnimations
|
animations: ucapAnimations,
|
||||||
})
|
})
|
||||||
export class SoundViewerComponent implements OnInit {
|
export class SoundViewerComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
|
@ -25,7 +26,7 @@ export class SoundViewerComponent implements OnInit {
|
||||||
fileDownloadUrl: string;
|
fileDownloadUrl: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
download = new EventEmitter<void>();
|
download = new EventEmitter<FileDownloadItem>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
closed = new EventEmitter<void>();
|
closed = new EventEmitter<void>();
|
||||||
|
@ -41,6 +42,7 @@ export class SoundViewerComponent implements OnInit {
|
||||||
currentTime = 0;
|
currentTime = 0;
|
||||||
volume = 0.1;
|
volume = 0.1;
|
||||||
loading = false;
|
loading = false;
|
||||||
|
fileDownloadItem: FileDownloadItem;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -90,7 +92,8 @@ export class SoundViewerComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickDownload(): void {
|
onClickDownload(): void {
|
||||||
this.download.emit();
|
this.fileDownloadItem = new FileDownloadItem();
|
||||||
|
this.download.emit(this.fileDownloadItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickClose(): void {
|
onClickClose(): void {
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
<div class="ucap-video-viewer-container">
|
<div class="ucap-video-viewer-container">
|
||||||
<mat-toolbar color="accent" class="ucap-video-viewer-header">
|
<mat-toolbar color="accent" class="ucap-video-viewer-header">
|
||||||
<!--<mat-icon class="ucap-video-viewer-icon">video_label</mat-icon>-->
|
<!--<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"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" class="ucap-video-viewer-icon">
|
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>
|
<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="7" y1="2" x2="7" y2="22"></line>
|
||||||
<line x1="17" y1="2" x2="17" y2="22"></line>
|
<line x1="17" y1="2" x2="17" y2="22"></line>
|
||||||
|
@ -23,9 +33,20 @@
|
||||||
(click)="onClickDownload()"
|
(click)="onClickDownload()"
|
||||||
>
|
>
|
||||||
<!--<mat-icon>get_app</mat-icon>-->
|
<!--<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"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<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" />
|
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>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<span class="stroke-bar"></span>
|
<span class="stroke-bar"></span>
|
||||||
|
@ -36,13 +57,27 @@
|
||||||
matTooltip="뷰어닫기"
|
matTooltip="뷰어닫기"
|
||||||
(click)="onClickClose()"
|
(click)="onClickClose()"
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
<svg
|
||||||
stroke-width="2" stroke-linecap="butt" stroke-linejoin="round">
|
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="18" y1="6" x2="6" y2="18"></line>
|
||||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
<mat-progress-bar
|
||||||
|
*ngIf="fileDownloadItem && fileDownloadItem.downloadingProgress$"
|
||||||
|
mode="determinate"
|
||||||
|
[value]="fileDownloadItem.downloadingProgress$ | async"
|
||||||
|
></mat-progress-bar>
|
||||||
<div class="ucap-video-viewer-body">
|
<div class="ucap-video-viewer-body">
|
||||||
<div
|
<div
|
||||||
class="ucap-video-viewer-video-icon"
|
class="ucap-video-viewer-video-icon"
|
||||||
|
|
|
@ -5,17 +5,18 @@ import {
|
||||||
Output,
|
Output,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ElementRef
|
ElementRef,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { ucapAnimations } from '../../animations';
|
import { ucapAnimations } from '../../animations';
|
||||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||||
import { MatSlider, MatSliderChange } from '@angular/material';
|
import { MatSlider, MatSliderChange } from '@angular/material';
|
||||||
|
import { FileDownloadItem } from '@ucap-webmessenger/api-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-video-viewer',
|
selector: 'ucap-video-viewer',
|
||||||
templateUrl: './video-viewer.component.html',
|
templateUrl: './video-viewer.component.html',
|
||||||
styleUrls: ['./video-viewer.component.scss'],
|
styleUrls: ['./video-viewer.component.scss'],
|
||||||
animations: ucapAnimations
|
animations: ucapAnimations,
|
||||||
})
|
})
|
||||||
export class VideoViewerComponent implements OnInit {
|
export class VideoViewerComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
|
@ -25,7 +26,7 @@ export class VideoViewerComponent implements OnInit {
|
||||||
fileDownloadUrl: string;
|
fileDownloadUrl: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
download = new EventEmitter<void>();
|
download = new EventEmitter<FileDownloadItem>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
closed = new EventEmitter<void>();
|
closed = new EventEmitter<void>();
|
||||||
|
@ -41,6 +42,7 @@ export class VideoViewerComponent implements OnInit {
|
||||||
currentTime = 0;
|
currentTime = 0;
|
||||||
volume = 0.1;
|
volume = 0.1;
|
||||||
loading = false;
|
loading = false;
|
||||||
|
fileDownloadItem: FileDownloadItem;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -90,7 +92,8 @@ export class VideoViewerComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickDownload(): void {
|
onClickDownload(): void {
|
||||||
this.download.emit();
|
this.fileDownloadItem = new FileDownloadItem();
|
||||||
|
this.download.emit(this.fileDownloadItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickClose(): void {
|
onClickClose(): void {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user