nandi/frqpublic Fork 0
49fb82f
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.

Share Discover and Settings, and the frame around them

The small two, and the cheapest of the ports: three definitions and 69 lines,
one new cell, one constant and one action, and the renderer needed nothing at
all — `frq.screens.settings` compiled for ClojureDart first time and drew
correctly on the first run. That is what the last three screens were for.

`tab-screen` comes with them because it is what puts a tab bar under a
screen, and all three of them are one.

Discover is worth looking at on the phone: it offers Open for a room you are
already in and Join for the rest, which is the shared screen reading
`frq.cells/channels` — the same logic, from the same file, over state the
phone filled in itself.

Two things the move exposed, both in text nobody had read in a while. The
about line said the components were painted on the Vidya/egui backend, which
has been two backends ago for some time and was never true on a phone; it is
a reader conditional now, like the TLS note, because what paints them is the
one thing that genuinely differs. And Quit is gone where there is nothing to
quit: closing an app is a window's idea and Android has its own way out, so
it asks `actions/desktop?` first.

frq.app is 565 lines. It was 1,744 this morning.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-11T23:22:02-07:00 Browse files
49fb82f parent: c0121fe
modified common/frq/actions.cljc +1 -1
@@ -138,4 +138,4 @@
138138 (defn profile-hover! [& args] (call :profile-hover! args))
139139 (defn profile-unhover! [& args] (call :profile-unhover! args))
140140 (defn profile-open! [& args] (call :profile-open! args))
141-
141+(defn toggle-hide-join-part! [] (call :toggle-hide-join-part! []))
@@ -138,4 +138,4 @@
138 (defn profile-hover! [& args] (call :profile-hover! args))138 (defn profile-hover! [& args] (call :profile-hover! args))
139 (defn profile-unhover! [& args] (call :profile-unhover! args))139 (defn profile-unhover! [& args] (call :profile-unhover! args))
140 (defn profile-open! [& args] (call :profile-open! args))140 (defn profile-open! [& args] (call :profile-open! args))
141-141+(defn toggle-hide-join-part! [] (call :toggle-hide-join-part! []))
modified common/frq/cells.cljc +17 -0
@@ -191,3 +191,20 @@
191191 ;; is a pill under many messages, and only the one under the pointer carries a
192192 ;; card.
193193 (defonce reaction-hover (atom nil))
194+
195+;; Comings and goings, hidden or not. A quiet room reads better with them —
196+;; they are how you notice someone arriving — and a busy one drowns in them,
197+;; so it is the reader's call. Only other people's: your own "Joined #chan" is
198+;; the answer to something you just did.
199+(defonce hide-join-part? (atom false))
200+
201+(def popular-channels
202+ [["#general" "General discussion"]
203+ ["#test" "Test channel"]
204+ ["#freeq" "freeq development & support"]
205+ ["#dev" "Programming & technology"]
206+ ["#music" "Music recommendations"]
207+ ["#random" "Off-topic chat"]])
208+
209+
210+;; joined as soon as the server sends 001
@@ -191,3 +191,20 @@
191 ;; is a pill under many messages, and only the one under the pointer carries a191 ;; is a pill under many messages, and only the one under the pointer carries a
192 ;; card.192 ;; card.
193 (defonce reaction-hover (atom nil))193 (defonce reaction-hover (atom nil))
194+
195+;; Comings and goings, hidden or not. A quiet room reads better with them —
196+;; they are how you notice someone arriving — and a busy one drowns in them,
197+;; so it is the reader's call. Only other people's: your own "Joined #chan" is
198+;; the answer to something you just did.
199+(defonce hide-join-part? (atom false))
200+
201+(def popular-channels
202+ [["#general" "General discussion"]
203+ ["#test" "Test channel"]
204+ ["#freeq" "freeq development & support"]
205+ ["#dev" "Programming & technology"]
206+ ["#music" "Music recommendations"]
207+ ["#random" "Off-topic chat"]])
208+
209+
210+;; joined as soon as the server sends 001
added common/frq/screens/settings.cljc +88 -0
new file mode 100644
@@ -0,0 +1,88 @@
1+(ns frq.screens.settings
2+ "Discover and Settings, and the frame the tab bar sits in.
3+
4+ The small two, and the last of frq.app's screens to move but the least
5+ interesting: a list of rooms to join and a page of switches. `tab-screen`
6+ comes with them because it is what puts a tab bar under a screen, and all
7+ three of them are one."
8+ (:require [clojure.string :as str]
9+ [frq.actions :as actions]
10+ [frq.cells :as cells]
11+ [frq.screens.chats :refer [below-list tab-bar]]
12+ [frq.screens.connect :refer [error-note]]))
13+
14+(defn- tab-screen
15+ "One of the three screens the tab bar moves between, in the chats screen's
16+ shape: the title at the top, the tabs pinned at the bottom, and `body`
17+ scrolling between them.
18+
19+ The same shape for all three, so switching tabs moves nothing but the
20+ middle. As pages they were centred columns of their own widths with the tabs
21+ wherever the content happened to end, and every switch resized the screen
22+ under the pointer."
23+ [title scroll-key & body]
24+ [:vbox {:spacing 8 :margin 12 :fill-height true}
25+ [:title {:label title}]
26+ [:vbox {:key :list :fill-height true}
27+ (into [:scroll {:scroll-key scroll-key :orientation :vertical
28+ :reserve (below-list) :spacing 8}]
29+ body)]
30+ [:vbox {:key :foot :spacing 8}
31+ [:separator {}]
32+ [tab-bar]]])
33+
34+(defn discover-screen []
35+ (tab-screen "Discover" "discover-list"
36+ [:dim-label {:label "Popular channels on freeq."}]
37+ [error-note]
38+ (for [[name blurb] cells/popular-channels]
39+ (let [joined? (get-in @cells/channels [name :joined?])]
40+ [:card {:key name}
41+ [:title-2 {:label name}]
42+ [:dim-label {:label blurb}]
43+ [:button {:label (if joined? "Open" "Join")
44+ :kind :primary
45+ :on-click #(if joined? (actions/open-channel! name) (actions/join! name))}]]))))
46+
47+(defn settings-screen []
48+ (tab-screen "Settings" "settings-list"
49+ [:card {}
50+ [:title-2 {:label "Connection"}]
51+ [:status {:label @cells/status :live (actions/connected?)}]
52+ [:label {:label (str "Server: " @cells/form-host ":" @cells/form-port)}]
53+ [:label {:label (str "Nick: " @cells/form-nick)}]
54+ (if-let [sess @cells/session]
55+ [:vbox {:spacing 2}
56+ [:label {:label (str "Signed in as " (:handle sess))}]
57+ [:dim-label {:label (or (:did sess) "")}]
58+ [:vbox {:key :forget}
59+ (when @cells/broker-token
60+ [:button {:label "Forget Bluesky session"
61+ :kind :destructive
62+ :on-click actions/forget-session!}])]]
63+ [:dim-label {:label "Guest — not signed in."}])
64+ [:separator {}]
65+ ;; Nothing to disconnect from when there is no connection the way back to
66+ ;; the connect screen is what is wanted then.
67+ [:vbox {:key :connection-action}
68+ (if (actions/connected?)
69+ [:button {:label "Disconnect" :kind :destructive :on-click actions/disconnect!}]
70+ [:button {:label "Back to connect"
71+ :on-click #(reset! cells/screen :connect)}])]]
72+ [:card {}
73+ [:title-2 {:label "Messages"}]
74+ [:checkbutton {:label "Hide join/part messages"
75+ :active @cells/hide-join-part?
76+ :on-toggled actions/toggle-hide-join-part!}]
77+ [:dim-label {:label "Hides other people arriving, leaving and quitting. The people panel still follows who is here."}]]
78+ [:card {}
79+ [:title-2 {:label "frq"}]
80+ ;; What this is, which is not the same sentence on both: the components
81+ ;; are the same file either way, and what paints them is not. Vidya and
82+ ;; egui were what it said, and both have been gone a while.
83+ [:dim-label {:label #?(:cljd "freeq client — the same glimmer components as the desktop, compiled by ClojureDart and painted by Flutter."
84+ :jolt "freeq client in jolt — glimmer components, painted by libcosmic.")}]
85+ ;; No Quit where there is nothing to quit: closing an app is a window's
86+ ;; idea, and Android has its own way of leaving one.
87+ (when (actions/desktop?)
88+ [:button {:label "Quit" :on-click actions/quit!}])]))
new file mode 100644
@@ -0,0 +1,88 @@
1+(ns frq.screens.settings
2+ "Discover and Settings, and the frame the tab bar sits in.
3+
4+ The small two, and the last of frq.app's screens to move but the least
5+ interesting: a list of rooms to join and a page of switches. `tab-screen`
6+ comes with them because it is what puts a tab bar under a screen, and all
7+ three of them are one."
8+ (:require [clojure.string :as str]
9+ [frq.actions :as actions]
10+ [frq.cells :as cells]
11+ [frq.screens.chats :refer [below-list tab-bar]]
12+ [frq.screens.connect :refer [error-note]]))
13+
14+(defn- tab-screen
15+ "One of the three screens the tab bar moves between, in the chats screen's
16+ shape: the title at the top, the tabs pinned at the bottom, and `body`
17+ scrolling between them.
18+
19+ The same shape for all three, so switching tabs moves nothing but the
20+ middle. As pages they were centred columns of their own widths with the tabs
21+ wherever the content happened to end, and every switch resized the screen
22+ under the pointer."
23+ [title scroll-key & body]
24+ [:vbox {:spacing 8 :margin 12 :fill-height true}
25+ [:title {:label title}]
26+ [:vbox {:key :list :fill-height true}
27+ (into [:scroll {:scroll-key scroll-key :orientation :vertical
28+ :reserve (below-list) :spacing 8}]
29+ body)]
30+ [:vbox {:key :foot :spacing 8}
31+ [:separator {}]
32+ [tab-bar]]])
33+
34+(defn discover-screen []
35+ (tab-screen "Discover" "discover-list"
36+ [:dim-label {:label "Popular channels on freeq."}]
37+ [error-note]
38+ (for [[name blurb] cells/popular-channels]
39+ (let [joined? (get-in @cells/channels [name :joined?])]
40+ [:card {:key name}
41+ [:title-2 {:label name}]
42+ [:dim-label {:label blurb}]
43+ [:button {:label (if joined? "Open" "Join")
44+ :kind :primary
45+ :on-click #(if joined? (actions/open-channel! name) (actions/join! name))}]]))))
46+
47+(defn settings-screen []
48+ (tab-screen "Settings" "settings-list"
49+ [:card {}
50+ [:title-2 {:label "Connection"}]
51+ [:status {:label @cells/status :live (actions/connected?)}]
52+ [:label {:label (str "Server: " @cells/form-host ":" @cells/form-port)}]
53+ [:label {:label (str "Nick: " @cells/form-nick)}]
54+ (if-let [sess @cells/session]
55+ [:vbox {:spacing 2}
56+ [:label {:label (str "Signed in as " (:handle sess))}]
57+ [:dim-label {:label (or (:did sess) "")}]
58+ [:vbox {:key :forget}
59+ (when @cells/broker-token
60+ [:button {:label "Forget Bluesky session"
61+ :kind :destructive
62+ :on-click actions/forget-session!}])]]
63+ [:dim-label {:label "Guest — not signed in."}])
64+ [:separator {}]
65+ ;; Nothing to disconnect from when there is no connection the way back to
66+ ;; the connect screen is what is wanted then.
67+ [:vbox {:key :connection-action}
68+ (if (actions/connected?)
69+ [:button {:label "Disconnect" :kind :destructive :on-click actions/disconnect!}]
70+ [:button {:label "Back to connect"
71+ :on-click #(reset! cells/screen :connect)}])]]
72+ [:card {}
73+ [:title-2 {:label "Messages"}]
74+ [:checkbutton {:label "Hide join/part messages"
75+ :active @cells/hide-join-part?
76+ :on-toggled actions/toggle-hide-join-part!}]
77+ [:dim-label {:label "Hides other people arriving, leaving and quitting. The people panel still follows who is here."}]]
78+ [:card {}
79+ [:title-2 {:label "frq"}]
80+ ;; What this is, which is not the same sentence on both: the components
81+ ;; are the same file either way, and what paints them is not. Vidya and
82+ ;; egui were what it said, and both have been gone a while.
83+ [:dim-label {:label #?(:cljd "freeq client — the same glimmer components as the desktop, compiled by ClojureDart and painted by Flutter."
84+ :jolt "freeq client in jolt — glimmer components, painted by libcosmic.")}]
85+ ;; No Quit where there is nothing to quit: closing an app is a window's
86+ ;; idea, and Android has its own way of leaving one.
87+ (when (actions/desktop?)
88+ [:button {:label "Quit" :on-click actions/quit!}])]))
modified flutter/README.md +5 -4
@@ -135,12 +135,13 @@ screen rather than the subtree that read it. Fine at this size.
135135 reads is `frq.cells` and what it calls is `frq.actions`, and each platform
136136 fills those in: `frq.state`'s reducers on the desktop, dart:io here.
137137
138-## Three screens shared, all drawn on both
138+## Five screens shared, all drawn on both
139139
140-`frq.screens.connect`, `frq.screens.chats` and `frq.screens.chat` are in
141-`common/`, with the cells under them in `frq.cells`, the derivations in
140+`frq.screens.connect`, `frq.screens.chats`, `frq.screens.chat` and
141+`frq.screens.settings` — the last carrying Discover, Settings and the frame the
142+tab bar sits in — are in `common/`, with the cells under them in `frq.cells`, the derivations in
142143 `frq.rooms`, the backend metrics in `frq.metrics` and everything a screen
143-cannot do itself behind `frq.actions`. `frq.app` is 621 lines and was 1,744.
144+cannot do itself behind `frq.actions`. `frq.app` is 565 lines and was 1,744.
144145
145146 What `Length::Fill` means took four goes to get right, and the rule it ended
146147 at is worth stating once: a child that fills is Flutter's `Expanded`, the
@@ -135,12 +135,13 @@ screen rather than the subtree that read it. Fine at this size.
135 reads is `frq.cells` and what it calls is `frq.actions`, and each platform135 reads is `frq.cells` and what it calls is `frq.actions`, and each platform
136 fills those in: `frq.state`'s reducers on the desktop, dart:io here.136 fills those in: `frq.state`'s reducers on the desktop, dart:io here.
137 137
138-## Three screens shared, all drawn on both138+## Five screens shared, all drawn on both
139 139
140-`frq.screens.connect`, `frq.screens.chats` and `frq.screens.chat` are in140+`frq.screens.connect`, `frq.screens.chats`, `frq.screens.chat` and
141-`common/`, with the cells under them in `frq.cells`, the derivations in141+`frq.screens.settings` — the last carrying Discover, Settings and the frame the
142+tab bar sits in — are in `common/`, with the cells under them in `frq.cells`, the derivations in
142 `frq.rooms`, the backend metrics in `frq.metrics` and everything a screen143 `frq.rooms`, the backend metrics in `frq.metrics` and everything a screen
143-cannot do itself behind `frq.actions`. `frq.app` is 621 lines and was 1,744.144+cannot do itself behind `frq.actions`. `frq.app` is 565 lines and was 1,744.
144 145
145 What `Length::Fill` means took four goes to get right, and the rule it ended146 What `Length::Fill` means took four goes to get right, and the rule it ended
146 at is worth stating once: a child that fills is Flutter's `Expanded`, the147 at is worth stating once: a child that fills is Flutter's `Expanded`, the
modified flutter/src/frq/main.cljd +8 -0
@@ -32,6 +32,7 @@
3232 [frq.screens.connect :as connect]
3333 [frq.screens.chats :as chats]
3434 [frq.screens.chat :as chat]
35+ [frq.screens.settings :as settings]
3536 [frq.rooms :as rooms]
3637 [frq.irc.parse :as irc]))
3738
@@ -275,6 +276,11 @@
275276 :toggle-users! (fn [] (swap! cells/show-users? not))
276277 :toggle-overview! (fn [] (swap! cells/overview? not))
277278 :toggle-chat-list! (fn [] (swap! cells/hide-chat-list? not))
279+ :toggle-hide-join-part! (fn [] (swap! cells/hide-join-part? not))
280+ :quit! (fn [] nil)
281+ :forget-session! (fn []
282+ (reset! cells/broker-token nil)
283+ (reset! cells/session nil))
278284 :jump-to-present! (fn [] (reset! cells/at-present? true))
279285 :open-channel! (fn [name]
280286 (reset! cells/current name)
@@ -329,4 +335,6 @@
329335 :connect [connect/connect-screen]
330336 :chats [chats/chats-screen]
331337 :chat [chat/chat-screen]
338+ :discover [settings/discover-screen]
339+ :settings [settings/settings-screen]
332340 [connected-screen]))))))
@@ -32,6 +32,7 @@
32 [frq.screens.connect :as connect]32 [frq.screens.connect :as connect]
33 [frq.screens.chats :as chats]33 [frq.screens.chats :as chats]
34 [frq.screens.chat :as chat]34 [frq.screens.chat :as chat]
35+ [frq.screens.settings :as settings]
35 [frq.rooms :as rooms]36 [frq.rooms :as rooms]
36 [frq.irc.parse :as irc]))37 [frq.irc.parse :as irc]))
37 38
@@ -275,6 +276,11 @@
275 :toggle-users! (fn [] (swap! cells/show-users? not))276 :toggle-users! (fn [] (swap! cells/show-users? not))
276 :toggle-overview! (fn [] (swap! cells/overview? not))277 :toggle-overview! (fn [] (swap! cells/overview? not))
277 :toggle-chat-list! (fn [] (swap! cells/hide-chat-list? not))278 :toggle-chat-list! (fn [] (swap! cells/hide-chat-list? not))
279+ :toggle-hide-join-part! (fn [] (swap! cells/hide-join-part? not))
280+ :quit! (fn [] nil)
281+ :forget-session! (fn []
282+ (reset! cells/broker-token nil)
283+ (reset! cells/session nil))
278 :jump-to-present! (fn [] (reset! cells/at-present? true))284 :jump-to-present! (fn [] (reset! cells/at-present? true))
279 :open-channel! (fn [name]285 :open-channel! (fn [name]
280 (reset! cells/current name)286 (reset! cells/current name)
@@ -329,4 +335,6 @@
329 :connect [connect/connect-screen]335 :connect [connect/connect-screen]
330 :chats [chats/chats-screen]336 :chats [chats/chats-screen]
331 :chat [chat/chat-screen]337 :chat [chat/chat-screen]
338+ :discover [settings/discover-screen]
339+ :settings [settings/settings-screen]
332 [connected-screen]))))))340 [connected-screen]))))))
modified src/frq/app.clj +2 -69
@@ -37,6 +37,8 @@
3737 ;; phone renders this very file.
3838 [frq.screens.chats :refer [below-list chats-screen conversation-row
3939 preview-line tab-bar]]
40+ [frq.screens.settings :refer [discover-screen settings-screen
41+ tab-screen]]
4042 [frq.screens.chat :refer [chat-screen emoji-picker message-row
4143 reactor-dialog sidebar-width
4244 users-panel]]
@@ -418,77 +420,8 @@
418420
419421 ;; ---------------------------------------------------------------- discover
420422
421-(defn- tab-screen
422- "One of the three screens the tab bar moves between, in the chats screen's
423- shape: the title at the top, the tabs pinned at the bottom, and `body`
424- scrolling between them.
425-
426- The same shape for all three, so switching tabs moves nothing but the
427- middle. As pages they were centred columns of their own widths with the tabs
428- wherever the content happened to end, and every switch resized the screen
429- under the pointer."
430- [title scroll-key & body]
431- [:vbox {:spacing 8 :margin 12 :fill-height true}
432- [:title {:label title}]
433- [:vbox {:key :list :fill-height true}
434- (into [:scroll {:scroll-key scroll-key :orientation :vertical
435- :reserve (below-list) :spacing 8}]
436- body)]
437- [:vbox {:key :foot :spacing 8}
438- [:separator {}]
439- [tab-bar]]])
440-
441-(defn discover-screen []
442- (tab-screen "Discover" "discover-list"
443- [:dim-label {:label "Popular channels on freeq."}]
444- [error-note]
445- (for [[name blurb] s/popular-channels]
446- (let [joined? (get-in @s/channels [name :joined?])]
447- [:card {:key name}
448- [:title-2 {:label name}]
449- [:dim-label {:label blurb}]
450- [:button {:label (if joined? "Open" "Join")
451- :kind :primary
452- :on-click #(if joined? (s/open-channel! name) (s/join! name))}]]))))
453-
454423 ;; ---------------------------------------------------------------- settings
455424
456-(defn settings-screen []
457- (tab-screen "Settings" "settings-list"
458- [:card {}
459- [:title-2 {:label "Connection"}]
460- [:status {:label @s/status :live (s/connected?)}]
461- [:label {:label (str "Server: " @s/form-host ":" @s/form-port)}]
462- [:label {:label (str "Nick: " @s/form-nick)}]
463- (if-let [sess @s/session]
464- [:vbox {:spacing 2}
465- [:label {:label (str "Signed in as " (:handle sess))}]
466- [:dim-label {:label (or (:did sess) "")}]
467- [:vbox {:key :forget}
468- (when @s/broker-token
469- [:button {:label "Forget Bluesky session"
470- :kind :destructive
471- :on-click s/forget-session!}])]]
472- [:dim-label {:label "Guest — not signed in."}])
473- [:separator {}]
474- ;; Nothing to disconnect from when there is no connection — the way back to
475- ;; the connect screen is what is wanted then.
476- [:vbox {:key :connection-action}
477- (if (s/connected?)
478- [:button {:label "Disconnect" :kind :destructive :on-click s/disconnect!}]
479- [:button {:label "Back to connect"
480- :on-click #(reset! s/screen :connect)}])]]
481- [:card {}
482- [:title-2 {:label "Messages"}]
483- [:checkbutton {:label "Hide join/part messages"
484- :active @s/hide-join-part?
485- :on-toggled s/toggle-hide-join-part!}]
486- [:dim-label {:label "Hides other people arriving, leaving and quitting. The people panel still follows who is here."}]]
487- [:card {}
488- [:title-2 {:label "frq"}]
489- [:dim-label {:label "freeq client in jolt — glimmer components on the Vidya/egui backend."}]
490- [:button {:label "Quit" :on-click platform/quit!}]]))
491-
492425 ;; ---------------------------------------------------------------- shell
493426
494427 (defn app []
@@ -37,6 +37,8 @@
37 ;; phone renders this very file.37 ;; phone renders this very file.
38 [frq.screens.chats :refer [below-list chats-screen conversation-row38 [frq.screens.chats :refer [below-list chats-screen conversation-row
39 preview-line tab-bar]]39 preview-line tab-bar]]
40+ [frq.screens.settings :refer [discover-screen settings-screen
41+ tab-screen]]
40 [frq.screens.chat :refer [chat-screen emoji-picker message-row42 [frq.screens.chat :refer [chat-screen emoji-picker message-row
41 reactor-dialog sidebar-width43 reactor-dialog sidebar-width
42 users-panel]]44 users-panel]]
@@ -418,77 +420,8 @@
418 420
419 ;; ---------------------------------------------------------------- discover421 ;; ---------------------------------------------------------------- discover
420 422
421-(defn- tab-screen
422- "One of the three screens the tab bar moves between, in the chats screen's
423- shape: the title at the top, the tabs pinned at the bottom, and `body`
424- scrolling between them.
425-
426- The same shape for all three, so switching tabs moves nothing but the
427- middle. As pages they were centred columns of their own widths with the tabs
428- wherever the content happened to end, and every switch resized the screen
429- under the pointer."
430- [title scroll-key & body]
431- [:vbox {:spacing 8 :margin 12 :fill-height true}
432- [:title {:label title}]
433- [:vbox {:key :list :fill-height true}
434- (into [:scroll {:scroll-key scroll-key :orientation :vertical
435- :reserve (below-list) :spacing 8}]
436- body)]
437- [:vbox {:key :foot :spacing 8}
438- [:separator {}]
439- [tab-bar]]])
440-
441-(defn discover-screen []
442- (tab-screen "Discover" "discover-list"
443- [:dim-label {:label "Popular channels on freeq."}]
444- [error-note]
445- (for [[name blurb] s/popular-channels]
446- (let [joined? (get-in @s/channels [name :joined?])]
447- [:card {:key name}
448- [:title-2 {:label name}]
449- [:dim-label {:label blurb}]
450- [:button {:label (if joined? "Open" "Join")
451- :kind :primary
452- :on-click #(if joined? (s/open-channel! name) (s/join! name))}]]))))
453-
454 ;; ---------------------------------------------------------------- settings423 ;; ---------------------------------------------------------------- settings
455 424
456-(defn settings-screen []
457- (tab-screen "Settings" "settings-list"
458- [:card {}
459- [:title-2 {:label "Connection"}]
460- [:status {:label @s/status :live (s/connected?)}]
461- [:label {:label (str "Server: " @s/form-host ":" @s/form-port)}]
462- [:label {:label (str "Nick: " @s/form-nick)}]
463- (if-let [sess @s/session]
464- [:vbox {:spacing 2}
465- [:label {:label (str "Signed in as " (:handle sess))}]
466- [:dim-label {:label (or (:did sess) "")}]
467- [:vbox {:key :forget}
468- (when @s/broker-token
469- [:button {:label "Forget Bluesky session"
470- :kind :destructive
471- :on-click s/forget-session!}])]]
472- [:dim-label {:label "Guest — not signed in."}])
473- [:separator {}]
474- ;; Nothing to disconnect from when there is no connection — the way back to
475- ;; the connect screen is what is wanted then.
476- [:vbox {:key :connection-action}
477- (if (s/connected?)
478- [:button {:label "Disconnect" :kind :destructive :on-click s/disconnect!}]
479- [:button {:label "Back to connect"
480- :on-click #(reset! s/screen :connect)}])]]
481- [:card {}
482- [:title-2 {:label "Messages"}]
483- [:checkbutton {:label "Hide join/part messages"
484- :active @s/hide-join-part?
485- :on-toggled s/toggle-hide-join-part!}]
486- [:dim-label {:label "Hides other people arriving, leaving and quitting. The people panel still follows who is here."}]]
487- [:card {}
488- [:title-2 {:label "frq"}]
489- [:dim-label {:label "freeq client in jolt — glimmer components on the Vidya/egui backend."}]
490- [:button {:label "Quit" :on-click platform/quit!}]]))
491-
492 ;; ---------------------------------------------------------------- shell425 ;; ---------------------------------------------------------------- shell
493 426
494 (defn app []427 (defn app []
modified src/frq/state.clj +3 -14
@@ -54,16 +54,8 @@
5454 (def search cells/search)
5555 (def login-url cells/login-url)
5656
57-(def popular-channels
58- [["#general" "General discussion"]
59- ["#test" "Test channel"]
60- ["#freeq" "freeq development & support"]
61- ["#dev" "Programming & technology"]
62- ["#music" "Music recommendations"]
63- ["#random" "Off-topic chat"]])
57+(def popular-channels cells/popular-channels)
6458
65-
66-;; joined as soon as the server sends 001
6759 (def auto-join "#test")
6860
6961 ;; How much backlog to ask for when the server did not volunteer any.
@@ -186,11 +178,7 @@
186178 ;; monotonic tick cannot be surprised by the system time moving.
187179 (defonce access-tick (atom 0))
188180
189-;; Comings and goings, hidden or not. A quiet room reads better with them —
190-;; they are how you notice someone arriving — and a busy one drowns in them,
191-;; so it is the reader's call. Only other people's: your own "Joined #chan" is
192-;; the answer to something you just did.
193-(defonce hide-join-part? (atom false))
181+(def hide-join-part? cells/hide-join-part?)
194182
195183 ;; Whether rooms.edn is the authority yet.
196184 ;;
@@ -1961,6 +1949,7 @@
19611949 :join! join!
19621950 :open-channel! open-channel!
19631951 :leave-channel! leave-channel!
1952+ :toggle-hide-join-part! toggle-hide-join-part!
19641953 :send-draft! send-draft!
19651954 :cancel-edit! cancel-edit!
19661955 :cancel-reply! cancel-reply!
@@ -54,16 +54,8 @@
54 (def search cells/search)54 (def search cells/search)
55 (def login-url cells/login-url)55 (def login-url cells/login-url)
56 56
57-(def popular-channels57+(def popular-channels cells/popular-channels)
58- [["#general" "General discussion"]
59- ["#test" "Test channel"]
60- ["#freeq" "freeq development & support"]
61- ["#dev" "Programming & technology"]
62- ["#music" "Music recommendations"]
63- ["#random" "Off-topic chat"]])
64 58
65-
66-;; joined as soon as the server sends 001
67 (def auto-join "#test")59 (def auto-join "#test")
68 60
69 ;; How much backlog to ask for when the server did not volunteer any.61 ;; How much backlog to ask for when the server did not volunteer any.
@@ -186,11 +178,7 @@
186 ;; monotonic tick cannot be surprised by the system time moving.178 ;; monotonic tick cannot be surprised by the system time moving.
187 (defonce access-tick (atom 0))179 (defonce access-tick (atom 0))
188 180
189-;; Comings and goings, hidden or not. A quiet room reads better with them —181+(def hide-join-part? cells/hide-join-part?)
190-;; they are how you notice someone arriving — and a busy one drowns in them,
191-;; so it is the reader's call. Only other people's: your own "Joined #chan" is
192-;; the answer to something you just did.
193-(defonce hide-join-part? (atom false))
194 182
195 ;; Whether rooms.edn is the authority yet.183 ;; Whether rooms.edn is the authority yet.
196 ;;184 ;;
@@ -1961,6 +1949,7 @@
1961 :join! join!1949 :join! join!
1962 :open-channel! open-channel!1950 :open-channel! open-channel!
1963 :leave-channel! leave-channel!1951 :leave-channel! leave-channel!
1952+ :toggle-hide-join-part! toggle-hide-join-part!
1964 :send-draft! send-draft!1953 :send-draft! send-draft!
1965 :cancel-edit! cancel-edit!1954 :cancel-edit! cancel-edit!
1966 :cancel-reply! cancel-reply!1955 :cancel-reply! cancel-reply!