修复"我的收藏"批量删除仍用原生 window.confirm(),是本工程已确立模式里同一类问题的第三处

现象:跟已经修过的两处同一类问题(46a98782"退出登录"、4773ee5f"解散群组")一样,
content-library-view.jsx 的收藏批量删除也还在用裸 window.confirm(),4773ee5f 的提交
说明里已经点名记录过这一处、留给第七章处理。

根因:window.confirm() 与本工程其它确认弹层的视觉不一致,且部分内嵌 WebView/kiosk
环境会直接禁用同步对话框(confirm() 恒返回 false,删除被静默拦下、用户毫无感知)。

修法:改成两段式 state(点"删除"先进"确认中"态渲染弹层,弹层里的"确定"才真正调用
batchDeleteFavorites),新增 .library-sheet-backdrop/.library-confirm-sheet 样式,
数值抄自本文件已有的 .personal-*/.group-* 同款弹层(46a98782/4773ee5f),保持视觉
语言一致。

验证:真实浏览器注册全新测试账号,在一个真实群聊里发送并收藏两条消息,进入"我的
收藏"多选模式,选中两项后:先测"点删除→点取消"(弹层消失、两项收藏原样保留、未
发出任何 batch-delete 请求);再测"点删除→点确定"(真实 POST .../favorites/
batch-delete 200 成功、两项 ok:true、列表正确清空为"暂无此类收藏"、toast 提示
"已删除所选收藏")。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-06 17:55:48 +08:00
co-authored by Claude Sonnet 5
parent c2e07a89b8
commit 31f2b4afea
3 changed files with 70 additions and 4 deletions
+13 -3
View File
@@ -347,8 +347,13 @@ function Favorites({view, hashParams, tinode, onToast}) {
});
}, [items]);
const toggle = id => setSelected(values => values.includes(id) ? values.filter(v => v !== id) : values.concat(id));
const deleteSelected = () => {
if (!window.confirm(`确定删除已选择的 ${selected.length} 项收藏吗?`)) return;
// 原来是裸 window.confirm()——跟这个工程已经修过的另外两处同一类问题(46a98782"退出登录"、
// 4773ee5f"解散群组")一样:跟本项目其它地方的自定义确认弹层视觉不一致,且部分内嵌WebView/
// kiosk环境会直接禁用同步对话框(confirm()恒返回false,删除被静默拦下、用户毫无感知)。
// 改成两段式 state:点"删除"先进"确认中"态渲染弹层,弹层里的"确定"才真正调用删除接口。
const [confirmingDelete, setConfirmingDelete] = React.useState(false);
const confirmDelete = () => {
setConfirmingDelete(false);
batchDeleteFavorites(selected).then(result => {
const okIds = new Set(((result && result.items) || []).filter(r => r.ok).map(r => r.favorite_id));
setItems(values => {
@@ -406,8 +411,13 @@ function Favorites({view, hashParams, tinode, onToast}) {
</main>
{selecting ? <nav className="library-batch-bar">
<button type="button" disabled={!selected.length} onClick={() => navigate('favorite-share', {ids: selected.join(',')})}><Icon>share</Icon><span>转发</span></button>
<button type="button" disabled={!selected.length} onClick={deleteSelected}><Icon>delete_outline</Icon><span>删除</span></button>
<button type="button" disabled={!selected.length} onClick={() => setConfirmingDelete(true)}><Icon>delete_outline</Icon><span>删除</span></button>
</nav> : null}
{confirmingDelete ? <div className="library-sheet-backdrop"><section className="library-confirm-sheet" role="dialog" aria-modal="true">
<Icon>delete_outline</Icon><h2>删除收藏</h2><p>确定删除已选择的 {selected.length} 项收藏吗?</p>
<button type="button" className="danger" onClick={confirmDelete}>确定</button>
<button type="button" onClick={() => setConfirmingDelete(false)}>取消</button>
</section></div> : null}
</div>;
}