From b9546c669a5aa2d7e3e5113b576a8ea5bee83243 Mon Sep 17 00:00:00 2001 From: Vaica <94612053+zqlit@users.noreply.github.com> Date: Sat, 31 Jan 2026 22:06:19 +0800 Subject: [PATCH] =?UTF-8?q?fixed=20=20=E5=BC=B9=E7=AA=97=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/Ying/assets/js/modules/artalk.js | 87 ++++++++++++++++++- .../Ying/assets/js/modules/floating-tools.js | 4 + themes/Ying/assets/js/modules/utils.js | 32 +++++-- 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/themes/Ying/assets/js/modules/artalk.js b/themes/Ying/assets/js/modules/artalk.js index 9d4959a9..736bafab 100644 --- a/themes/Ying/assets/js/modules/artalk.js +++ b/themes/Ying/assets/js/modules/artalk.js @@ -15,12 +15,93 @@ window.initArtalk = function() { } try { - var artalk = Artalk.init(window.artalkConfig); - window.artalk = artalk; // Expose to window for other scripts + // Logic for caching Artalk configuration to speed up rendering + // 1. Manual Refresh (F5): Request from server and save to localStorage + // 2. PJAX: Load from localStorage if available + + // Initialize initialization count to track PJAX usage + if (typeof window.artalkInitCount === 'undefined') { + window.artalkInitCount = 0; + } + window.artalkInitCount++; + + var config = Object.assign({}, window.artalkConfig); // Clone config + var server = config.server.replace(/\/$/, ''); + var confKey = 'artalk_conf_' + btoa(server); + var cachedConf = null; + + // Try to read cache + try { + var raw = localStorage.getItem(confKey); + if (raw) cachedConf = JSON.parse(raw); + } catch(e) { + console.warn('Failed to parse Artalk cache:', e); + } + + // Decision: Use Cache or Fetch? + // Use cache only if: + // 1. Not the first load (PJAX) + // 2. Cache exists + if (window.artalkInitCount > 1 && cachedConf) { + // Merge cache into config + // CAUTION: cachedConf contains page-specific data (like pageKey) from the previous page. + // We must ensure current window.artalkConfig overwrites it. + try { + // Defensive copy to avoid mutating cached object + var mergedConfig = Object.assign({}, config); + Object.assign(mergedConfig, cachedConf); + Object.assign(mergedConfig, window.artalkConfig); // Re-apply current page config + mergedConfig.useBackendConf = false; + + // Attempt to init with cache + window.artalk = Artalk.init(mergedConfig); + } catch (initErr) { + console.warn('Artalk init with cache failed, falling back to default:', initErr); + localStorage.removeItem(confKey); // Clear bad cache + window.artalk = Artalk.init(config); // Fallback to normal init + } + } else { + // First load or no cache: Allow Artalk to fetch (useBackendConf defaults to true) + window.artalk = Artalk.init(config); + } + + var artalk = window.artalk; // Local reference + + // Aggressive Config Saving Strategy + var saveConf = function() { + try { + // Attempt to find the full configuration object + // artalk.conf is the standard property in v2+ + // artalk.ctx.conf is for internal context access + var remoteConf = artalk.conf || (artalk.ctx && artalk.ctx.conf); + + if (remoteConf) { + // We only really want to cache the fields that come from the server, + // but saving the whole object is easier. We just have to be careful when merging. + localStorage.setItem(confKey, JSON.stringify(remoteConf)); + // console.log('Artalk: Config cached to', confKey); + } + } catch(e) { + console.error('Artalk saveConf error:', e); + } + }; + + // Hook into multiple events to ensure we capture the config after it's loaded + // 'conf-loaded' is the ideal event if supported + artalk.on('conf-loaded', saveConf); + + // 'mounted' is when the widget is ready + artalk.on('mounted', saveConf); + + // 'list-loaded' means comments (and likely config) are fetched + artalk.on('list-loaded', saveConf); + + // Fallback: Poll check after a few seconds (for slow networks) + setTimeout(saveConf, 2000); + setTimeout(saveConf, 5000); // Handle list-loaded event for lazy loading avatars and animations artalk.on('list-loaded', function() { - // Restore AI Comment if configured if (window.artalkConfig.aiComment) { var ai = window.artalkConfig.aiComment; var listBody = document.querySelector('.atk-list .atk-list-body'); diff --git a/themes/Ying/assets/js/modules/floating-tools.js b/themes/Ying/assets/js/modules/floating-tools.js index 5aef7fd3..030b176f 100644 --- a/themes/Ying/assets/js/modules/floating-tools.js +++ b/themes/Ying/assets/js/modules/floating-tools.js @@ -119,6 +119,10 @@ window.initFloatingTools = function() { if (window.artalk && typeof window.artalk.setDarkMode === 'function') { window.artalk.setDarkMode(newTheme === 'dark'); } + + if (window.showToast) { + window.showToast('已切换至 ' + (newTheme === 'dark' ? '深色' : '浅色') + '模式', 'success'); + } }); } diff --git a/themes/Ying/assets/js/modules/utils.js b/themes/Ying/assets/js/modules/utils.js index 153a4d1b..dd37218f 100644 --- a/themes/Ying/assets/js/modules/utils.js +++ b/themes/Ying/assets/js/modules/utils.js @@ -8,9 +8,15 @@ window.isMobile = function() { }; // Toast Message Helper -window.showToast = function(text) { +window.showToast = function(text, type) { + type = type || 'info'; // default to info if (typeof Qmsg !== 'undefined') { - Qmsg.info(text); + // Map common types to Qmsg methods + if (typeof Qmsg[type] === 'function') { + Qmsg[type](text); + } else { + Qmsg.info(text); + } } else { // Fallback custom toast let toast = document.querySelector('.custom-toast'); @@ -31,16 +37,26 @@ window.showToast = function(text) { opacity: 0; transition: opacity 0.3s; pointer-events: none; + display: flex; + align-items: center; + gap: 8px; `; document.body.appendChild(toast); } - toast.innerText = text; + + // Simple icon mapping for fallback + let icon = ''; + if (type === 'success') icon = '✅ '; + else if (type === 'error') icon = '❌ '; + else if (type === 'warning') icon = '⚠️ '; + + toast.innerText = icon + text; toast.style.opacity = '1'; if (window.toastTimeout) clearTimeout(window.toastTimeout); window.toastTimeout = setTimeout(() => { toast.style.opacity = '0'; - }, 2000); + }, 2500); } }; @@ -64,7 +80,7 @@ window.initThemeToggle = function() { html.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); - window.showToast('已切换至 ' + (newTheme === 'dark' ? '深色' : '浅色') + '模式'); + window.showToast('已切换至 ' + (newTheme === 'dark' ? '深色' : '浅色') + '模式', 'success'); // Trigger generic resize event to force charts/etc to redraw if needed window.dispatchEvent(new Event('resize')); @@ -149,12 +165,12 @@ window.initCodeCopy = function() { if (navigator.clipboard) { navigator.clipboard.writeText(code).then(() => { - window.showToast('代码已复制 / Copied!'); + window.showToast('代码已复制 / Copied!', 'success'); btn.innerHTML = ''; setTimeout(() => btn.innerHTML = '', 2000); }).catch(err => { console.error('Copy failed', err); - window.showToast('复制失败 / Failed'); + window.showToast('复制失败 / Failed', 'error'); }); } else { // Fallback @@ -164,7 +180,7 @@ window.initCodeCopy = function() { textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); - window.showToast('代码已复制 / Copied!'); + window.showToast('代码已复制 / Copied!', 'success'); } });