From 6d09b7d1e7c57b596ad3d927adbc885848b860f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= <mordae@anilinux.org>
Date: Sun, 9 Mar 2025 10:18:12 +0100
Subject: [PATCH] Indicate watch status

---
 lazy_player/__init__.py | 32 ++++++++++++++++++++++++++------
 lazy_player/style.css   | 17 +++++++++++++----
 2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/lazy_player/__init__.py b/lazy_player/__init__.py
index 53ba543..1ed4855 100644
--- a/lazy_player/__init__.py
+++ b/lazy_player/__init__.py
@@ -217,8 +217,8 @@ class MainWindow(Gtk.ApplicationWindow):
         box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
         box.set_spacing(8)
 
-        # Create icon placeholder
-        icon = Gtk.Box()
+        # Create icon image
+        icon = Gtk.Image()
         icon.set_css_classes(["file-icon"])
         box.append(icon)
 
@@ -231,12 +231,29 @@ class MainWindow(Gtk.ApplicationWindow):
 
     def _bind_list_item(self, factory: Gtk.SignalListItemFactory, list_item: Gtk.ListItem):
         box = cast(Gtk.Box, list_item.get_child())
-        icon = cast(Gtk.Box, box.get_first_child())
+        icon = cast(Gtk.Image, box.get_first_child())
         label = cast(Gtk.Label, box.get_last_child())
         item = cast(FileItem, list_item.get_item())
 
-        # Make icon transparent for directories
-        icon.set_opacity(0.0 if item.file_type == FileType.DIRECTORY else 1.0)
+        # Set appropriate icon
+        icon.set_opacity(1.0)
+        if item.file_type == FileType.DIRECTORY:
+            icon.set_from_icon_name("folder-symbolic")
+            icon.set_css_classes(["file-icon"])
+        else:
+            position = item.load_attribute("position", 0)
+            duration = item.load_attribute("duration", 1) or 1
+
+            if position == 0:
+                icon.set_from_icon_name("checkbox-symbolic")
+                icon.set_css_classes(["file-icon", "unwatched"])
+            elif (position / duration) >= 0.9:
+                icon.set_from_icon_name("object-select-symbolic")
+                icon.set_css_classes(["file-icon", "completed"])
+            else:
+                icon.set_from_icon_name("media-playback-pause-symbolic")
+                icon.set_css_classes(["file-icon", "in-progress"])
+
         label.set_text(item.name)
 
     def _on_selection_changed(
@@ -321,7 +338,7 @@ class MainWindow(Gtk.ApplicationWindow):
             return
 
         position = file_item.load_attribute("position", 0)
-        duration = file_item.load_attribute("duration", 1)
+        duration = file_item.load_attribute("duration", 1) or 1
 
         # If position exists and is >= 90% through, clear it
         if position > 0 and (position / duration) >= 0.9:
@@ -330,6 +347,9 @@ class MainWindow(Gtk.ApplicationWindow):
             # Otherwise mark as complete
             file_item.save_attribute("position", duration)
 
+        # Force the list to update the changed item
+        self.list_store.items_changed(self.selection_model.get_selected(), 1, 1)
+
     def _on_menu_key_pressed(
         self,
         keyval: int,
diff --git a/lazy_player/style.css b/lazy_player/style.css
index db079dd..9249466 100644
--- a/lazy_player/style.css
+++ b/lazy_player/style.css
@@ -5,10 +5,19 @@ listview > row {
 }
 
 .file-icon {
-  min-width: 32px;
-  min-height: 32px;
-  margin-right: 8px;
-  border: 1px solid #666;
+  -gtk-icon-size: 24px;
+}
+
+.unwatched {
+  color: #666;
+}
+
+.in-progress {
+  color: #ff0;
+}
+
+.completed {
+  color: #0f0;
 }
 
 #black-overlay {