修复长按消息菜单"撤回"功能完全失效:LOCAL_SEQID 经 webpack externals 解析为 undefined
现象:验证第2章长按消息弹出菜单的时间窗口门控时发现,无论消息是不是自己刚发的、群主/普通
成员、发送后多少秒,长按菜单里永远不出现"撤回"这一项——服务端 messagePolicy 明确返回
recall_window_seconds=120,但这个选项在任何情况下都不会出现。
根因:messages-view.jsx 原来 `import { ..., LOCAL_SEQID } from 'tinode-sdk'`,但
webpack.config.js 把 'tinode-sdk' 映射到全局变量 `tinode`(externals: {'tinode-sdk': 'tinode'}),
而这个全局对象(umd/tinode.dev.js 的 UMD 导出)只挂了 {AccessMode, Drafty, TheCard, Tinode}
四个键,从未包含 LOCAL_SEQID——尽管 tinode-sdk 的 ES 模块本身确实导出了这个常量
(umd/tinode.dev.js 内部仍以 `const LOCAL_SEQID = 0xFFFFFFF;` 定义并在多处话题方法里使用,只是
没有挂到对外暴露的全局对象上)。externals 映射对"这个键不在对象上"和"这个导出根本不存在"没有
区分,所以按名字导入被静默解析成 `undefined`,没有任何构建报错。撤回菜单项的门控条件
`params.seq > 0 && params.seq < LOCAL_SEQID` 因此变成 `seq < undefined`,在 JS 里恒为
false——不是时间窗口判断错了,是入口条件本身就从未为真过,撤回功能对所有用户、所有消息实质性
完全失效。
用控制台直接调用 MessagesView 实例的 handleShowMessageContextMenu 并打印各分支布尔值定位到
这一步:seq=2 这样明显合法的正整数,seqOk 却是 false,才追到 LOCAL_SEQID 本身是 undefined。
修复:messages-view.jsx 不再从 'tinode-sdk' 导入 LOCAL_SEQID,改为本文件内本地声明
`const LOCAL_SEQID = 0xFFFFFFF`,与 SDK 内部定义保持一致(未改动 webpack externals 映射本身——
其它页面都依赖它保持现状,改映射风险更大、影响面更广)。
验证:登录测试账号,在群聊里发一条新消息立即长按,确认"撤回"正确出现在菜单中;点击后
`POST /topics/{topic}/messages/{seq}/recall` 返回 200,消息从会话中正确消失;对比一条已经
超过 recall_window_seconds(同时也超过 edit_window_seconds)的旧消息,确认"撤回"和"编辑"
仍正确不显示,时间窗口判断本身未被破坏。
注:umd/index.dev.js 本次未随此提交提交——工作区里并行的其它 agent 仍在改
contact-management-view.jsx / sidepanel-view.jsx 且未提交,重新构建的 index.dev.js 会把它们的
未提交改动一起编译进同一产物文件,为避免混入不相关改动,只提交 messages-view.jsx 按路由懒加载
的独立 chunk(umd/src_views_messages-view_jsx.dev.js 及其 .map),不受这个问题影响。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5c688007c8
commit
b200dc2525
@@ -3,7 +3,24 @@
|
||||
import React, { Suspense } from 'react';
|
||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
import { Drafty, Tinode, TheCard, LOCAL_SEQID } from 'tinode-sdk';
|
||||
import { Drafty, Tinode, TheCard } from 'tinode-sdk';
|
||||
|
||||
// webpack.config.js maps the 'tinode-sdk' import to the global `tinode` UMD bundle, which only
|
||||
// re-exports {AccessMode, Drafty, TheCard, Tinode} (see umd/tinode.dev.js's own top-level export
|
||||
// list) -- LOCAL_SEQID was never one of them, despite tinode-sdk's ES module genuinely exporting
|
||||
// it (confirmed directly against umd/tinode.dev.js, which still defines it internally as
|
||||
// `const LOCAL_SEQID = 0xFFFFFFF;` and uses it in several of its own topic methods -- it's just
|
||||
// never attached to the UMD bundle's exported global object). Importing it by name here silently
|
||||
// resolved to `undefined` instead of a build error (an externals mapping can't tell "not on this
|
||||
// object" from "doesn't exist"), and every `seq < LOCAL_SEQID` below was therefore
|
||||
// `seq < undefined`, which JS always evaluates to false -- confirmed live: "撤回"
|
||||
// (menu_item_recall)never appeared in the long-press
|
||||
// menu for ANY message, own or admin, however fresh, because the seq-range check that's supposed
|
||||
// to just filter out not-yet-confirmed local placeholder messages was unconditionally rejecting
|
||||
// every real, server-confirmed message too. Hardcoding the same value the SDK itself uses (rather
|
||||
// than trying to change what webpack's externals map exposes, which every other page importing
|
||||
// from 'tinode-sdk' already depends on staying exactly as-is) is the narrowest fix.
|
||||
const LOCAL_SEQID = 0xFFFFFFF;
|
||||
|
||||
const CallPanel = React.lazy(_ => import('../widgets/call-panel.jsx'));
|
||||
import ChatMessage from '../widgets/chat-message.jsx';
|
||||
|
||||
Reference in New Issue
Block a user