very nice
This commit is contained in:
@@ -60,6 +60,7 @@ class ChtWindow(Adw.ApplicationWindow):
|
||||
on_transcript_ready=lambda segs: self._transcript_panel.add_items(segs),
|
||||
on_scene_marker=lambda ts: self._timeline.add_scene_marker(ts),
|
||||
on_recorder_restarted=lambda path: self._monitor.set_recording(path),
|
||||
on_manifest_updated=lambda: self._update_scrub_bar_manifest(),
|
||||
)
|
||||
|
||||
# Panels (own their selection state)
|
||||
@@ -252,20 +253,33 @@ class ChtWindow(Adw.ApplicationWindow):
|
||||
log.info("Waiting for sender...")
|
||||
|
||||
def _on_live_toggle(self):
|
||||
pos = self._monitor.get_live_position()
|
||||
self._timeline.toggle_live(live_player_pos=pos)
|
||||
if self._timeline.state.live:
|
||||
# Live → Scrub: don't load growing MKV, let user pick a segment
|
||||
self._timeline.toggle_live(live_player_pos=self._monitor.get_live_position())
|
||||
# Refresh manifest so scrub bar shows completed segments
|
||||
self._update_scrub_bar_manifest()
|
||||
else:
|
||||
# Scrub → Live: restore recording path and resume
|
||||
mgr = self._lifecycle.stream_mgr
|
||||
if mgr:
|
||||
self._monitor.set_recording(mgr.recording_path)
|
||||
self._timeline.toggle_live()
|
||||
|
||||
# -- Scrub --
|
||||
|
||||
def _update_scrub_bar_manifest(self):
|
||||
"""Refresh the scrub bar with the current session's segment manifest."""
|
||||
"""Refresh the scrub bar with the current session's segment manifest and frames."""
|
||||
mgr = self._lifecycle.stream_mgr
|
||||
if not mgr:
|
||||
return
|
||||
self._manifest = load_segment_manifest(mgr.session_dir)
|
||||
if not self._manifest:
|
||||
self._manifest = rebuild_manifest(mgr.session_dir)
|
||||
self._timeline_controls.scrub_bar.set_manifest(self._manifest)
|
||||
scrub_bar = self._timeline_controls.scrub_bar
|
||||
scrub_bar.set_manifest(self._manifest)
|
||||
# Feed frame thumbnails to the scrub bar
|
||||
frames = load_frame_index(mgr.frames_dir)
|
||||
scrub_bar.set_frames([{"timestamp": f["timestamp"], "path": str(f["path"])} for f in frames])
|
||||
|
||||
def _on_segment_activated(self, scrub_bar, segment_index):
|
||||
"""User clicked a segment block — request its proxy."""
|
||||
@@ -327,12 +341,16 @@ class ChtWindow(Adw.ApplicationWindow):
|
||||
def _scrub_tick(self):
|
||||
"""Release throttle so next scrub motion can update monitor."""
|
||||
self._scrub_pending = False
|
||||
cursor = self._timeline.state.cursor
|
||||
# Apply latest cursor position to monitor
|
||||
seg, local_time = global_time_to_segment(
|
||||
self._manifest, self._timeline.state.cursor
|
||||
)
|
||||
seg, local_time = global_time_to_segment(self._manifest, cursor)
|
||||
if seg:
|
||||
self._monitor.scrub_to(local_time)
|
||||
# Sync waveform, time labels, etc. at throttled rate
|
||||
self._timeline.emit("changed")
|
||||
# Highlight nearest frame/transcript
|
||||
self._frames_panel.highlight_nearest(cursor)
|
||||
self._transcript_panel.highlight_nearest(cursor)
|
||||
return False
|
||||
|
||||
def _capture_at_scrub_position(self):
|
||||
@@ -583,6 +601,10 @@ class ChtWindow(Adw.ApplicationWindow):
|
||||
self._frames_panel.load_items(items)
|
||||
self._known_frames = {item["id"] for item in items}
|
||||
self._agent_output.append(f" Loaded {len(items)} frame thumbnails.\n")
|
||||
# Update scrub bar thumbnails
|
||||
self._timeline_controls.scrub_bar.set_frames(
|
||||
[{"timestamp": e["timestamp"], "path": str(e["path"])} for e in entries]
|
||||
)
|
||||
|
||||
def _load_existing_transcript(self):
|
||||
if not self._lifecycle.stream_mgr:
|
||||
@@ -608,6 +630,7 @@ class ChtWindow(Adw.ApplicationWindow):
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(str(entry["path"]), 256, 144, True)
|
||||
auto = not self._transcript_panel.has_selection
|
||||
self._frames_panel.add_item(fid, pixbuf, entry["timestamp"], auto_select=auto)
|
||||
self._timeline_controls.scrub_bar.add_frame(entry["timestamp"], str(entry["path"]))
|
||||
except Exception as e:
|
||||
log.warning("Thumbnail load failed for %s: %s", fid, e)
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user