feat: show hidden annotations as collapsed cards in annotation pane

Hidden annotations appear in the annotation pane as small, disabled-looking
cards with the dither pattern overlay (var(--desktop)) at 40% opacity.

On hover, an "Unhide" button appears to remove the hidden flag.
Full content, controls, and metadata are hidden.

Hidden annotations still work in marks/autocomplete and maintain their marks.
They appear as normal bars in the timeline.

Add 'Hide from timeline' checkbox in the annotation edit form.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-06-30 16:38:38 -04:00
parent 1ea675567c
commit 4ffd831551
2 changed files with 48 additions and 22 deletions

View file

@ -83,7 +83,7 @@
(->> (:groups scene)
(keep (fn [[gid g]]
(when (and (= :annotation (:type g)) (= ctx (:parent g)))
(let [src-segs (when-not (get-in g [:meta :hidden]) (scene/resolve scene gid))
(let [src-segs (scene/resolve scene gid)
bars (scene/merge-bars
(mapcat (fn [{[a b] :src}] (scene/pieces segs a b)) src-segs))
reason (scene/broken-reason scene gid)

View file

@ -796,27 +796,53 @@
(if (seq anns)
(doall
(for [a anns]
^{:key (:id a)}
[:div.ann {:id (str "ann-" (name (:id a)))
:class (when (contains? active-set (:id a)) "active")
:style {"--ann-color" (:color a)}}
[:div.ann-head
[:div.ann-title
[:span.ann-swatch {:style {:background (:color a)}}]
(when (:broken a) [:span {:title (:reason a)} "△ "]) (:name a)
(when (seq (:script a)) [:span.script-badge {:title "linked to script"} "¶"])]
[:div.ann-actions
[jump-control open a scene segs]
[:button.expand-btn {:title "Expand" :on-click #(rf/dispatch [::events/expand (:id a)])}
"⤢" (when (pos? (:nested a)) [:span.nest-badge (:nested a)])]
(when authed?
[:button.edit-btn {:title "Edit"
:on-click #(rf/dispatch [::events/edit-draft (:id a)])} "✎"])
(when authed?
[:button.del-btn {:title "Delete"
:on-click #(when (js/confirm (str "Delete \"" (:name a) "\"?"))
(rf/dispatch [::events/delete-annotation (:id a)]))} "✕"])]]
(when (not-empty (:content a)) [content-display scene ctx (:content a)])]))
(let [grp (get-in scene [:groups (:id a)])]
^{:key (:id a)}
(if (:hidden a)
;; Hidden annotation: small collapsed card
(r/with-let [hov? (r/atom false)]
[:div.ann {:id (str "ann-" (name (:id a)))
:class (when (contains? active-set (:id a)) "active")
:style (merge {"--ann-color" (:color a)}
{:opacity 0.4
:background "var(--desktop)"
:background-size "2px 2px"
:min-height "28px"
:display "flex"
:align-items "center"
:justify-content "space-between"
:padding "2px 8px"})
:on-mouse-enter #(reset! hov? true)
:on-mouse-leave #(reset! hov? false)}
[:span.ann-title {:style {:font-size 12}}
[:span.ann-swatch {:style {:background (:color a)}}]
(:name a)]
(when @hov?
[:button.edit-btn {:title "Unhide"
:on-click #(rf/dispatch [::events/put-group (:id a)
(update grp :meta dissoc :hidden)])}
"Unhide"])])
;; Normal annotation: full card
[:div.ann {:id (str "ann-" (name (:id a)))
:class (when (contains? active-set (:id a)) "active")
:style {"--ann-color" (:color a)}}
[:div.ann-head
[:div.ann-title
[:span.ann-swatch {:style {:background (:color a)}}]
(when (:broken a) [:span {:title (:reason a)} "△ "]) (:name a)
(when (seq (:script a)) [:span.script-badge {:title "linked to script"} "¶"])]
[:div.ann-actions
[jump-control open a scene segs]
[:button.expand-btn {:title "Expand" :on-click #(rf/dispatch [::events/expand (:id a)])}
"⤢" (when (pos? (:nested a)) [:span.nest-badge (:nested a)])]
(when authed?
[:button.edit-btn {:title "Edit"
:on-click #(rf/dispatch [::events/edit-draft (:id a)])} "✎"])
(when authed?
[:button.del-btn {:title "Delete"
:on-click #(when (js/confirm (str "Delete \"" (:name a) "\"?"))
(rf/dispatch [::events/delete-annotation (:id a)]))} "✕"])]]
(when (not-empty (:content a)) [content-display scene ctx (:content a)])]))))
[:div.ann-empty "No annotations here."])]))))
(defn- to-frame [v len]