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