mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-14 00:04:08 +09:00
Add a list of popular remotes
This list will show when the user wants to add a new remote
This commit is contained in:
@@ -8,6 +8,7 @@ blueprints = custom_target('blueprints',
|
||||
'window.blp',
|
||||
'orphans.blp',
|
||||
'filter.blp',
|
||||
'popular_remotes.blp',
|
||||
),
|
||||
output: '.',
|
||||
command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
|
||||
@@ -48,7 +49,8 @@ warehouse_sources = [
|
||||
'common.py',
|
||||
'orphans.blp',
|
||||
'filter_window.py',
|
||||
'filter.blp'
|
||||
'filter.blp',
|
||||
'popular_remotes_window.py',
|
||||
]
|
||||
|
||||
install_data(warehouse_sources, install_dir: moduledir)
|
||||
|
||||
62
src/popular_remotes.blp
Normal file
62
src/popular_remotes.blp
Normal file
@@ -0,0 +1,62 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template PopularRemotesWindow : Adw.Window {
|
||||
default-width: 500;
|
||||
default-height: 450;
|
||||
title: _("Add a Remote");
|
||||
|
||||
Adw.ToolbarView main_toolbar_view {
|
||||
[top]
|
||||
HeaderBar header_bar {
|
||||
// [start]
|
||||
// Button refresh_button {
|
||||
// icon-name: "view-refresh-symbolic";
|
||||
// tooltip-text: _("Refresh the List of Installed Apps");
|
||||
// }
|
||||
}
|
||||
content:
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Stack main_stack {
|
||||
Box main_box {
|
||||
orientation: vertical;
|
||||
Overlay main_overlay {
|
||||
ScrolledWindow scrolled_window {
|
||||
vexpand: true;
|
||||
Adw.Clamp{
|
||||
Box {
|
||||
orientation: vertical;
|
||||
ListBox list_of_remotes {
|
||||
margin-top: 6;
|
||||
margin-bottom: 6;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
hexpand: true;
|
||||
valign: start;
|
||||
selection-mode: none;
|
||||
styles["boxed-list"]
|
||||
}
|
||||
ListBox custom_list {
|
||||
margin-top: 6;
|
||||
margin-bottom: 6;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
hexpand: true;
|
||||
valign: start;
|
||||
selection-mode: none;
|
||||
styles["boxed-list"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.StatusPage no_data {
|
||||
icon-name: "check-plain-symbolic";
|
||||
title: _("No Leftover Data");
|
||||
description: _("There is no leftover user data");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
179
src/popular_remotes_window.py
Normal file
179
src/popular_remotes_window.py
Normal file
@@ -0,0 +1,179 @@
|
||||
from gi.repository import Gtk, Adw, GLib, Gdk, Gio
|
||||
from .common import myUtils
|
||||
import subprocess
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/popular_remotes.ui")
|
||||
class PopularRemotesWindow(Adw.Window):
|
||||
__gtype_name__ = "PopularRemotesWindow"
|
||||
|
||||
list_of_remotes = Gtk.Template.Child()
|
||||
custom_list = Gtk.Template.Child()
|
||||
toast_overlay = Gtk.Template.Child()
|
||||
|
||||
remotes = [
|
||||
["elementary", "https://flatpak.elementary.io/repo.flatpakrepo", _("ElementoryOS's Apps")],
|
||||
["flathub", "https://dl.flathub.org/repo/flathub.flatpakrepo", _("The biggest repository of Flatpaks")],
|
||||
["flathub-beta", "https://flathub.org/beta-repo/flathub-beta.flatpakrepo", _("The beta branch of the biggest repository of Flatpaks")],
|
||||
["fedora", "oci+https://registry.fedoraproject.org", _("Flatpaks packaged by Fedora Linux")],
|
||||
["gnome-nightly", "https://nightly.gnome.org/gnome-nightly.flatpakrepo", _("Beta GNOME Apps and Runtimes")],
|
||||
["kdeapps", "https://distribute.kde.org/kdeapps.flatpakrepo", _("Beta KDE Apps and Runtimes")],
|
||||
]
|
||||
|
||||
def on_add_response(self, _dialog, response_id, _function):
|
||||
if response_id == "cancel":
|
||||
return
|
||||
|
||||
install_type = "--user"
|
||||
if not self.add_as_user:
|
||||
install_type = "--system"
|
||||
|
||||
self.name_to_add = self.name_to_add.strip()
|
||||
self.url_to_add = self.url_to_add.strip()
|
||||
|
||||
command = ['flatpak-spawn', '--host', 'flatpak', 'remote-add', '--if-not-exists', self.name_to_add, self.url_to_add, install_type]
|
||||
try:
|
||||
subprocess.run(command, capture_output=True, check=True)
|
||||
except Exception as e:
|
||||
self.toast_overlay.add_toast(Adw.Toast.new(_("Could not add {}").format(self.name_to_add)))
|
||||
print(e)
|
||||
self.generate_list()
|
||||
self.close()
|
||||
|
||||
def add_handler(self, _widget, name="", link=""):
|
||||
dialog = Adw.MessageDialog.new(self, _("Add Flatpak Remote"))
|
||||
dialog.set_close_response("cancel")
|
||||
dialog.add_response("cancel", _("Cancel"))
|
||||
dialog.add_response("continue", _("Add"))
|
||||
dialog.set_response_enabled("continue", False)
|
||||
dialog.set_response_appearance("continue", Adw.ResponseAppearance.SUGGESTED)
|
||||
|
||||
def name_update(widget):
|
||||
is_enabled = True
|
||||
self.name_to_add = widget.get_text()
|
||||
name_pattern = re.compile(r'^[a-zA-Z\-]+$')
|
||||
if not name_pattern.match(self.name_to_add):
|
||||
is_enabled = False
|
||||
|
||||
if is_enabled:
|
||||
widget.remove_css_class("error")
|
||||
else:
|
||||
widget.add_css_class("error")
|
||||
|
||||
if len(self.name_to_add) == 0:
|
||||
is_enabled = False
|
||||
|
||||
confirm_enabler(is_enabled)
|
||||
|
||||
def url_update(widget):
|
||||
is_enabled = True
|
||||
self.url_to_add = widget.get_text()
|
||||
url_pattern = re.compile(r'^[a-zA-Z0-9\-._~:/?#[\]@!$&\'()*+,;=]+$')
|
||||
if not url_pattern.match(self.url_to_add):
|
||||
is_enabled = False
|
||||
|
||||
if is_enabled:
|
||||
widget.remove_css_class("error")
|
||||
else:
|
||||
widget.add_css_class("error")
|
||||
|
||||
if len(self.url_to_add) == 0:
|
||||
is_enabled = False
|
||||
|
||||
confirm_enabler(is_enabled)
|
||||
|
||||
def confirm_enabler(is_enabled):
|
||||
if len(self.name_to_add) == 0 or len(self.url_to_add) == 0:
|
||||
is_enabled = False
|
||||
dialog.set_response_enabled("continue", is_enabled)
|
||||
|
||||
def set_user(widget):
|
||||
self.add_as_user = widget.get_active()
|
||||
|
||||
self.name_to_add = ""
|
||||
self.url_to_add = ""
|
||||
self.add_as_user = True
|
||||
|
||||
info_box = Gtk.Box(orientation="vertical")
|
||||
entry_list = Gtk.ListBox(selection_mode="none", margin_bottom=12)
|
||||
entry_list.add_css_class("boxed-list")
|
||||
|
||||
name_entry = Adw.EntryRow(title=_("Name"))
|
||||
name_entry.set_text(name)
|
||||
name_entry.connect("changed", name_update)
|
||||
|
||||
url_entry = Adw.EntryRow(title=_("URL"))
|
||||
url_entry.set_text(link)
|
||||
url_entry.connect("changed", url_update)
|
||||
|
||||
entry_list.append(name_entry)
|
||||
entry_list.append(url_entry)
|
||||
info_box.append(entry_list)
|
||||
|
||||
install_type_list = Gtk.ListBox(selection_mode="none")
|
||||
install_type_list.add_css_class("boxed-list")
|
||||
|
||||
user_row = Adw.ActionRow(title=_("User"), subtitle=_("Remote will be available to only you"))
|
||||
user_check = Gtk.CheckButton(active=True)
|
||||
user_check.connect("toggled", set_user)
|
||||
user_row.add_prefix(user_check)
|
||||
user_row.set_activatable_widget(user_check)
|
||||
|
||||
system_row = Adw.ActionRow(title=_("System"), subtitle=_("Remote will be available to every user on the system"))
|
||||
system_check = Gtk.CheckButton()
|
||||
system_row.add_prefix(system_check)
|
||||
system_check.set_group(user_check)
|
||||
system_row.set_activatable_widget(system_check)
|
||||
|
||||
install_type_list.append(user_row)
|
||||
install_type_list.append(system_row)
|
||||
|
||||
info_box.append(install_type_list)
|
||||
|
||||
dialog.set_extra_child(info_box)
|
||||
dialog.connect("response", self.on_add_response, dialog.choose_finish)
|
||||
Gtk.Window.present(dialog)
|
||||
|
||||
if name != "":
|
||||
name_update(name_entry)
|
||||
if link != "":
|
||||
url_update(url_entry)
|
||||
|
||||
def generate_list(self):
|
||||
self.host_remotes = self.my_utils.getHostRemotes()
|
||||
self.list_of_remotes.remove_all()
|
||||
self.custom_list.remove_all()
|
||||
host_remotes_names = []
|
||||
for i in range(len(self.host_remotes)):
|
||||
host_remotes_names.append(self.host_remotes[i][0])
|
||||
|
||||
for i in range(len(self.remotes)):
|
||||
remote_row = Adw.ActionRow(activatable=True)
|
||||
remote_row.set_title(self.remotes[i][0])
|
||||
remote_row.set_subtitle(self.remotes[i][2])
|
||||
image = Gtk.Image.new_from_icon_name("right-large-symbolic")
|
||||
remote_row.add_suffix(image)
|
||||
remote_row.connect("activated", self.add_handler, self.remotes[i][0], self.remotes[i][1])
|
||||
if self.remotes[i][0] not in host_remotes_names:
|
||||
self.list_of_remotes.append(remote_row)
|
||||
|
||||
image2 = Gtk.Image.new_from_icon_name("right-large-symbolic")
|
||||
custom_remote = Adw.ActionRow(activatable=True)
|
||||
custom_remote.set_title(_("Add a Custom Remote"))
|
||||
custom_remote.add_suffix(image2)
|
||||
custom_remote.connect("activated", self.add_handler)
|
||||
self.custom_list.append(custom_remote)
|
||||
|
||||
if not self.list_of_remotes.get_row_at_index(0):
|
||||
self.list_of_remotes.set_visible(False)
|
||||
|
||||
def __init__(self, parent_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.my_utils = myUtils(self)
|
||||
|
||||
self.connect("close-request", lambda *_: parent_window.generate_list())
|
||||
self.set_modal(True)
|
||||
self.set_transient_for(parent_window)
|
||||
self.generate_list()
|
||||
117
src/remotes.py
117
src/remotes.py
@@ -1,5 +1,6 @@
|
||||
from gi.repository import Gtk, Adw, GLib, Gdk, Gio
|
||||
from .common import myUtils
|
||||
from .popular_remotes_window import PopularRemotesWindow
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
@@ -22,117 +23,6 @@ class RemotesWindow(Adw.Window):
|
||||
data.append(row)
|
||||
return data
|
||||
|
||||
def on_add_response(self, _dialog, response_id, _function):
|
||||
if response_id == "cancel":
|
||||
return
|
||||
|
||||
install_type = "--user"
|
||||
if not self.add_as_user:
|
||||
install_type = "--system"
|
||||
|
||||
self.name_to_add = self.name_to_add.strip()
|
||||
self.url_to_add = self.url_to_add.strip()
|
||||
|
||||
command = ['flatpak-spawn', '--host', 'flatpak', 'remote-add', '--if-not-exists', self.name_to_add, self.url_to_add, install_type]
|
||||
try:
|
||||
subprocess.run(command, capture_output=True, check=True)
|
||||
except Exception as e:
|
||||
self.make_toast(_("Could not add {}").format(self.name_to_add))
|
||||
print(e)
|
||||
self.generate_list()
|
||||
|
||||
def add_handler(self, _widget):
|
||||
dialog = Adw.MessageDialog.new(self, _("Add Flatpak Remote"))
|
||||
dialog.set_close_response("cancel")
|
||||
dialog.add_response("cancel", _("Cancel"))
|
||||
dialog.add_response("continue", _("Add"))
|
||||
dialog.set_response_enabled("continue", False)
|
||||
dialog.set_response_appearance("continue", Adw.ResponseAppearance.SUGGESTED)
|
||||
|
||||
def name_update(widget):
|
||||
is_enabled = True
|
||||
self.name_to_add = widget.get_text()
|
||||
name_pattern = re.compile(r'^[a-zA-Z\-]+$')
|
||||
if not name_pattern.match(self.name_to_add):
|
||||
is_enabled = False
|
||||
|
||||
if is_enabled:
|
||||
widget.remove_css_class("error")
|
||||
else:
|
||||
widget.add_css_class("error")
|
||||
|
||||
if len(self.name_to_add) == 0:
|
||||
is_enabled = False
|
||||
|
||||
confirm_enabler(is_enabled)
|
||||
|
||||
def url_update(widget):
|
||||
is_enabled = True
|
||||
self.url_to_add = widget.get_text()
|
||||
url_pattern = re.compile(r'^[a-zA-Z0-9\-._~:/?#[\]@!$&\'()*+,;=]+$')
|
||||
if not url_pattern.match(self.url_to_add):
|
||||
is_enabled = False
|
||||
|
||||
if is_enabled:
|
||||
widget.remove_css_class("error")
|
||||
else:
|
||||
widget.add_css_class("error")
|
||||
|
||||
if len(self.url_to_add) == 0:
|
||||
is_enabled = False
|
||||
|
||||
confirm_enabler(is_enabled)
|
||||
|
||||
def confirm_enabler(is_enabled):
|
||||
if len(self.name_to_add) == 0 or len(self.url_to_add) == 0:
|
||||
is_enabled = False
|
||||
dialog.set_response_enabled("continue", is_enabled)
|
||||
|
||||
def set_user(widget):
|
||||
self.add_as_user = widget.get_active()
|
||||
|
||||
self.name_to_add = ""
|
||||
self.url_to_add = ""
|
||||
self.add_as_user = True
|
||||
|
||||
info_box = Gtk.Box(orientation="vertical")
|
||||
entry_list = Gtk.ListBox(selection_mode="none", margin_bottom=12)
|
||||
entry_list.add_css_class("boxed-list")
|
||||
|
||||
name_entry = Adw.EntryRow(title=_("Name"))
|
||||
name_entry.connect("changed", name_update)
|
||||
|
||||
url_entry = Adw.EntryRow(title=_("URL"))
|
||||
url_entry.connect("changed", url_update)
|
||||
|
||||
entry_list.append(name_entry)
|
||||
entry_list.append(url_entry)
|
||||
info_box.append(entry_list)
|
||||
|
||||
install_type_list = Gtk.ListBox(selection_mode="none")
|
||||
install_type_list.add_css_class("boxed-list")
|
||||
|
||||
user_row = Adw.ActionRow(title=_("User"), subtitle=_("Remote will be available to only you"))
|
||||
user_check = Gtk.CheckButton(active=True)
|
||||
user_check.connect("toggled", set_user)
|
||||
user_row.add_prefix(user_check)
|
||||
user_row.set_activatable_widget(user_check)
|
||||
|
||||
system_row = Adw.ActionRow(title=_("System"), subtitle=_("Remote will be available to every user on the system"))
|
||||
system_check = Gtk.CheckButton()
|
||||
system_row.add_prefix(system_check)
|
||||
system_check.set_group(user_check)
|
||||
system_row.set_activatable_widget(system_check)
|
||||
|
||||
install_type_list.append(user_row)
|
||||
install_type_list.append(system_row)
|
||||
|
||||
info_box.append(install_type_list)
|
||||
|
||||
dialog.set_extra_child(info_box)
|
||||
dialog.connect("response", self.on_add_response, dialog.choose_finish)
|
||||
Gtk.Window.present(dialog)
|
||||
|
||||
def remove_on_response(self, _dialog, response_id, _function, index):
|
||||
if response_id == "cancel":
|
||||
return
|
||||
@@ -195,6 +85,9 @@ class RemotesWindow(Adw.Window):
|
||||
remove_button.connect("clicked", self.remove_handler, i)
|
||||
remote_row.add_suffix(copy_button)
|
||||
remote_row.add_suffix(remove_button)
|
||||
|
||||
def showPopularRemotes(self, widget):
|
||||
PopularRemotesWindow(self).present()
|
||||
|
||||
def __init__(self, main_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -231,7 +124,7 @@ class RemotesWindow(Adw.Window):
|
||||
self.remotes_list.add_css_class("boxed-list")
|
||||
self.app_window = main_window
|
||||
|
||||
self.add_button.connect("clicked", self.add_handler)
|
||||
self.add_button.connect("clicked", self.showPopularRemotes)
|
||||
|
||||
# Window Stuffs
|
||||
self.set_title(self.window_title)
|
||||
|
||||
2
src/right-large-symbolic.svg
Normal file
2
src/right-large-symbolic.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 4 0.996094 v 1 c 0 0.296875 0.125 0.558594 0.328125 0.742187 l 5.257813 5.257813 l -5.257813 5.261718 l -0.035156 0.03125 c -0.179688 0.183594 -0.292969 0.433594 -0.292969 0.707032 v 1 h 1 c 0.277344 0 0.527344 -0.109375 0.707031 -0.292969 l 0.035157 -0.03125 l 6.671874 -6.675781 l -6.671874 -6.671875 c -0.183594 -0.199219 -0.449219 -0.328125 -0.742188 -0.328125 z m 0 0"/></svg>
|
||||
|
After Width: | Height: | Size: 519 B |
@@ -4,6 +4,7 @@
|
||||
<file preprocess="xml-stripblanks">window.ui</file>
|
||||
<file preprocess="xml-stripblanks">orphans.ui</file>
|
||||
<file preprocess="xml-stripblanks">filter.ui</file>
|
||||
<file preprocess="xml-stripblanks">popular_remotes.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
||||
<!-- <file preprocess="xml-stripblanks">../data/io.github.flattool.Warehouse.metainfo.xml.in</file> -->
|
||||
</gresource>
|
||||
@@ -17,5 +18,6 @@
|
||||
<file preprocess="xml-stripblanks">paper-filled-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">plus-large-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">funnel-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">right-large-symbolic.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
Reference in New Issue
Block a user