修复收藏/系统消息/通话记录批次的代码审查问题
- 通话结果"已拒绝"文案按视角区分(拒绝方看到"已拒绝"而非"对方已拒绝") - 通话记录页补充移动端返回头部与加载失败重试态 - 挂断时按是否已接通传递正确的挂断原因(cancelled) - 系统消息"全部标为已读"翻页加循环护栏,防止游标卡死;按钮可见性改用真实未读总数 - 收藏批量删除/转发在部分失败时保留失败项以便重试,而非无条件退出多选模式 - 收藏卡片边框/分类文字/侧栏图标颜色token修正
This commit is contained in:
@@ -193,7 +193,7 @@ function FavoriteCard({ item, selectMode, selected, onToggle }: { item: Favorite
|
||||
{body}
|
||||
{selectMode ? <SelectionCheckbox selected={selected} className="absolute -right-1 -top-1" /> : null}
|
||||
</div>
|
||||
<div className="flex items-center justify-between border-t border-border-list-item pt-2.5 text-xs text-text-tertiary-3">
|
||||
<div className="flex items-center justify-between border-t border-border-row pt-2.5 text-xs text-text-tertiary-3">
|
||||
<SourceLine source={item.source} />
|
||||
<span className="flex-none">{formatEventTimestamp(new Date(item.collected_at))}</span>
|
||||
</div>
|
||||
@@ -271,8 +271,16 @@ export function FavoritesLayout() {
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
invalidateAll();
|
||||
exitSelectMode();
|
||||
if (data?.failed?.length) setError(`${data.failed.length} 项删除失败,请重试`);
|
||||
// Exiting select mode unconditionally used to clear `selected` even on a PARTIAL failure --
|
||||
// the error toast named a count ("N项删除失败") but gave no way to act on it, so retrying
|
||||
// meant re-selecting from scratch by memory. Only actually-failed ids stay selected instead,
|
||||
// primed for an immediate retry.
|
||||
if (data?.failed?.length) {
|
||||
setSelected(new Set(data.failed.map((f) => f.favorite_id)));
|
||||
setError(`${data.failed.length} 项删除失败,请重试`);
|
||||
} else {
|
||||
exitSelectMode();
|
||||
}
|
||||
},
|
||||
onError: (err) => setError(err instanceof Error ? err.message : '删除失败'),
|
||||
});
|
||||
@@ -284,10 +292,13 @@ export function FavoritesLayout() {
|
||||
forwardFavorites([...selected], targetTopics, comment),
|
||||
onSuccess: (data) => {
|
||||
setForwarding(false);
|
||||
exitSelectMode();
|
||||
// Same `failed[]` gap as deleteMutation above (favorites.ts:101) -- forwarding to 3 targets can
|
||||
// succeed for 2 and fail for 1, and silently reporting "success" either way hides that.
|
||||
// succeed for 2 and fail for 1, and silently reporting "success" either way (including
|
||||
// clearing the favorites selection) hid that AND left nothing to retry from. The picker
|
||||
// itself still closes (which of several targets failed isn't tracked here) but the source
|
||||
// favorites stay selected so re-opening "转发" immediately can retry against the same set.
|
||||
if (data.failed?.length) setError(`${data.failed.length} 项转发失败,请重试`);
|
||||
else exitSelectMode();
|
||||
},
|
||||
onError: (err) => setError(err instanceof Error ? err.message : '转发失败'),
|
||||
});
|
||||
@@ -335,7 +346,7 @@ export function FavoritesLayout() {
|
||||
type="button"
|
||||
onClick={() => switchCategory(c.key)}
|
||||
className={`flex-none whitespace-nowrap rounded-2xl px-3.5 py-1.5 text-[13px] ${
|
||||
category === c.key ? 'bg-accent text-white' : 'bg-[#f1f2f4] text-text-body'
|
||||
category === c.key ? 'bg-accent text-white' : 'bg-[#f1f2f4] text-text-tertiary-1'
|
||||
}`}
|
||||
>
|
||||
{c.label}
|
||||
@@ -379,7 +390,7 @@ export function FavoritesLayout() {
|
||||
category === c.key ? 'bg-accent-selected-bg text-accent' : 'text-text-body hover:bg-[#f6f8fb]'
|
||||
}`}
|
||||
>
|
||||
<Icon name={c.icon} className="text-[18px]" />
|
||||
<Icon name={c.icon} className={`text-[18px] ${category === c.key ? '' : 'text-text-tertiary-4'}`} />
|
||||
<span className="flex-1 text-left">{c.label}</span>
|
||||
</button>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user