~comcloudway/melon

a3d902414456383664c76261dc79e0ed939826fd — Jakob Meier 6 months ago 855c9c9
add edit button for local playlists

The edit screen allows the user to change the playlist name and
description.

Additionally it allows the user the delete the playlist.
A confirmation dialog is shown before actually deleting the playlist.
Once confirmed, the playlist screen is closed and then the playlist is
deleted. This is done, so that the playlist-change doesn't reach the
playlist viewer
3 files changed, 137 insertions(+), 4 deletions(-)

M melon/playlist/__init__.py
M melon/playlist/create.py
M melon/widgets/simpledialog.py
M melon/playlist/__init__.py => melon/playlist/__init__.py +133 -3
@@ 10,7 10,8 @@ from melon.servers.utils import get_servers_list, get_server_instance
from melon.servers import Preference, PreferenceType
from melon.widgets.iconbutton import IconButton
from melon.widgets.feeditem import AdaptiveFeedItem
from melon.models import get_app_settings, get_local_playlist
from melon.widgets.simpledialog import SimpleDialog
from melon.models import get_app_settings, get_local_playlist, PlaylistWrapper, ensure_playlist, ensure_delete_local_playlist
from melon.models import is_server_enabled, ensure_server_disabled, ensure_server_enabled

class LocalPlaylistScreen(Adw.NavigationPage):


@@ 18,7 19,11 @@ class LocalPlaylistScreen(Adw.NavigationPage):
        super().__init__(*args, **kwargs)

        app_conf = get_app_settings()
        playlist = get_local_playlist(playlist_id)
        self.playlist = get_local_playlist(playlist_id)
        self.update()

    def update(self):
        playlist = self.playlist

        self.set_title(playlist.title)



@@ 30,6 35,10 @@ class LocalPlaylistScreen(Adw.NavigationPage):
        self.wrapper = Adw.Clamp()
        self.scrollview = Gtk.ScrolledWindow()

        # the edit button should be displayed on both screens
        edit_button = IconButton(_("Edit"), "document-edit-symbolic")
        edit_button.connect("clicked", lambda _: self.open_edit())

        if len(playlist.content) == 0:
            status = Adw.StatusPage()
            status.set_title(_("*crickets chirping*"))


@@ 38,7 47,11 @@ class LocalPlaylistScreen(Adw.NavigationPage):
            icon_button = IconButton(_("Start watching"), "video-display-symbolic")
            icon_button.set_action_name("win.home")
            box = Gtk.CenterBox()
            box.set_center_widget(icon_button)
            col = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
            col.append(icon_button)
            icon_button.set_margin_bottom(6)
            col.append(edit_button)
            box.set_center_widget(col)
            status.set_child(box)
            self.box = status
        else:


@@ 47,6 60,7 @@ class LocalPlaylistScreen(Adw.NavigationPage):
            group = Adw.PreferencesGroup()
            group.set_title(unidecode(playlist.title))
            group.set_description(unidecode(playlist.description))
            group.set_header_suffix(edit_button)
            app_conf = get_app_settings()
            self.box.add(group)
            # add playlist content to group as well


@@ 57,3 71,119 @@ class LocalPlaylistScreen(Adw.NavigationPage):
        self.wrapper.set_child(self.scrollview)
        self.toolbar_view.set_content(self.wrapper)
        self.set_child(self.toolbar_view)

    def open_edit(self):
        self.edit_diag = SimpleDialog()
        self.edit_diag.set_title(_("Edit Playlist"))

        page = Adw.PreferencesPage()

        # preference group for input
        input_group = Adw.PreferencesGroup()
        input_group.set_title(_("Playlist details"))
        input_group.set_description(_("Change playlist information"))
        self.input_title = Adw.EntryRow()
        self.input_title.set_title(_("Playlist name"))
        self.input_title.set_text(self.playlist.title)
        self.input_desc = Adw.EntryRow()
        self.input_desc.set_title(_("Playlist description"))
        self.input_desc.set_text(self.playlist.description)
        input_group.add(self.input_title)
        input_group.add(self.input_desc)
        save_btn = Adw.ActionRow()
        save_btn.set_title(_("Save details"))
        save_btn.set_subtitle(_("Change playlist title and description. (Closes the dialog)"))
        save_btn.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        save_btn.set_activatable(True)
        save_btn.connect("activated", lambda _: self.save_details())
        input_group.add(save_btn)
        page.add(input_group)

        # preference group for dangerous stuff
        dgroup = Adw.PreferencesGroup()
        delete_btn = Adw.ActionRow()
        delete_btn.set_title(_("Delete Playlist"))
        delete_btn.set_subtitle(_("Delete this playlist and it's content. This can NOT be undone."))
        delete_btn.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        delete_btn.set_activatable(True)
        delete_btn.connect("activated", lambda _: self.confirm_delete())
        dgroup.add(delete_btn)
        page.add(dgroup)

        # bottom bar with close button
        # to manually close the dialog
        # without applying changes
        bottom_bar = Gtk.Box()
        btn_cancel = IconButton(_("Close"), "process-stop-symbolic", tooltip=_("Close without chaning anything"))
        btn_cancel.connect(
            "clicked",
            lambda x: self.edit_diag.hide())
        padding = 12
        btn_cancel.set_vexpand(True)
        btn_cancel.set_hexpand(True)
        btn_cancel.set_margin_start(padding)
        btn_cancel.set_margin_end(padding)
        btn_cancel.set_margin_top(padding)
        btn_cancel.set_margin_bottom(padding)
        bottom_bar.append(btn_cancel)
        self.edit_diag.toolbar_view.add_bottom_bar(bottom_bar)

        self.edit_diag.set_widget(page)
        self.edit_diag.show()

    def save_details(self):
        self.playlist.title = self.input_title.get_text()
        self.playlist.description = self.input_desc.get_text()
        wrap = PlaylistWrapper.from_local(self.playlist)
        ensure_playlist(wrap)
        self.update()
        self.edit_diag.hide()

    def confirm_delete(self):
        # close edit dialog
        self.edit_diag.hide()
        # show delete confirmation dialog
        self.dlt_diag = SimpleDialog()
        self.dlt_diag.set_title(_("Delete Playlist"))

        info = Adw.PreferencesGroup()
        info.set_title(_("Do you really wan't to delete this playlist?"))
        info.set_description(_("This cannot be undone"))
        self.dlt_diag.set_widget(info)

        bottom_bar = Gtk.Box()
        btn_cancel = IconButton(_("Cancel"), "process-stop-symbolic", tooltip=_("Do not delete the playlist"))
        btn_confirm = IconButton(_("Delete"), "list-add-symbolic", tooltip=_("Delete this playlist"))
        btn_confirm.connect(
            "clicked",
            lambda _: self.delete()
        )
        btn_cancel.connect(
            "clicked",
            lambda _: self.dlt_diag.hide())

        padding = 12
        btn_confirm.set_vexpand(True)
        btn_confirm.set_hexpand(True)
        btn_confirm.set_margin_end(padding)
        btn_confirm.set_margin_start(padding/2)
        btn_confirm.set_margin_top(padding)
        btn_confirm.set_margin_bottom(padding)
        btn_cancel.set_vexpand(True)
        btn_cancel.set_hexpand(True)
        btn_cancel.set_margin_start(padding)
        btn_cancel.set_margin_end(padding/2)
        btn_cancel.set_margin_top(padding)
        btn_cancel.set_margin_bottom(padding)
        bottom_bar.append(btn_cancel)
        bottom_bar.append(btn_confirm)
        self.dlt_diag.toolbar_view.add_bottom_bar(bottom_bar)

        self.dlt_diag.show()

    def delete(self):
        # go home and delete afterwards
        # so that the reload/callback doesn't trigger
        self.activate_action("win.home", None)
        ensure_delete_local_playlist(self.playlist.id)
        self.dlt_diag.hide()

M melon/playlist/create.py => melon/playlist/create.py +1 -1
@@ 35,7 35,7 @@ class PlaylistCreatorDialog(SimpleDialog):
        input_group.set_description(_("Enter more playlist information"))

        self.input_title = Adw.EntryRow()
        self.input_title.set_title(_("Playlist Name"))
        self.input_title.set_title(_("Playlist name"))
        self.input_title.set_text(_("Unnamed Playlist"))
        self.input_desc = Adw.EntryRow()
        self.input_desc.set_title(_("Playlist description"))

M melon/widgets/simpledialog.py => melon/widgets/simpledialog.py +3 -0
@@ 12,6 12,9 @@ class SimpleDialog(Adw.Window):
        self.header_bar.set_title_widget(self.title)
        self.toolbar_view.add_top_bar(self.header_bar)
        self.set_content(self.toolbar_view)
        # this is a dialog and thus the main window should not be usable
        # when the dialog is opened
        self.set_modal(True)
    def set_title(self, text):
        self.title.set_title(text)
    def set_widget(self, child,padding=12):