~comcloudway/melon

f62eccf38eb8e85099199ee1e069302b4d47891c — Jakob Meier 6 months ago 9d70ecd
load thumbnails on separate thread
2 files changed, 61 insertions(+), 15 deletions(-)

A melon/background.py
M melon/widgets/feeditem.py
A melon/background.py => melon/background.py +25 -0
@@ 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)

M melon/widgets/feeditem.py => melon/widgets/feeditem.py +36 -15
@@ 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):