diff --git a/ui/controller/controller.go b/ui/controller/controller.go index 0c73893..ed80bb3 100644 --- a/ui/controller/controller.go +++ b/ui/controller/controller.go @@ -330,7 +330,8 @@ func (c *Controller) ShowSettingsDialog(themeUpdateCallbk func(), themeFiles map c.App.EQPresetManager, c.MainWindow, c.App.AutoEQManager, - c.App.ImageManager) + c.App.ImageManager, + c.ToastProvider) dlg.OnReplayGainSettingsChanged = func() { c.App.PlaybackManager.SetReplayGainOptions(c.App.Config.ReplayGain) } diff --git a/ui/dialogs/autoeqbrowser.go b/ui/dialogs/autoeqbrowser.go index d5ae1d1..a023622 100644 --- a/ui/dialogs/autoeqbrowser.go +++ b/ui/dialogs/autoeqbrowser.go @@ -20,13 +20,15 @@ import ( type AutoEQBrowser struct { SearchDialog *SearchDialog manager *backend.AutoEQManager + toastProvider ToastProvider allProfileResults []*mediaprovider.SearchResult OnProfileSelected func(*backend.AutoEQProfile) } -func NewAutoEQBrowser(manager *backend.AutoEQManager, im util.ImageFetcher) *AutoEQBrowser { +func NewAutoEQBrowser(manager *backend.AutoEQManager, im util.ImageFetcher, toastProvider ToastProvider) *AutoEQBrowser { ab := &AutoEQBrowser{ - manager: manager, + manager: manager, + toastProvider: toastProvider, } sd := NewSearchDialog( im, @@ -43,7 +45,6 @@ func (ab *AutoEQBrowser) fetchAllProfiles() error { ctx := context.Background() profiles, err := ab.manager.FetchIndex(ctx) if err != nil { - log.Printf("Error fetching AutoEQ index: %v", err) // Show empty results on error ab.allProfileResults = []*mediaprovider.SearchResult{} return fmt.Errorf("failed to fetch AutoEQ index: %w", err) @@ -83,14 +84,10 @@ func (ab *AutoEQBrowser) onSearched(query string) []*mediaprovider.SearchResult if ab.allProfileResults == nil { if err := ab.fetchAllProfiles(); err != nil { log.Printf("Failed to load AutoEQ profiles: %v", err) - // Return a single error result - return []*mediaprovider.SearchResult{ - { - Name: lang.L("Error loading AutoEQ profiles"), - ArtistName: lang.L("Check network connection and try again"), - Type: mediaprovider.ContentTypePlaylist, - }, - } + fyne.Do(func() { + ab.toastProvider.ShowErrorToast(lang.L("Error loading AutoEQ profiles")) + }) + return []*mediaprovider.SearchResult{} } } @@ -114,18 +111,20 @@ func (ab *AutoEQBrowser) SetOnDismiss(onDismiss func()) { func (ab *AutoEQBrowser) SetOnProfileSelected(callback func(*backend.AutoEQProfile)) { ab.OnProfileSelected = callback ab.SearchDialog.OnNavigateTo = func(_ mediaprovider.ContentType, profilePath string) { - // Fetch the full profile data - ctx := context.Background() - profile, err := ab.manager.FetchProfile(ctx, profilePath) - if err != nil { - log.Printf("Error fetching AutoEQ profile: %v", err) - // TODO: Show error dialog to user - return - } - - if ab.OnProfileSelected != nil { - ab.OnProfileSelected(profile) - } + go func() { + // Fetch the full profile data + profile, err := ab.manager.FetchProfile(context.Background(), profilePath) + fyne.Do(func() { + if err != nil { + log.Printf("Error loading AutoEQ profile: %v", err) + ab.toastProvider.ShowErrorToast(lang.L("Error loading AutoEQ profile")) + } else { + if ab.OnProfileSelected != nil { + ab.OnProfileSelected(profile) + } + } + }) + }() } } @@ -148,21 +147,3 @@ func (ab *AutoEQBrowser) Hide() { func (ab *AutoEQBrowser) Refresh() { ab.SearchDialog.Refresh() } - -// ShowErrorDialog displays an error message to the user -func ShowAutoEQError(window fyne.Window, err error) { - title := lang.L("Error") - message := lang.L("Failed to load profile") - - if err == backend.ErrProfileNotFound { - message = lang.L("Profile not found") - } else if strings.Contains(err.Error(), "context deadline exceeded") || - strings.Contains(err.Error(), "connection") { - message = lang.L("Network error. Check connection.") - } - - // Use a simple dialog (would need to import "fyne.io/fyne/v2/dialog") - // For now just log it - log.Printf("AutoEQ Error: %s - %v", message, err) - fmt.Printf("%s: %s\n", title, message) -} diff --git a/ui/dialogs/settingsdialog.go b/ui/dialogs/settingsdialog.go index 2d30438..fe7bfa5 100644 --- a/ui/dialogs/settingsdialog.go +++ b/ui/dialogs/settingsdialog.go @@ -50,12 +50,18 @@ type SettingsDialog struct { autoEQManager *backend.AutoEQManager imageManager util.ImageFetcher window fyne.Window + toastProvider ToastProvider clientDecidesScrobble bool content fyne.CanvasObject } +type ToastProvider interface { + ShowSuccessToast(message string) + ShowErrorToast(message string) +} + // TODO: having this depend on the mpv package for the AudioDevice type is kinda gross. Refactor. func NewSettingsDialog( config *backend.Config, @@ -71,6 +77,7 @@ func NewSettingsDialog( window fyne.Window, autoEQManager *backend.AutoEQManager, imageManager util.ImageFetcher, + toastProvider ToastProvider, ) *SettingsDialog { s := &SettingsDialog{ config: config, @@ -81,6 +88,7 @@ func NewSettingsDialog( autoEQManager: autoEQManager, imageManager: imageManager, window: window, + toastProvider: toastProvider, } s.ExtendBaseWidget(s) @@ -587,7 +595,7 @@ func (s *SettingsDialog) openAutoEQBrowser(geq *GraphicEqualizer, debouncer func return } - browser := NewAutoEQBrowser(s.autoEQManager, s.imageManager) + browser := NewAutoEQBrowser(s.autoEQManager, s.imageManager, s.toastProvider) // Show in a modal popup dialog var popup *widget.PopUp