feat(messaging-ui): Slack-style threaded-replies side panel

Replies (messages with parentInteractionId) now open in a right-hand ThreadPane
instead of inline quoting:
- extracted a shared Composer (draft + @mention autocomplete + attach) and
  MessageItem (bubble + mentions + attachment + reactions + reply affordance)
- Thread shows top-level messages only; a message with replies gets a
  '💬 N replies' link, and hovering shows 💬 'Reply in thread'
- ThreadPane renders the root + its replies + a composer that posts back with
  parentInteractionId; Messenger becomes 3-column (list | thread | pane),
  pane closes on conversation switch
- no contract/adapter/backend change (parentInteractionId was already wired)
- thread-pane render test (open → reply → parent shows the count); 58 green

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 00:29:54 +05:30
parent 7a0fb2ca97
commit fa93173b1f
8 changed files with 452 additions and 188 deletions
+57
View File
@@ -157,6 +157,26 @@
.miu-msg.is-mine .miu-bubble-row {
flex-direction: row-reverse;
}
.miu-msg-actions {
display: flex;
gap: 2px;
flex-shrink: 0;
}
.miu-thread-link {
align-self: flex-start;
margin-top: 3px;
padding: 3px 9px;
border-radius: 999px;
border: 1px solid var(--miu-border);
background: var(--miu-panel);
color: var(--miu-accent);
font-size: 12px;
font-weight: 600;
cursor: pointer;
}
.miu-msg.is-mine .miu-thread-link {
align-self: flex-end;
}
.miu-react-wrap {
position: relative;
flex-shrink: 0;
@@ -490,6 +510,43 @@
color: var(--miu-muted);
}
/* thread pane (Slack-style) */
.miu-pane {
width: 340px;
flex-shrink: 0;
display: flex;
flex-direction: column;
min-height: 0;
border-left: 1px solid var(--miu-border);
background: var(--miu-panel);
}
.miu-pane-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid var(--miu-border);
font-weight: 700;
}
.miu-pane-close {
border: none;
background: none;
color: var(--miu-muted);
cursor: pointer;
font-size: 15px;
}
.miu-pane-messages {
background: var(--miu-bg);
}
.miu-pane-divider {
font-size: 11.5px;
color: var(--miu-muted);
text-align: center;
margin: 4px 0;
padding-bottom: 4px;
border-bottom: 1px solid var(--miu-border);
}
/* misc */
.miu-empty {
padding: 24px;