feat(web): pagination, quote/reply, favorite, and single-message forward
- ConversationView: infinite-scroll "加载更多" -- scroll-to-40px triggers
topic.msgHasMoreMessages()+getMessagesPage() to fill exactly the missing
seq ranges (not naive since/before paging, since server-side deletions can
punch holes in an otherwise-contiguous range), with scroll position
preserved across the prepend.
- lib/tinode/send.ts: sendReply() ports the old app's exact quote
construction (Drafty.replyContent truncates, Drafty.quote wraps with the
sender's name, Drafty.append inlines the whole quote block ahead of the
new text -- the receiving side never needs to look up the original
message). forwardMessage() sends a single message directly to one picked
target topic (ForwardPickerModal) -- simplified from the old app's
stage-then-compose flow, trading that nicety for a much smaller dialog.
- lib/messages/drafty.tsx: added the 'QQ' Drafty style-tag case ported
against the SDK's actual Drafty.quote() output shape (no `key`/`data` of
its own -- verified by reading tinode.dev.js, not guessed).
- lib/api/messages.ts: favoriteMessages() -- a single message is just a
one-item batch against POST /v1/im/favorites/batch (confirmed in
docs/IM-前后端对接文档.md:1935).
- Context menu now shows 引用/复制/收藏/转发/多选/[撤回]/删除 in spec order
(README §3.5); 翻译 still deliberately absent (no real backend for it,
confirmed by research).
Verified end to end: sent a real quote reply and confirmed the exact wire
packet (head.reply, QQ fmt span, MN entity) and that it renders correctly
via the new QQ formatter case; favorite POSTed and returned created_count:1;
forward POSTed the expected {head:{forwarded:"topic:seq"}} packet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
bccbdff9b2
commit
6fcd779530
@@ -55,6 +55,14 @@ function formatNode(
|
||||
</a>
|
||||
);
|
||||
}
|
||||
case 'QQ':
|
||||
// Drafty.quote() has no `key`/`data` of its own (tinode.dev.js:2160-2168) -- it's a plain style
|
||||
// span wrapping mention(header,uid) + linebreak + body, all already rendered into `children`.
|
||||
return (
|
||||
<div key={key} className="mb-1.5 rounded border-l-2 border-accent bg-white/50 px-2 py-0.5 text-xs text-[#4a4f57]">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return <Fragment key={key}>{children}</Fragment>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user