diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/chat-app.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/chat-app.js | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js b/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js index a793527..6e9de5f 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/chat-app.js @@ -203,9 +203,17 @@ function ChatImage({ filename, entries, transportRef, gekRef }) { // read one answer. Empty means the group has no writable root right now — every // root is read-only, or the one drive that was writable is unplugged — and the // paperclip says so rather than producing a refusal from the node. +// +// `deviceReady` is "this connection has identified a device to the node", the +// one thing chat needs beyond being connected. It arrives as a prop, and that +// is the correction: it used to be read off the transport during render +// (`transportRef.current.devicePk`), and a ref changing re-renders nothing — so +// once a reconnect cleared it the composer stayed disabled for the rest of the +// session. Defaulting to `true` fails open: a wiring mistake here must never be +// able to leave someone with a dead textbox. function ChatPanel({ transportRef, username, userId, entries, gekRef, onRefreshIndex, onPreview, attachRoot = '', attachDir = '', - onActivity, status }) { + onActivity, status, deviceReady = true }) { const [messages, setMessages] = useState([]); const [hasMore, setHasMore] = useState(false); const [loadingOlder, setLoadingOlder] = useState(false); @@ -519,9 +527,26 @@ function ChatPanel({ transportRef, username, userId, entries, gekRef, // refuse a member claiming somebody else's key. Without it there is nothing // to send with, so the composer says so before anything is typed rather than // producing a refusal the reader cannot act on. - const transportNow = transportRef.current; - const cannotSend = !!(transportNow && transportNow.connected - && !transportNow.devicePk); + // + // Only while connected: before that the composer is enabled and `sendMessage` + // simply declines, which is what it always did — saying "this device cannot + // post" at someone who is merely still connecting names the wrong problem. + const cannotSend = status === 'connected' && !deviceReady; + + // The composer's disabled state has exactly two inputs, and neither of them + // was observable from outside the component. A "chat hangs, the textbox is + // not clickable" report arrived with a complete console dump that could not + // say which of the two it had been, nor when it started. This is what makes + // the next one answer that in one line. + useEffect(() => { + const why = sending ? 'send in flight' + : cannotSend ? 'device not identified to the node' + : null; + console.log('[MeshBay] chat composer:', why ? 'disabled (' + why + ')' : 'enabled'); + if (window.MeshBayTrace && window.MeshBayTrace.record) { + window.MeshBayTrace.record('chat_composer', { disabled: !!why, why }); + } + }, [sending, cannotSend]); const onKeyDown = useCallback((e) => { if (e.key === 'Enter' && !e.shiftKey) { |