ZHIWEI666 commited on
Commit
0e86eac
·
verified ·
1 Parent(s): 6687a40

Upload 104 files

Browse files
前端页面/components/UI交互提示组件.js CHANGED
@@ -894,10 +894,12 @@ export function createInstallProgress(container) {
894
 
895
  return {
896
  update(progress, message) {
897
- const p = Math.max(0, Math.min(100, progress));
898
- fill.style.width = `${p}%`;
899
- percent.textContent = `${p}%`;
900
- progressTrack.setAttribute("aria-valuenow", String(p));
 
 
901
  if (message) {
902
  stage.textContent = message;
903
  progressTrack.setAttribute("aria-valuetext", message);
 
894
 
895
  return {
896
  update(progress, message) {
897
+ if (Number.isFinite(progress)) {
898
+ const p = Math.max(0, Math.min(100, progress));
899
+ fill.style.width = `${p}%`;
900
+ percent.textContent = `${p}%`;
901
+ progressTrack.setAttribute("aria-valuenow", String(p));
902
+ }
903
  if (message) {
904
  stage.textContent = message;
905
  progressTrack.setAttribute("aria-valuetext", message);
前端页面/components/性能优化工具.js CHANGED
@@ -1463,7 +1463,10 @@ export function renderListLoadError(container, message, onRetry, t, error = null
1463
  retry.type = "button";
1464
  retry.className = "comfy-ranking-list-error__retry";
1465
  retry.textContent = t("common.retry");
1466
- retry.addEventListener("click", () => onRetry?.());
 
 
 
1467
 
1468
  status.append(text, retry);
1469
  container.replaceChildren(status);
 
1463
  retry.type = "button";
1464
  retry.className = "comfy-ranking-list-error__retry";
1465
  retry.textContent = t("common.retry");
1466
+ retry.addEventListener("click", () => {
1467
+ if (!status.isConnected || status.parentNode !== container) return;
1468
+ onRetry?.();
1469
+ });
1470
 
1471
  status.append(text, retry);
1472
  container.replaceChildren(status);
前端页面/core/侧边栏数据引擎.js CHANGED
@@ -176,7 +176,8 @@ export async function loadSidebarContent({
176
  prompts: { loadModule: getPromptsView, factory: 'createPromptsView', errorKey: 'feedback.load_prompts_failed' },
177
  };
178
  if (Object.hasOwn(domainViews, tab)) {
179
- await mountSidebarDomainView({ contentArea, currentUser, keyword, getViewOptions, renderToken, getRenderToken,
 
180
  ...domainViews[tab] });
181
  return;
182
  }
 
176
  prompts: { loadModule: getPromptsView, factory: 'createPromptsView', errorKey: 'feedback.load_prompts_failed' },
177
  };
178
  if (Object.hasOwn(domainViews, tab)) {
179
+ await mountSidebarDomainView({ contentArea, currentUser, keyword, getViewOptions: force === true
180
+ ? () => ({ ...getViewOptions?.(), force: true }) : getViewOptions, renderToken, getRenderToken,
181
  ...domainViews[tab] });
182
  return;
183
  }
前端页面/post/讨论区组件.js CHANGED
@@ -87,7 +87,7 @@ function _generateAvatarHtml(avatar, name) {
87
  /**
88
  * 💬 创建讨论区视图
89
  */
90
- export function createPostsView(currentUser, keyword = "", { sort: initialSort = "latest" } = {}) {
91
  if (activeViewCleanup) activeViewCleanup();
92
 
93
  currentUserCache = currentUser;
@@ -124,6 +124,7 @@ export function createPostsView(currentUser, keyword = "", { sort: initialSort =
124
  let networkRequestGeneration = 0;
125
  let disposed = false;
126
  let firstPageReady = false;
 
127
  const cardNavigation = createCardNavigationScope(window, () => !disposed, {
128
  captureSession: captureRequestSession,
129
  storageKeys: [CACHE.LEGACY_KEYS.TOKEN, CACHE.LEGACY_KEYS.USER]
@@ -317,8 +318,10 @@ export function createPostsView(currentUser, keyword = "", { sort: initialSort =
317
  postsGrid.appendChild(status);
318
  };
319
 
320
- const loadPosts = async (page = 1, append = false) => {
321
  if (disposed) return;
 
 
322
  if (!append && page === 1) firstPageReady = false;
323
  const viewGeneration = !append && page === 1 ? ++listViewGeneration : listViewGeneration;
324
  const requestedSort = currentSort;
@@ -332,7 +335,7 @@ export function createPostsView(currentUser, keyword = "", { sort: initialSort =
332
  allPostsData = proxyImages(cachedData);
333
  renderPostsFromCache(allPostsData, true);
334
  // 后台静默更新
335
- silentRefresh().finally(() => {
336
  if (disposed || viewGeneration !== listViewGeneration) return;
337
  if (searchKeyword && !allPostsData.some(post => _matchesSearch(post, searchKeyword))) {
338
  currentPaginator?.load();
@@ -351,7 +354,7 @@ export function createPostsView(currentUser, keyword = "", { sort: initialSort =
351
  requestGeneration = ++networkRequestGeneration;
352
  isLoadingFromNetwork = true;
353
  const readResponse = captureListRead(cacheKey);
354
- const res = await api.getPosts(page, PAGE_SIZE, requestedSort);
355
  if (viewGeneration !== listViewGeneration || requestGeneration !== networkRequestGeneration) {
356
  if (requestGeneration === networkRequestGeneration) {
357
  isLoadingFromNetwork = false;
@@ -443,7 +446,10 @@ export function createPostsView(currentUser, keyword = "", { sort: initialSort =
443
  renderPostsFromCache(allPostsData);
444
  showToast(t('post.network_cache'), "warning");
445
  } else {
446
- renderListLoadError(postsGrid, err?.name === 'ListCacheChangedError' ? t('feedback.list_changed_retry') : t('post.load_failed'), () => loadPosts(1, false), t, err);
 
 
 
447
  }
448
  }
449
  }
@@ -500,7 +506,7 @@ export function createPostsView(currentUser, keyword = "", { sort: initialSort =
500
  };
501
 
502
  // 后台静默更新
503
- const silentRefresh = async () => {
504
  if (disposed || isLoadingFromNetwork) return;
505
  const viewGeneration = listViewGeneration;
506
  const requestedSort = currentSort;
@@ -550,6 +556,8 @@ export function createPostsView(currentUser, keyword = "", { sort: initialSort =
550
  }
551
  isLoadingFromNetwork = false;
552
  console.warn("后台更新帖子失败(保留当前内容)");
 
 
553
  }
554
  if (searchKeyword && !allPostsData.some(post => _matchesSearch(post, searchKeyword))) {
555
  currentPaginator?.load();
 
87
  /**
88
  * 💬 创建讨论区视图
89
  */
90
+ export function createPostsView(currentUser, keyword = "", { sort: initialSort = "latest", force: initialForce = false } = {}) {
91
  if (activeViewCleanup) activeViewCleanup();
92
 
93
  currentUserCache = currentUser;
 
124
  let networkRequestGeneration = 0;
125
  let disposed = false;
126
  let firstPageReady = false;
127
+ let forceRefreshPending = initialForce === true;
128
  const cardNavigation = createCardNavigationScope(window, () => !disposed, {
129
  captureSession: captureRequestSession,
130
  storageKeys: [CACHE.LEGACY_KEYS.TOKEN, CACHE.LEGACY_KEYS.USER]
 
318
  postsGrid.appendChild(status);
319
  };
320
 
321
+ const loadPosts = async (page = 1, append = false, forceRequest = false) => {
322
  if (disposed) return;
323
+ const forceRefresh = !append && page === 1 && (forceRefreshPending || forceRequest === true);
324
+ if (forceRefresh) forceRefreshPending = false;
325
  if (!append && page === 1) firstPageReady = false;
326
  const viewGeneration = !append && page === 1 ? ++listViewGeneration : listViewGeneration;
327
  const requestedSort = currentSort;
 
335
  allPostsData = proxyImages(cachedData);
336
  renderPostsFromCache(allPostsData, true);
337
  // 后台静默更新
338
+ silentRefresh(forceRefresh).finally(() => {
339
  if (disposed || viewGeneration !== listViewGeneration) return;
340
  if (searchKeyword && !allPostsData.some(post => _matchesSearch(post, searchKeyword))) {
341
  currentPaginator?.load();
 
354
  requestGeneration = ++networkRequestGeneration;
355
  isLoadingFromNetwork = true;
356
  const readResponse = captureListRead(cacheKey);
357
+ const res = await api.getPosts(page, PAGE_SIZE, requestedSort, ...(forceRefresh ? [{ noCache: true }] : []));
358
  if (viewGeneration !== listViewGeneration || requestGeneration !== networkRequestGeneration) {
359
  if (requestGeneration === networkRequestGeneration) {
360
  isLoadingFromNetwork = false;
 
446
  renderPostsFromCache(allPostsData);
447
  showToast(t('post.network_cache'), "warning");
448
  } else {
449
+ renderListLoadError(postsGrid, err?.name === 'ListCacheChangedError' ? t('feedback.list_changed_retry') : t('post.load_failed'), () => {
450
+ if (disposed || isLoadingFromNetwork || requestedSort !== currentSort) return;
451
+ return loadPosts(1, false, forceRefresh);
452
+ }, t, err);
453
  }
454
  }
455
  }
 
506
  };
507
 
508
  // 后台静默更新
509
+ const silentRefresh = async (notifyFailure = false) => {
510
  if (disposed || isLoadingFromNetwork) return;
511
  const viewGeneration = listViewGeneration;
512
  const requestedSort = currentSort;
 
556
  }
557
  isLoadingFromNetwork = false;
558
  console.warn("后台更新帖子失败(保留当前内容)");
559
+ if (notifyFailure === true) showToast(t(err?.name === 'ListCacheChangedError'
560
+ ? 'feedback.list_changed_retry' : 'feedback.refresh_failed_cached'), 'warning');
561
  }
562
  if (searchKeyword && !allPostsData.some(post => _matchesSearch(post, searchKeyword))) {
563
  currentPaginator?.load();
前端页面/prompt/提示词组件.js CHANGED
@@ -124,7 +124,7 @@ function _generateAvatarHtml(avatar, name) {
124
  /**
125
  * 🧩 创建提示词视图
126
  */
127
- export function createPromptsView(currentUser, keyword = "", { sort: initialSort = "latest", type: initialType = "image", category: initialCategory = null, onFiltersChange } = {}) {
128
  if (activeViewCleanup) activeViewCleanup();
129
 
130
  currentUserCache = currentUser;
@@ -179,6 +179,7 @@ export function createPromptsView(currentUser, keyword = "", { sort: initialSort
179
  let currentPaginator = null;
180
  let disposed = false;
181
  let firstPageReady = false;
 
182
  const cardNavigation = createCardNavigationScope(window, () => !disposed, {
183
  captureSession: captureRequestSession,
184
  storageKeys: [CACHE.LEGACY_KEYS.TOKEN, CACHE.LEGACY_KEYS.USER]
@@ -441,8 +442,10 @@ export function createPromptsView(currentUser, keyword = "", { sort: initialSort
441
  }
442
  };
443
 
444
- const loadPrompts = async (page = 1, append = false) => {
445
  if (disposed) return;
 
 
446
  if (!append && page === 1) firstPageReady = false;
447
  const viewGeneration = !append && page === 1 ? ++listViewGeneration : listViewGeneration;
448
  const requestedType = currentType;
@@ -457,7 +460,7 @@ export function createPromptsView(currentUser, keyword = "", { sort: initialSort
457
  allPromptsData = proxyImages(cachedData);
458
  renderPromptsFromCache(allPromptsData, true);
459
  // 后台静默更新
460
- silentRefresh().finally(() => {
461
  if (disposed || viewGeneration !== listViewGeneration) return;
462
  if (searchKeyword && !allPromptsData.some(prompt => _matchesSearch(prompt, searchKeyword))) {
463
  currentPaginator?.load();
@@ -476,7 +479,7 @@ export function createPromptsView(currentUser, keyword = "", { sort: initialSort
476
  requestGeneration = ++networkRequestGeneration;
477
  isLoadingFromNetwork = true;
478
  const readResponse = captureListRead(cacheKey);
479
- const res = await api.getPrompts(requestedType, requestedCategory, page, PAGE_SIZE, requestedSort);
480
  if (viewGeneration !== listViewGeneration || requestGeneration !== networkRequestGeneration) {
481
  if (requestGeneration === networkRequestGeneration) {
482
  isLoadingFromNetwork = false;
@@ -567,7 +570,10 @@ export function createPromptsView(currentUser, keyword = "", { sort: initialSort
567
  renderPromptsFromCache(allPromptsData);
568
  showToast(t('prompt.network_cache'), "warning");
569
  } else {
570
- renderListLoadError(promptsGrid, err?.name === 'ListCacheChangedError' ? t('feedback.list_changed_retry') : t('prompt.load_failed'), () => loadPrompts(1, false), t, err);
 
 
 
571
  }
572
  }
573
  }
@@ -624,7 +630,7 @@ export function createPromptsView(currentUser, keyword = "", { sort: initialSort
624
  };
625
 
626
  // 后台静默更新
627
- const silentRefresh = async () => {
628
  if (disposed || isLoadingFromNetwork) return;
629
  const viewGeneration = listViewGeneration;
630
  const requestedType = currentType;
@@ -676,6 +682,8 @@ export function createPromptsView(currentUser, keyword = "", { sort: initialSort
676
  }
677
  isLoadingFromNetwork = false;
678
  console.warn("后台更新提示词失败(保留当前内容)");
 
 
679
  }
680
  if (searchKeyword && !allPromptsData.some(prompt => _matchesSearch(prompt, searchKeyword))) {
681
  currentPaginator?.load();
 
124
  /**
125
  * 🧩 创建提示词视图
126
  */
127
+ export function createPromptsView(currentUser, keyword = "", { sort: initialSort = "latest", type: initialType = "image", category: initialCategory = null, onFiltersChange, force: initialForce = false } = {}) {
128
  if (activeViewCleanup) activeViewCleanup();
129
 
130
  currentUserCache = currentUser;
 
179
  let currentPaginator = null;
180
  let disposed = false;
181
  let firstPageReady = false;
182
+ let forceRefreshPending = initialForce === true;
183
  const cardNavigation = createCardNavigationScope(window, () => !disposed, {
184
  captureSession: captureRequestSession,
185
  storageKeys: [CACHE.LEGACY_KEYS.TOKEN, CACHE.LEGACY_KEYS.USER]
 
442
  }
443
  };
444
 
445
+ const loadPrompts = async (page = 1, append = false, forceRequest = false) => {
446
  if (disposed) return;
447
+ const forceRefresh = !append && page === 1 && (forceRefreshPending || forceRequest === true);
448
+ if (forceRefresh) forceRefreshPending = false;
449
  if (!append && page === 1) firstPageReady = false;
450
  const viewGeneration = !append && page === 1 ? ++listViewGeneration : listViewGeneration;
451
  const requestedType = currentType;
 
460
  allPromptsData = proxyImages(cachedData);
461
  renderPromptsFromCache(allPromptsData, true);
462
  // 后台静默更新
463
+ silentRefresh(forceRefresh).finally(() => {
464
  if (disposed || viewGeneration !== listViewGeneration) return;
465
  if (searchKeyword && !allPromptsData.some(prompt => _matchesSearch(prompt, searchKeyword))) {
466
  currentPaginator?.load();
 
479
  requestGeneration = ++networkRequestGeneration;
480
  isLoadingFromNetwork = true;
481
  const readResponse = captureListRead(cacheKey);
482
+ const res = await api.getPrompts(requestedType, requestedCategory, page, PAGE_SIZE, requestedSort, ...(forceRefresh ? [{ noCache: true }] : []));
483
  if (viewGeneration !== listViewGeneration || requestGeneration !== networkRequestGeneration) {
484
  if (requestGeneration === networkRequestGeneration) {
485
  isLoadingFromNetwork = false;
 
570
  renderPromptsFromCache(allPromptsData);
571
  showToast(t('prompt.network_cache'), "warning");
572
  } else {
573
+ renderListLoadError(promptsGrid, err?.name === 'ListCacheChangedError' ? t('feedback.list_changed_retry') : t('prompt.load_failed'), () => {
574
+ if (disposed || isLoadingFromNetwork || requestedType !== currentType || requestedCategory !== currentCategory || requestedSort !== currentSort) return;
575
+ return loadPrompts(1, false, forceRefresh);
576
+ }, t, err);
577
  }
578
  }
579
  }
 
630
  };
631
 
632
  // 后台静默更新
633
+ const silentRefresh = async (notifyFailure = false) => {
634
  if (disposed || isLoadingFromNetwork) return;
635
  const viewGeneration = listViewGeneration;
636
  const requestedType = currentType;
 
682
  }
683
  isLoadingFromNetwork = false;
684
  console.warn("后台更新提示词失败(保留当前内容)");
685
+ if (notifyFailure === true) showToast(t(err?.name === 'ListCacheChangedError'
686
+ ? 'feedback.list_changed_retry' : 'feedback.refresh_failed_cached'), 'warning');
687
  }
688
  if (searchKeyword && !allPromptsData.some(prompt => _matchesSearch(prompt, searchKeyword))) {
689
  currentPaginator?.load();
前端页面/prompt/提示词详情组件.js CHANGED
@@ -469,18 +469,25 @@ function copyToClipboard(text, btnEl, current) {
469
  }
470
 
471
  function fallbackCopy(text, onSuccess, onFail) {
 
 
 
472
  try {
473
- const ta = document.createElement("textarea");
474
  ta.value = text;
475
  ta.style.cssText = "position: fixed; top: -9999px; opacity: 0;";
476
  document.body.appendChild(ta);
477
  ta.select();
478
- const ok = document.execCommand("copy");
479
- ta.remove();
480
- ok ? onSuccess() : onFail();
481
  } catch (e) {
482
- onFail();
 
 
 
 
 
483
  }
 
484
  }
485
 
486
  /**
 
469
  }
470
 
471
  function fallbackCopy(text, onSuccess, onFail) {
472
+ const previousFocus = document.activeElement;
473
+ let ta;
474
+ let copied = false;
475
  try {
476
+ ta = document.createElement("textarea");
477
  ta.value = text;
478
  ta.style.cssText = "position: fixed; top: -9999px; opacity: 0;";
479
  document.body.appendChild(ta);
480
  ta.select();
481
+ copied = document.execCommand("copy");
 
 
482
  } catch (e) {
483
+ } finally {
484
+ const restoreFocus = ta && document.activeElement === ta;
485
+ ta?.remove();
486
+ if (restoreFocus && previousFocus?.isConnected && previousFocus.getClientRects().length && document.hasFocus()) {
487
+ previousFocus.focus({ preventScroll: true });
488
+ }
489
  }
490
+ copied ? onSuccess() : onFail();
491
  }
492
 
493
  /**
前端页面/task/任务榜组件.js CHANGED
@@ -89,7 +89,7 @@ function _renderNoTasksView() {
89
  /**
90
  * 📝 创建任务榜视图
91
  */
92
- export function createTasksView(currentUser, keyword = "", { sort: initialSort = "latest", status: initialStatus = "" } = {}) {
93
  if (activeViewCleanup) activeViewCleanup();
94
  currentUserCache = currentUser;
95
  const searchKeyword = keyword.toLowerCase();
@@ -128,6 +128,7 @@ export function createTasksView(currentUser, keyword = "", { sort: initialSort =
128
  let networkRequestGeneration = 0;
129
  let disposed = false;
130
  let firstPageReady = false;
 
131
  const cardNavigation = createCardNavigationScope(window, () => !disposed, {
132
  captureSession: captureRequestSession,
133
  storageKeys: [CACHE.LEGACY_KEYS.TOKEN, CACHE.LEGACY_KEYS.USER]
@@ -234,8 +235,10 @@ export function createTasksView(currentUser, keyword = "", { sort: initialSort =
234
  };
235
 
236
  // 加载任务列表(支持缓存优先)
237
- const loadTasks = async (page = 1, append = false) => {
238
  if (disposed) return;
 
 
239
  if (!append && page === 1) firstPageReady = false;
240
  const viewGeneration = !append && page === 1 ? ++listViewGeneration : listViewGeneration;
241
  const requestedStatus = currentStatus;
@@ -250,7 +253,7 @@ export function createTasksView(currentUser, keyword = "", { sort: initialSort =
250
  allTasksData = proxyImages(cachedData);
251
  renderTasksFromCache(allTasksData);
252
  // 后台静默更新
253
- silentRefresh().finally(continueSearchPagination);
254
  return;
255
  }
256
  }
@@ -265,7 +268,7 @@ export function createTasksView(currentUser, keyword = "", { sort: initialSort =
265
  isLoadingFromNetwork = true;
266
 
267
  const readResponse = captureListRead(cacheKey);
268
- const res = await api.getTasks(page, PAGE_SIZE, requestedStatus || null, requestedSort);
269
  if (viewGeneration !== listViewGeneration || requestGeneration !== networkRequestGeneration) {
270
  if (requestGeneration === networkRequestGeneration) {
271
  isLoadingFromNetwork = false;
@@ -348,7 +351,10 @@ export function createTasksView(currentUser, keyword = "", { sort: initialSort =
348
  showToast(t('task.network_cache'), "warning");
349
  continueSearchPagination();
350
  } else {
351
- renderListLoadError(tasksList, err?.name === 'ListCacheChangedError' ? t('feedback.list_changed_retry') : t('task.load_failed'), () => loadTasks(1, false), t, err);
 
 
 
352
  }
353
  }
354
  }
@@ -400,7 +406,7 @@ export function createTasksView(currentUser, keyword = "", { sort: initialSort =
400
  };
401
 
402
  // 后台静默更新
403
- const silentRefresh = async () => {
404
  if (disposed || isLoadingFromNetwork) return;
405
  const viewGeneration = listViewGeneration;
406
  const requestedStatus = currentStatus;
@@ -451,6 +457,8 @@ export function createTasksView(currentUser, keyword = "", { sort: initialSort =
451
  }
452
  isLoadingFromNetwork = false;
453
  console.warn("后台更新任务失败(保留当前内容)");
 
 
454
  }
455
  continueSearchPagination();
456
  };
 
89
  /**
90
  * 📝 创建任务榜视图
91
  */
92
+ export function createTasksView(currentUser, keyword = "", { sort: initialSort = "latest", status: initialStatus = "", force: initialForce = false } = {}) {
93
  if (activeViewCleanup) activeViewCleanup();
94
  currentUserCache = currentUser;
95
  const searchKeyword = keyword.toLowerCase();
 
128
  let networkRequestGeneration = 0;
129
  let disposed = false;
130
  let firstPageReady = false;
131
+ let forceRefreshPending = initialForce === true;
132
  const cardNavigation = createCardNavigationScope(window, () => !disposed, {
133
  captureSession: captureRequestSession,
134
  storageKeys: [CACHE.LEGACY_KEYS.TOKEN, CACHE.LEGACY_KEYS.USER]
 
235
  };
236
 
237
  // 加载任务列表(支持缓存优先)
238
+ const loadTasks = async (page = 1, append = false, forceRequest = false) => {
239
  if (disposed) return;
240
+ const forceRefresh = !append && page === 1 && (forceRefreshPending || forceRequest === true);
241
+ if (forceRefresh) forceRefreshPending = false;
242
  if (!append && page === 1) firstPageReady = false;
243
  const viewGeneration = !append && page === 1 ? ++listViewGeneration : listViewGeneration;
244
  const requestedStatus = currentStatus;
 
253
  allTasksData = proxyImages(cachedData);
254
  renderTasksFromCache(allTasksData);
255
  // 后台静默更新
256
+ silentRefresh(forceRefresh).finally(continueSearchPagination);
257
  return;
258
  }
259
  }
 
268
  isLoadingFromNetwork = true;
269
 
270
  const readResponse = captureListRead(cacheKey);
271
+ const res = await api.getTasks(page, PAGE_SIZE, requestedStatus || null, requestedSort, ...(forceRefresh ? [{ noCache: true }] : []));
272
  if (viewGeneration !== listViewGeneration || requestGeneration !== networkRequestGeneration) {
273
  if (requestGeneration === networkRequestGeneration) {
274
  isLoadingFromNetwork = false;
 
351
  showToast(t('task.network_cache'), "warning");
352
  continueSearchPagination();
353
  } else {
354
+ renderListLoadError(tasksList, err?.name === 'ListCacheChangedError' ? t('feedback.list_changed_retry') : t('task.load_failed'), () => {
355
+ if (disposed || isLoadingFromNetwork || requestedStatus !== currentStatus || requestedSort !== currentSort) return;
356
+ return loadTasks(1, false, forceRefresh);
357
+ }, t, err);
358
  }
359
  }
360
  }
 
406
  };
407
 
408
  // 后台静默更新
409
+ const silentRefresh = async (notifyFailure = false) => {
410
  if (disposed || isLoadingFromNetwork) return;
411
  const viewGeneration = listViewGeneration;
412
  const requestedStatus = currentStatus;
 
457
  }
458
  isLoadingFromNetwork = false;
459
  console.warn("后台更新任务失败(保留当前内容)");
460
+ if (notifyFailure === true) showToast(t(err?.name === 'ListCacheChangedError'
461
+ ? 'feedback.list_changed_retry' : 'feedback.refresh_failed_cached'), 'warning');
462
  }
463
  continueSearchPagination();
464
  };