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

The way to Discover and Settings, from a conversation

The chat screen never carried the tab bar. On a narrow window that was
survivable, because `← Chats` goes back to a screen that has one — but
a wide window has no back button, the room list being a strip beside
the conversation instead, so from a room there was no way to either of
the other two screens at all. That is new as of the strip, and it is
what the strip took away.

So the bar is at the foot of this screen too, and Chats is lit while a
conversation is open: a conversation is what that tab leads to, and a
bar with nothing lit reads as one that has lost its place.

Wide only, and not for want of symmetry. Three tabs go to two lines at
300 points and this screen has no 120 points to spare — it overflowed
the moment they were added unconditionally, which is the same corner
the jump button found. On a narrow window `← Chats` is still the way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-19T22:51:46-07:00 Browse files
e20f5ab parent: 0e7cd32
modified nim/src/frq/screens/chat.nim +15 -1
@@ -17,6 +17,7 @@ import std/options
1717 import frq/[ui, cells, model, clock, reactions, textruns, members,
1818 glyphs, emoji, rooms, profile]
1919 from frq/screens/connect import errorNote
20+from frq/screens/frame import tabBar
2021
2122 const
2223 faceSize = 32
@@ -484,6 +485,18 @@ proc chatScreen*(s: State, connected: bool): Node =
484485 returnRow.children.add button("← back to " & s.overviewReturn,
485486 "overview.back")
486487
488+ # The same bar the other three screens carry, which this one did not have.
489+ # On a narrow window that was survivable: `← Chats` goes back to a screen
490+ # that has one. On a wide window there is no back button — the room list is
491+ # a strip instead — so Discover and Settings had no way in at all.
492+ #
493+ # Wide only, and not for symmetry's sake: a 300-point window puts these
494+ # three on two lines, and the chat screen has no 120 points to spare. It
495+ # overflowed the moment they were added unconditionally.
496+ var tabs = vbox(%*{"key": "tabs"})
497+ if s.wide:
498+ tabs.children.add tabBar(s)
499+
487500 var jump = vbox(%*{"key": "jump"})
488501 if not s.atPresent:
489502 jump.children.add button("↓ Jump to present", "jump.present")
@@ -544,4 +557,5 @@ proc chatScreen*(s: State, connected: bool): Node =
544557 returnRow,
545558 banners,
546559 separator(),
547- compose)
560+ compose,
561+ tabs)
@@ -17,6 +17,7 @@ import std/options
17 import frq/[ui, cells, model, clock, reactions, textruns, members,17 import frq/[ui, cells, model, clock, reactions, textruns, members,
18 glyphs, emoji, rooms, profile]18 glyphs, emoji, rooms, profile]
19 from frq/screens/connect import errorNote19 from frq/screens/connect import errorNote
20+from frq/screens/frame import tabBar
20 21
21 const22 const
22 faceSize = 3223 faceSize = 32
@@ -484,6 +485,18 @@ proc chatScreen*(s: State, connected: bool): Node =
484 returnRow.children.add button("← back to " & s.overviewReturn,485 returnRow.children.add button("← back to " & s.overviewReturn,
485 "overview.back")486 "overview.back")
486 487
488+ # The same bar the other three screens carry, which this one did not have.
489+ # On a narrow window that was survivable: `← Chats` goes back to a screen
490+ # that has one. On a wide window there is no back button — the room list is
491+ # a strip instead — so Discover and Settings had no way in at all.
492+ #
493+ # Wide only, and not for symmetry's sake: a 300-point window puts these
494+ # three on two lines, and the chat screen has no 120 points to spare. It
495+ # overflowed the moment they were added unconditionally.
496+ var tabs = vbox(%*{"key": "tabs"})
497+ if s.wide:
498+ tabs.children.add tabBar(s)
499+
487 var jump = vbox(%*{"key": "jump"})500 var jump = vbox(%*{"key": "jump"})
488 if not s.atPresent:501 if not s.atPresent:
489 jump.children.add button("↓ Jump to present", "jump.present")502 jump.children.add button("↓ Jump to present", "jump.present")
@@ -544,4 +557,5 @@ proc chatScreen*(s: State, connected: bool): Node =
544 returnRow,557 returnRow,
545 banners,558 banners,
546 separator(),559 separator(),
547- compose)560+ compose,
561+ tabs)
modified nim/src/frq/screens/frame.nim +6 -1
@@ -8,9 +8,14 @@ import std/json
88 import frq/[ui, cells]
99
1010 func tabBar*(s: State): Node =
11+ ## The three screens, and the way between them.
12+ ##
13+ ## Lit for a conversation as well as for the list, because a conversation is
14+ ## what the Chats tab leads to — a bar with nothing lit on it reads as a bar
15+ ## that has lost its place.
1116 hbox(%*{"spacing": 8},
1217 button("Chats", "screen.chats",
13- if s.screen == scChats: "primary" else: "default"),
18+ if s.screen in {scChats, scChat}: "primary" else: "default"),
1419 button("Discover", "screen.discover",
1520 if s.screen == scDiscover: "primary" else: "default"),
1621 button("Settings", "screen.settings",
@@ -8,9 +8,14 @@ import std/json
8 import frq/[ui, cells]8 import frq/[ui, cells]
9 9
10 func tabBar*(s: State): Node =10 func tabBar*(s: State): Node =
11+ ## The three screens, and the way between them.
12+ ##
13+ ## Lit for a conversation as well as for the list, because a conversation is
14+ ## what the Chats tab leads to — a bar with nothing lit on it reads as a bar
15+ ## that has lost its place.
11 hbox(%*{"spacing": 8},16 hbox(%*{"spacing": 8},
12 button("Chats", "screen.chats",17 button("Chats", "screen.chats",
13- if s.screen == scChats: "primary" else: "default"),18+ if s.screen in {scChats, scChat}: "primary" else: "default"),
14 button("Discover", "screen.discover",19 button("Discover", "screen.discover",
15 if s.screen == scDiscover: "primary" else: "default"),20 if s.screen == scDiscover: "primary" else: "default"),
16 button("Settings", "screen.settings",21 button("Settings", "screen.settings",
modified nim/tests/tscreens.nim +25 -0
@@ -258,6 +258,8 @@ suite "the chat screen's panes":
258258 at: 1_700_000_000_000'i64)]
259259 s.rooms["#test"] = r
260260 s.current = "#test"
261+ # What `room.open` does, and what the tab bar reads to light Chats.
262+ s.screen = scChat
261263
262264 test "the backlog and the rooms sit side by side when the list is up":
263265 # The toggle had a button and rendered nothing at all: `hideChatList` was
@@ -286,6 +288,29 @@ suite "the chat screen's panes":
286288 check t.find("scroll").anyIt(
287289 it.props{"scrollKey"}.getStr() == "messages-#test")
288290
291+ test "the way to Discover and Settings is on the screen":
292+ # It was not: the chat screen never carried the tab bar, and on a wide
293+ # window there is no back button either — the room list is a strip. So
294+ # from a conversation there was no way to either of them at all.
295+ let t = cht.chatScreen(s, true)
296+ check "Discover" in t.labels("button")
297+ check "Settings" in t.labels("button")
298+
299+ test "and Chats is lit, because a conversation is what it leads to":
300+ let t = cht.chatScreen(s, true)
301+ let chats = t.find("button").filterIt(
302+ it.props{"label"}.getStr() == "Chats")
303+ check chats.len == 1
304+ check chats[0].props{"kind"}.getStr() == "primary"
305+
306+ test "but not on a narrow window, which has no room for them":
307+ # Three tabs go to two lines at 300 points, and this screen has no 120
308+ # points to spare — `← Chats` is the way back there instead.
309+ s.windowWidth = wideWidth - 1
310+ let t = cht.chatScreen(s, true)
311+ check "Discover" notin t.labels("button")
312+ check "← Chats" in t.labels("button")
313+
289314 test "a room in the strip opens it, and the current one is lit":
290315 s.hideChatList = false
291316 let t = cht.chatScreen(s, true)
@@ -258,6 +258,8 @@ suite "the chat screen's panes":
258 at: 1_700_000_000_000'i64)]258 at: 1_700_000_000_000'i64)]
259 s.rooms["#test"] = r259 s.rooms["#test"] = r
260 s.current = "#test"260 s.current = "#test"
261+ # What `room.open` does, and what the tab bar reads to light Chats.
262+ s.screen = scChat
261 263
262 test "the backlog and the rooms sit side by side when the list is up":264 test "the backlog and the rooms sit side by side when the list is up":
263 # The toggle had a button and rendered nothing at all: `hideChatList` was265 # The toggle had a button and rendered nothing at all: `hideChatList` was
@@ -286,6 +288,29 @@ suite "the chat screen's panes":
286 check t.find("scroll").anyIt(288 check t.find("scroll").anyIt(
287 it.props{"scrollKey"}.getStr() == "messages-#test")289 it.props{"scrollKey"}.getStr() == "messages-#test")
288 290
291+ test "the way to Discover and Settings is on the screen":
292+ # It was not: the chat screen never carried the tab bar, and on a wide
293+ # window there is no back button either — the room list is a strip. So
294+ # from a conversation there was no way to either of them at all.
295+ let t = cht.chatScreen(s, true)
296+ check "Discover" in t.labels("button")
297+ check "Settings" in t.labels("button")
298+
299+ test "and Chats is lit, because a conversation is what it leads to":
300+ let t = cht.chatScreen(s, true)
301+ let chats = t.find("button").filterIt(
302+ it.props{"label"}.getStr() == "Chats")
303+ check chats.len == 1
304+ check chats[0].props{"kind"}.getStr() == "primary"
305+
306+ test "but not on a narrow window, which has no room for them":
307+ # Three tabs go to two lines at 300 points, and this screen has no 120
308+ # points to spare — `← Chats` is the way back there instead.
309+ s.windowWidth = wideWidth - 1
310+ let t = cht.chatScreen(s, true)
311+ check "Discover" notin t.labels("button")
312+ check "← Chats" in t.labels("button")
313+
289 test "a room in the strip opens it, and the current one is lit":314 test "a room in the strip opens it, and the current one is lit":
290 s.hideChatList = false315 s.hideChatList = false
291 let t = cht.chatScreen(s, true)316 let t = cht.chatScreen(s, true)