diff --git a/backend/config.go b/backend/config.go index 18b56be..3c7af37 100644 --- a/backend/config.go +++ b/backend/config.go @@ -4,6 +4,7 @@ import ( "encoding/json" "os" "path/filepath" + "strings" ) func GetDefaultMusicPath() string { @@ -67,3 +68,34 @@ func GetSpotFetchAPISettings() (bool, string) { return true, apiURL } + +func GetLinkResolverSetting() string { + settings, err := LoadConfigSettings() + if err != nil || settings == nil { + return linkResolverProviderSongstats + } + + resolver, _ := settings["linkResolver"].(string) + switch strings.TrimSpace(strings.ToLower(resolver)) { + case "songlink", linkResolverProviderDeezerSongLink: + return linkResolverProviderDeezerSongLink + case "", "songstats": + return linkResolverProviderSongstats + default: + return linkResolverProviderSongstats + } +} + +func GetLinkResolverAllowFallback() bool { + settings, err := LoadConfigSettings() + if err != nil || settings == nil { + return true + } + + allowFallback, ok := settings["allowResolverFallback"].(bool) + if !ok { + return true + } + + return allowFallback +} diff --git a/backend/link_resolver.go b/backend/link_resolver.go index b614ab1..3eaf044 100644 --- a/backend/link_resolver.go +++ b/backend/link_resolver.go @@ -30,32 +30,23 @@ func (s *SongLinkClient) resolveSpotifyTrackLinks(spotifyTrackID string, region } if links.ISRC != "" { - resolvers := prioritizeProviders("link_resolver", []string{ - linkResolverProviderSongstats, - linkResolverProviderDeezerSongLink, - }) + resolvers := orderedLinkResolvers() for _, resolver := range resolvers { switch resolver { case linkResolverProviderSongstats: addedData, songstatsErr := s.resolveLinksViaSongstats(links) - if addedData { - recordProviderSuccess("link_resolver", linkResolverProviderSongstats) - } else if songstatsErr != nil { - recordProviderFailure("link_resolver", linkResolverProviderSongstats) - } if songstatsErr != nil { attempts = append(attempts, fmt.Sprintf("songstats: %v", songstatsErr)) + } else if addedData { + fmt.Println("Using Songstats as configured link resolver") } case linkResolverProviderDeezerSongLink: addedData, deezerSongLinkErr := s.resolveLinksViaDeezerSongLink(links, region) - if addedData { - recordProviderSuccess("link_resolver", linkResolverProviderDeezerSongLink) - } else if deezerSongLinkErr != nil { - recordProviderFailure("link_resolver", linkResolverProviderDeezerSongLink) - } if deezerSongLinkErr != nil { attempts = append(attempts, fmt.Sprintf("deezer-songlink: %v", deezerSongLinkErr)) + } else if addedData { + fmt.Println("Using Songlink as configured link resolver") } } @@ -76,6 +67,28 @@ func (s *SongLinkClient) resolveSpotifyTrackLinks(spotifyTrackID string, region return links, errors.New(strings.Join(attempts, " | ")) } +func orderedLinkResolvers() []string { + preferred := GetLinkResolverSetting() + if !GetLinkResolverAllowFallback() { + if preferred == linkResolverProviderDeezerSongLink { + return []string{linkResolverProviderDeezerSongLink} + } + return []string{linkResolverProviderSongstats} + } + + if preferred == linkResolverProviderDeezerSongLink { + return []string{ + linkResolverProviderDeezerSongLink, + linkResolverProviderSongstats, + } + } + + return []string{ + linkResolverProviderSongstats, + linkResolverProviderDeezerSongLink, + } +} + func (s *SongLinkClient) resolveLinksViaSongstats(links *resolvedTrackLinks) (bool, error) { if links == nil || links.ISRC == "" { return false, fmt.Errorf("ISRC is required for Songstats resolver") diff --git a/frontend/src/assets/icons/songlink.ico b/frontend/src/assets/icons/songlink.ico new file mode 100644 index 0000000..4fdec81 Binary files /dev/null and b/frontend/src/assets/icons/songlink.ico differ diff --git a/frontend/src/assets/icons/songstats.png b/frontend/src/assets/icons/songstats.png new file mode 100644 index 0000000..fc8a223 Binary files /dev/null and b/frontend/src/assets/icons/songstats.png differ diff --git a/frontend/src/components/SettingsPage.tsx b/frontend/src/components/SettingsPage.tsx index 77a2ece..6249ac3 100644 --- a/frontend/src/components/SettingsPage.tsx +++ b/frontend/src/components/SettingsPage.tsx @@ -14,6 +14,8 @@ import { SelectFolder, OpenConfigFolder } from "../../wailsjs/go/main/App"; import { toastWithSound as toast } from "@/lib/toast-with-sound"; import { ApiStatusTab } from "./ApiStatusTab"; import { AmazonIcon, QobuzIcon, TidalIcon } from "./PlatformIcons"; +import songlinkIcon from "@/assets/icons/songlink.ico"; +import songstatsIcon from "@/assets/icons/songstats.png"; interface SettingsPageProps { onUnsavedChangesChange?: (hasUnsavedChanges: boolean) => void; onResetRequest?: (resetFn: () => void) => void; @@ -230,6 +232,44 @@ export function SettingsPage({ onUnsavedChangesChange, onResetRequest, }: Settin