feat(themes): polish workshop moderation and theme controls
Add the in-app tag editor, installed-theme reporting, readable moderation and report dialogs, and notification layering fixes. Persist server-assigned workshop IDs for stable republishes, hide self-reporting, fix report-button contrast, and disable macOS autocorrect and spell checking across launcher windows.
This commit is contained in:
1 parent
1f3fa026ce
commit
ebc5fbf9c4
17 files changed
+964
-156
No files matched your search
@@ -10,6 +10,8 @@ import * as fs from '@tauri-apps/plugin-fs';
|
||||
|
||||
export type Theme = {
|
||||
folder_name: string;
|
||||
/** Server-assigned workshop ID, when this theme has been published. */
|
||||
workshopId?: string;
|
||||
name: string;
|
||||
version: string;
|
||||
apiVersion: string;
|
||||
@@ -40,6 +42,7 @@ export type ThemeInfo = {
|
||||
name: string;
|
||||
version?: string;
|
||||
apiVersion?: string;
|
||||
workshopId?: string;
|
||||
author?: string;
|
||||
description?: string;
|
||||
nsfw?: boolean;
|
||||
@@ -165,6 +168,7 @@ const themeFromFolder = async (
|
||||
|
||||
return {
|
||||
folder_name: folderName,
|
||||
workshopId: typeof parsed.workshopId === 'string' ? parsed.workshopId : undefined,
|
||||
name: parsed.name,
|
||||
version: parsed.version ?? '1.0.0',
|
||||
apiVersion,
|
||||
@@ -559,6 +563,43 @@ export const saveThemeProject = async (
|
||||
return themeFolder;
|
||||
};
|
||||
|
||||
const updateInstalledThemeManifest = async (
|
||||
folderName: string,
|
||||
patch: Record<string, unknown>
|
||||
) => {
|
||||
const themeFolder = await path.join(await themesDirectory(), folderName);
|
||||
const configPath = await path.join(themeFolder, 'theme.json');
|
||||
if (!(await fs.exists(configPath))) {
|
||||
throw new Error('The installed theme.json file was not found.');
|
||||
}
|
||||
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(await fs.readTextFile(configPath));
|
||||
} catch {
|
||||
throw new Error('The installed theme.json file is not valid JSON.');
|
||||
}
|
||||
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
||||
throw new Error('The installed theme.json file is not a valid theme manifest.');
|
||||
}
|
||||
|
||||
const updated = { ...(parsed as Record<string, unknown>), ...patch };
|
||||
await fs.writeFile(
|
||||
configPath,
|
||||
new TextEncoder().encode(`${JSON.stringify(updated, null, 2)}\n`)
|
||||
);
|
||||
};
|
||||
|
||||
/** Write workshop tags into an installed theme's manifest without dropping other fields. */
|
||||
export const updateInstalledThemeTags = async (folderName: string, tags: string[]) =>
|
||||
updateInstalledThemeManifest(folderName, { tags });
|
||||
|
||||
/** Remember the server-assigned workshop ID so later publishes update the same theme. */
|
||||
export const updateInstalledThemeWorkshopId = async (
|
||||
folderName: string,
|
||||
workshopId: string
|
||||
) => updateInstalledThemeManifest(folderName, { workshopId });
|
||||
|
||||
export const exportThemeFolder = async (folderName: string, destinationPath: string) => {
|
||||
const themeFolder = await path.join(await themesDirectory(), folderName);
|
||||
await invoke('export_theme', { themeFolder, destinationPath });
|
||||
|
||||
Reference in new issue
Block a user