feat: reactions, link previews, mobile layout, TUI multi-network + /react usage hints

- TUI /react shows usage hint on bad/missing args instead of silently no-oping
- README: document /join /net /react slash commands and Ctrl+N keybinding
- README: add send_reaction IPC command and reaction IPC event to protocol reference
- FUTURE.md: mark reactions, link previews, responsive mobile layout, TUI
  multi-network and TUI reactions as shipped; add prose sections for each
- EXTENSIONS.md: add EXT-008 documenting reaction wire protocol, SQLite
  schema, IPC commands/events, history replay, and browser-mode implementation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-06-29 20:08:52 +02:00
parent 437deca6a0
commit d09aa2b219
4 changed files with 113 additions and 11 deletions

View File

@@ -636,6 +636,10 @@ func (m model) doSend(cmds []tea.Cmd) (model, []tea.Cmd) {
emoji = parts[1]
}
}
if emoji == "" {
m.errMsg = "usage: /react <emoji> or /react <n> <emoji> (e.g. /react 👍 or /react 3 ❤️)"
return m, cmds
}
msgs := m.messages[m.msgKey()]
var targetMid string
if targetIdx == -1 && len(msgs) > 0 {
@@ -643,14 +647,16 @@ func (m model) doSend(cmds []tea.Cmd) (model, []tea.Cmd) {
} else if targetIdx >= 0 && targetIdx < len(msgs) {
targetMid = msgs[targetIdx].mid
}
if targetMid != "" && emoji != "" {
cmds = append(cmds, sendIPC(m.enc, proto.IpcMessage{
Type: proto.CmdSendReaction,
NetworkID: m.activeNetworkID(),
ReactionMID: targetMid,
ReactionEmoji: emoji,
}))
if targetMid == "" {
m.errMsg = "usage: /react <emoji> or /react <n> <emoji> (e.g. /react 👍 or /react 3 ❤️)"
return m, cmds
}
cmds = append(cmds, sendIPC(m.enc, proto.IpcMessage{
Type: proto.CmdSendReaction,
NetworkID: m.activeNetworkID(),
ReactionMID: targetMid,
ReactionEmoji: emoji,
}))
return m, cmds
}