Move the chat screen's cells and actions ahead of the screen
Nine cells — the draft and its three companions, the jump tick, and the four toggles — into frq.cells, and the conversation screen's fourteen commands and two queries into frq.actions beside them. Also the call bar's three, which a phone answers by not installing, and the two assets: where a face or a picture is on disk once it is. Nothing moved yet that draws anything. The screen follows; this is the ground it stands on, and the TUI renders unchanged over it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0addab3 parent: 8c903d8 modified
common/frq/actions.cljc +44 -0 | @@ -37,3 +37,47 @@ | ||
| 37 | 37 | (defn join! [name] (call :join! [name])) |
| 38 | 38 | (defn open-channel! [name] (call :open-channel! [name])) |
| 39 | 39 | (defn leave-channel! [name] (call :leave-channel! [name])) |
| 40 | + | |
| 41 | +;; ------------------------------------------------------------------- chat | |
| 42 | +;; | |
| 43 | +;; The conversation screen's half. Commands where the screen asks for | |
| 44 | +;; something to happen, queries where it asks what is true — `wide?` is the | |
| 45 | +;; window's width and `member-count` is the server's answer, and neither is a | |
| 46 | +;; cell any screen could read for itself. | |
| 47 | + | |
| 48 | +(defn send-draft! [] (call :send-draft! [])) | |
| 49 | +(defn cancel-edit! [] (call :cancel-edit! [])) | |
| 50 | +(defn cancel-reply! [] (call :cancel-reply! [])) | |
| 51 | +(defn clear-attachment! [] (call :clear-attachment! [])) | |
| 52 | +(defn open-image-picker! [] (call :open-image-picker! [])) | |
| 53 | +(defn paste-image! [] (call :paste-image! [])) | |
| 54 | +(defn jump-to-present! [] (call :jump-to-present! [])) | |
| 55 | +(defn scrolled! [& args] (call :scrolled! args)) | |
| 56 | +(defn toggle-users! [] (call :toggle-users! [])) | |
| 57 | +(defn toggle-chat-list! [] (call :toggle-chat-list! [])) | |
| 58 | +(defn toggle-overview! [] (call :toggle-overview! [])) | |
| 59 | + | |
| 60 | +(defn wide? [] (boolean (call :wide? []))) | |
| 61 | +(defn member-count [name] (call :member-count [name])) | |
| 62 | + | |
| 63 | +;; ------------------------------------------------------------------ calls | |
| 64 | +;; | |
| 65 | +;; The media plane, which a phone has none of — `frq.av/available?` says so on | |
| 66 | +;; the desktop and nothing installs these here, so the call bar renders its | |
| 67 | +;; unavailable shape rather than being special-cased in the screen. | |
| 68 | + | |
| 69 | +(defn start-call! [] (call :start-call! [])) | |
| 70 | +(defn in-call? [] (boolean (call :in-call? []))) | |
| 71 | +(defn call-in [name] (call :call-in [name])) | |
| 72 | +(defn call-available? [] (boolean (call :call-available? []))) | |
| 73 | + | |
| 74 | +;; ----------------------------------------------------------------- assets | |
| 75 | +;; | |
| 76 | +;; Where a face or a picture is on disk, once it is. Both are a fetch and a | |
| 77 | +;; cache on the desktop, behind a glimmer reaction so one arriving wakes only | |
| 78 | +;; the rows that read it; the phone has neither yet and answers nil, which the | |
| 79 | +;; screens already treat as "not here". | |
| 80 | + | |
| 81 | +(defn avatar-path [actor] (call :avatar-path [actor])) | |
| 82 | +(defn image-path [url] (call :image-path [url])) | |
| 83 | + | |
| @@ -37,3 +37,47 @@ | |||
| 37 | (defn join! [name] (call :join! [name])) | 37 | (defn join! [name] (call :join! [name])) |
| 38 | (defn open-channel! [name] (call :open-channel! [name])) | 38 | (defn open-channel! [name] (call :open-channel! [name])) |
| 39 | (defn leave-channel! [name] (call :leave-channel! [name])) | 39 | (defn leave-channel! [name] (call :leave-channel! [name])) |
| 40 | + | ||
| 41 | +;; ------------------------------------------------------------------- chat | ||
| 42 | +;; | ||
| 43 | +;; The conversation screen's half. Commands where the screen asks for | ||
| 44 | +;; something to happen, queries where it asks what is true — `wide?` is the | ||
| 45 | +;; window's width and `member-count` is the server's answer, and neither is a | ||
| 46 | +;; cell any screen could read for itself. | ||
| 47 | + | ||
| 48 | +(defn send-draft! [] (call :send-draft! [])) | ||
| 49 | +(defn cancel-edit! [] (call :cancel-edit! [])) | ||
| 50 | +(defn cancel-reply! [] (call :cancel-reply! [])) | ||
| 51 | +(defn clear-attachment! [] (call :clear-attachment! [])) | ||
| 52 | +(defn open-image-picker! [] (call :open-image-picker! [])) | ||
| 53 | +(defn paste-image! [] (call :paste-image! [])) | ||
| 54 | +(defn jump-to-present! [] (call :jump-to-present! [])) | ||
| 55 | +(defn scrolled! [& args] (call :scrolled! args)) | ||
| 56 | +(defn toggle-users! [] (call :toggle-users! [])) | ||
| 57 | +(defn toggle-chat-list! [] (call :toggle-chat-list! [])) | ||
| 58 | +(defn toggle-overview! [] (call :toggle-overview! [])) | ||
| 59 | + | ||
| 60 | +(defn wide? [] (boolean (call :wide? []))) | ||
| 61 | +(defn member-count [name] (call :member-count [name])) | ||
| 62 | + | ||
| 63 | +;; ------------------------------------------------------------------ calls | ||
| 64 | +;; | ||
| 65 | +;; The media plane, which a phone has none of — `frq.av/available?` says so on | ||
| 66 | +;; the desktop and nothing installs these here, so the call bar renders its | ||
| 67 | +;; unavailable shape rather than being special-cased in the screen. | ||
| 68 | + | ||
| 69 | +(defn start-call! [] (call :start-call! [])) | ||
| 70 | +(defn in-call? [] (boolean (call :in-call? []))) | ||
| 71 | +(defn call-in [name] (call :call-in [name])) | ||
| 72 | +(defn call-available? [] (boolean (call :call-available? []))) | ||
| 73 | + | ||
| 74 | +;; ----------------------------------------------------------------- assets | ||
| 75 | +;; | ||
| 76 | +;; Where a face or a picture is on disk, once it is. Both are a fetch and a | ||
| 77 | +;; cache on the desktop, behind a glimmer reaction so one arriving wakes only | ||
| 78 | +;; the rows that read it; the phone has neither yet and answers nil, which the | ||
| 79 | +;; screens already treat as "not here". | ||
| 80 | + | ||
| 81 | +(defn avatar-path [actor] (call :avatar-path [actor])) | ||
| 82 | +(defn image-path [url] (call :image-path [url])) | ||
| 83 | + | ||
modified
common/frq/cells.cljc +62 -0 | @@ -52,3 +52,65 @@ | ||
| 52 | 52 | |
| 53 | 53 | (defonce broker-token (atom nil)) |
| 54 | 54 | (defonce login-url (atom nil)) ; shown while the browser is open |
| 55 | + | |
| 56 | +;; ------------------------------------------------------------------- chat | |
| 57 | +;; What the conversation screen reads. The compose bar's three companions — | |
| 58 | +;; a reply, an edit and an attachment — are apart from the draft rather than | |
| 59 | +;; written into it: a link pasted into the box is a line of unreadable text in | |
| 60 | +;; the middle of whatever the reader was typing. | |
| 61 | + | |
| 62 | +(defonce draft (atom "")) | |
| 63 | + | |
| 64 | +;; The message the draft is a rewrite of, as `{:channel :id}`, or nil when the | |
| 65 | +;; box is being used for something new. Only the id is kept: what is being | |
| 66 | +;; rewritten is in the box, and the line on screen is the thing it will replace. | |
| 67 | +(defonce editing (atom nil)) | |
| 68 | + | |
| 69 | +;; The message the draft is answering, as {:id :from :text}, or nil. Held whole | |
| 70 | +;; rather than as an id alone so the compose bar can say who is being answered | |
| 71 | +;; without going looking for them. | |
| 72 | +(defonce replying-to (atom nil)) | |
| 73 | + | |
| 74 | +;; The picture waiting to go out with the next line, or nil: | |
| 75 | +;; | |
| 76 | +;; {:path the copy on disk, which is what the preview paints | |
| 77 | +;; :url where freeq serves it, once the upload has landed | |
| 78 | +;; :status :uploading | :ready} | |
| 79 | +;; | |
| 80 | +;; Held apart from the draft rather than written into it. A link pasted into | |
| 81 | +;; the entry is a line of unreadable text in the middle of whatever the reader | |
| 82 | +;; was typing, and it puts their cursor somewhere they did not put it. The | |
| 83 | +;; picture is a picture until it is sent; the draft stays theirs. | |
| 84 | +;; | |
| 85 | +;; One at a time — a second paste replaces the first, which is what a reader | |
| 86 | +;; who pasted the wrong thing means by pasting the right one. | |
| 87 | +(defonce attachment (atom nil)) | |
| 88 | + | |
| 89 | +(defonce jump-tick (atom 0)) | |
| 90 | + | |
| 91 | +;; Whether the chat screen is showing who is in the channel. Off by default: | |
| 92 | +;; the panel costs the conversation a column, and the reader is here for the | |
| 93 | +;; conversation. | |
| 94 | +(defonce show-users? (atom false)) | |
| 95 | + | |
| 96 | +;; Whether the wide window is holding the chats list back, leaving the whole | |
| 97 | +;; row to the conversation. Only a wide window has anything to hide: below | |
| 98 | +;; `wide-width` the list and the conversation already take turns, and hiding | |
| 99 | +;; the list there would be hiding the only way to another room. | |
| 100 | +;; | |
| 101 | +;; Saved with the other settings rather than reset per launch: it is a choice | |
| 102 | +;; about how this screen is read, and a reader who wants the conversation | |
| 103 | +;; whole wants it whole again tomorrow. | |
| 104 | +(defonce hide-chat-list? (atom false)) | |
| 105 | + | |
| 106 | +;; Whether the conversation is sharing its room with the overview strip — | |
| 107 | +;; every channel's last lines in one list, under the one you are reading. | |
| 108 | +;; Saved for the same reason as the fold above it: it is a choice about how | |
| 109 | +;; this screen is laid out, and a layout a reader chose should be the one they | |
| 110 | +;; come back to. | |
| 111 | +(defonce overview? (atom false)) | |
| 112 | + | |
| 113 | +;; Whether the chat view is showing the newest line, and a counter the view | |
| 114 | +;; watches to be told to go back to it. A counter rather than a flag: a flag | |
| 115 | +;; would need clearing, and there is no frame in which to clear it. | |
| 116 | +(defonce at-present? (atom true)) | |
| @@ -52,3 +52,65 @@ | |||
| 52 | 52 | ||
| 53 | (defonce broker-token (atom nil)) | 53 | (defonce broker-token (atom nil)) |
| 54 | (defonce login-url (atom nil)) ; shown while the browser is open | 54 | (defonce login-url (atom nil)) ; shown while the browser is open |
| 55 | + | ||
| 56 | +;; ------------------------------------------------------------------- chat | ||
| 57 | +;; What the conversation screen reads. The compose bar's three companions — | ||
| 58 | +;; a reply, an edit and an attachment — are apart from the draft rather than | ||
| 59 | +;; written into it: a link pasted into the box is a line of unreadable text in | ||
| 60 | +;; the middle of whatever the reader was typing. | ||
| 61 | + | ||
| 62 | +(defonce draft (atom "")) | ||
| 63 | + | ||
| 64 | +;; The message the draft is a rewrite of, as `{:channel :id}`, or nil when the | ||
| 65 | +;; box is being used for something new. Only the id is kept: what is being | ||
| 66 | +;; rewritten is in the box, and the line on screen is the thing it will replace. | ||
| 67 | +(defonce editing (atom nil)) | ||
| 68 | + | ||
| 69 | +;; The message the draft is answering, as {:id :from :text}, or nil. Held whole | ||
| 70 | +;; rather than as an id alone so the compose bar can say who is being answered | ||
| 71 | +;; without going looking for them. | ||
| 72 | +(defonce replying-to (atom nil)) | ||
| 73 | + | ||
| 74 | +;; The picture waiting to go out with the next line, or nil: | ||
| 75 | +;; | ||
| 76 | +;; {:path the copy on disk, which is what the preview paints | ||
| 77 | +;; :url where freeq serves it, once the upload has landed | ||
| 78 | +;; :status :uploading | :ready} | ||
| 79 | +;; | ||
| 80 | +;; Held apart from the draft rather than written into it. A link pasted into | ||
| 81 | +;; the entry is a line of unreadable text in the middle of whatever the reader | ||
| 82 | +;; was typing, and it puts their cursor somewhere they did not put it. The | ||
| 83 | +;; picture is a picture until it is sent; the draft stays theirs. | ||
| 84 | +;; | ||
| 85 | +;; One at a time — a second paste replaces the first, which is what a reader | ||
| 86 | +;; who pasted the wrong thing means by pasting the right one. | ||
| 87 | +(defonce attachment (atom nil)) | ||
| 88 | + | ||
| 89 | +(defonce jump-tick (atom 0)) | ||
| 90 | + | ||
| 91 | +;; Whether the chat screen is showing who is in the channel. Off by default: | ||
| 92 | +;; the panel costs the conversation a column, and the reader is here for the | ||
| 93 | +;; conversation. | ||
| 94 | +(defonce show-users? (atom false)) | ||
| 95 | + | ||
| 96 | +;; Whether the wide window is holding the chats list back, leaving the whole | ||
| 97 | +;; row to the conversation. Only a wide window has anything to hide: below | ||
| 98 | +;; `wide-width` the list and the conversation already take turns, and hiding | ||
| 99 | +;; the list there would be hiding the only way to another room. | ||
| 100 | +;; | ||
| 101 | +;; Saved with the other settings rather than reset per launch: it is a choice | ||
| 102 | +;; about how this screen is read, and a reader who wants the conversation | ||
| 103 | +;; whole wants it whole again tomorrow. | ||
| 104 | +(defonce hide-chat-list? (atom false)) | ||
| 105 | + | ||
| 106 | +;; Whether the conversation is sharing its room with the overview strip — | ||
| 107 | +;; every channel's last lines in one list, under the one you are reading. | ||
| 108 | +;; Saved for the same reason as the fold above it: it is a choice about how | ||
| 109 | +;; this screen is laid out, and a layout a reader chose should be the one they | ||
| 110 | +;; come back to. | ||
| 111 | +(defonce overview? (atom false)) | ||
| 112 | + | ||
| 113 | +;; Whether the chat view is showing the newest line, and a counter the view | ||
| 114 | +;; watches to be told to go back to it. A counter rather than a flag: a flag | ||
| 115 | +;; would need clearing, and there is no frame in which to clear it. | ||
| 116 | +(defonce at-present? (atom true)) | ||
modified
src/frq/state.clj +27 -48 | @@ -69,19 +69,13 @@ | ||
| 69 | 69 | ;; How much backlog to ask for when the server did not volunteer any. |
| 70 | 70 | (def history-limit 100) |
| 71 | 71 | |
| 72 | -(defonce draft (atom "")) | |
| 73 | -;; The message the draft is answering, as {:id :from :text}, or nil. Held whole | |
| 74 | -;; rather than as an id alone so the compose bar can say who is being answered | |
| 75 | -;; without going looking for them. | |
| 76 | -(defonce replying-to (atom nil)) | |
| 72 | +(def draft cells/draft) | |
| 73 | +(def replying-to cells/replying-to) | |
| 77 | 74 | |
| 78 | 75 | (defn reply-to! [m] (reset! replying-to (select-keys m [:id :from :text]))) |
| 79 | 76 | (defn cancel-reply! [] (reset! replying-to nil)) |
| 80 | 77 | |
| 81 | -;; The message the draft is a rewrite of, as `{:channel :id}`, or nil when the | |
| 82 | -;; box is being used for something new. Only the id is kept: what is being | |
| 83 | -;; rewritten is in the box, and the line on screen is the thing it will replace. | |
| 84 | -(defonce editing (atom nil)) | |
| 78 | +(def editing cells/editing) | |
| 85 | 79 | |
| 86 | 80 | ;; The message the emoji picker is choosing for, as `{:channel :id}`, or nil |
| 87 | 81 | ;; when it is closed. The picker is a panel over the compose bar rather than a |
| @@ -97,22 +91,11 @@ | ||
| 97 | 91 | ;; so this is a screen of its own rather than a layer over the chat. |
| 98 | 92 | (defonce lightbox (atom nil)) ; {:path :url} |
| 99 | 93 | |
| 100 | -;; Whether the chat screen is showing who is in the channel. Off by default: | |
| 101 | -;; the panel costs the conversation a column, and the reader is here for the | |
| 102 | -;; conversation. | |
| 103 | -(defonce show-users? (atom false)) | |
| 94 | +(def show-users? cells/show-users?) | |
| 104 | 95 | |
| 105 | 96 | (defn toggle-users! [] (swap! show-users? not)) |
| 106 | 97 | |
| 107 | -;; Whether the wide window is holding the chats list back, leaving the whole | |
| 108 | -;; row to the conversation. Only a wide window has anything to hide: below | |
| 109 | -;; `wide-width` the list and the conversation already take turns, and hiding | |
| 110 | -;; the list there would be hiding the only way to another room. | |
| 111 | -;; | |
| 112 | -;; Saved with the other settings rather than reset per launch: it is a choice | |
| 113 | -;; about how this screen is read, and a reader who wants the conversation | |
| 114 | -;; whole wants it whole again tomorrow. | |
| 115 | -(defonce hide-chat-list? (atom false)) | |
| 98 | +(def hide-chat-list? cells/hide-chat-list?) | |
| 116 | 99 | |
| 117 | 100 | (declare save-prefs!) |
| 118 | 101 | |
| @@ -120,12 +103,7 @@ | ||
| 120 | 103 | (swap! hide-chat-list? not) |
| 121 | 104 | (save-prefs!)) |
| 122 | 105 | |
| 123 | -;; Whether the conversation is sharing its room with the overview strip — | |
| 124 | -;; every channel's last lines in one list, under the one you are reading. | |
| 125 | -;; Saved for the same reason as the fold above it: it is a choice about how | |
| 126 | -;; this screen is laid out, and a layout a reader chose should be the one they | |
| 127 | -;; come back to. | |
| 128 | -(defonce overview? (atom false)) | |
| 106 | +(def overview? cells/overview?) | |
| 129 | 107 | |
| 130 | 108 | (defn toggle-overview! [] |
| 131 | 109 | (swap! overview? not) |
| @@ -189,11 +167,8 @@ | ||
| 189 | 167 | (or (= :chat @screen) |
| 190 | 168 | (and (wide?) (= :chats @screen)))) |
| 191 | 169 | |
| 192 | -;; Whether the chat view is showing the newest line, and a counter the view | |
| 193 | -;; watches to be told to go back to it. A counter rather than a flag: a flag | |
| 194 | -;; would need clearing, and there is no frame in which to clear it. | |
| 195 | -(defonce at-present? (atom true)) | |
| 196 | -(defonce jump-tick (atom 0)) | |
| 170 | +(def at-present? cells/at-present?) | |
| 171 | +(def jump-tick cells/jump-tick) | |
| 197 | 172 | |
| 198 | 173 | ;; How a backend answers "did that scroll end at the end?". |
| 199 | 174 | ;; |
| @@ -1340,20 +1315,7 @@ | ||
| 1340 | 1315 | |
| 1341 | 1316 | ;; ------------------------------------------------------------------ pasting |
| 1342 | 1317 | |
| 1343 | -;; The picture waiting to go out with the next line, or nil: | |
| 1344 | -;; | |
| 1345 | -;; {:path the copy on disk, which is what the preview paints | |
| 1346 | -;; :url where freeq serves it, once the upload has landed | |
| 1347 | -;; :status :uploading | :ready} | |
| 1348 | -;; | |
| 1349 | -;; Held apart from the draft rather than written into it. A link pasted into | |
| 1350 | -;; the entry is a line of unreadable text in the middle of whatever the reader | |
| 1351 | -;; was typing, and it puts their cursor somewhere they did not put it. The | |
| 1352 | -;; picture is a picture until it is sent; the draft stays theirs. | |
| 1353 | -;; | |
| 1354 | -;; One at a time — a second paste replaces the first, which is what a reader | |
| 1355 | -;; who pasted the wrong thing means by pasting the right one. | |
| 1356 | -(defonce attachment (atom nil)) | |
| 1318 | +(def attachment cells/attachment) | |
| 1357 | 1319 | |
| 1358 | 1320 | ;; Each paste gets a file of its own rather than overwriting the last: the |
| 1359 | 1321 | ;; preview is painted from the file, and an upload may still be reading it. |
| @@ -2040,4 +2002,21 @@ | ||
| 2040 | 2002 | :connected? connected? |
| 2041 | 2003 | :join! join! |
| 2042 | 2004 | :open-channel! open-channel! |
| 2043 | - :leave-channel! leave-channel!}) | |
| 2005 | + :leave-channel! leave-channel! | |
| 2006 | + :send-draft! send-draft! | |
| 2007 | + :cancel-edit! cancel-edit! | |
| 2008 | + :cancel-reply! cancel-reply! | |
| 2009 | + :clear-attachment! clear-attachment! | |
| 2010 | + :open-image-picker! open-image-picker! | |
| 2011 | + :paste-image! paste-image! | |
| 2012 | + :jump-to-present! jump-to-present! | |
| 2013 | + :scrolled! scrolled! | |
| 2014 | + :toggle-users! toggle-users! | |
| 2015 | + :toggle-chat-list! toggle-chat-list! | |
| 2016 | + :toggle-overview! toggle-overview! | |
| 2017 | + :wide? wide? | |
| 2018 | + :member-count member-count | |
| 2019 | + :start-call! start-call! | |
| 2020 | + :in-call? av/in-call? | |
| 2021 | + :call-in av/call-in | |
| 2022 | + :call-available? av/available?}) | |
| @@ -69,19 +69,13 @@ | |||
| 69 | ;; How much backlog to ask for when the server did not volunteer any. | 69 | ;; How much backlog to ask for when the server did not volunteer any. |
| 70 | (def history-limit 100) | 70 | (def history-limit 100) |
| 71 | 71 | ||
| 72 | -(defonce draft (atom "")) | 72 | +(def draft cells/draft) |
| 73 | -;; The message the draft is answering, as {:id :from :text}, or nil. Held whole | 73 | +(def replying-to cells/replying-to) |
| 74 | -;; rather than as an id alone so the compose bar can say who is being answered | ||
| 75 | -;; without going looking for them. | ||
| 76 | -(defonce replying-to (atom nil)) | ||
| 77 | 74 | ||
| 78 | (defn reply-to! [m] (reset! replying-to (select-keys m [:id :from :text]))) | 75 | (defn reply-to! [m] (reset! replying-to (select-keys m [:id :from :text]))) |
| 79 | (defn cancel-reply! [] (reset! replying-to nil)) | 76 | (defn cancel-reply! [] (reset! replying-to nil)) |
| 80 | 77 | ||
| 81 | -;; The message the draft is a rewrite of, as `{:channel :id}`, or nil when the | 78 | +(def editing cells/editing) |
| 82 | -;; box is being used for something new. Only the id is kept: what is being | ||
| 83 | -;; rewritten is in the box, and the line on screen is the thing it will replace. | ||
| 84 | -(defonce editing (atom nil)) | ||
| 85 | 79 | ||
| 86 | ;; The message the emoji picker is choosing for, as `{:channel :id}`, or nil | 80 | ;; The message the emoji picker is choosing for, as `{:channel :id}`, or nil |
| 87 | ;; when it is closed. The picker is a panel over the compose bar rather than a | 81 | ;; when it is closed. The picker is a panel over the compose bar rather than a |
| @@ -97,22 +91,11 @@ | |||
| 97 | ;; so this is a screen of its own rather than a layer over the chat. | 91 | ;; so this is a screen of its own rather than a layer over the chat. |
| 98 | (defonce lightbox (atom nil)) ; {:path :url} | 92 | (defonce lightbox (atom nil)) ; {:path :url} |
| 99 | 93 | ||
| 100 | -;; Whether the chat screen is showing who is in the channel. Off by default: | 94 | +(def show-users? cells/show-users?) |
| 101 | -;; the panel costs the conversation a column, and the reader is here for the | ||
| 102 | -;; conversation. | ||
| 103 | -(defonce show-users? (atom false)) | ||
| 104 | 95 | ||
| 105 | (defn toggle-users! [] (swap! show-users? not)) | 96 | (defn toggle-users! [] (swap! show-users? not)) |
| 106 | 97 | ||
| 107 | -;; Whether the wide window is holding the chats list back, leaving the whole | 98 | +(def hide-chat-list? cells/hide-chat-list?) |
| 108 | -;; row to the conversation. Only a wide window has anything to hide: below | ||
| 109 | -;; `wide-width` the list and the conversation already take turns, and hiding | ||
| 110 | -;; the list there would be hiding the only way to another room. | ||
| 111 | -;; | ||
| 112 | -;; Saved with the other settings rather than reset per launch: it is a choice | ||
| 113 | -;; about how this screen is read, and a reader who wants the conversation | ||
| 114 | -;; whole wants it whole again tomorrow. | ||
| 115 | -(defonce hide-chat-list? (atom false)) | ||
| 116 | 99 | ||
| 117 | (declare save-prefs!) | 100 | (declare save-prefs!) |
| 118 | 101 | ||
| @@ -120,12 +103,7 @@ | |||
| 120 | (swap! hide-chat-list? not) | 103 | (swap! hide-chat-list? not) |
| 121 | (save-prefs!)) | 104 | (save-prefs!)) |
| 122 | 105 | ||
| 123 | -;; Whether the conversation is sharing its room with the overview strip — | 106 | +(def overview? cells/overview?) |
| 124 | -;; every channel's last lines in one list, under the one you are reading. | ||
| 125 | -;; Saved for the same reason as the fold above it: it is a choice about how | ||
| 126 | -;; this screen is laid out, and a layout a reader chose should be the one they | ||
| 127 | -;; come back to. | ||
| 128 | -(defonce overview? (atom false)) | ||
| 129 | 107 | ||
| 130 | (defn toggle-overview! [] | 108 | (defn toggle-overview! [] |
| 131 | (swap! overview? not) | 109 | (swap! overview? not) |
| @@ -189,11 +167,8 @@ | |||
| 189 | (or (= :chat @screen) | 167 | (or (= :chat @screen) |
| 190 | (and (wide?) (= :chats @screen)))) | 168 | (and (wide?) (= :chats @screen)))) |
| 191 | 169 | ||
| 192 | -;; Whether the chat view is showing the newest line, and a counter the view | 170 | +(def at-present? cells/at-present?) |
| 193 | -;; watches to be told to go back to it. A counter rather than a flag: a flag | 171 | +(def jump-tick cells/jump-tick) |
| 194 | -;; would need clearing, and there is no frame in which to clear it. | ||
| 195 | -(defonce at-present? (atom true)) | ||
| 196 | -(defonce jump-tick (atom 0)) | ||
| 197 | 172 | ||
| 198 | ;; How a backend answers "did that scroll end at the end?". | 173 | ;; How a backend answers "did that scroll end at the end?". |
| 199 | ;; | 174 | ;; |
| @@ -1340,20 +1315,7 @@ | |||
| 1340 | 1315 | ||
| 1341 | ;; ------------------------------------------------------------------ pasting | 1316 | ;; ------------------------------------------------------------------ pasting |
| 1342 | 1317 | ||
| 1343 | -;; The picture waiting to go out with the next line, or nil: | 1318 | +(def attachment cells/attachment) |
| 1344 | -;; | ||
| 1345 | -;; {:path the copy on disk, which is what the preview paints | ||
| 1346 | -;; :url where freeq serves it, once the upload has landed | ||
| 1347 | -;; :status :uploading | :ready} | ||
| 1348 | -;; | ||
| 1349 | -;; Held apart from the draft rather than written into it. A link pasted into | ||
| 1350 | -;; the entry is a line of unreadable text in the middle of whatever the reader | ||
| 1351 | -;; was typing, and it puts their cursor somewhere they did not put it. The | ||
| 1352 | -;; picture is a picture until it is sent; the draft stays theirs. | ||
| 1353 | -;; | ||
| 1354 | -;; One at a time — a second paste replaces the first, which is what a reader | ||
| 1355 | -;; who pasted the wrong thing means by pasting the right one. | ||
| 1356 | -(defonce attachment (atom nil)) | ||
| 1357 | 1319 | ||
| 1358 | ;; Each paste gets a file of its own rather than overwriting the last: the | 1320 | ;; Each paste gets a file of its own rather than overwriting the last: the |
| 1359 | ;; preview is painted from the file, and an upload may still be reading it. | 1321 | ;; preview is painted from the file, and an upload may still be reading it. |
| @@ -2040,4 +2002,21 @@ | |||
| 2040 | :connected? connected? | 2002 | :connected? connected? |
| 2041 | :join! join! | 2003 | :join! join! |
| 2042 | :open-channel! open-channel! | 2004 | :open-channel! open-channel! |
| 2043 | - :leave-channel! leave-channel!}) | 2005 | + :leave-channel! leave-channel! |
| 2006 | + :send-draft! send-draft! | ||
| 2007 | + :cancel-edit! cancel-edit! | ||
| 2008 | + :cancel-reply! cancel-reply! | ||
| 2009 | + :clear-attachment! clear-attachment! | ||
| 2010 | + :open-image-picker! open-image-picker! | ||
| 2011 | + :paste-image! paste-image! | ||
| 2012 | + :jump-to-present! jump-to-present! | ||
| 2013 | + :scrolled! scrolled! | ||
| 2014 | + :toggle-users! toggle-users! | ||
| 2015 | + :toggle-chat-list! toggle-chat-list! | ||
| 2016 | + :toggle-overview! toggle-overview! | ||
| 2017 | + :wide? wide? | ||
| 2018 | + :member-count member-count | ||
| 2019 | + :start-call! start-call! | ||
| 2020 | + :in-call? av/in-call? | ||
| 2021 | + :call-in av/call-in | ||
| 2022 | + :call-available? av/available?}) | ||