From f62eccf38eb8e85099199ee1e069302b4d47891c Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 29 Feb 2024 14:58:29 +0100 Subject: [PATCH] load thumbnails on separate thread --- melon/background.py | 25 +++++++++++++++++++ melon/widgets/feeditem.py | 51 +++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 melon/background.py diff --git a/melon/background.py b/melon/background.py new file mode 100644 index 0000000..ed131dd --- /dev/null +++ b/melon/background.py @@ -0,0 +1,25 @@ +import threading +from time import sleep + +class Queue(): + tasks = [] + thread = None + starting = False + def __init__(self, workers=1): + for i in range(workers): + self.thread = threading.Thread(target=self.run, name=str(i)) + self.thread.daemon = True + self.thread.start() + def run(self): + while True: + while not self.tasks: + sleep(1) + task = self.tasks.pop(0) + func = task[0] + args = task[1] + # run task + func(*args) + def add(self, func, *args): + self.tasks.append((func, args)) + +queue = Queue(1) diff --git a/melon/widgets/feeditem.py b/melon/widgets/feeditem.py index bb76458..2aa337f 100644 --- a/melon/widgets/feeditem.py +++ b/melon/widgets/feeditem.py @@ -7,6 +7,8 @@ from melon.servers import Resource,Video,Playlist,Channel from melon.servers.utils import pixbuf_from_url from melon.widgets.iconbutton import IconButton from melon.models import PlaylistWrapperType,PlaylistWrapper +import threading +from melon.background import queue class AdaptiveFeedItem(Adw.ActionRow): """ @@ -14,16 +16,30 @@ class AdaptiveFeedItem(Adw.ActionRow): """ def __init__(self, resource:Resource, show_preview=True, clickable=True, *args, **kwargs): super().__init__(*args, **kwargs) - pixbuf = None + self.res = resource + self.show_preview = show_preview + self.clickable = clickable + self.update() + def set_resource(self, resource: Resource): + self.res = resource + self.update() + def update(self): + if self.res is None: + return + resource = self.res + show_preview = self.show_preview + clickable = self.clickable + self.set_activatable(clickable) + self.set_action_target_value( + GLib.Variant("as", [resource.server, resource.id])) + thumb_url = None if isinstance(resource, Video): - if show_preview: - pixbuf = pixbuf_from_url(resource.thumbnail) + thumb_url = resource.thumbnail self.set_title(resource.title.replace("&","&")) self.set_subtitle(resource.channel[0].replace("&","&")) self.set_action_name("win.player") elif isinstance(resource, Playlist): - if show_preview: - pixbuf = pixbuf_from_url(resource.thumbnail) + thumb_url = resource.thumbnail self.set_title(resource.title.replace("&","&")) pad = "" if len(resource.description) > 80: @@ -32,8 +48,7 @@ class AdaptiveFeedItem(Adw.ActionRow): self.set_subtitle(sub.replace("&","&")) self.set_action_name("win.browse_playlist") elif isinstance(resource, Channel): - if show_preview: - pixbuf = pixbuf_from_url(resource.avatar) + thumb_url = resource.avatar self.set_title(resource.name.replace("&","&")) pad = "" if len(resource.bio) > 80: @@ -43,16 +58,22 @@ class AdaptiveFeedItem(Adw.ActionRow): self.set_action_name("win.browse_channel") self.preview = Adw.Avatar() self.preview.set_size(48) + self.preview.set_show_initials(True) + self.preview.set_text(self.get_title()) + self.add_prefix(self.preview) + if show_preview: + queue.add(self.update_avatar, thumb_url) + + def update_avatar(self, url): + pixbuf = pixbuf_from_url(url) if not pixbuf is None: texture = Gdk.Texture.new_for_pixbuf(pixbuf) - self.preview.set_custom_image(texture) - else: - self.preview.set_show_initials(True) - self.preview.set_text(self.get_title()) - self.add_prefix(self.preview) - self.set_activatable(clickable) - self.set_action_target_value( - GLib.Variant("as", [resource.server, resource.id])) + GLib.idle_add(self.complete_avatar, texture) + def complete_avatar(self, texture): + self.preview.set_custom_image(texture) + # return false to cancel the idle job + return False + class AdaptivePlaylistFeedItem(Adw.ActionRow): def __init__(self, playlist:PlaylistWrapper, show_preview=True, *args, **kwargs): -- 2.38.5