From a2fa9848258b91c3f833a11751af1bf4c1a5bae2 Mon Sep 17 00:00:00 2001 From: Andrii Shafar Date: Mon, 27 Mar 2023 19:28:18 +0300 Subject: [PATCH] feat: extend title screen to include additional actions (#66) Co-authored-by: Marco Ceppi --- .gitignore | 1 + tests/example-final-screen.yml | 24 +++++++++++++++ yafti/plugin/run.py | 11 +++++++ yafti/screen/title.py | 55 ++++++++++++++++++++++++++++++++-- 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 tests/example-final-screen.yml diff --git a/.gitignore b/.gitignore index c2404ae..0a80269 100644 --- a/.gitignore +++ b/.gitignore @@ -159,3 +159,4 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +.vscode/ \ No newline at end of file diff --git a/tests/example-final-screen.yml b/tests/example-final-screen.yml new file mode 100644 index 0000000..c298a99 --- /dev/null +++ b/tests/example-final-screen.yml @@ -0,0 +1,24 @@ +title: uBlue First Boot +properties: + mode: "run-on-change" +actions: + pre: + post: +screens: + first-screen: + source: yafti.screen.title + values: + title: "That was pretty cool" + icon: "/path/to/icon" + description: | + Time to play overwatch + final-screen: + source: yafti.screen.title + values: + title: "All done" + icon: "/path/to/icon" + links: + - "Gnome Software": + run: /usr/bin/gnome-software + description: | + Thanks for installing, join the community, next steps diff --git a/yafti/plugin/run.py b/yafti/plugin/run.py index fbbda34..ece57ba 100644 --- a/yafti/plugin/run.py +++ b/yafti/plugin/run.py @@ -49,6 +49,8 @@ import asyncio import shlex import subprocess +from os.path import isfile +from shutil import which from pydantic import validate_arguments @@ -59,6 +61,15 @@ class Run(YaftiPlugin): async def exec(self, cmd: str) -> subprocess.CompletedProcess: log.debug("running command", cmd=cmd) + + # spawn command in host when running from container + is_container = isfile("/run/.containerenv") or isfile("/.dockerenv") + if not isfile(cmd) and is_container: + if which("distrobox-host-exec"): + cmd = f"distrobox-host-exec {cmd}" + elif which("flatpak-spawn"): + cmd = f"flatpak-spawn --host {cmd}" + proc = await asyncio.create_subprocess_shell( cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) diff --git a/yafti/screen/title.py b/yafti/screen/title.py index 4bb0274..8d9418c 100644 --- a/yafti/screen/title.py +++ b/yafti/screen/title.py @@ -1,8 +1,12 @@ -from typing import Optional +import asyncio +from functools import partial +from typing import Optional, List from gi.repository import Adw, Gtk from yafti.abc import YaftiScreen, YaftiScreenConfig +from yafti import events +from yafti.registry import PLUGINS _xml = """\ @@ -37,10 +41,57 @@ class Config(YaftiScreenConfig): title: str description: str icon: Optional[str] = None + links: List[dict[str, dict]] = None def __init__( - self, title: str = None, description: str = None, icon: str = None, **kwargs + self, + title: str = None, + description: str = None, + icon: str = None, + links: List[dict[str, str]] = None, + **kwargs ): super().__init__(**kwargs) self.status_page.set_title(title) self.status_page.set_description(description) + + if links: + links_list_box = self.render_links_list_box() + self.append_action_rows(links, links_list_box) + + def render_links_list_box(self): + links_list_box = Gtk.ListBox() + links_list_box.set_selection_mode(Gtk.SelectionMode.NONE) + links_list_box.add_css_class("boxed-list") + self.status_page.set_child(links_list_box) + return links_list_box + + def append_action_rows(self, links, links_list_box): + for link in links: + title, action = list(link.items())[0] + plugin, config = list(action.items())[0] + events.register("on_action_row_open") + + events.on( + "on_action_row_open", lambda _: self.on_action_row_open(plugin, config) + ) + + def do_emit(*args, **kwargs): + asyncio.create_task(events.emit(*args, **kwargs)) + + _on_clicked = partial(do_emit, "on_action_row_open") + + link_action_row = Adw.ActionRow() + + action_btn = Gtk.Button() + action_btn.set_label("Open") + action_btn.set_valign(Gtk.Align.CENTER) + action_btn.connect("clicked", _on_clicked) + + link_action_row.set_title(title) + link_action_row.add_suffix(action_btn) + + links_list_box.append(link_action_row) + + async def on_action_row_open(self, plugin, config): + await PLUGINS.get(plugin)(config)