Commit 0f64aa0
Changed files (5)
packages
i18n
src
src
components
aside
packages/i18n/src/en/web/index.ts
@@ -4,6 +4,7 @@ const en_web = {
common: {
open: 'Open',
close: 'Close',
+ refresh: 'Refresh',
},
navigation: {
title: 'Navigation',
packages/i18n/src/zh-CN/web/index.ts
@@ -4,6 +4,7 @@ const zh_CN_web = {
common: {
open: '打开',
close: '关闭',
+ refresh: '刷新',
},
navigation: {
title: '导航',
packages/i18n/src/zh-TW/web/index.ts
@@ -4,6 +4,7 @@ const zh_TW_web = {
common: {
open: '打開',
close: '關閉',
+ refresh: '刷新',
},
navigation: {
title: '導航',
packages/i18n/src/i18n-types.ts
@@ -183,6 +183,10 @@ export type NamespaceWebTranslation = {
* Close
*/
close: string
+ /**
+ * Refresh
+ */
+ refresh: string
}
navigation: {
/**
@@ -583,6 +587,10 @@ export type TranslationFunctions = {
* Close
*/
close: () => LocalizedString
+ /**
+ * Refresh
+ */
+ refresh: () => LocalizedString
}
navigation: {
/**
src/components/aside/RecentCommentsCard.vue
@@ -10,8 +10,68 @@ import { onMounted, ref } from 'vue';
const comments = ref<CommentData[]>([]);
const loading = ref(true);
-// 根据评论系统类型加载不同的评论数据
+const cacheKey = 'recent-comments-cache';
+const cacheExpireTime = 30 * 60 * 1000; // 30 min
+
+interface CacheData {
+ data: CommentData[];
+ timestamp: number;
+ provider: string;
+}
+
+function getFromCache(): CommentData[] | null {
+ try {
+ const cached = localStorage.getItem(cacheKey);
+ if (!cached) return null;
+
+ const cacheData: CacheData = JSON.parse(cached);
+
+ // 检查缓存是否过期
+ const isExpired = Date.now() - cacheData.timestamp > cacheExpireTime;
+ if (isExpired) {
+ localStorage.removeItem(cacheKey);
+ return null;
+ }
+
+ // 检查评论系统是否变更
+ if (cacheData.provider !== commentConfig.provider) {
+ localStorage.removeItem(cacheKey);
+ return null;
+ }
+
+ // 恢复 Date 对象(JSON 序列化会将 Date 转为字符串)
+ return cacheData.data.map((comment) => ({
+ ...comment,
+ time: new Date(comment.time),
+ }));
+ } catch (error) {
+ console.warn('Failed to read from cache:', error);
+ localStorage.removeItem(cacheKey);
+ return null;
+ }
+}
+
+function saveToCache(data: CommentData[]): void {
+ try {
+ const cacheData: CacheData = {
+ data,
+ timestamp: Date.now(),
+ provider: commentConfig.provider,
+ };
+ localStorage.setItem(cacheKey, JSON.stringify(cacheData));
+ } catch (error) {
+ console.warn('Failed to save to cache:', error);
+ }
+}
+
async function loadComments() {
+ const cachedComments = getFromCache();
+ if (cachedComments) {
+ comments.value = cachedComments;
+ loading.value = false;
+ return;
+ }
+
const provider = (() => {
switch (commentConfig.provider) {
case 'twikoo':
@@ -28,7 +88,9 @@ async function loadComments() {
})();
try {
- comments.value = await provider.setup();
+ const data = await provider.setup();
+ comments.value = data;
+ saveToCache(data);
} catch (error) {
console.error('Failed to load recent comments:', error);
comments.value = [];
@@ -37,6 +99,12 @@ async function loadComments() {
}
}
+function refreshComments() {
+ localStorage.removeItem(cacheKey);
+ loading.value = true;
+ loadComments();
+}
+
onMounted(() => {
loadComments();
});
@@ -45,8 +113,17 @@ onMounted(() => {
<template>
<div id="recent-comments-card" class="card border-base-300 bg-base-200/25 border">
<div class="card-body px-4 py-2">
- <div class="card-title">
- {{ t.info.recentComments() }}
+ <div class="card-title flex justify-between">
+ <span>{{ t.info.recentComments() }}</span>
+ <button
+ @click="refreshComments"
+ class="btn btn-ghost btn-sm btn-square text-base"
+ :disabled="loading"
+ :title="t.common.refresh()"
+ :aria-label="t.common.refresh()"
+ >
+ ↻
+ </button>
</div>
<ul class="list">
<template v-if="!loading">