Green update indicator, fixed-width tile grid for fullscreen

This commit is contained in:
2026-03-31 20:00:46 -05:00
parent 209ad0010e
commit 95ce30a209
2 changed files with 26 additions and 15 deletions

View File

@@ -67,6 +67,8 @@ REBOOT_COMMAND = [
UPDATE_CHECK_INTERVAL = 1800 UPDATE_CHECK_INTERVAL = 1800
TILE_GRID_WIDTH = 640
# ── Autostart helpers ──────────────────────────────────────────── # ── Autostart helpers ────────────────────────────────────────────
@@ -146,10 +148,7 @@ def check_for_updates() -> bool:
# ── IP address helpers ─────────────────────────────────────────── # ── IP address helpers ───────────────────────────────────────────
def _get_internal_ip(): def _get_internal_ip():
"""Get the primary LAN IP address."""
try: try:
# Connect to a public IP (doesn't actually send data)
# to determine which interface would be used
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(2) s.settimeout(2)
s.connect(("1.1.1.1", 80)) s.connect(("1.1.1.1", 80))
@@ -158,7 +157,6 @@ def _get_internal_ip():
return ip return ip
except Exception: except Exception:
pass pass
# Fallback: hostname -I
try: try:
result = subprocess.run( result = subprocess.run(
["hostname", "-I"], ["hostname", "-I"],
@@ -174,7 +172,6 @@ def _get_internal_ip():
def _get_external_ip(): def _get_external_ip():
"""Get the public IP via a lightweight HTTP service."""
for url in [ for url in [
"https://api.ipify.org", "https://api.ipify.org",
"https://ifconfig.me/ip", "https://ifconfig.me/ip",
@@ -491,7 +488,6 @@ class SovranHubWindow(Adw.ApplicationWindow):
GLib.timeout_add_seconds(5, self._check_for_updates_once) GLib.timeout_add_seconds(5, self._check_for_updates_once)
GLib.timeout_add_seconds(UPDATE_CHECK_INTERVAL, self._periodic_update_check) GLib.timeout_add_seconds(UPDATE_CHECK_INTERVAL, self._periodic_update_check)
# Fetch IPs in background
GLib.timeout_add_seconds(1, self._fetch_ips_once) GLib.timeout_add_seconds(1, self._fetch_ips_once)
# ── IP Address Bar ─────────────────────────────────────────── # ── IP Address Bar ───────────────────────────────────────────
@@ -508,7 +504,6 @@ class SovranHubWindow(Adw.ApplicationWindow):
css_classes=["ip-bar"], css_classes=["ip-bar"],
) )
# Internal IP
internal_box = Gtk.Box( internal_box = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL, orientation=Gtk.Orientation.HORIZONTAL,
spacing=6, spacing=6,
@@ -531,12 +526,8 @@ class SovranHubWindow(Adw.ApplicationWindow):
internal_box.append(internal_label) internal_box.append(internal_label)
internal_box.append(self._internal_ip_label) internal_box.append(self._internal_ip_label)
# Separator sep = Gtk.Separator(orientation=Gtk.Orientation.VERTICAL)
sep = Gtk.Separator(
orientation=Gtk.Orientation.VERTICAL,
)
# External IP
external_box = Gtk.Box( external_box = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL, orientation=Gtk.Orientation.HORIZONTAL,
spacing=6, spacing=6,
@@ -629,6 +620,14 @@ class SovranHubWindow(Adw.ApplicationWindow):
) )
self._tiles_box.append(sep) self._tiles_box.append(sep)
# Fixed-width container — tiles stay centered and compact
container = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL,
halign=Gtk.Align.CENTER,
css_classes=["tiles-container"],
)
container.set_size_request(TILE_GRID_WIDTH, -1)
flowbox = Gtk.FlowBox( flowbox = Gtk.FlowBox(
max_children_per_line=4, max_children_per_line=4,
min_children_per_line=2, min_children_per_line=2,
@@ -656,7 +655,8 @@ class SovranHubWindow(Adw.ApplicationWindow):
flowbox.append(tile) flowbox.append(tile)
self._tiles.append(tile) self._tiles.append(tile)
self._tiles_box.append(flowbox) container.append(flowbox)
self._tiles_box.append(container)
GLib.idle_add(self._refresh_all) GLib.idle_add(self._refresh_all)
@@ -680,7 +680,7 @@ class SovranHubWindow(Adw.ApplicationWindow):
self._update_available = available self._update_available = available
if available: if available:
self._update_btn.set_label("Update Available") self._update_btn.set_label("Update Available")
self._update_btn.set_css_classes(["destructive-action"]) self._update_btn.set_css_classes(["update-available"])
self._update_btn.set_tooltip_text("A new version of Sovran_SystemsOS is available!") self._update_btn.set_tooltip_text("A new version of Sovran_SystemsOS is available!")
self._badge.set_visible(True) self._badge.set_visible(True)
else: else:

View File

@@ -18,10 +18,17 @@
font-size: 0.75em; font-size: 0.75em;
} }
.update-badge { .update-badge {
color: #e01b24; color: #2ec27e;
font-size: 1.2em; font-size: 1.2em;
font-weight: bold; font-weight: bold;
} }
.update-available {
background: #2ec27e;
color: white;
}
.update-available:hover {
background: #26a269;
}
.ip-bar { .ip-bar {
padding: 8px 16px; padding: 8px 16px;
border-radius: 8px; border-radius: 8px;
@@ -32,3 +39,7 @@
font-weight: bold; font-weight: bold;
color: @accent_color; color: @accent_color;
} }
.tiles-container {
margin-left: auto;
margin-right: auto;
}