diff --git a/src/main/events/themes/copy-theme-achievement-sound.ts b/src/main/events/themes/copy-theme-achievement-sound.ts index aec22cb2..e2c927fd 100644 --- a/src/main/events/themes/copy-theme-achievement-sound.ts +++ b/src/main/events/themes/copy-theme-achievement-sound.ts @@ -18,7 +18,7 @@ const copyThemeAchievementSound = async ( throw new Error("Theme not found"); } - const themeDir = getThemePath(themeId); + const themeDir = getThemePath(themeId, theme.name); if (!fs.existsSync(themeDir)) { fs.mkdirSync(themeDir, { recursive: true }); diff --git a/src/main/events/themes/get-theme-sound-data-url.ts b/src/main/events/themes/get-theme-sound-data-url.ts index b9ace306..a93538dd 100644 --- a/src/main/events/themes/get-theme-sound-data-url.ts +++ b/src/main/events/themes/get-theme-sound-data-url.ts @@ -1,5 +1,6 @@ import { registerEvent } from "../register-event"; import { getThemeSoundPath } from "@main/helpers"; +import { themesSublevel } from "@main/level"; import fs from "node:fs"; import path from "node:path"; import { logger } from "@main/services"; @@ -9,7 +10,8 @@ const getThemeSoundDataUrl = async ( themeId: string ): Promise => { try { - const soundPath = getThemeSoundPath(themeId); + const theme = await themesSublevel.get(themeId); + const soundPath = getThemeSoundPath(themeId, theme?.name); if (!soundPath || !fs.existsSync(soundPath)) { return null; diff --git a/src/main/events/themes/get-theme-sound-path.ts b/src/main/events/themes/get-theme-sound-path.ts index 37783949..11658c6a 100644 --- a/src/main/events/themes/get-theme-sound-path.ts +++ b/src/main/events/themes/get-theme-sound-path.ts @@ -1,11 +1,13 @@ import { registerEvent } from "../register-event"; import { getThemeSoundPath } from "@main/helpers"; +import { themesSublevel } from "@main/level"; const getThemeSoundPathEvent = async ( _event: Electron.IpcMainInvokeEvent, themeId: string ): Promise => { - return getThemeSoundPath(themeId); + const theme = await themesSublevel.get(themeId); + return getThemeSoundPath(themeId, theme?.name); }; registerEvent("getThemeSoundPath", getThemeSoundPathEvent); diff --git a/src/main/events/themes/import-theme-sound-from-store.ts b/src/main/events/themes/import-theme-sound-from-store.ts index 135353b2..66da6cb3 100644 --- a/src/main/events/themes/import-theme-sound-from-store.ts +++ b/src/main/events/themes/import-theme-sound-from-store.ts @@ -28,7 +28,7 @@ const importThemeSoundFromStore = async ( timeout: 10000, }); - const themeDir = getThemePath(themeId); + const themeDir = getThemePath(themeId, theme.name); if (!fs.existsSync(themeDir)) { fs.mkdirSync(themeDir, { recursive: true }); diff --git a/src/main/events/themes/remove-theme-achievement-sound.ts b/src/main/events/themes/remove-theme-achievement-sound.ts index 4ca738f3..6c17bb6f 100644 --- a/src/main/events/themes/remove-theme-achievement-sound.ts +++ b/src/main/events/themes/remove-theme-achievement-sound.ts @@ -2,6 +2,7 @@ import { registerEvent } from "../register-event"; import fs from "node:fs"; import { getThemePath } from "@main/helpers"; import { themesSublevel } from "@main/level"; +import { THEMES_PATH } from "@main/constants"; import path from "node:path"; const removeThemeAchievementSound = async ( @@ -13,19 +14,27 @@ const removeThemeAchievementSound = async ( throw new Error("Theme not found"); } - const themeDir = getThemePath(themeId); + const themeDir = getThemePath(themeId, theme.name); + const legacyThemeDir = path.join(THEMES_PATH, themeId); - if (!fs.existsSync(themeDir)) { - return; - } - - const formats = ["wav", "mp3", "ogg", "m4a"]; - - for (const format of formats) { - const soundPath = path.join(themeDir, `achievement.${format}`); - if (fs.existsSync(soundPath)) { - await fs.promises.unlink(soundPath); + const removeFromDir = async (dir: string) => { + if (!fs.existsSync(dir)) { + return; } + + const formats = ["wav", "mp3", "ogg", "m4a"]; + + for (const format of formats) { + const soundPath = path.join(dir, `achievement.${format}`); + if (fs.existsSync(soundPath)) { + await fs.promises.unlink(soundPath); + } + } + }; + + await removeFromDir(themeDir); + if (themeDir !== legacyThemeDir) { + await removeFromDir(legacyThemeDir); } await themesSublevel.put(themeId, { diff --git a/src/main/helpers/index.ts b/src/main/helpers/index.ts index ae19fbdb..550db81f 100644 --- a/src/main/helpers/index.ts +++ b/src/main/helpers/index.ts @@ -38,23 +38,56 @@ export const normalizePath = (str: string) => export const addTrailingSlash = (str: string) => str.endsWith("/") ? str : `${str}/`; -export const getThemePath = (themeId: string) => - path.join(THEMES_PATH, themeId); +const sanitizeFolderName = (name: string): string => { + return name + .toLowerCase() + .replace(/[^a-z0-9-_\s]/g, "") + .replace(/\s+/g, "-") + .replace(/-+/g, "-") + .replace(/^-|-$/g, ""); +}; -export const getThemeSoundPath = (themeId: string): string | null => { - const themeDir = getThemePath(themeId); +export const getThemePath = (themeId: string, themeName?: string): string => { + if (themeName) { + const sanitizedName = sanitizeFolderName(themeName); + if (sanitizedName) { + return path.join(THEMES_PATH, sanitizedName); + } + } + return path.join(THEMES_PATH, themeId); +}; + +export const getThemeSoundPath = ( + themeId: string, + themeName?: string +): string | null => { + const themeDir = getThemePath(themeId, themeName); + const legacyThemeDir = themeName ? path.join(THEMES_PATH, themeId) : null; + + const checkDir = (dir: string): string | null => { + if (!fs.existsSync(dir)) { + return null; + } + + const formats = ["wav", "mp3", "ogg", "m4a"]; + + for (const format of formats) { + const soundPath = path.join(dir, `achievement.${format}`); + if (fs.existsSync(soundPath)) { + return soundPath; + } + } - if (!fs.existsSync(themeDir)) { return null; + }; + + const soundPath = checkDir(themeDir); + if (soundPath) { + return soundPath; } - const formats = ["wav", "mp3", "ogg", "m4a"]; - - for (const format of formats) { - const soundPath = path.join(themeDir, `achievement.${format}`); - if (fs.existsSync(soundPath)) { - return soundPath; - } + if (legacyThemeDir) { + return checkDir(legacyThemeDir); } return null; diff --git a/src/main/services/notifications/index.ts b/src/main/services/notifications/index.ts index 926ba47a..b8ff480c 100644 --- a/src/main/services/notifications/index.ts +++ b/src/main/services/notifications/index.ts @@ -47,7 +47,10 @@ async function getAchievementSoundPath(): Promise { const activeTheme = allThemes.find((theme) => theme.isActive); if (activeTheme?.hasCustomSound) { - const themeSoundPath = getThemeSoundPath(activeTheme.id); + const themeSoundPath = getThemeSoundPath( + activeTheme.id, + activeTheme.name + ); if (themeSoundPath) { return themeSoundPath; }