diff --git a/js/themeStore.js b/js/themeStore.js index 89ed5cd..009f673 100644 --- a/js/themeStore.js +++ b/js/themeStore.js @@ -2,7 +2,37 @@ import { syncManager } from './accounts/pocketbase.js'; import { authManager } from './accounts/auth.js'; import { navigate } from './router.js'; +const THEMES_PER_PAGE = 50; + +const GENERIC_FONT_FAMILIES = [ + 'serif', + 'sans-serif', + 'monospace', + 'cursive', + 'fantasy', + 'system-ui', + 'inter', + 'ibm plex mono', + 'roboto', + 'open sans', + 'lato', + 'montserrat', + 'poppins', + 'apple music', + 'sf pro display', + 'courier new', + 'times new roman', + 'arial', + 'helvetica', + 'verdana', + 'tahoma', + 'trebuchet ms', + 'impact', + 'gill sans', +]; + export class ThemeStore { + static EXPECTED_USER_ID_LENGTH = 15; constructor() { this.pb = syncManager.pb; this.modal = document.getElementById('theme-store-modal'); @@ -119,7 +149,7 @@ export class ThemeStore { } try { - const result = await this.pb.collection('themes').getList(1, 50, { + const result = await this.pb.collection('themes').getList(1, THEMES_PER_PAGE, { sort: '-created', filter: query ? `name ~ "${query}" || description ~ "${query}"` : '', expand: 'author', @@ -375,33 +405,7 @@ export class ThemeStore { const fontFamilyValue = fontMatch[1].trim(); const mainFont = fontFamilyValue.split(',')[0].trim().replace(/['"]/g, ''); - const genericFamilies = [ - 'serif', - 'sans-serif', - 'monospace', - 'cursive', - 'fantasy', - 'system-ui', - 'inter', - 'ibm plex mono', - 'roboto', - 'open sans', - 'lato', - 'montserrat', - 'poppins', - 'apple music', - 'sf pro display', - 'courier new', - 'times new roman', - 'arial', - 'helvetica', - 'verdana', - 'tahoma', - 'trebuchet ms', - 'impact', - 'gill sans', - ]; - const isPresetOrGeneric = genericFamilies.some((generic) => mainFont.toLowerCase() === generic); + const isPresetOrGeneric = GENERIC_FONT_FAMILIES.some((generic) => mainFont.toLowerCase() === generic); if (!isPresetOrGeneric) { const FONT_LINK_ID = 'monochrome-dynamic-font'; @@ -460,6 +464,7 @@ export class ThemeStore { document.querySelectorAll('.theme-option').forEach((el) => el.classList.remove('active')); document.querySelector('[data-theme="custom"]')?.classList.add('active'); + // Force reflow to ensure theme changes are applied immediately document.documentElement.style.display = 'none'; document.documentElement.offsetHeight; document.documentElement.style.display = ''; @@ -526,9 +531,9 @@ export class ThemeStore { userId = dbUser.id; userName = dbUser.username || dbUser.display_name || fbUser.email; - if (userId.length !== 15) { + if (userId.length !== ThemeStore.EXPECTED_USER_ID_LENGTH) { throw new Error( - `Your user ID is corrupted (${userId.length} chars, expected 15). ` + + `Your user ID is corrupted (${userId.length} chars, expected ${ThemeStore.EXPECTED_USER_ID_LENGTH}). ` + `Please go to Settings > System > Clear Cloud Data, then log out and back in.` ); } @@ -581,8 +586,9 @@ export class ThemeStore { alert(msg); } else { const message = err.message || err.data?.message || 'Unknown error'; - const debugInfo = `\n\nDebug: User ID: ${userId} (${userId?.length} chars) | Status: ${err.status}`; - alert(`Failed to upload theme: ${message}${debugInfo}`); + const debugInfo = `User ID: ${userId} (${userId?.length} chars) | Status: ${err.status}`; + console.error('Upload failed (debug info):', debugInfo); + alert(`Failed to upload theme: ${message}`); } } } diff --git a/js/visualizers/kawarp.js b/js/visualizers/kawarp.js index 02f8503..a147ac6 100644 --- a/js/visualizers/kawarp.js +++ b/js/visualizers/kawarp.js @@ -13,10 +13,12 @@ const KAWARP_DEFAULTS = { const BEAT_THRESHOLD = 0.75; const SPEED_MULTIPLIER = 4; const SCALE_BOOST_PCT = 2; +const BOOSTED_SCALE = KAWARP_DEFAULTS.scale + SCALE_BOOST_PCT / 100; const SCALE_LERP_UP = 0.5; const SCALE_LERP_DOWN = 0.12; const SCALE_THRESHOLD = 0.001; const ANALYSIS_INTERVAL = 100; +const CACHE_BUST_PARAM = 'not-from-cache-please'; export class KawarpPreset { constructor() { @@ -115,7 +117,7 @@ export class KawarpPreset { // cached non-CORS response from the tag (same pattern as ui.js) const sep = url.includes('?') ? '&' : '?'; this.kawarp - .loadImage(`${url}${sep}not-from-cache-please`) + .loadImage(`${url}${sep}${CACHE_BUST_PARAM}`) .catch((err) => console.warn('[Kawarp] Failed to load cover:', err)); } @@ -149,7 +151,7 @@ export class KawarpPreset { ? KAWARP_DEFAULTS.animationSpeed * SPEED_MULTIPLIER : KAWARP_DEFAULTS.animationSpeed; - this._targetScale = isBeat ? KAWARP_DEFAULTS.scale + SCALE_BOOST_PCT / 100 : KAWARP_DEFAULTS.scale; + this._targetScale = isBeat ? BOOSTED_SCALE : KAWARP_DEFAULTS.scale; this._lastAnalysisTime = now; }