Organize Other Stuff into Media / Social / Whimsy sections

Add a 'section' field to ExtraKindDef and group content types in both
FeedSettingsForm and ContentSettings with labeled section headers.
This commit is contained in:
Chad Curtis
2026-02-21 00:19:08 -06:00
parent 151ea6ab75
commit 5c89dc8ea0
3 changed files with 56 additions and 9 deletions
+17 -4
View File
@@ -164,7 +164,7 @@ import { ChestIcon } from '@/components/icons/ChestIcon';
import { useFeedSettings } from '@/hooks/useFeedSettings';
import { useEncryptedSettings } from '@/hooks/useEncryptedSettings';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { EXTRA_KINDS } from '@/lib/extraKinds';
import { EXTRA_KINDS, SECTION_ORDER, SECTION_LABELS } from '@/lib/extraKinds';
import type { ExtraKindDef, SubKindDef } from '@/lib/extraKinds';
import { cn } from '@/lib/utils';
@@ -289,9 +289,22 @@ function ContentTypeRow({ def }: { def: ExtraKindDef }) {
function FeedSettingsFormInternals() {
return (
<>
{EXTRA_KINDS.map((def) => (
<ContentTypeRow key={def.showKey} def={def} />
))}
{SECTION_ORDER.map((section) => {
const sectionKinds = EXTRA_KINDS.filter((def) => def.section === section);
if (sectionKinds.length === 0) return null;
return (
<div key={section}>
<div className="px-3 pt-4 pb-2">
<span className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">
{SECTION_LABELS[section]}
</span>
</div>
{sectionKinds.map((def) => (
<ContentTypeRow key={def.showKey} def={def} />
))}
</div>
);
})}
</>
);
}
+18 -5
View File
@@ -4,7 +4,7 @@ import { Switch } from '@/components/ui/switch';
import { useFeedSettings } from '@/hooks/useFeedSettings';
import { useEncryptedSettings } from '@/hooks/useEncryptedSettings';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { EXTRA_KINDS } from '@/lib/extraKinds';
import { EXTRA_KINDS, SECTION_ORDER, SECTION_LABELS } from '@/lib/extraKinds';
import type { ExtraKindDef, SubKindDef } from '@/lib/extraKinds';
import { cn } from '@/lib/utils';
@@ -157,10 +157,23 @@ export function FeedSettingsForm() {
<span className="text-[11px] font-medium text-muted-foreground w-[52px] text-center">Feed</span>
</div>
{/* Content type rows */}
{EXTRA_KINDS.map((def) => (
<ContentTypeRow key={def.showKey} def={def} />
))}
{/* Content type rows grouped by section */}
{SECTION_ORDER.map((section) => {
const sectionKinds = EXTRA_KINDS.filter((def) => def.section === section);
if (sectionKinds.length === 0) return null;
return (
<div key={section}>
<div className="px-3 pt-4 pb-2">
<span className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">
{SECTION_LABELS[section]}
</span>
</div>
{sectionKinds.map((def) => (
<ContentTypeRow key={def.showKey} def={def} />
))}
</div>
);
})}
</div>
);
}
+21
View File
@@ -15,6 +15,19 @@ export interface SubKindDef {
addressable: boolean;
}
/** Section labels for grouping extra kinds in settings UI. */
export type ExtraKindSection = 'media' | 'social' | 'whimsy';
/** Display labels for each section. */
export const SECTION_LABELS: Record<ExtraKindSection, string> = {
media: 'Media',
social: 'Social',
whimsy: 'Whimsy',
};
/** Ordered list of sections for consistent rendering. */
export const SECTION_ORDER: ExtraKindSection[] = ['media', 'social', 'whimsy'];
/** Metadata for an extra (non-kind-1) content type. */
export interface ExtraKindDef {
kind: number;
@@ -32,6 +45,8 @@ export interface ExtraKindDef {
addressable: boolean;
/** Optional sub-kinds that break this entry into granular options. */
subKinds?: SubKindDef[];
/** Section grouping for the settings UI. */
section: ExtraKindSection;
}
/** All supported extra content kinds. */
@@ -44,6 +59,7 @@ export const EXTRA_KINDS: ExtraKindDef[] = [
description: 'Short-form videos',
route: 'vines',
addressable: true,
section: 'media',
},
{
kind: 1068,
@@ -53,6 +69,7 @@ export const EXTRA_KINDS: ExtraKindDef[] = [
description: 'Community polls and votes',
route: 'polls',
addressable: false,
section: 'social',
},
{
kind: 37516,
@@ -61,6 +78,7 @@ export const EXTRA_KINDS: ExtraKindDef[] = [
description: 'Geocaches & found logs',
route: 'treasures',
addressable: true,
section: 'whimsy',
subKinds: [
{
kind: 37516,
@@ -88,6 +106,7 @@ export const EXTRA_KINDS: ExtraKindDef[] = [
description: 'Color moment palettes',
route: 'colors',
addressable: false,
section: 'whimsy',
},
{
kind: 39089,
@@ -97,6 +116,7 @@ export const EXTRA_KINDS: ExtraKindDef[] = [
description: 'Curated follow recommendations',
route: 'packs',
addressable: true,
section: 'social',
},
{
kind: 30311,
@@ -106,6 +126,7 @@ export const EXTRA_KINDS: ExtraKindDef[] = [
description: 'Live streaming events',
route: 'streams',
addressable: true,
section: 'media',
},
];