diff --git a/sublime/ui/app_styles.css b/sublime/ui/app_styles.css index 18a4816..133030d 100644 --- a/sublime/ui/app_styles.css +++ b/sublime/ui/app_styles.css @@ -221,7 +221,8 @@ #load-error-image, #load-error-label { - margin-bottom: 10px; + margin-bottom: 5px; + margin-right: 20px; } /* ********** Artists & Albums ********** */ diff --git a/sublime/ui/artists.py b/sublime/ui/artists.py index 46dfeeb..f7d290c 100644 --- a/sublime/ui/artists.py +++ b/sublime/ui/artists.py @@ -141,7 +141,9 @@ class ArtistList(Gtk.Box): "Artist list", "load artists", has_data=len(artists) > 0, - offline_mode=self._app_config.offline_mode, + offline_mode=( + self._app_config.offline_mode if self._app_config else False + ), ) self.error_container.pack_start(load_error, True, True, 0) self.error_container.show_all() @@ -300,6 +302,9 @@ class ArtistDetailPanel(Gtk.Box): self.pack_start(self.big_info_panel, False, True, 0) + self.error_container = Gtk.Box() + self.add(self.error_container) + self.album_list_scrolledwindow = Gtk.ScrolledWindow() self.albums_list = AlbumsListWithSongs() self.albums_list.connect( @@ -310,6 +315,7 @@ class ArtistDetailPanel(Gtk.Box): def update(self, app_config: AppConfiguration): self.artist_id = app_config.state.selected_artist_id + self.offline_mode = app_config.offline_mode if app_config.state.selected_artist_id is None: self.big_info_panel.hide() self.album_list_scrolledwindow.hide() @@ -322,8 +328,8 @@ class ArtistDetailPanel(Gtk.Box): app_config=app_config, order_token=self.update_order_token, ) - self.refresh_button.set_sensitive(not app_config.offline_mode) - self.download_all_button.set_sensitive(not app_config.offline_mode) + self.refresh_button.set_sensitive(not self.offline_mode) + self.download_all_button.set_sensitive(not self.offline_mode) @util.async_callback( AdapterManager.get_artist, @@ -398,6 +404,24 @@ class ArtistDetailPanel(Gtk.Box): artist.artist_image_url, force=force, order_token=order_token, ) + for c in self.error_container.get_children(): + self.error_container.remove(c) + if is_partial: + has_data = len(artist.albums or []) > 0 + load_error = LoadError( + "Artist data", + "load artist details", + has_data=has_data, + offline_mode=self.offline_mode, + ) + self.error_container.pack_start(load_error, True, True, 0) + self.error_container.show_all() + if not has_data: + self.album_list_scrolledwindow.hide() + else: + self.error_container.hide() + self.album_list_scrolledwindow.show() + self.albums = artist.albums or [] self.albums_list.update(artist, app_config, force=force) diff --git a/sublime/ui/common/load_error.py b/sublime/ui/common/load_error.py index e283619..d505510 100644 --- a/sublime/ui/common/load_error.py +++ b/sublime/ui/common/load_error.py @@ -15,7 +15,9 @@ class LoadError(Gtk.Box): inner_box.pack_start(Gtk.Box(), True, True, 0) - error_description_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + error_and_button_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + + icon_and_button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) if offline_mode: icon_name = "cloud-offline-symbolic" @@ -27,30 +29,28 @@ class LoadError(Gtk.Box): image = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.DIALOG) image.set_name("load-error-image") - error_description_box.add(image) + icon_and_button_box.add(image) - error_description_box.add( - Gtk.Label( - label=label, justify=Gtk.Justification.CENTER, name="load-error-label" - ) - ) + icon_and_button_box.add(Gtk.Label(label=label, name="load-error-label")) - box = Gtk.Box() - box.pack_start(Gtk.Box(), True, True, 0) + error_and_button_box.add(icon_and_button_box) + + button_centerer_box = Gtk.Box() + button_centerer_box.pack_start(Gtk.Box(), True, True, 0) if offline_mode: go_online_button = Gtk.Button(label="Go Online") go_online_button.set_action_name("app.go-online") - box.add(go_online_button) + button_centerer_box.add(go_online_button) else: retry_button = Gtk.Button(label="Retry") retry_button.set_action_name("app.refresh-window") - box.add(retry_button) + button_centerer_box.add(retry_button) - box.pack_start(Gtk.Box(), True, True, 0) - error_description_box.add(box) + button_centerer_box.pack_start(Gtk.Box(), True, True, 0) + error_and_button_box.add(button_centerer_box) - inner_box.add(error_description_box) + inner_box.add(error_and_button_box) inner_box.pack_start(Gtk.Box(), True, True, 0) diff --git a/sublime/ui/icons/cloud-offline-symbolic.svg b/sublime/ui/icons/cloud-offline-symbolic.svg index ad06dae..7fc2dc7 100644 --- a/sublime/ui/icons/cloud-offline-symbolic.svg +++ b/sublime/ui/icons/cloud-offline-symbolic.svg @@ -1,3 +1,3 @@ - + diff --git a/sublime/ui/playlists.py b/sublime/ui/playlists.py index 90134a8..bc0d528 100644 --- a/sublime/ui/playlists.py +++ b/sublime/ui/playlists.py @@ -370,8 +370,11 @@ class PlaylistDetailPanel(Gtk.Overlay): self.playlist_box.add(playlist_info_box) + self.error_container = Gtk.Box() + self.playlist_box.add(self.error_container) + # Playlist songs list - playlist_view_scroll_window = Gtk.ScrolledWindow() + self.playlist_song_scroll_window = Gtk.ScrolledWindow() self.playlist_song_store = Gtk.ListStore( bool, # clickable @@ -442,9 +445,9 @@ class PlaylistDetailPanel(Gtk.Overlay): ) self.playlist_song_store.connect("row-deleted", self.on_playlist_model_row_move) - playlist_view_scroll_window.add(self.playlist_songs) + self.playlist_song_scroll_window.add(self.playlist_songs) - self.playlist_box.pack_start(playlist_view_scroll_window, True, True, 0) + self.playlist_box.pack_start(self.playlist_song_scroll_window, True, True, 0) self.add(self.playlist_box) playlist_view_spinner = Gtk.Spinner(active=True) @@ -543,6 +546,24 @@ class PlaylistDetailPanel(Gtk.Overlay): # Update the artwork. self.update_playlist_artwork(playlist.cover_art, order_token=order_token) + for c in self.error_container.get_children(): + self.error_container.remove(c) + if is_partial: + has_data = len(playlist.songs) > 0 + load_error = LoadError( + "Playlist data", + "load playlist details", + has_data=has_data, + offline_mode=self.offline_mode, + ) + self.error_container.pack_start(load_error, True, True, 0) + self.error_container.show_all() + if not has_data: + self.playlist_song_scroll_window.hide() + else: + self.error_container.hide() + self.playlist_song_scroll_window.show() + # Update the song list model. This requires some fancy diffing to # update the list. self.editing_playlist_song_list = True