fix(feed): hide_read 模式下,有提示条时推迟文章 splice 到提示条消失后
This commit is contained in:
@@ -193,9 +193,11 @@ async function toggleRead(a: ArticleListItem) {
|
|||||||
await readsApi.mark(a.id)
|
await readsApi.mark(a.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// === 关键:先 await 提示条 fetch,再 splice ===
|
// === 关键:先 await 提示条 fetch,再决定是否 splice ===
|
||||||
// 原因:hide_read 模式下,350ms 后 items.splice 会把 a 移除,wrapper 跟着走。
|
// 原因:hide_read 模式下,如果 360ms 内就把 a 从 items 移除,
|
||||||
// 如果 category-count 比 350ms 慢,wrapper 还没渲染就被切走 → 用户看不到。
|
// articlesWithPrompts 跟着过滤,wrapper 就被切走 → 用户看不到提示条。
|
||||||
|
// 解决:如果 fetch 完发现有提示条 → 把 splice 推迟到 8s 提示条到期再 splice;
|
||||||
|
// 如果没有提示条 → 照旧 360ms splice。
|
||||||
if (!wasRead && a.category) {
|
if (!wasRead && a.category) {
|
||||||
try {
|
try {
|
||||||
const fetchPromise = maybePromptCategoryRead(a)
|
const fetchPromise = maybePromptCategoryRead(a)
|
||||||
@@ -209,7 +211,41 @@ async function toggleRead(a: ArticleListItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hide_read 模式:卡片从列表里消失(用户预期行为)
|
// hide_read 模式:卡片从列表里消失(用户预期行为)
|
||||||
|
// 但如果该文章有提示条,推迟 splice 到提示条消失后再做
|
||||||
if (!wasRead && hideRead.value) {
|
if (!wasRead && hideRead.value) {
|
||||||
|
const hasPrompt = (categoryPromptsByArticle.value.get(a.id)?.length ?? 0) > 0
|
||||||
|
const delay = hasPrompt ? 8200 : 360 // 有提示:让提示条走完 8s;无提示:照旧
|
||||||
|
if (hasPrompt) {
|
||||||
|
// 监听 8s 计时器到期 / dismiss / confirm
|
||||||
|
// 用 watchEffect 监听 Map 变化,提示条消失后再 splice
|
||||||
|
const stopWatch = watch(
|
||||||
|
() => categoryPromptsByArticle.value.get(a.id),
|
||||||
|
(newVal) => {
|
||||||
|
if (!newVal || newVal.length === 0) {
|
||||||
|
stopWatch()
|
||||||
|
const idx = items.value.findIndex((x) => x.id === a.id)
|
||||||
|
if (idx >= 0) {
|
||||||
|
pendingRemoval.value.add(a.id)
|
||||||
|
items.value.splice(idx, 1)
|
||||||
|
pendingRemoval.value.delete(a.id)
|
||||||
|
if (total.value > 0) total.value -= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: false },
|
||||||
|
)
|
||||||
|
// 兜底:8.2s 强制结束(防止 watch 漏掉)
|
||||||
|
setTimeout(() => {
|
||||||
|
stopWatch()
|
||||||
|
const idx = items.value.findIndex((x) => x.id === a.id)
|
||||||
|
if (idx >= 0) {
|
||||||
|
pendingRemoval.value.add(a.id)
|
||||||
|
items.value.splice(idx, 1)
|
||||||
|
pendingRemoval.value.delete(a.id)
|
||||||
|
if (total.value > 0) total.value -= 1
|
||||||
|
}
|
||||||
|
}, delay)
|
||||||
|
} else {
|
||||||
const idx = items.value.findIndex((x) => x.id === a.id)
|
const idx = items.value.findIndex((x) => x.id === a.id)
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
pendingRemoval.value.add(a.id)
|
pendingRemoval.value.add(a.id)
|
||||||
@@ -218,7 +254,8 @@ async function toggleRead(a: ArticleListItem) {
|
|||||||
if (i >= 0) items.value.splice(i, 1)
|
if (i >= 0) items.value.splice(i, 1)
|
||||||
pendingRemoval.value.delete(a.id)
|
pendingRemoval.value.delete(a.id)
|
||||||
if (total.value > 0) total.value -= 1
|
if (total.value > 0) total.value -= 1
|
||||||
}, 360)
|
}, delay)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
|||||||
Reference in New Issue
Block a user