1
This commit is contained in:
138
src/services/subtitleTemplateCatalog.js
Normal file
138
src/services/subtitleTemplateCatalog.js
Normal file
@@ -0,0 +1,138 @@
|
||||
const STORAGE_KEY = "aiclient_custom_subtitle_templates";
|
||||
|
||||
let systemTemplatesCache = null;
|
||||
|
||||
/**
|
||||
* @typedef {Object} SubtitleTemplateItem
|
||||
* @property {string} id
|
||||
* @property {string} name
|
||||
* @property {string} [description]
|
||||
* @property {Record<string, unknown>} config
|
||||
* @property {boolean} [isSystem]
|
||||
* @property {number} [is_system]
|
||||
* @property {number} [createdAt]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @returns {Promise<SubtitleTemplateItem[]>}
|
||||
*/
|
||||
export async function loadSystemSubtitleTemplates() {
|
||||
if (systemTemplatesCache) return systemTemplatesCache;
|
||||
const res = await fetch("/subtitle-templates/system-templates.json");
|
||||
if (!res.ok) throw new Error("无法加载系统字幕模板");
|
||||
const data = await res.json();
|
||||
systemTemplatesCache = (data.subtitleTemplates || []).map((t) => ({
|
||||
...t,
|
||||
isSystem: true,
|
||||
is_system: 1,
|
||||
}));
|
||||
return systemTemplatesCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {SubtitleTemplateItem[]}
|
||||
*/
|
||||
export function loadCustomSubtitleTemplates() {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) return [];
|
||||
const parsed = JSON.parse(raw);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SubtitleTemplateItem[]} templates
|
||||
*/
|
||||
export function saveCustomSubtitleTemplates(templates) {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(templates));
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<SubtitleTemplateItem[]>}
|
||||
*/
|
||||
export async function loadAllSubtitleTemplates() {
|
||||
const system = await loadSystemSubtitleTemplates();
|
||||
const custom = loadCustomSubtitleTemplates();
|
||||
return [...system, ...custom];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @returns {Promise<SubtitleTemplateItem | null>}
|
||||
*/
|
||||
export async function getSubtitleTemplateById(id) {
|
||||
const all = await loadAllSubtitleTemplates();
|
||||
return all.find((t) => t.id === id) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
*/
|
||||
export function isSystemSubtitleTemplateId(id) {
|
||||
return (
|
||||
String(id || "").startsWith("template_system") ||
|
||||
String(id || "").startsWith("system-")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SubtitleTemplateItem} template
|
||||
*/
|
||||
export function cloneSubtitleTemplate(template) {
|
||||
const now = Date.now();
|
||||
return {
|
||||
...JSON.parse(JSON.stringify(template)),
|
||||
id: `custom_${now}`,
|
||||
name: `${template.name} 副本`,
|
||||
isSystem: false,
|
||||
is_system: 0,
|
||||
createdAt: now,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SubtitleTemplateItem[]} templates
|
||||
*/
|
||||
export function downloadSubtitleTemplatesJson(templates, filename = "subtitle-templates.json") {
|
||||
const blob = new Blob(
|
||||
[
|
||||
JSON.stringify(
|
||||
{
|
||||
version: "1.0.0",
|
||||
exportedAt: new Date().toISOString(),
|
||||
subtitleTemplates: templates,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
],
|
||||
{ type: "application/json" },
|
||||
);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
* @returns {Promise<SubtitleTemplateItem[]>}
|
||||
*/
|
||||
export async function parseImportedSubtitleTemplates(file) {
|
||||
const text = await file.text();
|
||||
const data = JSON.parse(text);
|
||||
const list = data.subtitleTemplates || data.templates || data;
|
||||
if (!Array.isArray(list)) throw new Error("无效的模板文件格式");
|
||||
return list.map((t, i) => ({
|
||||
...t,
|
||||
id: t.id || `imported_${Date.now()}_${i}`,
|
||||
isSystem: false,
|
||||
is_system: 0,
|
||||
createdAt: t.createdAt || Date.now(),
|
||||
}));
|
||||
}
|
||||
Reference in New Issue
Block a user