This commit is contained in:
병준 박 2020-01-03 16:18:39 +09:00
commit 4bb3a7dece
18 changed files with 214 additions and 26 deletions

View File

@ -513,15 +513,18 @@ ipcMain.on(
const buffer: Buffer = args[0];
const fileName: string = args[1];
const mimeType: string = args[2];
const customSavePath: string = args[3];
let savePath: string = path.join(
!!args[3]
? args[3]
: !!appStorage.downloadPath
!!appStorage.downloadPath
? appStorage.downloadPath
: app.getPath('downloads'),
fileName
);
savePath = await FileUtil.uniqueFileName(savePath);
if (!!customSavePath) {
savePath = customSavePath;
} else {
savePath = await FileUtil.uniqueFileName(savePath);
}
fse.writeFile(savePath, buffer, err => {
if (!err) {
@ -594,6 +597,20 @@ ipcMain.on(
}
);
ipcMain.on(
FileChannel.SelectSaveFilePath,
(event: IpcMainEvent, ...args: any[]) => {
dialog
.showSaveDialog({ defaultPath: args[0] })
.then(obj => {
event.returnValue = obj.filePath;
})
.catch(obj => {
event.returnValue = undefined;
});
}
);
ipcMain.on(
IdleStateChannel.StartCheck,
(event: IpcMainEvent, ...args: any[]) => {

View File

@ -68,6 +68,14 @@
(openProfile)="onClickOpenProfile($event)"
(click)="onToggleUser(userInfo)"
(contextmenu)="onContextMenuOrgUser($event, userInfo)"
[matTooltip]="
userInfo.companyName +
' / ' +
userInfo.lineNumber +
' / ' +
userInfo.hpNumber
"
matTooltipPosition="after"
>
</ucap-profile-user-list-item>
</cdk-virtual-scroll-viewport>
@ -90,6 +98,14 @@
(openProfile)="onClickOpenProfile($event)"
(click)="onToggleUser(userInfo)"
(contextmenu)="onContextMenuOrgUser($event, userInfo)"
[matTooltip]="
userInfo.companyName +
' / ' +
userInfo.lineNumber +
' / ' +
userInfo.hpNumber
"
matTooltipPosition="after"
>
</ucap-profile-user-list-item>
</cdk-virtual-scroll-viewport>

View File

@ -5,7 +5,8 @@ import {
ViewChild,
AfterViewInit,
Output,
EventEmitter
EventEmitter,
Inject
} from '@angular/core';
import {
ucapAnimations,
@ -58,7 +59,7 @@ import {
KEY_STICKER_HISTORY
} from '@app/types';
import { RoomInfo, UserInfo, RoomType } from '@ucap-webmessenger/protocol-room';
import { tap, take, map, catchError } from 'rxjs/operators';
import { tap, take, map, catchError, finalize } from 'rxjs/operators';
import {
FileInfo,
FormComponent as UCapUiChatFormComponent
@ -70,7 +71,7 @@ import {
MatSnackBarRef,
SimpleSnackBar
} from '@angular/material';
import { FileUploadItem } from '@ucap-webmessenger/api';
import { FileUploadItem, FileDownloadItem } from '@ucap-webmessenger/api';
import {
CommonApiService,
FileTalkSaveRequest,
@ -88,7 +89,7 @@ import {
FileViewerDialogData,
FileViewerDialogResult
} from '@app/layouts/common/dialogs/file-viewer.dialog.component';
import { FileUtil, StickerFilesInfo } from '@ucap-webmessenger/core';
import { FileUtil, StickerFilesInfo, MimeUtil } from '@ucap-webmessenger/core';
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
import { StatusCode } from '@ucap-webmessenger/api';
import {
@ -107,6 +108,7 @@ import {
MassDetailComponent,
MassDetailDialogData
} from '../dialogs/chat/mass-detail.component';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
@Component({
selector: 'app-layout-messenger-messages',
@ -204,6 +206,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
private clipboardService: ClipboardService,
private dialogService: DialogService,
private snackBarService: SnackBarService,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private logger: NGXLogger
) {
this.sessionVerInfo = this.sessionStorageService.get<VersionInfo2Response>(
@ -844,8 +847,29 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
}
/** File Save, Save As */
onSave(value: { fileInfo: FileInfo; type: string }) {
onSave(value: {
fileInfo: FileEventJson;
fileDownloadItem: FileDownloadItem;
type: string;
}) {
this.logger.debug('fileSave', value);
if (value.type === 'saveAs') {
this.nativeService
.selectSaveFilePath(value.fileInfo.fileName)
.then(result => {
console.log(result);
if (!!result && result.length > 0) {
this.saveFile(value, result);
} else {
this.snackBarService.open('저장경로 지정에 실패하였습니다.', '확인');
}
})
.catch(reason => {
this.snackBarService.open('저장경로 지정에 실패하였습니다.', '확인');
});
} else {
this.saveFile(value);
}
}
onFileDragEnter(items: DataTransferItemList) {
@ -861,6 +885,65 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
this.logger.debug('onFileDragLeave');
}
saveFile(
value: {
fileInfo: FileEventJson;
fileDownloadItem: FileDownloadItem;
type: string;
},
savePath?: string
) {
this.commonApiService
.fileTalkDownload({
userSeq: this.loginRes.userSeq,
deviceType: this.environmentsInfo.deviceType,
token: this.loginRes.tokenString,
attachmentsSeq: value.fileInfo.attachmentSeq,
fileDownloadItem: value.fileDownloadItem
})
.pipe(
take(1),
map(async rawBlob => {
const mimeType = MimeUtil.getMimeFromExtension(
FileUtil.getExtension(value.fileInfo.fileName)
);
const blob = rawBlob.slice(0, rawBlob.size, mimeType);
FileUtil.fromBlobToBuffer(blob)
.then(buffer => {
this.nativeService
.saveFile(buffer, value.fileInfo.fileName, mimeType, savePath)
.then(result => {
if (!!result) {
this.snackBarService.open(
`파일이 경로[${result}]에 저장되었습니다.`,
'',
{
duration: 3000,
verticalPosition: 'bottom'
}
);
} else {
this.snackBarService.open('파일 저장에 실패하였습니다.', '확인');
}
})
.catch(reason => {
this.snackBarService.open('파일 저장에 실패하였습니다.', '확인');
});
})
.catch(reason => {
this.logger.error('download', reason);
});
}),
finalize(() => {
setTimeout(() => {
value.fileDownloadItem.downloadingProgress$ = undefined;
}, 1000);
})
)
.subscribe();
}
async onFileSelected(fileUploadItems: FileUploadItem[]) {
this.logger.debug('onFileSelected', fileUploadItems);
this.clearView();

View File

@ -239,11 +239,17 @@ export class AlbumBoxComponent implements OnInit, OnDestroy {
}
);
} else {
this.snackBarService.open('파일 저장에 실패하였습니다.');
this.snackBarService.open(
'파일 저장에 실패하였습니다.',
'확인'
);
}
})
.catch(reason => {
this.snackBarService.open('파일 저장에 실패하였습니다.');
this.snackBarService.open(
'파일 저장에 실패하였습니다.',
'확인'
);
});
})
.catch(reason => {

View File

@ -275,11 +275,17 @@ export class FileBoxComponent implements OnInit, OnDestroy {
}
);
} else {
this.snackBarService.open('파일 저장에 실패하였습니다.');
this.snackBarService.open(
'파일 저장에 실패하였습니다.',
'확인'
);
}
})
.catch(reason => {
this.snackBarService.open('파일 저장에 실패하였습니다.');
this.snackBarService.open(
'파일 저장에 실패하였습니다.',
'확인'
);
});
})
.catch(reason => {

View File

@ -68,7 +68,7 @@ export class AppAuthenticationService {
...environment.productConfig.defaultSettings.chat,
downloadPath: `${await this.nativeService.getPath(
'documents'
)}/LG UCAP downloads`
)}/Messenger downloads`
}
}
};

View File

@ -185,6 +185,12 @@ export class BrowserNativeService extends NativeService {
});
}
selectSaveFilePath(defaultPath?: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
resolve('');
});
}
windowStateChanged(): Observable<WindowState> {
return new Observable<WindowState>(subscriber => {
try {

View File

@ -304,6 +304,18 @@ export class ElectronNativeService implements NativeService {
});
}
selectSaveFilePath(defaultPath?: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
try {
resolve(
this.ipcRenderer.sendSync(FileChannel.SelectSaveFilePath, defaultPath)
);
} catch (error) {
reject(error);
}
});
}
windowStateChanged(): Observable<WindowState> {
if (!this.windowStateChangedSubject) {
this.windowStateChangedSubject = new Subject<WindowState>();

View File

@ -35,7 +35,8 @@ export enum FileChannel {
SaveFile = 'UCAP::file::saveFile',
ReadFile = 'UCAP::file::readFile',
GetPath = 'UCAP::file::getPath',
SelectDirectory = 'UCAP::file::selectDirectory'
SelectDirectory = 'UCAP::file::selectDirectory',
SelectSaveFilePath = 'UCAP::file::SelectSaveFilePath'
}
export enum WindowStateChannel {

View File

@ -58,6 +58,7 @@ export abstract class NativeService {
abstract openTargetItem(filePath?: string): Promise<boolean>;
abstract getPath(name: NativePathName): Promise<string>;
abstract selectDirectory(): Promise<string>;
abstract selectSaveFilePath(defaultPath?: string): Promise<string>;
abstract windowStateChanged(): Observable<WindowState>;
abstract windowClose(): void;

View File

@ -15,6 +15,7 @@ import { RoleCode } from '@ucap-webmessenger/protocol-authentication';
import { DeptSearchType } from '../types/dept-search.type';
import { CallMode } from '@ucap-webmessenger/core';
import { UserInfoSS } from '../models/user-info-ss';
import { WorkStatusType } from 'projects/ucap-webmessenger-protocol-status/src/lib/types/work-status.type';
export interface DeptUserRequest extends ProtocolRequest {
/** DivCD(s) */
@ -113,7 +114,15 @@ export const decodeDeptUserData: ProtocolDecoder<DeptUserData> = (
deptSeq: info[25],
isPrivacyAgree: info[26] === 'Y' ? true : false,
isValidLogin: info[27] === 'Y' ? true : false,
employeeType: info[28] as EmployeeType
employeeType: info[28] as EmployeeType,
// [daesang]
companyName: info[29],
responsibilities: info[30],
workstatus: info[31] as WorkStatusType,
job: info[32],
customerInfo: info[33],
workplace: info[34]
});
});
return decodeProtocolMessage(message, {

View File

@ -1,4 +1,4 @@
<div class="bubble-main">
<div class="bubble-main" (click)="onClickOpenViewer()">
<!--파일명에 따라 doc exe hwp ppt xls zip 으로 추가되고 나머지 파일 명은 file로 기간이 만료된 파일은 그뒤에 disable도 추가-->
<!-- <div class="file-img" [ngClass]="fileInfo.FileExt"></div> -->
<div [ngClass]="['mime-icon', 'light', 'ico-' + fileInfo.fileExt]">

View File

@ -15,6 +15,8 @@ export class AttachFileComponent implements OnInit {
@Output()
save = new EventEmitter<string>();
@Output()
openViewer = new EventEmitter();
constructor(private logger: NGXLogger) {}
@ -26,4 +28,7 @@ export class AttachFileComponent implements OnInit {
onClickSaveAs() {
this.save.emit('saveAs');
}
onClickOpenViewer() {
this.openViewer.emit();
}
}

View File

@ -6,7 +6,7 @@
*ngSwitchCase="FileType.File"
[fileInfo]="fileInfo"
[expired]="getExpiredFile()"
(click)="onClickFileViewer(fileInfo)"
(openViewer)="onClickFileViewer(fileInfo)"
(save)="onSave($event)"
>
</ucap-chat-message-box-attach-file>
@ -14,7 +14,7 @@
*ngSwitchCase="FileType.Sound"
[fileInfo]="fileInfo"
[expired]="getExpiredFile()"
(click)="onClickFileViewer(fileInfo)"
(openViewer)="onClickFileViewer(fileInfo)"
(save)="onSave($event)"
>
</ucap-chat-message-box-attach-file>
@ -28,7 +28,8 @@
*ngSwitchCase="FileType.Video"
[fileInfo]="fileInfo"
[expired]="getExpiredFile()"
(click)="onClickFileViewer(fileInfo)"
(openViewer)="onClickFileViewer(fileInfo)"
(save)="onSave($event)"
></ucap-chat-message-box-video>
<ucap-chat-message-box-text
*ngSwitchDefault

View File

@ -4,7 +4,7 @@ import {
InfoResponse,
FileEventJson
} from '@ucap-webmessenger/protocol-event';
import { StatusCode } from '@ucap-webmessenger/api';
import { StatusCode, FileDownloadItem } from '@ucap-webmessenger/api';
import { FileType } from '@ucap-webmessenger/protocol-file';
import { NGXLogger } from 'ngx-logger';
@ -20,11 +20,16 @@ export class FileComponent implements OnInit {
eventInfoStatus: InfoResponse;
@Output()
save = new EventEmitter<{ fileInfo: FileEventJson; type: string }>();
save = new EventEmitter<{
fileInfo: FileEventJson;
fileDownloadItem: FileDownloadItem;
type: string;
}>();
@Output()
fileViewer = new EventEmitter<FileEventJson>();
fileInfo?: FileEventJson;
fileDownloadItem: FileDownloadItem;
errorMessage?: string;
FileType = FileType;
@ -37,6 +42,8 @@ export class FileComponent implements OnInit {
this.errorMessage =
this.message.sentMessageJson.errorMessage || '[Error] System Error!!';
}
this.fileDownloadItem = new FileDownloadItem();
}
getExpiredFile() {
@ -58,7 +65,11 @@ export class FileComponent implements OnInit {
onSave(value: string) {
if (!this.getExpiredFile()) {
this.save.emit({ fileInfo: this.fileInfo, type: value });
this.save.emit({
fileInfo: this.fileInfo,
fileDownloadItem: this.fileDownloadItem,
type: value
});
}
}
}

View File

@ -1,4 +1,4 @@
<div class="bubble-main">
<div class="bubble-main" (click)="onClickOpenViewer()">
<div class="file-thumbimg">
<img *ngIf="!!fileInfo.thumbUrl" [src]="fileInfo.thumbUrl" />
</div>

View File

@ -15,6 +15,8 @@ export class VideoComponent implements OnInit {
@Output()
save = new EventEmitter<string>();
@Output()
openViewer = new EventEmitter();
constructor(private logger: NGXLogger) {}
@ -26,4 +28,7 @@ export class VideoComponent implements OnInit {
onClickSaveAs() {
this.save.emit('saveAs');
}
onClickOpenViewer() {
this.openViewer.emit();
}
}

View File

@ -14,6 +14,7 @@ import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { FileInfo } from '../models/file-info.json';
import { DatePipe } from '@angular/common';
import moment from 'moment';
import { FileDownloadItem } from '@ucap-webmessenger/api';
@Component({
selector: 'ucap-chat-messages',
@ -67,7 +68,11 @@ export class MessagesComponent implements OnInit {
@Output()
fileViewer = new EventEmitter<FileEventJson>();
@Output()
save = new EventEmitter<{ fileInfo: FileInfo; type: string }>();
save = new EventEmitter<{
fileInfo: FileEventJson;
fileDownloadItem: FileDownloadItem;
type: string;
}>();
@Output()
contextMenu = new EventEmitter<{
event: MouseEvent;
@ -233,7 +238,11 @@ export class MessagesComponent implements OnInit {
}
/** [Event] Attach File Save & Save As */
onSave(value: { fileInfo: FileInfo; type: string }) {
onSave(value: {
fileInfo: FileEventJson;
fileDownloadItem: FileDownloadItem;
type: string;
}) {
this.save.emit(value);
}