refactor: 统一中文文案并简化组件结构,提升代码可读性
移除 chrome.i18n 后,将各功能页面、布局与工具模块的 UI 文案改为内联中文; 删除冗余注释与过度抽象(如 ToolCard、StatCard),精简 props 与状态管理; 同步优化 JsonTools、StorageCleaner、Timestamp、TestDataGenerator、Dashboard、 Base64Converter、RightClickRestorer、TextStatistics、TopBar、RouterProvider、 ThemeModeProvider 及生成器库与 utils 工具文件。
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { DiffNode, DiffResult, DiffType } from '@/pages/JsonTools/types';
|
||||
import type { DiffNode, DiffResult } from '@/pages/JsonTools/types';
|
||||
|
||||
const ROOT_PATH = '$';
|
||||
const SENTINEL = Symbol('missing');
|
||||
@@ -37,7 +37,6 @@ const diffNode = (
|
||||
path: string,
|
||||
diffPaths: string[],
|
||||
): DiffNode => {
|
||||
// 分支 1:节点增加行为拦截 (叶子节点状态)
|
||||
if (left === SENTINEL && right !== SENTINEL) {
|
||||
diffPaths.push(path);
|
||||
return {
|
||||
@@ -51,7 +50,6 @@ const diffNode = (
|
||||
};
|
||||
}
|
||||
|
||||
// 分支 2:节点删除行为拦截 (叶子节点状态)
|
||||
if (right === SENTINEL && left !== SENTINEL) {
|
||||
diffPaths.push(path);
|
||||
return {
|
||||
@@ -181,5 +179,3 @@ export const diffJson = (left: unknown, right: unknown): DiffResult => {
|
||||
diffCount: diffPaths.length,
|
||||
};
|
||||
};
|
||||
|
||||
export type { DiffNode, DiffResult, DiffType };
|
||||
|
||||
@@ -70,12 +70,12 @@ export async function clearAllIndexedDBs(
|
||||
|
||||
const deleteReq = indexedDB.deleteDatabase(dbName);
|
||||
const timeoutId = setTimeout(() => {
|
||||
console.warn('IndexedDB delete timeout:', dbName);
|
||||
console.warn(`IndexedDB 删除超时: ${dbName}`);
|
||||
settle('timeout');
|
||||
}, timeoutMs);
|
||||
|
||||
deleteReq.onblocked = () => {
|
||||
console.warn('IndexedDB delete blocked:', dbName);
|
||||
console.warn(`IndexedDB 删除被阻塞: ${dbName}`);
|
||||
settle('blocked');
|
||||
};
|
||||
deleteReq.onsuccess = () => settle('deleted');
|
||||
@@ -137,7 +137,7 @@ export async function clearAllIndexedDBs(
|
||||
const transaction = db.transaction(storeNames, 'readwrite');
|
||||
// 必须在 clear 请求完成前注册 oncomplete,否则事务可能已结束导致永久挂起
|
||||
const transactionDone = waitForTransaction(transaction, clearStoreTimeoutMs);
|
||||
void transactionDone.catch(() => undefined);
|
||||
void transactionDone.catch(() => {});
|
||||
const errors = (
|
||||
await Promise.all(
|
||||
storeNames.map((storeName) => clearStore(transaction.objectStore(storeName), storeName)),
|
||||
@@ -145,23 +145,11 @@ export async function clearAllIndexedDBs(
|
||||
).filter((error): error is string => Boolean(error));
|
||||
|
||||
if (errors.length > 0) {
|
||||
try {
|
||||
transaction.abort();
|
||||
} catch {
|
||||
// ignore abort failures on already-finished transactions
|
||||
}
|
||||
transaction.abort();
|
||||
return { success: false, errors };
|
||||
}
|
||||
|
||||
try {
|
||||
await transactionDone;
|
||||
} catch {
|
||||
return {
|
||||
success: false,
|
||||
errors: [`清空 IndexedDB 失败(${dbName}),请刷新后重试`],
|
||||
};
|
||||
}
|
||||
|
||||
await transactionDone;
|
||||
return { success: true, errors: [] };
|
||||
} catch {
|
||||
return {
|
||||
|
||||
@@ -23,7 +23,7 @@ export function isUnsupportedPageUrl(url: string | undefined): boolean {
|
||||
if (!url) return true;
|
||||
const protocol = getUrlProtocol(url);
|
||||
if (!protocol) return true;
|
||||
return (RESTRICTED_PROTOCOLS as readonly string[]).includes(protocol);
|
||||
return RESTRICTED_PROTOCOLS.some((p) => p === protocol);
|
||||
}
|
||||
|
||||
/** 用于 storage cleaner tab 检测(前缀匹配,兼容无 protocol 的场景) */
|
||||
|
||||
@@ -9,8 +9,6 @@ import {
|
||||
} from '@/utils/indexedDbCleaner';
|
||||
import { browser } from 'wxt/browser';
|
||||
|
||||
type CleanScriptResult = IndexedDBCleanResult;
|
||||
|
||||
export async function getCurrentTab() {
|
||||
// For popup pages, we need to get the active tab from the browser window that triggered the popup.
|
||||
// We should ONLY care about the currently active tab in the last focused window.
|
||||
@@ -220,7 +218,7 @@ export async function clearCookies(url: string): Promise<StorageCleanResult> {
|
||||
*/
|
||||
async function runCleanScript<A extends unknown[] = []>(
|
||||
tabId: number,
|
||||
func: (...args: A) => CleanScriptResult | Promise<CleanScriptResult>,
|
||||
func: (...args: A) => IndexedDBCleanResult | Promise<IndexedDBCleanResult>,
|
||||
errorLabel: string,
|
||||
args?: A,
|
||||
): Promise<StorageCleanResult> {
|
||||
|
||||
@@ -15,7 +15,7 @@ export function getSyncSnapshot<T>(
|
||||
}
|
||||
return (parsed as T) ?? defaultValue;
|
||||
} catch (error) {
|
||||
console.error(`[SyncSnapshot] Failed to read snapshot/${key}:`, error);
|
||||
console.error(`读取快照失败 (${key}):`, error);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export const persistThemeModeSnapshot = (mode: ThemeMode): void => {
|
||||
try {
|
||||
localStorage.setItem(THEME_MODE_SNAPSHOT_KEY, JSON.stringify(mode));
|
||||
} catch (error) {
|
||||
console.error('[Theme Snapshot Error] LocalStorage quota exceeded:', error);
|
||||
console.error('保存主题快照失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ export const useStorageState = <K extends keyof StorageSchema>(
|
||||
setValueInternal(next);
|
||||
}, []);
|
||||
|
||||
// Only load from storage once on mount
|
||||
useEffect(() => {
|
||||
if (hasLoadedFromStorage.current) return;
|
||||
|
||||
@@ -64,7 +63,6 @@ export const useStorageState = <K extends keyof StorageSchema>(
|
||||
};
|
||||
}, [defaultValue, key, validator]);
|
||||
|
||||
// Save to storage and localStorage snapshot when value changes (after initial load)
|
||||
useEffect(() => {
|
||||
if (!isInitialized) return;
|
||||
if (!loadSucceededRef.current && !userModifiedRef.current) return;
|
||||
|
||||
Reference in New Issue
Block a user