From 1a8859d4a25fc6a2546fcdb114a4b6bd5b3c4eb5 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 9 Apr 2024 09:11:58 +0200 Subject: [PATCH] add right-click / long-press dialog/bottom sheet for video feed items can be used to play the video, view channel info, open the video in the browser or add it to a playlist this should be the preferred way to playlist a video, because it doesn't add said video to the history --- melon/widgets/feeditem.py | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/melon/widgets/feeditem.py b/melon/widgets/feeditem.py index 589bad3..ddeba42 100644 --- a/melon/widgets/feeditem.py +++ b/melon/widgets/feeditem.py @@ -10,6 +10,8 @@ from melon.models import PlaylistWrapperType,PlaylistWrapper import threading from melon.background import queue from unidecode import unidecode +from gettext import gettext as _ +from melon.utils import pass_me, many class AdaptiveFeedItem(Adw.ActionRow): """ @@ -21,6 +23,7 @@ class AdaptiveFeedItem(Adw.ActionRow): self.show_preview = show_preview self.clickable = clickable self.onClick = onClick + self.menuitems = [] self.update() def set_resource(self, resource: Resource): self.res = resource @@ -42,6 +45,17 @@ class AdaptiveFeedItem(Adw.ActionRow): self.set_subtitle(unidecode(resource.channel[0]).replace("&","&")) if self.onClick is None: self.set_action_name("win.player") + # only videos support rightclickt/long press + # to show a dialog/bottom sheet with options + click_ctr = Gtk.GestureClick() + # set the click gesture handler to only listen for right clicks + click_ctr.set_button(3) + self.add_controller(click_ctr) + click_ctr.connect("pressed", lambda e,n,x,y: self._show_video_bottom_sheet()) + long_ctr = Gtk.GestureLongPress() + self.add_controller(long_ctr) + long_ctr.connect("pressed", lambda e,x,y: self._show_video_bottom_sheet()) + elif isinstance(resource, Playlist): thumb_url = resource.thumbnail self.set_title(unidecode(resource.title).replace("&","&")) @@ -88,6 +102,40 @@ class AdaptiveFeedItem(Adw.ActionRow): # return false to cancel the idle job return False + def _show_video_bottom_sheet(self): + if not isinstance(self.res, Video): + return + diag = Adw.Dialog() + diag.set_can_close(True) + diag.present(self) + tbv = Adw.ToolbarView() + hb = Adw.HeaderBar() + tbv.add_top_bar(hb) + diag.set_child(tbv); + page = Adw.PreferencesPage() + group = Adw.PreferencesGroup() + group.set_title(self.res.title) + group.set_description(self.res.channel[0]) + # add predefined options to list + predefined = [ + (_("Watch now"), lambda: self.activate_action("win.player", GLib.Variant("as", [self.res.server, self.res.id]))), + (_("Add to playlist"), lambda: self.activate_action("win.add_to_playlist", GLib.Variant("as", [self.res.server, self.res.id]))), + (_("Open in browser"), lambda: Gtk.UriLauncher.new(uri=self.res.url).launch()), + (_("View channel"), lambda: self.activate_action("win.browse_channel", GLib.Variant("as", [self.res.server, self.res.channel[1]]))) + ] + # add predefined list before custom menu entries and add them + for dt in predefined + self.menuitems: + row = Adw.ActionRow() + row.set_title(dt[0]) + row.set_activatable(True) + # run callback & close dialog on click + row.connect("activated", pass_me(lambda _, cb: many( + cb(), + diag.close() + ), dt[1])) + group.add(row) + page.add(group) + tbv.set_content(page) class AdaptivePlaylistFeedItem(Adw.ActionRow): def __init__(self, playlist:PlaylistWrapper, show_preview=True, onClick=None, *args, **kwargs): -- 2.38.5