Merge pull request 'add search bar' (#754) from hsjobeki-main into main

This commit is contained in:
clan-bot
2024-01-21 11:16:14 +00:00
6 changed files with 44 additions and 139 deletions

View File

@@ -22,6 +22,7 @@ class Views:
_instance: "None | Views" = None
view: Adw.ViewStack
main_window: Adw.ApplicationWindow = None
# Make sure the VMS class is used as a singleton
def __init__(self) -> None:
@@ -35,3 +36,6 @@ class Views:
cls.view = Adw.ViewStack()
return cls._instance
def set_main_window(self, window: Adw.ApplicationWindow) -> None:
self.main_window = window

View File

@@ -123,10 +123,20 @@ class VMS:
cls._instance = cls.__new__(cls)
cls.list_store = Gio.ListStore.new(VM)
for vm in get_initial_vms():
for vm in get_saved_vms():
cls.list_store.append(vm)
return cls._instance
def filter_by_name(self, text: str) -> None:
if text:
filtered_list = self.list_store
filtered_list.remove_all()
for vm in get_saved_vms():
if text.lower() in vm.data.flake.clan_name.lower():
filtered_list.append(vm)
else:
self.refresh()
def handle_vm_stopped(self, func: Callable[[VM, VM], None]) -> None:
for vm in self.list_store:
vm.connect("vm_stopped", func)
@@ -144,11 +154,11 @@ class VMS:
def refresh(self) -> None:
self.list_store.remove_all()
for vm in get_initial_vms():
for vm in get_saved_vms():
self.list_store.append(vm)
def get_initial_vms() -> list[VM]:
def get_saved_vms() -> list[VM]:
vm_list = []
try:

View File

@@ -25,6 +25,14 @@ avatar {
box-shadow: none;
}
.search-entry {
margin-bottom: 12px;
}
searchbar {
margin-bottom: 25px;
}
/* TODO: Disable shadow for empty lists */
/* list:empty {
box-shadow: none;

View File

@@ -5,6 +5,7 @@ import gi
from clan_cli.history.add import HistoryEntry
from clan_vm_manager.models.use_join import Join, JoinValue
from clan_vm_manager.models.use_views import Views
gi.require_version("Adw", "1")
from gi.repository import Adw, Gdk, Gio, GObject, Gtk
@@ -57,16 +58,31 @@ class ClanList(Gtk.Box):
)
self.vm_boxed_list.add_css_class("vm-list")
search_bar = Gtk.SearchBar()
# This widget will typically be the top-level window
search_bar.set_key_capture_widget(Views.use().main_window)
entry = Gtk.SearchEntry()
entry.set_placeholder_text("Search cLan")
entry.connect("search-changed", self.on_search_changed)
entry.add_css_class("search-entry")
search_bar.set_child(entry)
self.append(search_bar)
self.append(self.join_boxed_list)
self.append(self.vm_boxed_list)
def on_search_changed(self, entry: Gtk.SearchEntry) -> None:
VMS.use().filter_by_name(entry.get_text())
# Disable the shadow if the list is empty
if not VMS.use().list_store.get_n_items():
self.vm_boxed_list.add_css_class("no-shadow")
def render_vm_row(self, boxed_list: Gtk.ListBox, item: VM) -> Gtk.Widget:
if boxed_list.has_css_class("no-shadow"):
boxed_list.remove_css_class("no-shadow")
flake = item.data.flake
row = Adw.ActionRow()
print("Creating", item.data.flake.flake_attr)
# Title
row.set_title(flake.clan_name)

View File

@@ -1,135 +0,0 @@
from functools import partial
import gi
from clan_cli.errors import ClanError
from clan_cli.history.add import add_history
from clan_vm_manager.errors.show_error import show_error_dialog
from clan_vm_manager.models.use_join import JoinValue
gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
from gi.repository import Adw, Gio, GObject, Gtk
class TrustValues(GObject.Object):
data: JoinValue
def __init__(self, data: JoinValue) -> None:
super().__init__()
print("TrustValues", data)
self.data = data
class Trust(Gtk.Box):
def __init__(
self,
) -> None:
super().__init__(orientation=Gtk.Orientation.VERTICAL)
# self.on_trust = on_trust
# self.url: ClanURI | None = Join.use().
def render(item: TrustValues) -> Gtk.Widget:
row = Adw.ActionRow()
row.set_title(str(item.data.url))
row.add_css_class("trust")
avatar = Adw.Avatar()
avatar.set_text(str(item.data.url))
avatar.set_show_initials(True)
avatar.set_size(50)
row.add_prefix(avatar)
cancel_button = Gtk.Button(label="Cancel")
cancel_button.add_css_class("error")
trust_button = Gtk.Button(label="Join")
trust_button.add_css_class("success")
trust_button.connect("clicked", partial(self.on_trust_clicked, item.data))
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
box.set_valign(Gtk.Align.CENTER)
box.append(cancel_button)
box.append(trust_button)
# switch.connect("notify::active", partial(self.on_row_toggle, item.data))
row.add_suffix(box)
return row
boxed_list = Gtk.ListBox()
boxed_list.set_selection_mode(Gtk.SelectionMode.NONE)
boxed_list.add_css_class("boxed-list")
list_store = Gio.ListStore.new(TrustValues)
# list_store.append(TrustValues(data=initial_values))
# icon = Gtk.Image.new_from_pixbuf(
# GdkPixbuf.Pixbuf.new_from_file_at_scale(
# filename=str(assets.loc / "placeholder.jpeg"),
# width=256,
# height=256,
# preserve_aspect_ratio=True,
# )
# )
boxed_list.bind_model(list_store, create_widget_func=render)
self.append(boxed_list)
# layout = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
# # layout.set_border_width(20)
# layout.set_spacing(20)
# if self.url is not None:
# self.entry = Gtk.Label(label=str(self.url))
# layout.append(icon)
# layout.append(Gtk.Label(label="Clan URL"))
# else:
# layout.append(Gtk.Label(label="Enter Clan URL"))
# self.entry = Gtk.Entry()
# # Autocomplete
# # TODO: provide intelligent suggestions
# completion_list = Gtk.ListStore(str)
# completion_list.append(["clan://"])
# completion = Gtk.EntryCompletion()
# completion.set_model(completion_list)
# completion.set_text_column(0)
# completion.set_popup_completion(False)
# completion.set_inline_completion(True)
# self.entry.set_completion(completion)
# self.entry.set_placeholder_text("clan://")
# layout.append(self.entry)
# if self.url is None:
# trust_button = Gtk.Button(label="Load cLAN-URL")
# else:
# trust_button = Gtk.Button(label="Trust cLAN-URL")
# trust_button.connect("clicked", self.on_trust_clicked)
# layout.append(trust_button)
def on_trust_clicked(self, item: JoinValue, widget: Gtk.Widget) -> None:
try:
uri = item.url
# or ClanURI(self.entry.get_text())
print(f"trusted: {uri}")
if uri:
add_history(uri)
# history = list_history()
# found = filter(
# lambda item: item.flake.flake_url == uri.get_internal(), history
# )
# if found:
# [item] = found
# self.on_trust(uri.get_internal(), item.flake)
except ClanError as e:
pass
show_error_dialog(e)

View File

@@ -23,6 +23,8 @@ class MainWindow(Adw.ApplicationWindow):
# Initialize all views
stack_view = Views.use().view
Views.use().set_main_window(self)
stack_view.add_named(ClanList(), "list")
stack_view.set_visible_child_name(config.initial_view)