Added Similar Artists
This commit is contained in:
@@ -396,8 +396,8 @@ class CacheManager(metaclass=Singleton):
|
||||
)
|
||||
|
||||
def filename_future_done(f):
|
||||
on_song_download_complete(song_id)
|
||||
self.download_limiter_semaphore.release()
|
||||
on_song_download_complete(song_id)
|
||||
|
||||
song_filename_future.add_done_callback(filename_future_done)
|
||||
|
||||
|
@@ -48,10 +48,15 @@
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#playlist-comment, #playlist-stats, #artist-bio, #artist-stats {
|
||||
#playlist-comment, #playlist-stats, #artist-bio, #artist-stats, #similar-artists {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#similar-artist-button {
|
||||
padding: 0;
|
||||
margin: -10px 0 0 10px;
|
||||
}
|
||||
|
||||
/* ********** Playback Controls ********** */
|
||||
#player-controls-album-artwork #player-controls-album-artwork {
|
||||
min-height: 70px;
|
||||
|
@@ -229,6 +229,18 @@ class ArtistDetailPanel(Gtk.Box):
|
||||
self.artist_bio.set_line_wrap(True)
|
||||
artist_details_box.add(self.artist_bio)
|
||||
|
||||
self.similar_artists_box = Gtk.Box(
|
||||
orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
self.similar_artists_label = self.make_label(name='similar-artists')
|
||||
self.similar_artists_box.add(self.similar_artists_label)
|
||||
|
||||
self.similar_artists_button_box = Gtk.Box(
|
||||
orientation=Gtk.Orientation.HORIZONTAL)
|
||||
self.similar_artists_box.add(self.similar_artists_button_box)
|
||||
|
||||
artist_details_box.add(self.similar_artists_box)
|
||||
|
||||
self.artist_stats = self.make_label(name='artist-stats')
|
||||
artist_details_box.add(self.artist_stats)
|
||||
|
||||
@@ -272,7 +284,22 @@ class ArtistDetailPanel(Gtk.Box):
|
||||
def update_artist_info(self, artist_info: ArtistInfo2):
|
||||
self.artist_bio.set_markup(util.esc(''.join(artist_info.biography)))
|
||||
|
||||
# TODO combine these two sources and prefer artist info version.
|
||||
if len(artist_info.similarArtist or []) > 0:
|
||||
self.similar_artists_label.set_markup('<b>Similar Artists:</b> ')
|
||||
for c in self.similar_artists_button_box.get_children():
|
||||
self.similar_artists_button_box.remove(c)
|
||||
|
||||
for artist in artist_info.similarArtist[:5]:
|
||||
self.similar_artists_button_box.add(
|
||||
Gtk.LinkButton(
|
||||
uri=f'artist://{artist.id}',
|
||||
label=artist.name,
|
||||
name='similar-artist-button',
|
||||
))
|
||||
self.similar_artists_box.show_all()
|
||||
else:
|
||||
self.similar_artists_box.hide()
|
||||
|
||||
@util.async_callback(
|
||||
lambda *a, **k: CacheManager.get_artist_artwork(*a, **k),
|
||||
before_download=lambda self: self.set_artwork_loading(True),
|
||||
|
@@ -25,13 +25,16 @@ class EditFormDialog(Gtk.Dialog):
|
||||
editing = existing_object is not None
|
||||
Gtk.Dialog.__init__(
|
||||
self,
|
||||
f'Edit {self.get_object_name(existing_object)}'
|
||||
title=f'Edit {self.get_object_name(existing_object)}'
|
||||
if editing else f'Create New {self.entity_name}',
|
||||
parent,
|
||||
0,
|
||||
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
||||
transient_for=parent,
|
||||
flags=0,
|
||||
)
|
||||
self.add_buttons(
|
||||
Gtk.STOCK_CANCEL,
|
||||
Gtk.ResponseType.CANCEL,
|
||||
Gtk.STOCK_EDIT if editing else Gtk.STOCK_ADD,
|
||||
Gtk.ResponseType.OK),
|
||||
Gtk.ResponseType.OK,
|
||||
)
|
||||
|
||||
if not existing_object:
|
||||
|
@@ -25,10 +25,10 @@ class EditServerDialog(EditFormDialog):
|
||||
]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
test_server = Gtk.Button('Test Connection to Server')
|
||||
test_server = Gtk.Button(label='Test Connection to Server')
|
||||
test_server.connect('clicked', self.on_test_server_clicked)
|
||||
|
||||
open_in_browser = Gtk.Button('Open in Browser')
|
||||
open_in_browser = Gtk.Button(label='Open in Browser')
|
||||
open_in_browser.connect('clicked', self.on_open_in_browser_clicked)
|
||||
|
||||
self.extra_buttons = [test_server, open_in_browser]
|
||||
@@ -47,16 +47,22 @@ class EditServerDialog(EditFormDialog):
|
||||
# Try to ping, and show a message box with whether or not it worked.
|
||||
try:
|
||||
server.ping()
|
||||
dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO,
|
||||
Gtk.ButtonsType.OK,
|
||||
'Connection to server successful.')
|
||||
dialog = Gtk.MessageDialog(
|
||||
transient_for=self,
|
||||
message_type=Gtk.MessageType.INFO,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text='Connection to server successful.',
|
||||
)
|
||||
dialog.format_secondary_markup(
|
||||
f"Connection to {self.data['Server address'].get_text()} successful."
|
||||
)
|
||||
except Exception as err:
|
||||
dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR,
|
||||
Gtk.ButtonsType.OK,
|
||||
'Connection to server unsuccessful.')
|
||||
dialog = Gtk.MessageDialog(
|
||||
transient_for=self,
|
||||
message_type=Gtk.MessageType.ERROR,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text='Connection to server unsuccessful.',
|
||||
)
|
||||
dialog.format_secondary_markup(
|
||||
f"Connection to {self.data['Server address'].get_text()} resulted in the following error:\n\n{err}"
|
||||
)
|
||||
@@ -77,7 +83,13 @@ class ConfigureServersDialog(Gtk.Dialog):
|
||||
}
|
||||
|
||||
def __init__(self, parent, config):
|
||||
Gtk.Dialog.__init__(self, 'Connect to Server', parent, 0, ())
|
||||
Gtk.Dialog.__init__(
|
||||
self,
|
||||
title='Connect to Server',
|
||||
transient_for=parent,
|
||||
flags=0,
|
||||
add_buttons=(),
|
||||
)
|
||||
|
||||
self.server_configs = config.servers
|
||||
self.selected_server_index = config.current_server
|
||||
|
@@ -78,6 +78,18 @@ def show_song_popover(
|
||||
show_remove_from_playlist_button: bool = False,
|
||||
extra_menu_items: List[Tuple[Gtk.ModelButton, Any]] = [],
|
||||
):
|
||||
def on_add_to_up_next_click(button):
|
||||
print('up next click')
|
||||
|
||||
def on_add_to_queue_click(button):
|
||||
print('add to queue click')
|
||||
|
||||
def on_go_to_album_click(button):
|
||||
print('go to album click')
|
||||
|
||||
def on_go_to_artist_click(button):
|
||||
print('go to artist click')
|
||||
|
||||
def on_download_songs_click(button):
|
||||
CacheManager.batch_download_songs(
|
||||
song_ids,
|
||||
@@ -99,26 +111,32 @@ def show_song_popover(
|
||||
song_count = len(song_ids)
|
||||
|
||||
# Determine if we should enable the download button.
|
||||
sensitive = False
|
||||
download_sensitive = False
|
||||
for song_id in song_ids:
|
||||
details = CacheManager.get_song_details(song_id)
|
||||
status = CacheManager.get_cached_status(details.result())
|
||||
if status == SongCacheStatus.NOT_CACHED:
|
||||
sensitive = True
|
||||
download_sensitive = True
|
||||
break
|
||||
|
||||
menu_items = [
|
||||
(Gtk.ModelButton(text='Add to up next'), None),
|
||||
(Gtk.ModelButton(text='Add to queue'), None),
|
||||
(Gtk.ModelButton(text='Add to up next'), on_add_to_up_next_click),
|
||||
(Gtk.ModelButton(text='Add to queue'), on_add_to_queue_click),
|
||||
(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), None),
|
||||
(Gtk.ModelButton(text='Go to album'), None),
|
||||
(Gtk.ModelButton(text='Go to artist'), None),
|
||||
(
|
||||
Gtk.ModelButton(text='Go to album', sensitive=len(song_ids) == 1),
|
||||
on_go_to_album_click,
|
||||
),
|
||||
(
|
||||
Gtk.ModelButton(text='Go to artist', sensitive=len(song_ids) == 1),
|
||||
on_go_to_artist_click,
|
||||
),
|
||||
(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), None),
|
||||
(
|
||||
Gtk.ModelButton(
|
||||
text=(f"Download {pluralize('song', song_count)}"
|
||||
if song_count > 1 else 'Download Song'),
|
||||
sensitive=sensitive,
|
||||
sensitive=download_sensitive,
|
||||
),
|
||||
on_download_songs_click,
|
||||
),
|
||||
|
Reference in New Issue
Block a user