diff --git a/package.json b/package.json index 8ccf9443..d9751a9e 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "productName": "SubMiner", "executableName": "SubMiner", "artifactName": "SubMiner-${version}.${ext}", - "icon": "assets/SubMiner.png", + "icon": "assets/SubMiner-square.png", "directories": { "output": "release" }, @@ -142,7 +142,7 @@ "zip" ], "category": "public.app-category.video", - "icon": "assets/SubMiner.png", + "icon": "assets/SubMiner-square.png", "hardenedRuntime": true, "entitlements": "build/entitlements.mac.plist", "entitlementsInherit": "build/entitlements.mac.plist", diff --git a/src/core/services/yomitan-extension-paths.ts b/src/core/services/yomitan-extension-paths.ts index 5256b450..d6863edc 100644 --- a/src/core/services/yomitan-extension-paths.ts +++ b/src/core/services/yomitan-extension-paths.ts @@ -68,6 +68,15 @@ export function resolveExternalYomitanExtensionPath( return null; } - const candidate = path.join(path.resolve(normalizedProfilePath), 'extensions', 'yomitan'); - return existsSync(path.join(candidate, 'manifest.json')) ? candidate : null; + const candidate = path.join(normalizedProfilePath, 'extensions', 'yomitan'); + const fallbackCandidate = path.join(path.resolve(normalizedProfilePath), 'extensions', 'yomitan'); + + const candidates = candidate === fallbackCandidate ? [candidate] : [candidate, fallbackCandidate]; + for (const root of candidates) { + if (existsSync(path.join(root, 'manifest.json'))) { + return root; + } + } + + return null; } diff --git a/src/core/services/youtube/ytdlp-command.ts b/src/core/services/youtube/ytdlp-command.ts index 10996e15..a0731595 100644 --- a/src/core/services/youtube/ytdlp-command.ts +++ b/src/core/services/youtube/ytdlp-command.ts @@ -1,5 +1,44 @@ +import fs from 'node:fs'; +import path from 'node:path'; + const DEFAULT_YTDLP_COMMAND = 'yt-dlp'; +const WINDOWS_YTDLP_COMMANDS = ['yt-dlp.cmd', 'yt-dlp.exe', 'yt-dlp']; + +function resolveFromPath(commandName: string): string | null { + if (!process.env.PATH) { + return null; + } + + const searchPaths = process.env.PATH.split(path.delimiter); + for (const searchPath of searchPaths) { + const candidate = path.join(searchPath, commandName); + try { + fs.accessSync(candidate, fs.constants.X_OK); + return candidate; + } catch { + continue; + } + } + + return null; +} export function getYoutubeYtDlpCommand(): string { - return process.env.SUBMINER_YTDLP_BIN?.trim() || DEFAULT_YTDLP_COMMAND; + const explicitCommand = process.env.SUBMINER_YTDLP_BIN?.trim(); + if (explicitCommand) { + return explicitCommand; + } + + if (process.platform !== 'win32') { + return DEFAULT_YTDLP_COMMAND; + } + + for (const commandName of WINDOWS_YTDLP_COMMANDS) { + const resolved = resolveFromPath(commandName); + if (resolved) { + return resolved; + } + } + + return DEFAULT_YTDLP_COMMAND; }