...
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-11-17 15:59:35 +08:00
parent 22a0cf46fb
commit 0bf3b718b2
35 changed files with 204 additions and 841 deletions

View File

@@ -0,0 +1,58 @@
import {
TranslationHistoryArraySchema,
TranslationHistorySchema,
} from "@/lib/interfaces";
import z from "zod";
import { shallowEqual } from "../utils";
export const getLocalStorageOperator = <T extends z.ZodTypeAny>(
key: string,
schema: T,
) => {
return {
get: (): z.infer<T> => {
try {
const item = globalThis.localStorage.getItem(key);
if (!item) return [];
const rawData = JSON.parse(item) as z.infer<T>;
const result = schema.safeParse(rawData);
if (result.success) {
return result.data;
} else {
console.error(
"Invalid data structure in localStorage:",
result.error,
);
return [];
}
} catch (e) {
console.error(`Failed to parse ${key} data:`, e);
return [];
}
},
set: (data: z.infer<T>) => {
if (!globalThis.localStorage) return;
globalThis.localStorage.setItem(key, JSON.stringify(data));
return data;
},
};
};
const MAX_HISTORY_LENGTH = 50;
export const tlso = getLocalStorageOperator<
typeof TranslationHistoryArraySchema
>("translator", TranslationHistoryArraySchema);
export const tlsoPush = (item: z.infer<typeof TranslationHistorySchema>) => {
const oldHistory = tlso.get();
if (oldHistory.some((v) => shallowEqual(v, item))) return oldHistory;
const newHistory = [...oldHistory, item].slice(-MAX_HISTORY_LENGTH);
tlso.set(newHistory);
return newHistory;
};

15
src/lib/browser/tts.ts Normal file
View File

@@ -0,0 +1,15 @@
import { ProsodyOptions, EdgeTTS } from "edge-tts-universal/browser";
export async function getTTSAudioUrl(
text: string,
short_name: string,
options: ProsodyOptions | undefined = undefined,
) {
const tts = new EdgeTTS(text, short_name, options);
try {
const result = await tts.synthesize();
return URL.createObjectURL(result.audio);
} catch (e) {
throw e;
}
}