425 lines
11 KiB
TypeScript
Raw Normal View History

2019-11-19 19:34:53 +09:00
import { ipcRenderer, remote, shell } from 'electron';
2019-09-18 15:02:21 +09:00
import { Observable, Subject } from 'rxjs';
2019-09-19 10:40:16 +09:00
2019-11-01 11:25:54 +09:00
import {
NativeService,
WindowState,
2019-11-09 17:29:02 +09:00
NotificationRequest,
2019-12-12 17:15:09 +09:00
WindowIdle,
UpdateInfo,
2019-12-24 11:41:50 +09:00
UpdateCheckConfig,
NativePathName,
NativeType
2019-11-01 11:25:54 +09:00
} from '@ucap-webmessenger/native';
import { share } from 'rxjs/operators';
2019-11-09 17:29:02 +09:00
import {
NotificationChannel,
UpdaterChannel,
FileChannel,
WindowStateChannel,
IdleStateChannel,
2019-11-12 18:54:21 +09:00
ChatChannel,
2019-12-17 16:39:02 +09:00
MessengerChannel,
MessageChannel
2019-11-09 17:29:02 +09:00
} from '../types/channel.type';
2019-11-11 15:53:39 +09:00
import { Injectable } from '@angular/core';
2019-11-11 18:09:47 +09:00
import { TranslateLoaderService } from '../translate/electron-loader';
import { TranslateLoader } from '@ngx-translate/core';
2019-11-19 16:44:50 +09:00
import { StatusCode } from '@ucap-webmessenger/core';
2019-09-18 15:02:21 +09:00
2019-11-11 15:53:39 +09:00
@Injectable({
2019-11-19 16:44:50 +09:00
providedIn: 'root'
2019-11-11 15:53:39 +09:00
})
2019-09-18 15:02:21 +09:00
export class ElectronNativeService implements NativeService {
2019-11-12 18:54:21 +09:00
private ipcRenderer: typeof ipcRenderer;
private remote: typeof remote;
2019-11-19 19:34:53 +09:00
private shell: typeof shell;
2019-11-12 18:54:21 +09:00
2019-11-19 16:44:50 +09:00
private logoutSubject: Subject<void> | null = null;
private logout$: Observable<void> | null = null;
private changeStatusSubject: Subject<StatusCode> | null = null;
private changeStatus$: Observable<StatusCode> | null = null;
private showSettingSubject: Subject<void> | null = null;
private showSetting$: Observable<void> | null = null;
private windowStateChangedSubject: Subject<WindowState> | null = null;
private windowStateChanged$: Observable<WindowState> | null = null;
private idleStateChangedSubject: Subject<WindowIdle> | null = null;
private idleStateChanged$: Observable<WindowIdle> | null = null;
private chatOpenRoomSubject: Subject<string> | null = null;
private chatOpenRoom$: Observable<string> | null = null;
2019-12-17 16:39:02 +09:00
private msgOpenMessageSubject: Subject<string> | null = null;
private msgOpenMessage$: Observable<string> | null = null;
2019-12-12 17:15:09 +09:00
private backgroundCheckForUpdatesSubject: Subject<UpdateInfo> | null = null;
private backgroundCheckForUpdates$: Observable<UpdateInfo> | null = null;
2019-12-24 11:41:50 +09:00
type(): NativeType {
return NativeType.Electron;
}
2019-11-11 18:09:47 +09:00
postAppInit(): void {}
2019-11-19 16:44:50 +09:00
logout(): Observable<void> {
if (!this.logoutSubject) {
this.logoutSubject = new Subject<void>();
this.logout$ = this.logoutSubject.asObservable().pipe(share());
}
this.ipcRenderer.on(MessengerChannel.Logout, (event: any) => {
this.logoutSubject.next();
});
return this.logout$;
}
getNetworkInfo(): Promise<any> {
return new Promise<string>((resolve, reject) => {
try {
resolve(this.ipcRenderer.sendSync(MessengerChannel.GetNetworkInfo));
} catch (error) {
reject(error);
}
});
}
2019-11-19 16:44:50 +09:00
changeStatus(): Observable<StatusCode> {
if (!this.changeStatusSubject) {
this.changeStatusSubject = new Subject<StatusCode>();
this.changeStatus$ = this.changeStatusSubject
.asObservable()
.pipe(share());
}
this.ipcRenderer.on(
MessengerChannel.ChangeStatus,
(event: any, statusCode: StatusCode) => {
this.changeStatusSubject.next(statusCode);
}
);
return this.changeStatus$;
}
showSetting(): Observable<void> {
if (!this.showSettingSubject) {
this.showSettingSubject = new Subject<void>();
this.showSetting$ = this.showSettingSubject.asObservable().pipe(share());
}
this.ipcRenderer.on(MessengerChannel.ShowSetting, (event: any) => {
this.showSettingSubject.next();
});
return this.showSetting$;
}
2019-12-17 17:27:08 +09:00
changeAutoLaunch(autoLaunch: boolean): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
resolve(
this.ipcRenderer.sendSync(
MessengerChannel.ChangeAutoLaunch,
autoLaunch
)
);
} catch (error) {
reject(error);
}
});
}
2019-12-18 17:11:58 +09:00
changeStartupHideWindow(startupHideWindow: boolean): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
resolve(
this.ipcRenderer.sendSync(
MessengerChannel.ChangeStartupHideWindow,
startupHideWindow
)
);
} catch (error) {
reject(error);
}
});
}
changeDownloadPath(downloadPath: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
try {
resolve(
this.ipcRenderer.sendSync(
MessengerChannel.ChangeDownloadPath,
downloadPath
)
);
} catch (error) {
reject(error);
}
});
}
2019-11-09 17:29:02 +09:00
notify(noti: NotificationRequest): void {
2019-11-12 18:54:21 +09:00
this.ipcRenderer.send(NotificationChannel.Notify, noti);
2019-11-09 17:29:02 +09:00
}
closeAllNotify(): void {
2019-11-12 18:54:21 +09:00
this.ipcRenderer.send(NotificationChannel.CloseAllNotify);
2019-09-18 15:02:21 +09:00
}
2019-12-16 02:33:40 +09:00
checkForUpdates(currentVersion: string): Promise<boolean> {
2019-11-13 15:28:33 +09:00
return new Promise<boolean>((resolve, reject) => {
2019-09-18 15:02:21 +09:00
try {
2019-12-16 02:33:40 +09:00
resolve(
this.ipcRenderer.sendSync(UpdaterChannel.Check, currentVersion)
);
2019-09-18 15:02:21 +09:00
} catch (error) {
2019-11-13 15:28:33 +09:00
reject(error);
2019-09-18 15:02:21 +09:00
}
});
}
2019-12-12 17:15:09 +09:00
checkForInstantUpdates(config: UpdateCheckConfig): Observable<UpdateInfo> {
if (!this.backgroundCheckForUpdatesSubject) {
this.backgroundCheckForUpdatesSubject = new Subject<UpdateInfo>();
this.backgroundCheckForUpdates$ = this.backgroundCheckForUpdatesSubject
.asObservable()
.pipe(share());
}
this.ipcRenderer.send(UpdaterChannel.StartCheckInstant, config);
this.ipcRenderer.on(
UpdaterChannel.ExistInstant,
(event: any, updateInfo: UpdateInfo) => {
this.backgroundCheckForUpdatesSubject.next(updateInfo);
}
);
return this.backgroundCheckForUpdates$;
}
applyInstantUpdates(): void {
this.ipcRenderer.send(UpdaterChannel.ApplyInstant);
}
2019-09-18 15:02:21 +09:00
showImageViewer(): void {
2019-11-12 18:54:21 +09:00
this.ipcRenderer.send(FileChannel.ShowImageViewer);
2019-09-18 15:02:21 +09:00
}
2019-11-13 15:28:33 +09:00
readFile(path: string): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
try {
2019-12-18 13:44:26 +09:00
const buffer = this.ipcRenderer.sendSync(FileChannel.ReadFile, path);
if (!!buffer) {
resolve(buffer);
} else {
reject(buffer as Error);
}
} catch (error) {
2019-11-13 15:28:33 +09:00
reject(error);
}
});
2019-09-18 15:02:21 +09:00
}
2019-11-07 11:37:33 +09:00
saveFile(
buffer: Buffer,
fileName: string,
2019-11-13 15:28:33 +09:00
mimeType: string,
2019-11-07 11:37:33 +09:00
path?: string
2019-11-13 15:28:33 +09:00
): Promise<string> {
return new Promise<string>((resolve, reject) => {
try {
2019-11-13 15:28:33 +09:00
resolve(
2019-11-12 18:54:21 +09:00
this.ipcRenderer.sendSync(
FileChannel.SaveFile,
buffer,
fileName,
2019-11-13 15:28:33 +09:00
mimeType,
2019-11-12 18:54:21 +09:00
path
)
2019-11-07 11:37:33 +09:00
);
} catch (error) {
2019-11-13 15:28:33 +09:00
reject(error);
}
});
}
openDefaultDownloadFolder(): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
resolve(
this.ipcRenderer.sendSync(FileChannel.OpenFolderItem, undefined, true)
);
} catch (error) {
reject(error);
}
});
}
openTargetFolder(folderPath?: string, make?: boolean): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
resolve(
this.ipcRenderer.sendSync(
FileChannel.OpenFolderItem,
folderPath,
!make ? false : make
)
);
} catch (error) {
reject(error);
}
});
}
openTargetItem(filePath?: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
resolve(
this.ipcRenderer.sendSync(FileChannel.OpenFolderItem, filePath, false)
);
} catch (error) {
reject(error);
}
});
}
2019-12-24 11:41:50 +09:00
getPath(name: NativePathName): Promise<string> {
return new Promise<string>((resolve, reject) => {
try {
resolve(this.ipcRenderer.sendSync(FileChannel.GetPath, name));
} catch (error) {
reject(error);
}
});
}
2019-12-24 16:16:13 +09:00
selectDirectory(): Promise<string> {
return new Promise<string>((resolve, reject) => {
try {
resolve(this.ipcRenderer.sendSync(FileChannel.SelectDirectory));
} catch (error) {
reject(error);
}
});
}
windowStateChanged(): Observable<WindowState> {
if (!this.windowStateChangedSubject) {
this.windowStateChangedSubject = new Subject<WindowState>();
this.windowStateChanged$ = this.windowStateChangedSubject
.asObservable()
.pipe(share());
}
2019-11-12 18:54:21 +09:00
this.ipcRenderer.on(
2019-11-09 17:29:02 +09:00
WindowStateChannel.Changed,
2019-11-12 18:54:21 +09:00
(event: any, windowState: WindowState) => {
this.windowStateChangedSubject.next(windowState);
}
);
return this.windowStateChanged$;
}
windowClose(): void {
2019-11-12 18:54:21 +09:00
const currentWindow = this.remote.getCurrentWindow();
if (!currentWindow) {
return;
}
currentWindow.close();
}
windowMinimize(): void {
2019-11-12 18:54:21 +09:00
const currentWindow = this.remote.getCurrentWindow();
if (!currentWindow) {
return;
}
currentWindow.minimize();
}
windowMaximize(): void {
2019-11-12 18:54:21 +09:00
const currentWindow = this.remote.getCurrentWindow();
if (!currentWindow) {
return;
}
if (currentWindow.isMaximized()) {
currentWindow.unmaximize();
} else {
currentWindow.maximize();
}
}
idleStateChanged(): Observable<WindowIdle> {
if (!this.idleStateChangedSubject) {
this.idleStateChangedSubject = new Subject<WindowIdle>();
this.idleStateChanged$ = this.idleStateChangedSubject
.asObservable()
.pipe(share());
}
2019-11-12 18:54:21 +09:00
this.ipcRenderer.send(IdleStateChannel.StartCheck);
2019-11-12 18:54:21 +09:00
this.ipcRenderer.on(
2019-11-09 17:29:02 +09:00
IdleStateChannel.Changed,
2019-11-12 18:54:21 +09:00
(event: any, idleState: WindowIdle) => {
this.idleStateChangedSubject.next(idleState);
}
);
return this.idleStateChanged$;
}
chatOpenRoom(): Observable<string> {
if (!this.chatOpenRoomSubject) {
this.chatOpenRoomSubject = new Subject<WindowIdle>();
this.chatOpenRoom$ = this.chatOpenRoomSubject
.asObservable()
.pipe(share());
}
2019-11-12 18:54:21 +09:00
this.ipcRenderer.on(ChatChannel.OpenRoom, (event: any, roomSeq: string) => {
this.chatOpenRoomSubject.next(roomSeq);
});
return this.chatOpenRoom$;
}
2019-12-17 16:39:02 +09:00
msgOpenMessage(): Observable<string> {
if (!this.msgOpenMessageSubject) {
this.msgOpenMessageSubject = new Subject<WindowIdle>();
this.msgOpenMessage$ = this.msgOpenMessageSubject
.asObservable()
.pipe(share());
}
this.ipcRenderer.on(
MessageChannel.OpenMessage,
(event: any, messageSeq: string) => {
this.msgOpenMessageSubject.next(messageSeq);
}
);
return this.msgOpenMessage$;
}
2019-11-11 18:09:47 +09:00
getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader {
return new TranslateLoaderService(this, prefix, suffix);
}
2019-11-19 19:34:53 +09:00
openDefaultBrowser(url: string): void {
this.shell.openExternal(url);
}
2019-11-12 18:54:21 +09:00
get isElectron() {
return window && (window as any).process && (window as any).process.type;
}
constructor() {
if (this.isElectron) {
this.ipcRenderer = (window as any).require('electron').ipcRenderer;
this.remote = (window as any).require('electron').remote;
2019-11-19 19:34:53 +09:00
this.shell = (window as any).require('electron').shell;
2019-11-12 18:54:21 +09:00
}
}
2019-09-18 15:02:21 +09:00
}