feat(web): 下线自主注册与协议勾选,修复转发消息报错,转发选择器分组+全选
按产品决定移除面向国内客户不适用的自主注册入口:删除 /register 路由 及 RegisterPage、登录页"马上注册"链接、登录/注册共用的协议勾选组件 Agreement,以及仅注册流程使用的 registerAccount/queueAccExtra 等 死代码;登录不再依赖勾选协议才能提交。 修复转发消息报错(真实高频bug,不限于个别场景):`forwardMessage`/ `sendText` 发送前只是 `tinode.getTopic()` 取一个本地话题对象,从未 真正订阅——SDK 要求话题处于 attached 状态才允许发布,而只有当前正 打开的会话才满足这一点,一旦切换过/离开过某个会话(哪怕之前订阅过 预览),它就会变回未订阅状态。也就是说转发给"当前会话之外"几乎任何 一个联系人都会失败。新增 `ensureTopicAttached()`,在转发前按需临时 订阅目标话题,单条转发和多选批量转发两处都已接入,实机验证对未打开 过的好友/群转发均成功。 转发选择器(ForwardPickerModal)按好友/群聊分组显示(原来混在一个 列表里),并加了"全选/取消全选",避免多个接收方时逐条点选。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
1826d2906f
commit
46b3288880
@@ -95,8 +95,8 @@ export function getMessagesSnapshot(topicName: string): StoredMessage[] {
|
||||
|
||||
/** Deduped the same way openConversation/connect are -- subscribing the same `me` topic twice
|
||||
* concurrently is the same non-idempotent-WS-call shape as those (currently reachable from
|
||||
* RequireAuth.tsx/LoginPage.tsx/RegisterPage.tsx, which don't overlap today, but this is cheap
|
||||
* insurance against a future call site that does, e.g. a manual "reload contacts" retry button). */
|
||||
* RequireAuth.tsx/LoginPage.tsx, which don't overlap today, but this is cheap insurance against a
|
||||
* future call site that does, e.g. a manual "reload contacts" retry button). */
|
||||
let inFlightMeSubscribe: Promise<unknown> | null = null;
|
||||
|
||||
/** Call once at session start (after login) -- chat-list metadata only, no message bodies. */
|
||||
@@ -214,6 +214,34 @@ export async function closeConversation(topicName: string): Promise<void> {
|
||||
await getTinode().getTopic(topicName).leave(false).catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure a topic can be published to right now, without disturbing whichever conversation is
|
||||
* actually open. `Topic.publishMessage()` rejects outright unless `_attached` is true, and that's
|
||||
* only reliably the case for the ONE topic openConversation/closeConversation currently has open --
|
||||
* any OTHER topic you've ever actually opened and then navigated away from goes back to detached and
|
||||
* STAYS that way (closeConversation's leave() doesn't restore prefetchPreview's original one-shot
|
||||
* subscription, and prefetchPreview itself no-ops on a topic it's already touched once, attached or
|
||||
* not). That covers forwarding a message to anyone other than the person/group you're currently
|
||||
* chatting with -- i.e. most real forwards -- so this isn't a rare edge case to special-case around,
|
||||
* it's the common one. Reuses `inFlightSubscribe` so a concurrent openConversation() for the same
|
||||
* topic is awaited/shared rather than racing it with a second `{sub}` packet (see openConversation's
|
||||
* own comment above for why that matters). Deliberately left attached afterward rather than re-left --
|
||||
* same "cheap to leave attached, likely reopened soon anyway" call prefetchPreview already makes.
|
||||
*/
|
||||
export function ensureTopicAttached(topicName: string): Promise<Topic> {
|
||||
const topic = getTinode().getTopic(topicName);
|
||||
const pending = inFlightSubscribe.get(topicName);
|
||||
if (pending) return pending;
|
||||
if (topic.isSubscribed()) return Promise.resolve(topic);
|
||||
wireTopicCallbacks(topic);
|
||||
const promise = topic.subscribe().then(() => topic);
|
||||
inFlightSubscribe.set(topicName, promise);
|
||||
promise.finally(() => {
|
||||
if (inFlightSubscribe.get(topicName) === promise) inFlightSubscribe.delete(topicName);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
let chatListSnapshot: Contact[] | null = null;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user