feat(settings): add downloaded page and filter settings

This commit is contained in:
Darkraise
2026-08-11 18:15:09 +07:00
parent 170956197a
commit 3cef0feb7c
4 changed files with 88 additions and 0 deletions
@@ -0,0 +1,9 @@
-- ===================================
-- Migration 004: Downloaded games page and filter settings
-- ===================================
INSERT OR IGNORE INTO system_settings (key, value, data_type, category, description, is_public, default_value, validation_schema)
VALUES
('features.enable_downloaded_page', '1', 'boolean', 'features', 'Show the Downloaded games page', 1, '1', '{"type":"boolean"}'),
('features.enable_downloaded_page_for_guests', '0', 'boolean', 'features', 'Allow guests to see the Downloaded games page', 1, '0', '{"type":"boolean"}'),
('features.enable_downloaded_filter_default', '0', 'boolean', 'features', 'Turn the downloaded filter on by default when browsing', 1, '0', '{"type":"boolean"}');
@@ -181,6 +181,77 @@ export function FeaturesSettingsTab({ tabContentVariants }: FeaturesSettingsTabP
disabled={updateSystemSettings.isPending}
/>
</div>
{/* Downloaded page */}
<div className="flex items-center justify-between">
<div className="space-y-0.5">
<Label htmlFor="enable-downloaded-page" className="text-base">
Enable Downloaded Page
</Label>
<p className="text-sm text-muted-foreground">
Show a page listing only games whose files are downloaded.
</p>
</div>
<Switch
id="enable-downloaded-page"
checked={featureSettings.enableDownloadedPage !== false}
onCheckedChange={(checked: boolean) => {
updateSystemSettings.mutate({
category: 'features',
settings: { enableDownloadedPage: checked },
});
}}
disabled={updateSystemSettings.isPending}
/>
</div>
{featureSettings.enableDownloadedPage !== false ? (
<div className="flex items-center justify-between pl-6 border-l-2 border-border">
<div className="space-y-0.5">
<Label htmlFor="enable-downloaded-page-guests" className="text-base">
Show Downloaded Page To Guests
</Label>
<p className="text-sm text-muted-foreground">
Let signed-out guests open the Downloaded page.
</p>
</div>
<Switch
id="enable-downloaded-page-guests"
checked={featureSettings.enableDownloadedPageForGuests === true}
onCheckedChange={(checked: boolean) => {
updateSystemSettings.mutate({
category: 'features',
settings: { enableDownloadedPageForGuests: checked },
});
}}
disabled={updateSystemSettings.isPending}
/>
</div>
) : null}
{/* Downloaded filter default */}
<div className="flex items-center justify-between">
<div className="space-y-0.5">
<Label htmlFor="enable-downloaded-filter-default" className="text-base">
Filter To Downloaded By Default
</Label>
<p className="text-sm text-muted-foreground">
Browse pages start with the downloaded filter on. This one also applies to admins;
anyone can still switch it off per page.
</p>
</div>
<Switch
id="enable-downloaded-filter-default"
checked={featureSettings.enableDownloadedFilterDefault === true}
onCheckedChange={(checked: boolean) => {
updateSystemSettings.mutate({
category: 'features',
settings: { enableDownloadedFilterDefault: checked },
});
}}
disabled={updateSystemSettings.isPending}
/>
</div>
</div>
</div>
) : null}
+5
View File
@@ -21,6 +21,11 @@ export function useFeatureFlags() {
// Cosmetic chrome rather than a capability: no admin bypass, otherwise an
// admin could never hide the button in their own session.
enableLuckyButton: (features.enableLuckyButton ?? true) !== false,
enableDownloadedPage: isAdmin || (features.enableDownloadedPage ?? true),
// Default-off flags are read strictly: the `?? true` fallback used above would
// invert them while public settings are still loading or if the key is missing.
enableDownloadedPageForGuests: features.enableDownloadedPageForGuests === true,
enableDownloadedFilterDefault: features.enableDownloadedFilterDefault === true,
isFeatureEnabled: (featureName: string) => {
return isAdmin || ((features as Record<string, unknown>)[featureName] ?? true) !== false;
},
+3
View File
@@ -18,6 +18,9 @@ export interface FeatureSettings {
enableStatistics: boolean;
enableRatings: boolean;
enableLuckyButton: boolean;
enableDownloadedPage: boolean;
enableDownloadedPageForGuests: boolean;
enableDownloadedFilterDefault: boolean;
}
export interface GameSettings {