feat(themes): persist publisher id in theme manifests
Publishing now stamps the signed-in EZPPFarm user ID into theme.json and saves it before packaging, so installed theme cards can resolve avatars by stable user ID. Older manifests keep the author-name fallback.
This commit is contained in:
1 parent
5eea428802
commit
11aefee7ed
4 files changed
+35
-6
No files matched your search
@@ -3343,7 +3343,8 @@
|
|||||||
async function openPublishDialog() {
|
async function openPublishDialog() {
|
||||||
if (exporting || saving || publishing) return;
|
if (exporting || saving || publishing) return;
|
||||||
|
|
||||||
if (!$currentUser) {
|
const user = $currentUser;
|
||||||
|
if (!user) {
|
||||||
sileo.error({
|
sileo.error({
|
||||||
title: 'Authentication Required',
|
title: 'Authentication Required',
|
||||||
description:
|
description:
|
||||||
@@ -3361,8 +3362,12 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty) {
|
const authorIdChanged = definition.authorId !== user.id;
|
||||||
await saveTheme({ notify: false });
|
if (authorIdChanged) definition.authorId = user.id;
|
||||||
|
|
||||||
|
if (dirty || authorIdChanged) {
|
||||||
|
const saved = await saveTheme({ notify: false });
|
||||||
|
if (!saved) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
publishThemeId = definition.workshopId ?? '';
|
publishThemeId = definition.workshopId ?? '';
|
||||||
|
|||||||
@@ -646,6 +646,8 @@ export type ThemeV2Definition = {
|
|||||||
version: string;
|
version: string;
|
||||||
apiVersion: '2.0';
|
apiVersion: '2.0';
|
||||||
author: string;
|
author: string;
|
||||||
|
/** EZPPFarm user ID of the publisher, written when the theme is published. */
|
||||||
|
authorId?: number;
|
||||||
description?: string;
|
description?: string;
|
||||||
/** Workshop discovery tags for this theme. */
|
/** Workshop discovery tags for this theme. */
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
@@ -755,6 +757,11 @@ const normalizeWorkshopId = (raw: unknown): string | undefined => {
|
|||||||
return WORKSHOP_ID_PATTERN.test(id) ? id : undefined;
|
return WORKSHOP_ID_PATTERN.test(id) ? id : undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const normalizeAuthorId = (raw: unknown): number | undefined => {
|
||||||
|
if (typeof raw !== 'number' || !Number.isSafeInteger(raw) || raw <= 0) return undefined;
|
||||||
|
return raw;
|
||||||
|
};
|
||||||
|
|
||||||
const clampInteger = (value: unknown, fallback: number, min: number, max: number) =>
|
const clampInteger = (value: unknown, fallback: number, min: number, max: number) =>
|
||||||
Math.round(clamp(value, fallback, min, max));
|
Math.round(clamp(value, fallback, min, max));
|
||||||
|
|
||||||
@@ -1913,6 +1920,7 @@ export const normalizeThemeV2 = (raw: Partial<ThemeV2Definition>): ThemeV2Defini
|
|||||||
version: text(raw.version, '1.0.0'),
|
version: text(raw.version, '1.0.0'),
|
||||||
apiVersion: '2.0',
|
apiVersion: '2.0',
|
||||||
author: text(raw.author, 'Unknown'),
|
author: text(raw.author, 'Unknown'),
|
||||||
|
authorId: normalizeAuthorId(raw.authorId),
|
||||||
description: text(raw.description),
|
description: text(raw.description),
|
||||||
tags: normalizeThemeTags(raw.tags),
|
tags: normalizeThemeTags(raw.tags),
|
||||||
workshopId: normalizeWorkshopId(raw.workshopId),
|
workshopId: normalizeWorkshopId(raw.workshopId),
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ export type Theme = {
|
|||||||
version: string;
|
version: string;
|
||||||
apiVersion: string;
|
apiVersion: string;
|
||||||
author: string;
|
author: string;
|
||||||
|
/** EZPPFarm user ID stored in the manifest when the theme is published. */
|
||||||
|
authorId?: number;
|
||||||
description: string;
|
description: string;
|
||||||
nsfw: boolean;
|
nsfw: boolean;
|
||||||
scriptUrl: string;
|
scriptUrl: string;
|
||||||
@@ -44,6 +46,7 @@ export type ThemeInfo = {
|
|||||||
apiVersion?: string;
|
apiVersion?: string;
|
||||||
workshopId?: string;
|
workshopId?: string;
|
||||||
author?: string;
|
author?: string;
|
||||||
|
authorId?: number;
|
||||||
description?: string;
|
description?: string;
|
||||||
nsfw?: boolean;
|
nsfw?: boolean;
|
||||||
entry?: string;
|
entry?: string;
|
||||||
@@ -173,6 +176,12 @@ const themeFromFolder = async (
|
|||||||
version: parsed.version ?? '1.0.0',
|
version: parsed.version ?? '1.0.0',
|
||||||
apiVersion,
|
apiVersion,
|
||||||
author: parsed.author ?? 'Unknown',
|
author: parsed.author ?? 'Unknown',
|
||||||
|
authorId:
|
||||||
|
typeof parsed.authorId === 'number' &&
|
||||||
|
Number.isSafeInteger(parsed.authorId) &&
|
||||||
|
parsed.authorId > 0
|
||||||
|
? parsed.authorId
|
||||||
|
: undefined,
|
||||||
description: parsed.description ?? '',
|
description: parsed.description ?? '',
|
||||||
nsfw: parsed.nsfw === true,
|
nsfw: parsed.nsfw === true,
|
||||||
scriptUrl,
|
scriptUrl,
|
||||||
@@ -523,6 +532,7 @@ export const reloadThemes = async () => {
|
|||||||
preview: theme.preview,
|
preview: theme.preview,
|
||||||
version: theme.version,
|
version: theme.version,
|
||||||
author: theme.author,
|
author: theme.author,
|
||||||
|
authorId: theme.authorId,
|
||||||
apiVersion: theme.apiVersion,
|
apiVersion: theme.apiVersion,
|
||||||
description: theme.description,
|
description: theme.description,
|
||||||
nsfw: theme.nsfw,
|
nsfw: theme.nsfw,
|
||||||
|
|||||||
@@ -422,6 +422,14 @@
|
|||||||
return ownedWorkshopThemeNames.includes(theme.name.trim().toLowerCase());
|
return ownedWorkshopThemeNames.includes(theme.name.trim().toLowerCase());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const themeAuthorAvatarUrl = (theme: Theme) => {
|
||||||
|
if (theme.authorId && theme.authorId > 0) {
|
||||||
|
return `https://a.ez-pp.farm/${theme.authorId}`;
|
||||||
|
}
|
||||||
|
const author = theme.author.trim();
|
||||||
|
return author ? `https://a.ez-pp.farm/${encodeURIComponent(author)}` : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
let loadedUserId: number | undefined;
|
let loadedUserId: number | undefined;
|
||||||
return currentUser.subscribe((user) => {
|
return currentUser.subscribe((user) => {
|
||||||
@@ -4073,9 +4081,7 @@
|
|||||||
class="size-5 shrink-0 border border-white/20 bg-theme-800"
|
class="size-5 shrink-0 border border-white/20 bg-theme-800"
|
||||||
>
|
>
|
||||||
<Avatar.Image
|
<Avatar.Image
|
||||||
src={theme.author.trim()
|
src={themeAuthorAvatarUrl(theme)}
|
||||||
? `https://a.ez-pp.farm/${encodeURIComponent(theme.author.trim())}`
|
|
||||||
: undefined}
|
|
||||||
alt={theme.author || 'Unknown author'}
|
alt={theme.author || 'Unknown author'}
|
||||||
class="object-cover"
|
class="object-cover"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in new issue
Block a user