diff --git a/lazy_player/__init__.py b/lazy_player/__init__.py index e4503f5..4f5b6cc 100644 --- a/lazy_player/__init__.py +++ b/lazy_player/__init__.py @@ -130,15 +130,18 @@ class MainWindow(Gtk.ApplicationWindow): self._navigate_to(file_item.full_path) return - position = file_item.load_attribute("position", 0) - duration = file_item.load_attribute("duration", 1) or 1 + position = file_item.saved_position + duration = file_item.saved_duration if (position / duration) >= 0.99: position = 0 # Start playing the video - track = file_item.load_attribute("subtitle_track", -2) - self.video_player.play(file_item.full_path, position, track) + self.video_player.play( + file_item.full_path, + position, + file_item.saved_subtitle_track, + ) self.last_position_save = self.now self.stack.set_visible_child_name("player") @@ -204,8 +207,8 @@ class MainWindow(Gtk.ApplicationWindow): 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 + position = item.saved_position + duration = item.saved_duration if position == 0: icon.set_from_icon_name("media-playback-start-symbolic") @@ -218,7 +221,7 @@ class MainWindow(Gtk.ApplicationWindow): icon.set_css_classes(["file-icon", "in-progress"]) label.set_text(item.name) - item.connect("notify::attrs-changed", update_icon) + item.connect("notify::saved-position", update_icon) update_icon() def _navigate_to(self, path: Path): @@ -336,15 +339,15 @@ class MainWindow(Gtk.ApplicationWindow): if file_item.file_type == FileType.DIRECTORY: return - position = file_item.load_attribute("position", 0) - duration = file_item.load_attribute("duration", 1) or 1 + position = file_item.saved_position + duration = file_item.saved_duration # If position exists and is >= 99% through, clear it if position > 0 and (position / duration) >= 0.99: - file_item.save_attribute("position", None) + file_item.saved_position = 0 else: # Otherwise mark as complete - file_item.save_attribute("position", duration) + file_item.saved_position = duration # Force the list to update the changed item self.list_model.items_changed(self.selection_model.get_selected(), 1, 1) @@ -395,11 +398,11 @@ class MainWindow(Gtk.ApplicationWindow): position = self.video_player.get_position() if position is not None: - file_item.save_attribute("position", position) + file_item.saved_position = position duration = self.video_player.get_duration() if duration is not None: - file_item.save_attribute("duration", duration) + file_item.saved_duration = duration def show_overlay_text(self, text: str, timeout_seconds: float = 1.0) -> None: """Show text in a centered overlay that disappears after timeout""" diff --git a/lazy_player/file_model.py b/lazy_player/file_model.py index 8e53c56..3bba64a 100644 --- a/lazy_player/file_model.py +++ b/lazy_player/file_model.py @@ -22,29 +22,53 @@ class FileItem(GObject.Object): __gtype_name__ = "FileItem" - attrs_changed = GObject.Property(type=int, default=0) - def __init__(self, name: str, file_type: FileType, full_path: Path): super().__init__() - self.attrs_changed = 0 self.name = name self.file_type = file_type self.full_path = full_path - @overload - def load_attribute(self, name: str, dfl: str) -> str: ... + @GObject.Property(type=GObject.TYPE_UINT64) + def saved_position(self) -> int: + return self._load_attribute("position", 0) + + @saved_position.setter + def set_saved_position(self, value: int): + self._save_attribute("position", value if value else None) + self.notify("saved-position") + + @GObject.Property(type=GObject.TYPE_UINT64) + def saved_duration(self): + return self._load_attribute("duration", 1) or 1 + + @saved_duration.setter + def set_saved_duration(self, value: int): + self._save_attribute("duration", value if value > 0 else None) + self.notify("saved-duration") + + @GObject.Property(type=int) + def saved_subtitle_track(self): + return self._load_attribute("subtitle_track", -2) + + @saved_subtitle_track.setter + def set_saved_subtitle_track(self, value: int): + self._save_attribute("subtitle_track", value if value >= -1 else None) + self.notify("saved-subtitle-track") @overload - def load_attribute(self, name: str, dfl: int) -> int: ... + def _load_attribute(self, name: str, dfl: str) -> str: ... - def load_attribute(self, name: str, dfl: str | int) -> str | int: + @overload + def _load_attribute(self, name: str, dfl: int) -> int: ... + + def _load_attribute(self, name: str, dfl: str | int) -> str | int: try: strval = os.getxattr(self.full_path, f"user.lazy_player.{name}") return type(dfl)(strval) except OSError: return dfl - def save_attribute(self, name: str, value: str | float | int | None) -> None: + def _save_attribute(self, name: str, value: str | float | int | None) -> None: try: if value is None: os.removexattr(self.full_path, f"user.lazy_player.{name}") @@ -53,8 +77,6 @@ class FileItem(GObject.Object): except OSError: pass - self.notify("attrs-changed") - class FileListModel(GObject.Object, Gio.ListModel): """A ListModel implementation for FileItems"""