nandi/frqpublic Fork 0
a1cd517
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Say who reacted, when the pointer rests on a pill

A count says three people; it does not say which three, which is the thing
a room is read for. Resting on a pill raises the names beside it, the way
resting on a face raises the profile card — one card at a time, hung on the
hovered pill alone, and only where there is a pointer to hover with.

The pins move with it: the chip learned its hover in jolt-native, so the
build takes both libraries and glimmer-vidya from the commit that has it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-08-31T18:14:41-07:00 Browse files
a1cd517 parent: ae207b8
modified deps.edn +1 -1
@@ -13,7 +13,7 @@
1313 :deps {jolt-lang/glimmer {:git/url "https://gitlab.com/nandithebull/glimmer"
1414 :git/sha "399df371c790d690fb6e4560c3d4d7f838502857"}
1515 nandi/glimmer-vidya {:git/url "https://gitlab.com/nandithebull/jolt-native"
16- :git/sha "70072e8e48ad396caeab6f6bd18b999cf449ec8f"
16+ :git/sha "c71fc595f031aaa5cb461735af1865146f7b42ec"
1717 :deps/root "jolt/glimmer-vidya"}}
1818
1919 ;; Both objects come from gitlab.com/nandithebull/jolt-native, one crate each,
@@ -13,7 +13,7 @@
13 :deps {jolt-lang/glimmer {:git/url "https://gitlab.com/nandithebull/glimmer"13 :deps {jolt-lang/glimmer {:git/url "https://gitlab.com/nandithebull/glimmer"
14 :git/sha "399df371c790d690fb6e4560c3d4d7f838502857"}14 :git/sha "399df371c790d690fb6e4560c3d4d7f838502857"}
15 nandi/glimmer-vidya {:git/url "https://gitlab.com/nandithebull/jolt-native"15 nandi/glimmer-vidya {:git/url "https://gitlab.com/nandithebull/jolt-native"
16- :git/sha "70072e8e48ad396caeab6f6bd18b999cf449ec8f"16+ :git/sha "c71fc595f031aaa5cb461735af1865146f7b42ec"
17 :deps/root "jolt/glimmer-vidya"}}17 :deps/root "jolt/glimmer-vidya"}}
18 18
19 ;; Both objects come from gitlab.com/nandithebull/jolt-native, one crate each,19 ;; Both objects come from gitlab.com/nandithebull/jolt-native, one crate each,
modified justfile +1 -1
@@ -13,7 +13,7 @@ checkout := parent_directory(`git rev-parse --path-format=absolute --git-common-
1313 # gets a clone of the gitlab repo under .jolt-native, pinned to the same commit
1414 # deps.edn takes glimmer-vidya from.
1515 jolt_native_url := "https://gitlab.com/nandithebull/jolt-native.git"
16-jolt_native_sha := "70072e8e48ad396caeab6f6bd18b999cf449ec8f"
16+jolt_native_sha := "c71fc595f031aaa5cb461735af1865146f7b42ec"
1717 jolt_native := `
1818 checkout="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"
1919 if [ -d "$checkout/../jolt-native" ]; then
@@ -13,7 +13,7 @@ checkout := parent_directory(`git rev-parse --path-format=absolute --git-common-
13 # gets a clone of the gitlab repo under .jolt-native, pinned to the same commit13 # gets a clone of the gitlab repo under .jolt-native, pinned to the same commit
14 # deps.edn takes glimmer-vidya from.14 # deps.edn takes glimmer-vidya from.
15 jolt_native_url := "https://gitlab.com/nandithebull/jolt-native.git"15 jolt_native_url := "https://gitlab.com/nandithebull/jolt-native.git"
16-jolt_native_sha := "70072e8e48ad396caeab6f6bd18b999cf449ec8f"16+jolt_native_sha := "c71fc595f031aaa5cb461735af1865146f7b42ec"
17 jolt_native := `17 jolt_native := `
18 checkout="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"18 checkout="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"
19 if [ -d "$checkout/../jolt-native" ]; then19 if [ -d "$checkout/../jolt-native" ]; then
modified src/frq/app.jolt +35 -6
@@ -329,6 +329,24 @@
329329 :size pill-size
330330 :on-click #(s/reply-to! m)}]])
331331
332+(defn- reactor-card
333+ "Who is on a reaction, beside the pointer resting on it.
334+
335+ The pill carries a number, and a number is the one thing about a reaction
336+ nobody wants: who it was is what a room is read for. Names, one to a line,
337+ with your own said as \"you\" — you are the one name in the list you cannot
338+ learn anything from."
339+ [emoji nicks]
340+ [:vbox {:spacing 4}
341+ [:hbox {:spacing 6}
342+ [:reaction {:key :glyph :emoji emoji :size pill-size}]
343+ [:dim-label {:label (str (count nicks)
344+ (if (= 1 (count nicks)) " reaction" " reactions"))}]]
345+ [:vbox {:key :who :spacing 2}
346+ (for [nick (sort nicks)]
347+ [:label {:key nick
348+ :label (if (= nick @s/form-nick) "you" nick)}])]])
349+
332350 (defn- reaction-row
333351 "What people have put on a message, under it.
334352
@@ -340,12 +358,23 @@
340358 (let [reactions (:reactions m)]
341359 [:hbox {:key :pills :spacing 4}
342360 (for [emoji (sort (keys reactions))]
343- [:reaction {:key emoji
344- :emoji emoji
345- :size pill-size
346- :count (count (get reactions emoji))
347- :mine (s/my-reaction? m emoji)
348- :on-click #(s/toggle-reaction! channel m emoji)}])]))
361+ [:reaction (cond-> {:key emoji
362+ :emoji emoji
363+ :size pill-size
364+ :count (count (get reactions emoji))
365+ :mine (s/my-reaction? m emoji)
366+ :on-click #(s/toggle-reaction! channel m emoji)}
367+ ;; Where there is a pointer to ask with, resting on a pill
368+ ;; says who put it there. On a phone the pill is a button
369+ ;; and nothing more: there is no hover to answer.
370+ (platform/desktop?)
371+ (assoc :on-hover #(s/hover-reaction! (:id m) emoji)
372+ :on-unhover #(s/unhover-reaction! (:id m) emoji)))
373+ ;; Only the hovered pill carries a card: the panel is painted from
374+ ;; whatever children the node has, and a channel's worth of unseen
375+ ;; lists is a tree nobody looks at.
376+ (when (and (platform/desktop?) (s/hovering-reaction? (:id m) emoji))
377+ [reactor-card emoji (get reactions emoji)])])]))
349378
350379 (def ^:private picker-columns
351380 "Emoji to a row, at the picker's own size. Narrow enough that the grid fits a
@@ -329,6 +329,24 @@
329 :size pill-size329 :size pill-size
330 :on-click #(s/reply-to! m)}]])330 :on-click #(s/reply-to! m)}]])
331 331
332+(defn- reactor-card
333+ "Who is on a reaction, beside the pointer resting on it.
334+
335+ The pill carries a number, and a number is the one thing about a reaction
336+ nobody wants: who it was is what a room is read for. Names, one to a line,
337+ with your own said as \"you\" — you are the one name in the list you cannot
338+ learn anything from."
339+ [emoji nicks]
340+ [:vbox {:spacing 4}
341+ [:hbox {:spacing 6}
342+ [:reaction {:key :glyph :emoji emoji :size pill-size}]
343+ [:dim-label {:label (str (count nicks)
344+ (if (= 1 (count nicks)) " reaction" " reactions"))}]]
345+ [:vbox {:key :who :spacing 2}
346+ (for [nick (sort nicks)]
347+ [:label {:key nick
348+ :label (if (= nick @s/form-nick) "you" nick)}])]])
349+
332 (defn- reaction-row350 (defn- reaction-row
333 "What people have put on a message, under it.351 "What people have put on a message, under it.
334 352
@@ -340,12 +358,23 @@
340 (let [reactions (:reactions m)]358 (let [reactions (:reactions m)]
341 [:hbox {:key :pills :spacing 4}359 [:hbox {:key :pills :spacing 4}
342 (for [emoji (sort (keys reactions))]360 (for [emoji (sort (keys reactions))]
343- [:reaction {:key emoji361+ [:reaction (cond-> {:key emoji
344- :emoji emoji362+ :emoji emoji
345- :size pill-size363+ :size pill-size
346- :count (count (get reactions emoji))364+ :count (count (get reactions emoji))
347- :mine (s/my-reaction? m emoji)365+ :mine (s/my-reaction? m emoji)
348- :on-click #(s/toggle-reaction! channel m emoji)}])]))366+ :on-click #(s/toggle-reaction! channel m emoji)}
367+ ;; Where there is a pointer to ask with, resting on a pill
368+ ;; says who put it there. On a phone the pill is a button
369+ ;; and nothing more: there is no hover to answer.
370+ (platform/desktop?)
371+ (assoc :on-hover #(s/hover-reaction! (:id m) emoji)
372+ :on-unhover #(s/unhover-reaction! (:id m) emoji)))
373+ ;; Only the hovered pill carries a card: the panel is painted from
374+ ;; whatever children the node has, and a channel's worth of unseen
375+ ;; lists is a tree nobody looks at.
376+ (when (and (platform/desktop?) (s/hovering-reaction? (:id m) emoji))
377+ [reactor-card emoji (get reactions emoji)])])]))
349 378
350 (def ^:private picker-columns379 (def ^:private picker-columns
351 "Emoji to a row, at the picker's own size. Narrow enough that the grid fits a380 "Emoji to a row, at the picker's own size. Narrow enough that the grid fits a
modified src/frq/state.jolt +23 -0
@@ -1149,6 +1149,29 @@
11491149 [m emoji]
11501150 (boolean (some #{@form-nick} (get (:reactions m) emoji))))
11511151
1152+;; The pill the pointer is resting on, or nil — `{:id msgid :emoji glyph}`.
1153+;; One at a time, and named by the message as well as the glyph: the same emoji
1154+;; is a pill under many messages, and only the one under the pointer carries a
1155+;; card.
1156+(defonce reaction-hover (atom nil))
1157+
1158+(defn hover-reaction!
1159+ "The pointer has come to rest on a pill."
1160+ [msgid emoji]
1161+ (reset! reaction-hover {:id msgid :emoji emoji}))
1162+
1163+(defn unhover-reaction!
1164+ "The pointer has left that pill. Guarded by which one is being left, so
1165+ crossing straight from one pill to the next — both edges in a frame — cannot
1166+ take down the card that has just been raised."
1167+ [msgid emoji]
1168+ (swap! reaction-hover #(when-not (= {:id msgid :emoji emoji} %) %)))
1169+
1170+(defn hovering-reaction?
1171+ "Whether this is the pill the card belongs to."
1172+ [msgid emoji]
1173+ (= {:id msgid :emoji emoji} @reaction-hover))
1174+
11521175 (defn toggle-reaction!
11531176 "Put my emoji on a message, or take it off if it is already mine.
11541177
@@ -1149,6 +1149,29 @@
1149 [m emoji]1149 [m emoji]
1150 (boolean (some #{@form-nick} (get (:reactions m) emoji))))1150 (boolean (some #{@form-nick} (get (:reactions m) emoji))))
1151 1151
1152+;; The pill the pointer is resting on, or nil — `{:id msgid :emoji glyph}`.
1153+;; One at a time, and named by the message as well as the glyph: the same emoji
1154+;; is a pill under many messages, and only the one under the pointer carries a
1155+;; card.
1156+(defonce reaction-hover (atom nil))
1157+
1158+(defn hover-reaction!
1159+ "The pointer has come to rest on a pill."
1160+ [msgid emoji]
1161+ (reset! reaction-hover {:id msgid :emoji emoji}))
1162+
1163+(defn unhover-reaction!
1164+ "The pointer has left that pill. Guarded by which one is being left, so
1165+ crossing straight from one pill to the next — both edges in a frame — cannot
1166+ take down the card that has just been raised."
1167+ [msgid emoji]
1168+ (swap! reaction-hover #(when-not (= {:id msgid :emoji emoji} %) %)))
1169+
1170+(defn hovering-reaction?
1171+ "Whether this is the pill the card belongs to."
1172+ [msgid emoji]
1173+ (= {:id msgid :emoji emoji} @reaction-hover))
1174+
1152 (defn toggle-reaction!1175 (defn toggle-reaction!
1153 "Put my emoji on a message, or take it off if it is already mine.1176 "Put my emoji on a message, or take it off if it is already mine.
1154 1177