From 778b4f6ee67b0f5fa1a72a7df25e73f9f119d1bc Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Sat, 3 Feb 2024 16:03:17 +0100 Subject: [PATCH] [feature-107] Can now open .bplist file with BSManager --- assets/bsm_file.ico | Bin 0 -> 410598 bytes package.json | 2 +- src/main/main.ts | 40 +++++++++---- .../local-playlists-manager.service.ts | 27 +++++---- src/main/services/file-association.service.ts | 56 ++++++++++++++++++ 5 files changed, 100 insertions(+), 25 deletions(-) create mode 100644 assets/bsm_file.ico create mode 100644 src/main/services/file-association.service.ts diff --git a/assets/bsm_file.ico b/assets/bsm_file.ico new file mode 100644 index 0000000000000000000000000000000000000000..48c48c62790567d23b1d28aebdf28937d2d31d27 GIT binary patch literal 410598 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 z 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 literal 0 HcmV?d00001 diff --git a/package.json b/package.json index b65c38c0..565697fd 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "owner": "Zagrios" }, "fileAssociations": [ - { "ext": "bplist", "description": "Beat Saber Playlist", "icon": "./assets/favicon.ico", "role": "Viewer" } + { "ext": "bplist", "description": "Beat Saber Playlist (BSManager)", "icon": "./assets/bsm_file.ico", "role": "Viewer" } ] }, "repository": { diff --git a/src/main/main.ts b/src/main/main.ts index 6cf82c74..c3d69279 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -21,6 +21,7 @@ import { BSLauncherService } from "./services/bs-launcher/bs-launcher.service"; import { IpcRequest } from "shared/models/ipc"; import { LivShortcut } from "./services/liv/liv-shortcut.service"; import { SteamLauncherService } from "./services/bs-launcher/steam-launcher.service"; +import { FileAssociationService } from "./services/file-association.service"; const isDebug = process.env.NODE_ENV === "development" || process.env.DEBUG_PROD === "true"; @@ -69,19 +70,29 @@ const initServicesMustBeInitialized = () => { BSLauncherService.getInstance(); } +const findDeepLinkInArgs = (args: string[]): string => { + return args.find(arg => DeepLinkService.getInstance().isDeepLink(arg)); +} + +const findAssociatedFileInArgs = (args: string[]): string => { + return args.find(arg => FileAssociationService.getInstance().isFileAssociated(arg)); +} + const gotTheLock = app.requestSingleInstanceLock(); if (!gotTheLock) { app.quit(); } else { app.on("second-instance", (_, argv) => { - const deepLink = argv.find(arg => DeepLinkService.getInstance().isDeepLink(arg)); + const deepLink = findDeepLinkInArgs(argv); + const associatedFile = findAssociatedFileInArgs(argv); - if (!deepLink) { - return; + if (deepLink) { + DeepLinkService.getInstance().dispatchLinkOpened(deepLink); + } else if (associatedFile) { + FileAssociationService.getInstance().handleFileAssociation(associatedFile); } - DeepLinkService.getInstance().dispatchLinkOpened(deepLink); }); app.on("window-all-closed", () => { @@ -90,25 +101,28 @@ if (!gotTheLock) { }) app.whenReady().then(() => { - + app.setAppUserModelId(APP_NAME); initServicesMustBeInitialized(); - - const deepLink = process.argv.find(arg => DeepLinkService.getInstance().isDeepLink(arg)); - if (!deepLink) { - createWindow(); - } else { + const deepLink = findDeepLinkInArgs(process.argv); + const associatedFile = findAssociatedFileInArgs(process.argv); + + if (deepLink) { DeepLinkService.getInstance().dispatchLinkOpened(deepLink); + } else if (associatedFile) { + FileAssociationService.getInstance().handleFileAssociation(associatedFile); + } else { + createWindow(); } - + SteamLauncherService.getInstance().restoreSteamVR(); - + // Log renderer errors ipcMain.on("log-error", (_, args: IpcRequest) => { log.error(args?.args); }); - + }).catch(log.error); } diff --git a/src/main/services/additional-content/local-playlists-manager.service.ts b/src/main/services/additional-content/local-playlists-manager.service.ts index 22881e54..a22d8e22 100644 --- a/src/main/services/additional-content/local-playlists-manager.service.ts +++ b/src/main/services/additional-content/local-playlists-manager.service.ts @@ -12,7 +12,7 @@ import { readFileSync } from "fs"; import { BeatSaverService } from "../thrid-party/beat-saver/beat-saver.service"; import { copy, copyFile, pathExists, realpath } from "fs-extra"; import { Progression, ensureFolderExist, pathExist } from "../../helpers/fs.helpers"; -import { IpcService } from "../ipc.service"; +import { FileAssociationService } from "../file-association.service"; export class LocalPlaylistsManagerService { private static instance: LocalPlaylistsManagerService; @@ -33,18 +33,18 @@ export class LocalPlaylistsManagerService { private readonly maps: LocalMapsManagerService; private readonly request: RequestService; private readonly deepLink: DeepLinkService; + private readonly fileAssociation: FileAssociationService; private readonly windows: WindowManagerService; private readonly bsaver: BeatSaverService; - private readonly ipc: IpcService; private constructor() { this.maps = LocalMapsManagerService.getInstance(); this.versions = BSLocalVersionService.getInstance(); this.request = RequestService.getInstance(); this.deepLink = DeepLinkService.getInstance(); + this.fileAssociation = FileAssociationService.getInstance(); this.windows = WindowManagerService.getInstance(); this.bsaver = BeatSaverService.getInstance(); - this.ipc = IpcService.getInstance(); this.deepLink.addLinkOpenedListener(this.DEEP_LINKS.BeatSaver, link => { log.info("DEEP-LINK RECEIVED FROM", this.DEEP_LINKS.BeatSaver, link); @@ -52,11 +52,16 @@ export class LocalPlaylistsManagerService { const bplistUrl = url.host === "playlist" ? url.pathname.replace("/", "") : ""; this.openOneClickDownloadPlaylistWindow(bplistUrl); }); + + this.fileAssociation.registerFileAssociation(".bplist", filePath => { + log.info("FILE ASSOCIATION RECEIVED", filePath); + this.openOneClickDownloadPlaylistWindow(filePath); + }); } private async getPlaylistsFolder(version?: BSVersion) { if (!version) { - throw "Playlists are not available to be linked yet"; + throw new Error("Playlists are not available to be linked yet"); } const versionFolder = await this.versions.getVersionPath(version); @@ -79,14 +84,14 @@ export class LocalPlaylistsManagerService { } return lastValueFrom(this.request.downloadFile(bslistSource, destFile)).then(res => res.data); } - - private async readPlaylistFile(path: string): Promise { - if (!(await pathExist(path))) { - throw `bplist file not exist at ${path}`; + + private async readPlaylistFile(filePath: string): Promise { + if (!(await pathExist(filePath))) { + throw new Error(`bplist file not exist at ${filePath}`); } - const rawContent = readFileSync(path).toString(); + const rawContent = readFileSync(filePath).toString(); return JSON.parse(rawContent); } @@ -102,8 +107,8 @@ export class LocalPlaylistsManagerService { const bpListFilePath = await this.installBPListFile(bpListUrl, version); const bpList = await this.readPlaylistFile(bpListFilePath); - - const progress: Progression = { + + const progress: Progression = { total: bpList.songs.length, current: 0, data: { diff --git a/src/main/services/file-association.service.ts b/src/main/services/file-association.service.ts new file mode 100644 index 00000000..c43795e9 --- /dev/null +++ b/src/main/services/file-association.service.ts @@ -0,0 +1,56 @@ +import { pathExistsSync } from "fs-extra"; +import path from "path"; +import log from "electron-log"; + +export class FileAssociationService { + private static instance: FileAssociationService; + + public static getInstance(): FileAssociationService { + if (!FileAssociationService.instance) { + FileAssociationService.instance = new FileAssociationService(); + } + return FileAssociationService.instance; + } + + private readonly listeners = new Map(); + + private constructor() {} + + private getAbsolutePath(filePath: string) { + return path.isAbsolute(filePath) ? filePath : path.join(process.cwd(), filePath); + } + + public registerFileAssociation(ext: ExtKey, fn: Listerner) { + if (!this.listeners.has(ext)) { + this.listeners.set(ext, [] as Listerner[]); + } + + this.listeners.get(ext).push(fn); + } + + public isFileAssociated(filePath: string): boolean { + const fileExt = path.extname(filePath) as ExtKey; + return this.listeners.has(fileExt); + } + + public handleFileAssociation(filePath: string) { + const absolutePath = this.getAbsolutePath(filePath); + + if(!pathExistsSync(absolutePath)) { + log.error(`[FileAssociationService] File not found: ${absolutePath}`); + return; + } + + const fileExt = path.extname(absolutePath) as ExtKey; + const listeners = this.listeners.get(fileExt); + + if (!listeners) { + log.error(`[FileAssociationService] No listeners for file: ${absolutePath}`); + return; + } + + listeners.forEach(listener => listener(this.getAbsolutePath(filePath))); + } +} +type ExtKey = `.${string}`; +type Listerner = (filePath: string) => void;