diff --git a/plugins/defs.d.ts b/plugins/defs.d.ts index c475fcf..7817f8b 100644 --- a/plugins/defs.d.ts +++ b/plugins/defs.d.ts @@ -38,7 +38,7 @@ export type LFMSettings = { listeningTo: boolean; ignoreSpotify: boolean; verboseLogging: boolean; - service: ServiceType; + service: ServiceType | undefined; // Service-specific settings librefmUsername?: string; librefmApiKey?: string; diff --git a/plugins/multi-scrobbler/src/changelog.ts b/plugins/multi-scrobbler/src/changelog.ts deleted file mode 100644 index 129eb2c..0000000 --- a/plugins/multi-scrobbler/src/changelog.ts +++ /dev/null @@ -1,61 +0,0 @@ -interface ChangelogEntry { - version: string; - date: string; - changes: string[]; -} - -export const changelog: ChangelogEntry[] = [ - { - version: "3.0.0", - date: "2025-01-21", - changes: [ - "Complete plugin rewrite with multi-service support", - "Added support for Last.fm, Libre.fm, and ListenBrainz", - "Replaced toast notifications with comprehensive console logging", - "Enhanced timestamp handling with proper start/end times", - "Improved error handling and retry logic", - "Added service validation and connection testing", - "New settings UI with per-service configuration", - "Better credential management for multiple services", - "Enhanced verbose logging for debugging", - "Improved activity updates with service detection", - "Added dynamic app name with track variables", - "Better album art handling and fallbacks", - "Comprehensive status monitoring and reporting", - ], - }, - { - version: "2.3.0", - date: "2025-09-19", - changes: [ - "1. I TRIED SO HARD 2. remove backend error 3. factor settings tab 4. factor V2 5. factor V3 6. factor V4 7. factor V5 8. factor V6 9. Full settings refactor :3", - ], - }, - { - version: "2.2.0", - date: "2025-09-13", - changes: ["Remember kids! Do not sniff crack!"], - }, - { - version: "2.0.0", - date: "2025-09-13", - changes: ["Fix settings scrolling"], - }, - { - version: "1.3.0", - date: "2025-09-13", - changes: ["fix reanimated"], - }, - { - version: "1.2.0", - date: "2025-09-13", - changes: ["test"], - }, - { - version: "1.1.0", - date: "2025-09-12", - changes: ["fixed reanimated issue??"], - }, -]; - -export const currentVersion = "3.0.0"; diff --git a/plugins/multi-scrobbler/src/constants.ts b/plugins/multi-scrobbler/src/constants.ts index 832f0b7..9fbb96b 100644 --- a/plugins/multi-scrobbler/src/constants.ts +++ b/plugins/multi-scrobbler/src/constants.ts @@ -50,7 +50,7 @@ const Constants = { listeningTo: true, ignoreSpotify: true, verboseLogging: false, - service: "lastfm" as ServiceType, + service: undefined as ServiceType | undefined, librefmUsername: "", librefmApiKey: "", listenbrainzUsername: "", diff --git a/plugins/multi-scrobbler/src/index.tsx b/plugins/multi-scrobbler/src/index.tsx index e2439dd..e024620 100644 --- a/plugins/multi-scrobbler/src/index.tsx +++ b/plugins/multi-scrobbler/src/index.tsx @@ -74,10 +74,16 @@ async function tryInitialize() { } async function validateAndInitialize() { + // Check if user has selected a service first + if (!currentSettings.service) { + log("No service selected. Please configure a service in plugin settings."); + return; + } + const serviceName = serviceFactory.getCurrentService().getServiceName(); // Make sure we have credentials for whatever service is selected - const service = currentSettings.service || "lastfm"; + const service = currentSettings.service; let hasCredentials = false; switch (service) { @@ -86,14 +92,11 @@ async function validateAndInitialize() { break; case "librefm": hasCredentials = !!( - (currentSettings.librefmUsername || currentSettings.username) && - (currentSettings.librefmApiKey || currentSettings.apiKey) + currentSettings.librefmUsername && currentSettings.librefmApiKey ); break; case "listenbrainz": - hasCredentials = !!( - currentSettings.listenbrainzUsername || currentSettings.username - ); + hasCredentials = !!currentSettings.listenbrainzUsername; break; } @@ -128,11 +131,16 @@ export default { log("Plugin loading..."); pluginState.pluginStopped = false; - // Show what we're starting with - const serviceName = serviceFactory.getCurrentService().getServiceName(); - log( - `Configuration: Service=${serviceName}, Update Interval=${currentSettings.timeInterval}s, Verbose=${currentSettings.verboseLogging}`, - ); + // Check if service is configured + if (!currentSettings.service) { + log("No service configured. Please select a service in plugin settings."); + } else { + // Show what we're starting with + const serviceName = serviceFactory.getCurrentService().getServiceName(); + log( + `Configuration: Service=${serviceName}, Update Interval=${currentSettings.timeInterval}s, Verbose=${currentSettings.verboseLogging}`, + ); + } // Add to sidebar if user wants it try { @@ -200,12 +208,16 @@ export default { // Switch services if needed if (oldService !== newService && newService) { - log(`Service changed from ${oldService} to ${newService}`); + log(`Service changed from ${oldService || "none"} to ${newService}`); await switchService(newService); - } else if (!pluginState.pluginStopped) { - // Just restart with the updated settings + } else if (!pluginState.pluginStopped && currentSettings.service) { + // Just restart with the updated settings (only if service is selected) log("Restarting with updated settings..."); await tryInitialize(); + } else if (!currentSettings.service) { + // Service was unselected, stop the plugin + log("Service unselected, stopping plugin..."); + stop(); } }, diff --git a/plugins/multi-scrobbler/src/services/LibreFmService.ts b/plugins/multi-scrobbler/src/services/LibreFmService.ts index 3ee57da..60bb69c 100644 --- a/plugins/multi-scrobbler/src/services/LibreFmService.ts +++ b/plugins/multi-scrobbler/src/services/LibreFmService.ts @@ -38,131 +38,137 @@ interface LibreFMTrack { } export class LibreFmService extends BaseService { - getServiceName(): string { - return "Libre.fm"; - } + getServiceName(): string { + return "Libre.fm"; + } - protected logVerbose(...args: any[]): void { - if (currentSettings.verboseLogging) { - console.log(`[${this.getServiceName()}] Verbose:`, ...args); - } + protected logVerbose(...args: any[]): void { + if (currentSettings.verboseLogging) { + console.log(`[${this.getServiceName()}] Verbose:`, ...args); } + } - async validateCredentials(): Promise { + async validateCredentials(): Promise { + try { + const username = currentSettings.librefmUsername; + const apiKey = currentSettings.librefmApiKey; + + if (!username || !apiKey) { + throw new Error("Username or API key not set for Libre.fm"); + } + + const params = new URLSearchParams({ + method: "user.getinfo", + user: username, + api_key: apiKey, + format: "json", + }); + + const url = `${Constants.SERVICES.librefm.baseUrl}?${params}`; + await this.makeRequest(url); + + this.log("Credentials validation successful"); + return true; + } catch (error) { + this.logError("Credentials validation failed:", error); + return false; + } + } + + async fetchLatestScrobble(): Promise { + try { + const username = currentSettings.librefmUsername; + const apiKey = currentSettings.librefmApiKey; + + if (!username || !apiKey) { + throw new Error("Username or API key not set for Libre.fm"); + } + + this.logVerbose("Fetching latest scrobble for user:", username); + + const params = new URLSearchParams({ + method: "user.getrecenttracks", + user: username, + api_key: apiKey, + limit: "1", + extended: "1", + format: "json", + }); + + const url = `${Constants.SERVICES.librefm.baseUrl}?${params}`; + const data: LibreFMResponse = await this.makeRequest(url); + + const lastTrack = data?.recenttracks?.track?.[0]; + if (!lastTrack) { + throw new Error("No tracks found"); + } + + this.logVerbose("Raw track data:", lastTrack); + + const isNowPlaying = Boolean(lastTrack["@attr"]?.nowplaying); + const trackTimestamp = lastTrack.date?.uts + ? parseInt(lastTrack.date.uts) + : Math.floor(Date.now() / 1000); + + let duration: number | null = null; + let endTime: number | null = null; + + // Fetch track duration if it's currently playing + if (isNowPlaying) { try { - const username = currentSettings.librefmUsername || currentSettings.username; - const apiKey = currentSettings.librefmApiKey || currentSettings.apiKey; + const trackInfoParams = new URLSearchParams({ + method: "track.getInfo", + track: lastTrack.name, + artist: lastTrack.artist.name, + api_key: apiKey, + format: "json", + }); - if (!username || !apiKey) { - throw new Error("Username or API key not set for Libre.fm"); + const trackInfoUrl = `${Constants.SERVICES.librefm.baseUrl}?${trackInfoParams}`; + const trackInfo: LibreFMResponse = + await this.makeRequest(trackInfoUrl); + + if (trackInfo?.track?.duration) { + duration = parseInt(trackInfo.track.duration); + if (duration > 0) { + // Duration is in milliseconds, convert to seconds + duration = Math.floor(duration / 1000); + endTime = trackTimestamp + duration; } - - const params = new URLSearchParams({ - method: "user.getinfo", - user: username, - api_key: apiKey, - format: "json", - }); - - const url = `${Constants.SERVICES.librefm.baseUrl}?${params}`; - await this.makeRequest(url); - - this.log("Credentials validation successful"); - return true; + } } catch (error) { - this.logError("Credentials validation failed:", error); - return false; - } - } - - async fetchLatestScrobble(): Promise { - try { - const username = currentSettings.librefmUsername || currentSettings.username; - const apiKey = currentSettings.librefmApiKey || currentSettings.apiKey; - - if (!username || !apiKey) { - throw new Error("Username or API key not set for Libre.fm"); - } - - this.logVerbose("Fetching latest scrobble for user:", username); - - const params = new URLSearchParams({ - method: "user.getrecenttracks", - user: username, - api_key: apiKey, - limit: "1", - extended: "1", - format: "json", - }); - - const url = `${Constants.SERVICES.librefm.baseUrl}?${params}`; - const data: LibreFMResponse = await this.makeRequest(url); - - const lastTrack = data?.recenttracks?.track?.[0]; - if (!lastTrack) { - throw new Error("No tracks found"); - } - - this.logVerbose("Raw track data:", lastTrack); - - const isNowPlaying = Boolean(lastTrack["@attr"]?.nowplaying); - const trackTimestamp = lastTrack.date?.uts ? parseInt(lastTrack.date.uts) : Math.floor(Date.now() / 1000); - - let duration: number | null = null; - let endTime: number | null = null; - - // Fetch track duration if it's currently playing - if (isNowPlaying) { - try { - const trackInfoParams = new URLSearchParams({ - method: "track.getInfo", - track: lastTrack.name, - artist: lastTrack.artist.name, - api_key: apiKey, - format: "json", - }); - - const trackInfoUrl = `${Constants.SERVICES.librefm.baseUrl}?${trackInfoParams}`; - const trackInfo: LibreFMResponse = await this.makeRequest(trackInfoUrl); - - if (trackInfo?.track?.duration) { - duration = parseInt(trackInfo.track.duration); - if (duration > 0) { - // Duration is in milliseconds, convert to seconds - duration = Math.floor(duration / 1000); - endTime = trackTimestamp + duration; - } - } - } catch (error) { - this.logVerbose("Failed to fetch track duration:", error); - } - } - - const albumArt = this.processAlbumArt( - lastTrack.image?.find(img => img.size === "large")?.["#text"] - ); - - const track: Track = { - name: lastTrack.name, - artist: lastTrack.artist.name, - album: lastTrack.album["#text"], - albumArt, - url: lastTrack.url, - date: lastTrack.date?.["#text"] ?? "now", - nowPlaying: isNowPlaying, - loved: lastTrack.loved === "1", - from: trackTimestamp, - to: endTime, - duration, - }; - - this.logVerbose("Processed track:", track); - this.log(`${isNowPlaying ? "Now playing" : "Last played"}:`, `${track.artist} - ${track.name}`); - - return track; - } catch (error) { - this.logError("Failed to fetch latest scrobble:", error); - throw error; + this.logVerbose("Failed to fetch track duration:", error); } + } + + const albumArt = this.processAlbumArt( + lastTrack.image?.find((img) => img.size === "large")?.["#text"], + ); + + const track: Track = { + name: lastTrack.name, + artist: lastTrack.artist.name, + album: lastTrack.album["#text"], + albumArt, + url: lastTrack.url, + date: lastTrack.date?.["#text"] ?? "now", + nowPlaying: isNowPlaying, + loved: lastTrack.loved === "1", + from: trackTimestamp, + to: endTime, + duration, + }; + + this.logVerbose("Processed track:", track); + this.log( + `${isNowPlaying ? "Now playing" : "Last played"}:`, + `${track.artist} - ${track.name}`, + ); + + return track; + } catch (error) { + this.logError("Failed to fetch latest scrobble:", error); + throw error; } + } } diff --git a/plugins/multi-scrobbler/src/services/ListenBrainzService.ts b/plugins/multi-scrobbler/src/services/ListenBrainzService.ts index ed32ec1..fb8e3b5 100644 --- a/plugins/multi-scrobbler/src/services/ListenBrainzService.ts +++ b/plugins/multi-scrobbler/src/services/ListenBrainzService.ts @@ -37,156 +37,171 @@ interface ListenBrainzPlayingNowResponse { } export class ListenBrainzService extends BaseService { - getServiceName(): string { - return "ListenBrainz"; - } + getServiceName(): string { + return "ListenBrainz"; + } - protected logVerbose(...args: any[]): void { - if (currentSettings.verboseLogging) { - console.log(`[${this.getServiceName()}] Verbose:`, ...args); + protected logVerbose(...args: any[]): void { + if (currentSettings.verboseLogging) { + console.log(`[${this.getServiceName()}] Verbose:`, ...args); + } + } + + async validateCredentials(): Promise { + try { + const username = currentSettings.listenbrainzUsername; + const token = currentSettings.listenbrainzToken; + + if (!username) { + throw new Error("Username not set for ListenBrainz"); + } + + // For ListenBrainz, we don't need a token to read public data + // But we can test the connection by fetching user listens + const url = `${Constants.SERVICES.listenbrainz.baseUrl}/user/${encodeURIComponent(username)}/listens?count=1`; + + const headers: Record = {}; + if (token) { + headers["Authorization"] = `Token ${token}`; + } + + await this.makeRequest(url, { headers }); + + this.log("Credentials validation successful"); + return true; + } catch (error) { + this.logError("Credentials validation failed:", error); + return false; + } + } + + async fetchLatestScrobble(): Promise { + try { + const username = currentSettings.listenbrainzUsername; + const token = currentSettings.listenbrainzToken; + + if (!username) { + throw new Error("Username not set for ListenBrainz"); + } + + this.logVerbose("Fetching latest scrobble for user:", username); + + // First check for currently playing track + let currentlyPlaying: ListenBrainzListen | null = null; + try { + const playingNowUrl = `${Constants.SERVICES.listenbrainz.baseUrl}/user/${encodeURIComponent(username)}/playing-now`; + const headers: Record = {}; + if (token) { + headers["Authorization"] = `Token ${token}`; } - } - async validateCredentials(): Promise { + const playingNowData: ListenBrainzPlayingNowResponse = + await this.makeRequest(playingNowUrl, { headers }); + if (playingNowData.listens && playingNowData.listens.length > 0) { + currentlyPlaying = playingNowData.listens[0]; + currentlyPlaying.playing_now = true; + } + } catch (error) { + this.logVerbose( + "No currently playing track or failed to fetch:", + error, + ); + } + + let latestListen: ListenBrainzListen; + + if (currentlyPlaying) { + latestListen = currentlyPlaying; + this.logVerbose("Using currently playing track"); + } else { + // Fetch recent listens + const url = `${Constants.SERVICES.listenbrainz.baseUrl}/user/${encodeURIComponent(username)}/listens?count=1`; + const headers: Record = {}; + if (token) { + headers["Authorization"] = `Token ${token}`; + } + + const data: ListenBrainzResponse = await this.makeRequest(url, { + headers, + }); + + if (!data.listens || data.listens.length === 0) { + throw new Error("No listens found"); + } + + latestListen = data.listens[0]; + this.logVerbose("Using latest completed listen"); + } + + this.logVerbose("Raw listen data:", latestListen); + + const isNowPlaying = Boolean(latestListen.playing_now); + const trackTimestamp = + latestListen.listened_at || Math.floor(Date.now() / 1000); + + let duration: number | null = null; + let endTime: number | null = null; + + // Extract duration from additional_info if available + if (latestListen.track_metadata.additional_info?.duration_ms) { + duration = Math.floor( + latestListen.track_metadata.additional_info.duration_ms / 1000, + ); + if (isNowPlaying && duration > 0) { + endTime = trackTimestamp + duration; + } + } + + // Try to get album art from MusicBrainz or other sources + const albumArt: string | null = null; + if (latestListen.track_metadata.additional_info?.release_mbid) { try { - const username = currentSettings.listenbrainzUsername || currentSettings.username; - const token = currentSettings.listenbrainzToken; - - if (!username) { - throw new Error("Username not set for ListenBrainz"); - } - - // For ListenBrainz, we don't need a token to read public data - // But we can test the connection by fetching user listens - const url = `${Constants.SERVICES.listenbrainz.baseUrl}/user/${encodeURIComponent(username)}/listens?count=1`; - - const headers: Record = {}; - if (token) { - headers["Authorization"] = `Token ${token}`; - } - - await this.makeRequest(url, { headers }); - - this.log("Credentials validation successful"); - return true; + // We could fetch cover art from Cover Art Archive, but for now we'll leave it null + // albumArt = `https://coverartarchive.org/release/${latestListen.track_metadata.additional_info.release_mbid}/front`; } catch (error) { - this.logError("Credentials validation failed:", error); - return false; + this.logVerbose("Failed to fetch album art:", error); } + } + + const track: Track = { + name: latestListen.track_metadata.track_name, + artist: latestListen.track_metadata.artist_name, + album: latestListen.track_metadata.release_name || "", + albumArt, + url: + latestListen.track_metadata.additional_info?.origin_url || + `https://listenbrainz.org/user/${username}`, + date: isNowPlaying + ? "now" + : new Date(trackTimestamp * 1000).toISOString(), + nowPlaying: isNowPlaying, + loved: false, // ListenBrainz doesn't have a direct "loved" concept + from: trackTimestamp, + to: endTime, + duration, + }; + + this.logVerbose("Processed track:", track); + this.log( + `${isNowPlaying ? "Now playing" : "Last played"}:`, + `${track.artist} - ${track.name}`, + ); + + return track; + } catch (error) { + this.logError("Failed to fetch latest listen:", error); + throw error; } + } - async fetchLatestScrobble(): Promise { - try { - const username = currentSettings.listenbrainzUsername || currentSettings.username; - const token = currentSettings.listenbrainzToken; - - if (!username) { - throw new Error("Username not set for ListenBrainz"); - } - - this.logVerbose("Fetching latest scrobble for user:", username); - - // First check for currently playing track - let currentlyPlaying: ListenBrainzListen | null = null; - try { - const playingNowUrl = `${Constants.SERVICES.listenbrainz.baseUrl}/user/${encodeURIComponent(username)}/playing-now`; - const headers: Record = {}; - if (token) { - headers["Authorization"] = `Token ${token}`; - } - - const playingNowData: ListenBrainzPlayingNowResponse = await this.makeRequest(playingNowUrl, { headers }); - if (playingNowData.listens && playingNowData.listens.length > 0) { - currentlyPlaying = playingNowData.listens[0]; - currentlyPlaying.playing_now = true; - } - } catch (error) { - this.logVerbose("No currently playing track or failed to fetch:", error); - } - - let latestListen: ListenBrainzListen; - - if (currentlyPlaying) { - latestListen = currentlyPlaying; - this.logVerbose("Using currently playing track"); - } else { - // Fetch recent listens - const url = `${Constants.SERVICES.listenbrainz.baseUrl}/user/${encodeURIComponent(username)}/listens?count=1`; - const headers: Record = {}; - if (token) { - headers["Authorization"] = `Token ${token}`; - } - - const data: ListenBrainzResponse = await this.makeRequest(url, { headers }); - - if (!data.listens || data.listens.length === 0) { - throw new Error("No listens found"); - } - - latestListen = data.listens[0]; - this.logVerbose("Using latest completed listen"); - } - - this.logVerbose("Raw listen data:", latestListen); - - const isNowPlaying = Boolean(latestListen.playing_now); - const trackTimestamp = latestListen.listened_at || Math.floor(Date.now() / 1000); - - let duration: number | null = null; - let endTime: number | null = null; - - // Extract duration from additional_info if available - if (latestListen.track_metadata.additional_info?.duration_ms) { - duration = Math.floor(latestListen.track_metadata.additional_info.duration_ms / 1000); - if (isNowPlaying && duration > 0) { - endTime = trackTimestamp + duration; - } - } - - // Try to get album art from MusicBrainz or other sources - const albumArt: string | null = null; - if (latestListen.track_metadata.additional_info?.release_mbid) { - try { - // We could fetch cover art from Cover Art Archive, but for now we'll leave it null - // albumArt = `https://coverartarchive.org/release/${latestListen.track_metadata.additional_info.release_mbid}/front`; - } catch (error) { - this.logVerbose("Failed to fetch album art:", error); - } - } - - const track: Track = { - name: latestListen.track_metadata.track_name, - artist: latestListen.track_metadata.artist_name, - album: latestListen.track_metadata.release_name || "", - albumArt, - url: latestListen.track_metadata.additional_info?.origin_url || - `https://listenbrainz.org/user/${username}`, - date: isNowPlaying ? "now" : new Date(trackTimestamp * 1000).toISOString(), - nowPlaying: isNowPlaying, - loved: false, // ListenBrainz doesn't have a direct "loved" concept - from: trackTimestamp, - to: endTime, - duration, - }; - - this.logVerbose("Processed track:", track); - this.log(`${isNowPlaying ? "Now playing" : "Last played"}:`, `${track.artist} - ${track.name}`); - - return track; - } catch (error) { - this.logError("Failed to fetch latest listen:", error); - throw error; - } - } - - protected getErrorMessage(error: any): string { + protected getErrorMessage(error: any): string { // ListenBrainz uses different error format - if (error.error) { - return error.error; - } - if (error.message) { - return error.message; - } - return error.toString() || "Unknown error"; + if (error.error) { + return error.error; } + if (error.message) { + return error.message; + } + return error.toString() || "Unknown error"; + } } diff --git a/plugins/multi-scrobbler/src/services/ServiceFactory.ts b/plugins/multi-scrobbler/src/services/ServiceFactory.ts index 34fa93e..6e64057 100644 --- a/plugins/multi-scrobbler/src/services/ServiceFactory.ts +++ b/plugins/multi-scrobbler/src/services/ServiceFactory.ts @@ -26,7 +26,13 @@ export class ServiceFactory { this.serviceInstances = new Map(); } - const type = serviceType || currentSettings.service || "lastfm"; + const type = serviceType || currentSettings.service; + + if (!type) { + throw new Error( + "[ServiceFactory] No service type specified and no default service configured", + ); + } if (!this.serviceInstances.has(type)) { this.serviceInstances.set(type, this.createService(type)); @@ -48,10 +54,9 @@ export class ServiceFactory { case "listenbrainz": return new ListenBrainzService(); default: - console.warn( - `[ServiceFactory] Unknown service type: ${serviceType}, falling back to Last.fm`, + throw new Error( + `[ServiceFactory] Unknown service type: ${serviceType}`, ); - return new LastFmService(); } } diff --git a/plugins/multi-scrobbler/src/ui/ChangelogView.tsx b/plugins/multi-scrobbler/src/ui/ChangelogView.tsx deleted file mode 100644 index c3c3344..0000000 --- a/plugins/multi-scrobbler/src/ui/ChangelogView.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { clipboard } from "@vendetta/metro/common"; -import { getAssetIDByName } from "@vendetta/ui/assets"; -import { Forms, General } from "@vendetta/ui/components"; -import { showToast } from "@vendetta/ui/toasts"; -import { changelog, currentVersion } from "../changelog"; -import { React } from "@vendetta/metro/common"; -import { findByProps } from "@vendetta/metro"; - -const { TableRowGroup, TableRow, Stack } = findByProps( - "TableSwitchRow", - "TableRowGroup", - "Stack", - "TableRow", -); -const { ScrollView } = General; - -export default function ChangelogView() { - return ( - - - - { - clipboard.setString(currentVersion); - showToast( - "Version copied to clipboard", - getAssetIDByName("toast_copy_link"), - ); - }} - > - - Copy - - - } - /> - - - - {changelog.map((entry, index) => ( - - - - Version {entry.version} - - - {entry.date} - - - {entry.changes.map((change, changeIndex) => ( - - • {change} - - ))} - - ))} - - - - ); -} diff --git a/plugins/multi-scrobbler/src/ui/pages/Settings.tsx b/plugins/multi-scrobbler/src/ui/pages/Settings.tsx index f833244..b5a43ee 100644 --- a/plugins/multi-scrobbler/src/ui/pages/Settings.tsx +++ b/plugins/multi-scrobbler/src/ui/pages/Settings.tsx @@ -35,7 +35,7 @@ plugin.storage.listenbrainzUsername ??= ""; plugin.storage.listenbrainzToken ??= ""; plugin.storage.addToSidebar ??= true; -const get = (k: string, fallback: any = "") => plugin.storage[k] ?? fallback; +const get = (k: string, fallback?: any) => plugin.storage[k] ?? fallback; const set = (k: string, v: any) => (plugin.storage[k] = v); // Last.fm Settings Page @@ -145,7 +145,7 @@ function LibreFmSettingsPage() { { set("librefmUsername", v); @@ -154,7 +154,7 @@ function LibreFmSettingsPage() { isClearable /> { set("librefmApiKey", v); @@ -422,7 +422,7 @@ export default function Settings() { const navigation = NavigationNative.useNavigation(); const [, forceUpdate] = React.useReducer((x) => x + 1, 0); - const currentService = get("service", "lastfm") as ServiceType; + const currentService = get("service") as ServiceType; const getCredentialStatus = (service: ServiceType) => { switch (service) { @@ -432,15 +432,14 @@ export default function Settings() { : "❌ Missing credentials"; } case "librefm": { - const librefmUser = get("librefmUsername") || get("username"); - const librefmKey = get("librefmApiKey") || get("apiKey"); - return librefmUser && librefmKey + return get("librefmUsername") && get("librefmApiKey") ? "✅ Configured" : "❌ Missing credentials"; } case "listenbrainz": { - const lbUser = get("listenbrainzUsername") || get("username"); - return lbUser ? "✅ Configured" : "❌ Missing username"; + return get("listenbrainzUsername") + ? "✅ Configured" + : "❌ Missing username"; } default: return "❓ Unknown"; @@ -454,7 +453,11 @@ export default function Settings() { {(["lastfm", "librefm", "listenbrainz"] as ServiceType[]).map( (service) => (