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
@@ -2,11 +2,16 @@
|
||||
import DefaultThemePreview from '$assets/default_preview.png';
|
||||
import Logo from '$assets/logo.png';
|
||||
import { ezppfarm } from '$lib/api/ezpp';
|
||||
import {
|
||||
fetchCommunityThemeDetails,
|
||||
type CommunityTheme,
|
||||
} from '$lib/communityThemes';
|
||||
import DiagnosticsPanel from '$lib/components/diagnostics/DiagnosticsPanel.svelte';
|
||||
import LogViewer from '$lib/components/logs/LogViewer.svelte';
|
||||
import NotificationHub from '$lib/components/notifications/NotificationHub.svelte';
|
||||
import DiscordPresenceEditor from '$lib/components/presence/DiscordPresenceEditor.svelte';
|
||||
import ThemeIcon from '$lib/components/theme/ThemeIcon.svelte';
|
||||
import ThemeReportDialog from '$lib/components/theme/ThemeReportDialog.svelte';
|
||||
import ThemeV2Elements from '$lib/components/theme/ThemeV2Elements.svelte';
|
||||
import * as AlertDialog from '$lib/components/ui/alert-dialog';
|
||||
import * as Avatar from '$lib/components/ui/avatar';
|
||||
@@ -158,6 +163,7 @@
|
||||
ChevronRight,
|
||||
Clock,
|
||||
ExternalLink,
|
||||
Flag,
|
||||
Globe,
|
||||
Medal,
|
||||
TrendingDown,
|
||||
@@ -302,6 +308,9 @@
|
||||
};
|
||||
let restoreCandidate = $state<{ theme: Theme; backup: ThemeBackup } | undefined>(undefined);
|
||||
let restoringTheme = $state(false);
|
||||
let installedReportOpen = $state(false);
|
||||
let installedReportTarget = $state<CommunityTheme | null>(null);
|
||||
let installedReportLoading = $state(false);
|
||||
let logViewerOpen = $state(false);
|
||||
let presenceEditorOpen = $state(false);
|
||||
|
||||
@@ -339,6 +348,12 @@
|
||||
});
|
||||
});
|
||||
|
||||
const isOwnInstalledTheme = (theme: Theme) =>
|
||||
Boolean(
|
||||
$currentUser &&
|
||||
theme.author.trim().toLowerCase() === $currentUser.name.trim().toLowerCase()
|
||||
);
|
||||
|
||||
const themeButtonLabel = (theme: Theme, activeFolder: string | undefined) => {
|
||||
if (activeFolder === theme.folder_name) return 'Theme in use';
|
||||
if (theme.status === 'downloading') {
|
||||
@@ -432,6 +447,38 @@
|
||||
});
|
||||
};
|
||||
|
||||
const openInstalledReport = async (theme: Theme) => {
|
||||
if (!$currentUser) {
|
||||
sileo.error({
|
||||
title: 'Login required',
|
||||
description: 'Log in to EZPPFarm to report a community theme.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (installedReportLoading) return;
|
||||
|
||||
installedReportLoading = true;
|
||||
try {
|
||||
const target = await fetchCommunityThemeDetails(theme.folder_name);
|
||||
if (target.isOwner) {
|
||||
sileo.error({
|
||||
title: 'You cannot report your own theme',
|
||||
description: 'Reporting is available for themes created by other users.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
installedReportTarget = target;
|
||||
installedReportOpen = true;
|
||||
} catch (err) {
|
||||
sileo.error({
|
||||
title: 'Theme not available in the workshop',
|
||||
description: err instanceof Error ? err.message : String(err),
|
||||
});
|
||||
} finally {
|
||||
installedReportLoading = false;
|
||||
}
|
||||
};
|
||||
|
||||
const requestThemeApply = async (theme: Theme) => {
|
||||
if (theme.status !== 'installed') {
|
||||
const downloadThemeResult = await downloadTheme(theme);
|
||||
@@ -1972,6 +2019,8 @@
|
||||
</AlertDialog.Content>
|
||||
</AlertDialog.Root>
|
||||
|
||||
<ThemeReportDialog bind:open={installedReportOpen} theme={installedReportTarget} />
|
||||
|
||||
<div class="grid grid-cols-[0.085fr_1fr] h-screen relative" bind:this={dragAndDrop.ref}>
|
||||
{#if dragAndDrop.isDraggingOverApp && !droppedTheme}
|
||||
<div
|
||||
@@ -3993,6 +4042,19 @@
|
||||
{/if}
|
||||
</Button>
|
||||
{/if}
|
||||
{#if $currentUser && !isOwnInstalledTheme(theme) && theme.status === 'installed' && theme.name !== 'Default' && theme.folder_name !== 'default'}
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
class="size-7 shrink-0 text-muted-foreground hover:bg-amber-500/15 hover:text-amber-300"
|
||||
title="Report theme"
|
||||
aria-label={`Report ${theme.name}`}
|
||||
disabled={installedReportLoading}
|
||||
onclick={() => void openInstalledReport(theme)}
|
||||
>
|
||||
<Flag class="size-3.5" />
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user