diff --git a/data/ui/DrawingPerspective.ui b/data/ui/DrawingPerspective.ui index be67857..4814059 100644 --- a/data/ui/DrawingPerspective.ui +++ b/data/ui/DrawingPerspective.ui @@ -15,6 +15,46 @@ True False + + + True + False + 5 + 5 + True + + + False + True + 0 + + + + + True + False + 10 + 10 + last synchronized: + + + False + True + 1 + + + + + True + False + 2 seconds ago + + + False + True + 2 + + True @@ -23,7 +63,7 @@ True True - 1 + 3 @@ -32,12 +72,12 @@ False 10 10 - battery-000 + battery-empty-symbolic False True - 2 + 4 diff --git a/tuhigui/drawingperspective.py b/tuhigui/drawingperspective.py index 7488939..4de8e6e 100644 --- a/tuhigui/drawingperspective.py +++ b/tuhigui/drawingperspective.py @@ -16,6 +16,7 @@ from .drawing import Drawing from .svg import JsonSvg import json +import time import gi gi.require_version("Gtk", "3.0") @@ -23,6 +24,24 @@ import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger('drawingperspective') +def relative_time(seconds): + MIN = 60 + H = 60 * MIN + DAY = 24 * H + WEEK = 7 * DAY + + if seconds < 30: + return 'just now' + if seconds < 5 * MIN: + return 'a few minutes ago' + if seconds < H: + return f'{int(seconds/MIN/10) * 10} minutes ago' + if seconds < DAY: + return f'{int(seconds/H)} hours ago' + if seconds < 4 * WEEK: + return f'{int(seconds/D)} days ago' + return 'a long time ago' + @Gtk.Template(resource_path="/org/freedesktop/TuhiGui/ui/DrawingPerspective.ui") class DrawingPerspective(Gtk.Stack): @@ -30,10 +49,15 @@ class DrawingPerspective(Gtk.Stack): image_battery = Gtk.Template.Child() flowbox_drawings = Gtk.Template.Child() + spinner_sync = Gtk.Template.Child() + label_last_sync = Gtk.Template.Child() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.known_drawings = [] + self.last_sync_time = 0 + self._sync_label_timer = GObject.timeout_add_seconds(60, self._update_sync_label) + self._update_sync_label() def _update_drawings(self, device, pspec): for ts in self.device.drawings_available: @@ -56,6 +80,7 @@ class DrawingPerspective(Gtk.Stack): device.connect('notify::connected', self._on_connected) device.connect('notify::listening', self._on_listening_stopped) + device.connect('notify::sync-state', self._on_sync_state) self.device.connect('notify::drawings-available', self._update_drawings) @@ -79,6 +104,19 @@ class DrawingPerspective(Gtk.Stack): def name(self): return "drawing_perspective" + def _on_sync_state(self, device, pspec): + if device.sync_state: + self.spinner_sync.start() + else: + self.spinner_sync.stop() + self.last_sync_time = time.time() + self._update_sync_label() + + def _update_sync_label(self): + now = time.time() + self.label_last_sync.set_text(f'{relative_time(now - self.last_sync_time)}') + return True + def _on_connected(self, device, pspec): # Turns out we don't really care about whether the device is # connected or not, it has little effect on how we work here diff --git a/tuhigui/tuhi.py b/tuhigui/tuhi.py index b5074f8..64c3702 100644 --- a/tuhigui/tuhi.py +++ b/tuhigui/tuhi.py @@ -169,6 +169,7 @@ class TuhiKeteDevice(_DBusObject): self.is_registering = False self._bluez_device = BlueZDevice(self.property('BlueZDevice')) self._bluez_device.connect('notify::connected', self._on_connected) + self._sync_state = 0 @classmethod def is_device_address(cls, string): @@ -208,6 +209,10 @@ class TuhiKeteDevice(_DBusObject): def connected(self): return self._bluez_device.connected + @GObject.Property + def sync_state(self): + return self._sync_state + def _on_connected(self, bluez_device, pspec): self.notify('connected') @@ -246,6 +251,9 @@ class TuhiKeteDevice(_DBusObject): elif err < 0: logger.error(f'{self}: an error occured: {os.strerror(-err)}') self.notify('listening') + elif signal == 'SyncState': + self._sync_state = parameters[0] + self.notify('sync-state') def _on_properties_changed(self, proxy, changed_props, invalidated_props): if changed_props is None: