@openrails/contentkit-ui 0.103.1 → 0.104.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -43
- package/dist/client/beacons.d.ts +3 -13
- package/dist/client/beacons.js +4 -45
- package/dist/client/beacons.js.map +1 -1
- package/dist/client/client.d.ts +3 -0
- package/dist/client/client.js +45 -43
- package/dist/client/client.js.map +1 -1
- package/dist/client/content/favorites.d.ts +2 -0
- package/dist/client/content/favorites.js.map +1 -1
- package/dist/client/content/types.d.ts +3 -0
- package/dist/client/content/types.js.map +1 -1
- package/dist/client/discovery.d.ts +28 -3
- package/dist/client/discovery.js +22 -1
- package/dist/client/discovery.js.map +1 -1
- package/dist/client/engagement.d.ts +70 -0
- package/dist/client/engagement.js +191 -0
- package/dist/client/engagement.js.map +1 -0
- package/dist/client/generated/routes.d.ts +35 -9
- package/dist/client/generated/routes.js +59 -2
- package/dist/client/generated/routes.js.map +1 -1
- package/dist/client/generated/wire.d.ts +53 -12
- package/dist/client/generated/wire.js.map +1 -1
- package/dist/client/guest-reading-history.d.ts +40 -0
- package/dist/client/guest-reading-history.js +144 -0
- package/dist/client/guest-reading-history.js.map +1 -0
- package/dist/client/index.d.ts +4 -2
- package/dist/client/stats.d.ts +5 -5
- package/dist/client/stats.js.map +1 -1
- package/dist/client.js +24 -22
- package/dist/components/admin/content-manager.d.ts +1 -1
- package/dist/components/admin/content-manager.js +342 -302
- package/dist/components/admin/content-manager.js.map +1 -1
- package/dist/components/admin/page-review.js +106 -97
- package/dist/components/admin/page-review.js.map +1 -1
- package/dist/components/admin/quick-search.d.ts +14 -0
- package/dist/components/admin/quick-search.js +60 -0
- package/dist/components/admin/quick-search.js.map +1 -0
- package/dist/components/admin/reader-content-editor.d.ts +6 -0
- package/dist/components/admin/reader-content-editor.js +733 -0
- package/dist/components/admin/reader-content-editor.js.map +1 -0
- package/dist/components/admin/reader-manifest.js +120 -105
- package/dist/components/admin/reader-manifest.js.map +1 -1
- package/dist/components/admin/stats-dashboard.d.ts +4 -4
- package/dist/components/admin/stats-dashboard.js +132 -134
- package/dist/components/admin/stats-dashboard.js.map +1 -1
- package/dist/components/content/daily-releases.js +143 -191
- package/dist/components/content/daily-releases.js.map +1 -1
- package/dist/components/content/editor-save.d.ts +32 -0
- package/dist/components/content/editor-save.js +51 -0
- package/dist/components/content/editor-save.js.map +1 -0
- package/dist/components/content/editors.d.ts +17 -2
- package/dist/components/content/editors.js +359 -328
- package/dist/components/content/editors.js.map +1 -1
- package/dist/components/content/favorites.d.ts +6 -0
- package/dist/components/content/favorites.js +33 -0
- package/dist/components/content/favorites.js.map +1 -0
- package/dist/components/content/filter-dialog.js +19 -15
- package/dist/components/content/filter-dialog.js.map +1 -1
- package/dist/components/content/filters.d.ts +2 -0
- package/dist/components/content/filters.js +5 -1
- package/dist/components/content/filters.js.map +1 -1
- package/dist/components/content/grid.d.ts +34 -13
- package/dist/components/content/grid.js +300 -271
- package/dist/components/content/grid.js.map +1 -1
- package/dist/components/content/history.d.ts +6 -0
- package/dist/components/content/history.js +91 -0
- package/dist/components/content/history.js.map +1 -0
- package/dist/components/content/index.d.ts +1 -0
- package/dist/components/content/offer-fields.d.ts +1 -1
- package/dist/components/content/offer-fields.js +86 -64
- package/dist/components/content/offer-fields.js.map +1 -1
- package/dist/components/content/search.d.ts +11 -4
- package/dist/components/content/search.js +22 -11
- package/dist/components/content/search.js.map +1 -1
- package/dist/components/content/summary-tile.d.ts +14 -0
- package/dist/components/content/summary-tile.js +63 -0
- package/dist/components/content/summary-tile.js.map +1 -0
- package/dist/components/groups/memberships.d.ts +11 -1
- package/dist/components/groups/memberships.js +1 -1
- package/dist/components/groups/memberships.js.map +1 -1
- package/dist/components/media-folder-editor.d.ts +4 -0
- package/dist/components/media-folder-editor.js +178 -168
- package/dist/components/media-folder-editor.js.map +1 -1
- package/dist/components/video-mini-player.d.ts +4 -1
- package/dist/components/video-mini-player.js +77 -71
- package/dist/components/video-mini-player.js.map +1 -1
- package/dist/components/video-player.d.ts +4 -1
- package/dist/components/video-player.js +280 -276
- package/dist/components/video-player.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -14
- package/dist/locales/admin/de.js +33 -8
- package/dist/locales/admin/de.js.map +1 -1
- package/dist/locales/admin/en.d.ts +29 -4
- package/dist/locales/admin/en.js +33 -8
- package/dist/locales/admin/en.js.map +1 -1
- package/dist/locales/admin/es.js +33 -8
- package/dist/locales/admin/es.js.map +1 -1
- package/dist/locales/admin/ja.js +33 -8
- package/dist/locales/admin/ja.js.map +1 -1
- package/dist/locales/admin/ko.js +33 -8
- package/dist/locales/admin/ko.js.map +1 -1
- package/dist/locales/admin/zh.js +33 -8
- package/dist/locales/admin/zh.js.map +1 -1
- package/dist/locales/discovery/de.js +0 -1
- package/dist/locales/discovery/de.js.map +1 -1
- package/dist/locales/discovery/en.d.ts +0 -1
- package/dist/locales/discovery/en.js +0 -1
- package/dist/locales/discovery/en.js.map +1 -1
- package/dist/locales/discovery/es.js +0 -1
- package/dist/locales/discovery/es.js.map +1 -1
- package/dist/locales/discovery/ja.js +0 -1
- package/dist/locales/discovery/ja.js.map +1 -1
- package/dist/locales/discovery/ko.js +0 -1
- package/dist/locales/discovery/ko.js.map +1 -1
- package/dist/locales/discovery/zh.js +0 -1
- package/dist/locales/discovery/zh.js.map +1 -1
- package/dist/locales/en.d.ts +29 -5
- package/dist/react/discovery.d.ts +20 -17
- package/dist/react/discovery.js +273 -221
- package/dist/react/discovery.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/page-review.d.ts +1 -1
- package/dist/react/page-review.js +6 -5
- package/dist/react/page-review.js.map +1 -1
- package/dist/react/resources.d.ts +3 -1
- package/dist/react/resources.js +4 -0
- package/dist/react/resources.js.map +1 -1
- package/dist/react/stats.d.ts +2 -2
- package/dist/react/stats.js.map +1 -1
- package/dist/react/use-draft.d.ts +8 -0
- package/dist/react/use-draft.js +35 -0
- package/dist/react/use-draft.js.map +1 -0
- package/dist/react/use-engagement.d.ts +26 -0
- package/dist/react/use-engagement.js +221 -0
- package/dist/react/use-engagement.js.map +1 -0
- package/dist/react/use-resource.d.ts +4 -3
- package/dist/react/use-resource.js +2 -1
- package/dist/react/use-resource.js.map +1 -1
- package/dist/react.js +12 -11
- package/dist/styles.css +1 -1
- package/dist/ui/dialog.d.ts +2 -1
- package/dist/ui/dialog.js +23 -20
- package/dist/ui/dialog.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editors.js","names":[],"sources":["../../../src/components/content/editors.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useEffect, useId, useMemo, useRef, useState, type ReactNode, type SetStateAction } from \"react\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { fromLocalInput, parseAttributes, toLocalInput } from \"../../client/group-fields.js\";\nimport type { Content, ContentModel, Listing, Rule, Segment, Version } from \"../../client/generated/wire.js\";\nimport { useLanguageName, useMessages } from \"../../i18n/context.js\";\nimport { useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useKinds } from \"../../react/groups.js\";\nimport { useMediaRead } from \"../../react/read.js\";\nimport { usePresets } from \"../../react/public.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Input } from \"#ckui/ui/input\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { ReaderManifestEditor } from \"../admin/reader-manifest.js\";\nimport { PageReview } from \"../admin/page-review.js\";\nimport { VideoMediaEditor, videoPaths } from \"../admin/media-item-panel.js\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { MediaFolderEditor } from \"../media-folder-editor.js\";\nimport { SortableList } from \"../sortable-list.js\";\nimport { ErrorLine, useAction } from \"../social/parts.js\";\nimport { GroupPicker, labelOf, useGroupNames, type Labels } from \"../groups/parts.js\";\nimport { AttributeFields, formOf } from \"../groups/fields.js\";\nimport { MembershipEditor } from \"../groups/memberships.js\";\nimport { OfferFields } from \"./offer-fields.js\";\n\ninterface Common {\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n labels?: Labels;\n}\n\nconst NONE = \"__none__\";\nconst LISTINGS: readonly Listing[] = [\"listed\", \"members\", \"unlisted\"];\nconst COMMENTS = [\"open\", \"closed\", \"hidden\"] as const;\ntype Comments = (typeof COMMENTS)[number];\nconst LEVELS: readonly Rule[\"level\"][] = [\"public\", \"tier\", \"ppv\", \"group\", \"group_ppv\"];\nconst grouped = (l: Rule[\"level\"]) => l === \"group\" || l === \"group_ppv\";\n\nfunction Section({ title, ckui, children }: { title: ReactNode; ckui: string; children: ReactNode }) {\n return (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui={ckui}>\n <h3 className=\"font-medium\">{title}</h3>\n {children}\n </section>\n );\n}\n\nfunction Saved({ show }: { show: boolean }) {\n const { t } = useMessages();\n return show ? (\n <span role=\"status\" className=\"text-muted-foreground\">\n {t(\"contentEditor.saved\")}\n </span>\n ) : null;\n}\n\n/** The content model's kind, when it loaded. */\nfunction useKind(kind: string, client?: ContentKitClient): { model: ContentModel | null; spec: ContentModel[\"kinds\"][string] | undefined } {\n const { kinds } = useKinds({ client });\n return { model: kinds, spec: kinds?.kinds[kind] };\n}\n\n// A fresh record rebases clean fields; only an explicit save/discard settles edits.\n// Per-field counters also protect edits made while that operation is pending.\nfunction useDraft<T extends object>(seed: T) {\n const [value, setValue] = useState(seed);\n const draft = useRef({ value: seed, dirty: new Set<keyof T>(), edits: new Map<keyof T, number>() });\n useEffect(() => {\n const next = { ...seed };\n for (const key of draft.current.dirty) next[key] = draft.current.value[key];\n draft.current.value = next;\n setValue(next);\n }, [seed]);\n const edit = (update: SetStateAction<T>) => {\n const d = draft.current;\n const next = typeof update === \"function\" ? (update as (value: T) => T)(d.value) : update;\n for (const key of new Set([...Object.keys(d.value), ...Object.keys(next)] as (keyof T)[])) {\n if (!Object.is(d.value[key], next[key])) {\n d.dirty.add(key);\n d.edits.set(key, (d.edits.get(key) ?? 0) + 1);\n }\n }\n d.value = next;\n setValue(next);\n };\n const checkpoint = () => {\n const edits = new Map(draft.current.edits);\n return (canonical: T) => {\n const d = draft.current;\n const next = { ...canonical };\n for (const key of new Set([...Object.keys(d.value), ...Object.keys(canonical)] as (keyof T)[])) {\n if (d.edits.get(key) !== edits.get(key)) next[key] = d.value[key];\n else d.dirty.delete(key);\n }\n d.value = next;\n setValue(next);\n return d.dirty.size === 0;\n };\n };\n return { value, edit, checkpoint };\n}\n\nfunction useEditorKey(id: string, client: ContentKitClient, scope: string) {\n const [identity, setIdentity] = useState({ id, client, scope, key: 0 });\n if (identity.id !== id || identity.client !== client || identity.scope !== scope) {\n const next = { id, client, scope, key: identity.key + 1 };\n setIdentity(next);\n return next.key;\n }\n return identity.key;\n}\n\nfunction useEditorReload(content: Content, own?: ContentKitClient) {\n const { client, store, scope, language } = useContentScope(own);\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n return async () => {\n const fresh = await client.contents.get(content.id, language ?? content.language);\n let latest = fresh;\n if (mounted.current) store.patch<Content | null>(\n (tag) => tag.type === \"content\" && tag.id === content.id && (tag.readScope ?? \"{}\") === scope,\n (current) => {\n if (current && current.revision > latest.revision) latest = current;\n return latest;\n },\n );\n return latest;\n };\n}\n\n/** Listing and the kind's declared attributes. */\nexport function ContentDetailsEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <ContentDetailsForm key={key} {...p} client={client} />;\n}\n\nfunction ContentDetailsForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { spec } = useKind(content.kind, p.client);\n const declared = useMemo(() => spec?.attributes ?? {}, [spec]);\n const fields = useDraft(useMemo(() => ({ listing: content.listing, comments: content.comments }), [content.listing, content.comments]));\n const attrs = useDraft(useMemo(() => formOf(declared, content.attributes), [declared, content.attributes]));\n const { listing, comments } = fields.value;\n const reload = useEditorReload(content, p.client);\n const [invalid, setInvalid] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.details\")} ckui=\"content-details\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setInvalid(null);\n setSaved(false);\n let attributes: Record<string, unknown>;\n try {\n attributes = parseAttributes(declared, attrs.value);\n } catch (err) {\n return setInvalid((err as Error).message);\n }\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(() => client.contents.update(content.id, { listing, comments, attributes, revision: content.revision })).then((d) => {\n if (!d) return;\n const cleanFields = settleFields({ listing: d.listing, comments: d.comments });\n const cleanAttrs = settleAttrs(formOf(declared, d.attributes));\n setSaved(cleanFields && cleanAttrs);\n });\n }}\n >\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.listing\")}</Label>\n <Select value={listing} onValueChange={(v) => { fields.edit((f) => ({ ...f, listing: v as Listing })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.listing\")}>\n <SelectValue>{(v: string) => t(`contentEditor.listing_${v as Listing}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LISTINGS.map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.listing_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.comments\")}</Label>\n <Select value={comments} onValueChange={(v) => { fields.edit((f) => ({ ...f, comments: v as Comments })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.comments\")}>\n <SelectValue>{(v: string) => t(`contentEditor.comments_${v as Comments}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {COMMENTS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`contentEditor.comments_${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <AttributeFields declared={declared} form={attrs.value} onChange={(n, v) => { attrs.edit((a) => ({ ...a, [n]: v })); setSaved(false); }} labels={p.labels} />\n {invalid && <ErrorLine>{invalid}</ErrorLine>}\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settleFields({ listing: d.listing, comments: d.comments });\n settleAttrs(formOf(declared, d.attributes));\n setInvalid(null);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n </Section>\n );\n}\n\n/** A rule's form: level, tiers, group (the content's owner group by default), the preview its kind has and when it turns free. */\nfunction RuleFields({ value, onChange, model, kind, owner, labels, client }: { value: Rule; onChange: (r: Rule) => void; model: ContentModel | null; kind: string; owner?: string; labels?: Labels; client: ContentKitClient }) {\n const { t } = useMessages();\n const id = useId();\n const tiers = model?.tiers ?? [];\n const spec = model?.kinds[kind];\n const groupKinds = Object.entries(model?.entity_kinds ?? {})\n .filter(([, g]) => g.sellable || g.auth_scope)\n .map(([k]) => k);\n // Picked once the model has loaded: its first group kind until one is chosen.\n const [chosenKind, setGroupKind] = useState<string>();\n const groupKind = chosenKind ?? groupKinds[0] ?? \"\";\n const named = useGroupNames(value.group_id ? [value.group_id] : [], { client });\n const group = value.group_id ? named.get(value.group_id) : undefined;\n const set = (patch: Partial<Rule>) => onChange({ ...value, ...patch });\n const pages = spec?.presentation === \"reader\";\n const segments = !!spec?.segments;\n return (\n <div className=\"grid gap-3\" data-ckui=\"rule-fields\">\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.access\")}</Label>\n <Select\n value={value.level}\n onValueChange={(v) => {\n const level = v as Rule[\"level\"];\n onChange({ level, group_id: grouped(level) ? value.group_id || owner : undefined, preview: value.preview, free_after: value.free_after });\n }}\n >\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.access\")}>\n <SelectValue>{(v: string) => t(`contentEditor.level_${v as Rule[\"level\"]}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LEVELS.filter((l) => (l !== \"tier\" || tiers.length) && (!l.startsWith(\"group\") || groupKinds.length)).map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.level_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {value.level === \"tier\" && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.tiers\")}</legend>\n {tiers.map((tier) => (\n <label key={tier} className=\"flex items-center gap-2\">\n <Switch\n checked={value.tiers?.includes(tier) ?? false}\n onCheckedChange={(on) => set({ tiers: on ? [...(value.tiers ?? []), tier] : (value.tiers ?? []).filter((x) => x !== tier) })}\n aria-label={labelOf(labels, tier)}\n />\n {labelOf(labels, tier)}\n </label>\n ))}\n </fieldset>\n )}\n {grouped(value.level) && (\n <div className=\"flex flex-wrap items-end gap-2\">\n {group || value.group_id ? (\n <span className=\"rounded-md border border-border px-2 py-0.5\" data-ckui=\"rule-group\">\n {group ? group.name || group.slug : value.group_id}\n </span>\n ) : null}\n {groupKinds.length > 1 && (\n <Select value={groupKind} onValueChange={(v) => setGroupKind(String(v))}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupEditor.edgeKind\")}>\n <SelectValue>{(v: string) => labelOf(labels, v)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {groupKinds.map((k) => (\n <SelectItem key={k} value={k}>\n {labelOf(labels, k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n {groupKind && <GroupPicker key={groupKind} kind={groupKind} label={t(\"contentEditor.group\")} client={client} onPick={(g) => set({ group_id: g.id })} />}\n </div>\n )}\n {value.level !== \"public\" && (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {pages && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-pages`}>{t(\"contentEditor.previewPages\")}</Label>\n <Input\n id={`${id}-pages`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.pages ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, pages: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n {segments && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-segments`}>{t(\"contentEditor.previewSegments\")}</Label>\n <Input\n id={`${id}-segments`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.segments ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, segments: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-free`}>{t(\"contentEditor.freeAfter\")}</Label>\n <Input id={`${id}-free`} className=\"h-8\" type=\"datetime-local\" value={toLocalInput(value.free_after)} onChange={(e) => set({ free_after: fromLocalInput(e.target.value) })} />\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/** A rule the server takes: a group level names its group. */\nconst complete = (r: Rule) => !grouped(r.level) || !!r.group_id;\n\n/** A rule as stored: empty previews and absent fields left out. */\nfunction cleanRule(r: Rule): Rule {\n const preview = r.preview && (r.preview.pages || r.preview.segments) ? { pages: r.preview.pages || undefined, segments: r.preview.segments || undefined } : undefined;\n return {\n level: r.level,\n tiers: r.level === \"tier\" ? r.tiers : undefined,\n group_id: r.level === \"group\" || r.level === \"group_ppv\" ? r.group_id : undefined,\n preview: r.level === \"public\" ? undefined : preview,\n free_after: r.level === \"public\" ? undefined : r.free_after,\n };\n}\n\n/** Who may open the content and what it sells for. */\nexport function AccessEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <AccessForm key={key} {...p} client={client} />;\n}\n\nfunction AccessForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { model } = useKind(content.kind, p.client);\n const rule = useDraft(content.access);\n const reload = useEditorReload(content, p.client);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.accessTitle\")} ckui=\"access-editor\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setSaved(false);\n const settle = rule.checkpoint();\n void save.run(() => client.contents.update(content.id, { access: cleanRule(rule.value), revision: content.revision })).then((d) => d && setSaved(settle(d.access)));\n }}\n >\n <RuleFields value={rule.value} onChange={(r) => { rule.edit(r); setSaved(false); }} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !complete(rule.value)}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settle = rule.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settle(d.access);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n <OfferFields\n offer={content.offer}\n pending={offer.pending}\n onSell={(terms) => void offer.run(() => client.offers.sell({ content: content.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id }))}\n />\n <ErrorLine error={offer.error} />\n </Section>\n );\n}\n\n/** A version's name in the editor: its label, else its languages and traits. */\nexport function versionLabel(v: Version, languageName: (l: string) => string, labels?: Labels): string {\n return v.label || [...v.languages.map(languageName), ...v.traits.map((x) => labelOf(labels, x))].join(\" · \");\n}\n\n/**\n * A content's versions: order, languages, traits, label, state and\n * schedule, an access override and its own offer, segments (chapters) and\n * the version's media folder; add and delete. A kind whose one version is\n * hidden shows only that version's segments and media.\n */\nexport function VersionsEditor({ content, media = true, ...p }: Common & { content: Content; media?: boolean }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const languageName = useLanguageName();\n const { model, spec } = useKind(content.kind, p.client);\n const order = useAction(\"content.save\", p.onError);\n const add = useAction(\"content.save\", p.onError);\n const [open, setOpen] = useState<string | null>(null);\n const versions = useMemo(() => [...content.versions].sort((a, b) => a.position - b.position), [content.versions]);\n if (!spec) return null;\n if (spec.versions.hidden) {\n const only = versions[0];\n if (!only || (!media && !spec.segments)) return null;\n return (\n <Section title={t(\"contentEditor.media\")} ckui=\"version-media\">\n {spec.segments && <SegmentsEditor content={content} version={only} {...p} />}\n {media && <VersionMedia content={content} version={only} model={model} {...p} />}\n </Section>\n );\n }\n const languages = model?.languages ?? [];\n return (\n <Section title={t(\"contentEditor.versions\")} ckui=\"versions-editor\">\n <SortableList\n items={versions}\n id={(v) => v.id}\n name={(v) => versionLabel(v, languageName, p.labels)}\n label={t(\"contentEditor.versions\")}\n disabled={order.pending || versions.length < 2}\n onMove={(from, to) => {\n const ids = versions.map((v) => v.id);\n const [moved] = ids.splice(from, 1);\n ids.splice(to, 0, moved!);\n void order.run(() => client.contents.orderVersions(content.id, ids));\n }}\n >\n {(v, handle) => (\n <div className=\"grid gap-2 rounded-md border border-border p-2\" data-ckui=\"version-row\" data-version={v.id}>\n <div className=\"flex flex-wrap items-center gap-2\">\n {versions.length > 1 && handle}\n <span className=\"min-w-0 flex-1 font-medium break-words\">{versionLabel(v, languageName, p.labels)}</span>\n <Badge variant={v.live ? \"default\" : \"outline\"}>{t(v.live ? \"contentEditor.live\" : v.state === \"draft\" ? \"contentManager.draft\" : \"contentManager.scheduled\")}</Badge>\n {v.access && <Badge variant=\"secondary\">{t(`contentEditor.level_${v.access.level}`)}</Badge>}\n {v.pages ? <span className=\"text-xs text-muted-foreground\">{t(\"contentEditor.pageCount\", { count: v.pages })}</span> : null}\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" aria-expanded={open === v.id} onClick={() => setOpen(open === v.id ? null : v.id)}>\n {t(open === v.id ? \"contentEditor.close\" : \"contentEditor.edit\")}\n </Button>\n </div>\n {open === v.id && <VersionForm content={content} version={v} model={model} media={media} {...p} />}\n </div>\n )}\n </SortableList>\n <ErrorLine error={order.error} />\n <AddVersion\n languages={languages}\n many={spec?.versions.languages === \"many\"}\n pending={add.pending}\n // A new version is a draft: open it for its media.\n onAdd={(input) => void add.run(() => client.contents.addVersion(content.id, input)).then((v) => v && setOpen(v.id))}\n />\n <ErrorLine error={add.error} />\n </Section>\n );\n}\n\nfunction LanguageFields({ languages, value, many, onChange }: { languages: readonly string[]; value: readonly string[]; many: boolean; onChange: (v: string[]) => void }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n if (!many)\n return (\n <Select value={value[0] ?? NONE} onValueChange={(v) => onChange(v === NONE ? [] : [String(v)])}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.versionLanguage\")}>\n <SelectValue>{(v: string) => (v === NONE ? t(\"contentEditor.chooseLanguage\") : languageName(v))}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {languageName(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n return (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.versionLanguages\")}</legend>\n {languages.map((l) => (\n <label key={l} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={value.includes(l)} onCheckedChange={(on) => onChange(on ? [...value, l] : value.filter((x) => x !== l))} aria-label={languageName(l)} />\n {languageName(l)}\n </label>\n ))}\n </fieldset>\n );\n}\n\nfunction AddVersion({ languages, many, pending, onAdd }: { languages: readonly string[]; many: boolean; pending: boolean; onAdd: (v: { languages: string[] }) => void }) {\n const { t } = useMessages();\n const [langs, setLangs] = useState<string[]>([]);\n return (\n <div className=\"flex flex-wrap items-center gap-2\" data-ckui=\"add-version\">\n <LanguageFields languages={languages} value={langs} many={many} onChange={setLangs} />\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={pending || !langs.length}\n onClick={() => {\n onAdd({ languages: langs });\n setLangs([]);\n }}\n >\n {t(\"contentEditor.addVersion\")}\n </Button>\n </div>\n );\n}\n\nfunction VersionForm({ content, version: v, model, media, ...p }: Common & { content: Content; version: Version; model: ContentModel | null; media: boolean }) {\n const { t } = useMessages();\n const id = useId();\n const client = useContentKitClient(p.client);\n const spec = model?.kinds[content.kind];\n const [langs, setLangs] = useState<string[]>(v.languages);\n const [traits, setTraits] = useState<string[]>(v.traits);\n const [label, setLabel] = useState(v.label ?? \"\");\n const [draft, setDraft] = useState(v.state === \"draft\");\n const [at, setAt] = useState(toLocalInput(v.publish_at));\n const [own, setOwn] = useState(!!v.access);\n const [rule, setRule] = useState<Rule>(v.access ?? content.access);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const remove = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n return (\n <div className=\"grid gap-4 pt-2\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setSaved(false);\n void save\n .run(() =>\n client.contents.updateVersion(content.id, v.id, {\n languages: langs,\n traits,\n label: label.trim(),\n state: draft ? \"draft\" : \"published\",\n publish_at: fromLocalInput(at),\n ...(own ? { access: cleanRule(rule) } : { clear_access: !!v.access }),\n }),\n )\n .then((d) => d && setSaved(true));\n }}\n >\n <LanguageFields languages={model?.languages ?? []} value={langs} many={spec?.versions.languages === \"many\"} onChange={setLangs} />\n {!!spec?.versions.traits?.length && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.traits\")}</legend>\n {spec.versions.traits.map((x) => (\n <label key={x} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={traits.includes(x)} onCheckedChange={(on) => setTraits(on ? [...traits, x] : traits.filter((y) => y !== x))} aria-label={labelOf(p.labels, x)} />\n {labelOf(p.labels, x)}\n </label>\n ))}\n </fieldset>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-label`}>{t(\"contentEditor.versionLabel\")}</Label>\n <Input id={`${id}-label`} className=\"h-8\" value={label} onChange={(e) => setLabel(e.target.value)} />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-at`}>{t(\"contentEditor.versionPublishAt\")}</Label>\n <Input id={`${id}-at`} className=\"h-8\" type=\"datetime-local\" value={at} onChange={(e) => setAt(e.target.value)} />\n </div>\n </div>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={draft} onCheckedChange={setDraft} />\n {t(\"contentEditor.versionDraft\")}\n </label>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={own} onCheckedChange={setOwn} />\n {t(\"contentEditor.ownAccess\")}\n </label>\n {own && <RuleFields value={rule} onChange={setRule} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />}\n <ErrorLine error={save.error} />\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !langs.length || (own && !complete(rule))}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Saved show={saved} />\n <Button type=\"button\" size=\"sm\" variant=\"destructive\" className=\"ms-auto\" disabled={remove.pending} onClick={() => void remove.run(() => client.contents.removeVersion(content.id, v.id))}>\n {t(\"contentEditor.deleteVersion\")}\n </Button>\n </div>\n <ErrorLine error={remove.error} />\n </form>\n <OfferFields\n offer={v.offer}\n pending={offer.pending}\n onSell={(terms) => void offer.run(() => client.offers.sell({ content: content.id, version: v.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id, version: v.id }))}\n />\n <ErrorLine error={offer.error} />\n {spec?.segments && <SegmentsEditor content={content} version={v} {...p} />}\n {media && <VersionCover content={content} version={v} {...p} />}\n {media && <VersionMedia content={content} version={v} model={model} {...p} />}\n {media && spec?.presentation === \"reader\" && <ReaderManifestEditor content={content.id} version={v.id} client={p.client} onError={p.onError} />}\n </div>\n );\n}\n\n/**\n * A version's own cover, where its kind has covers: the cover upload its\n * editors selected, else its first. Versions share no files.\n */\nexport function VersionCover({ content, version: v, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { presets } = usePresets({ client });\n const save = useAction(\"content.save\", p.onError);\n const input = useRef<HTMLInputElement>(null);\n const [fresh, setFresh] = useState<string | null>(null);\n useEffect(() => () => void (fresh && URL.revokeObjectURL(fresh)), [fresh]);\n if (!presets.some((r) => r.kind === content.kind && r.name === \"cover\")) return null;\n const src = fresh ?? v.cover?.url;\n const pick = (file: File | null) =>\n void save.run(async () => {\n if (!file) {\n setFresh(null);\n return client.contents.setCover(content.id, v.id, null);\n }\n const ref = { kind: content.kind, id: content.id, version: v.id };\n const up = await client.media.uploadNamed(ref, file, { path: await client.media.presetPath(content.kind, \"cover\", file) });\n const saved = await client.contents.setCover(content.id, v.id, up.name);\n if (typeof URL.createObjectURL === \"function\") setFresh(URL.createObjectURL(file));\n return saved;\n });\n return (\n <div className=\"grid gap-1.5\" data-ckui=\"version-cover\">\n <span className=\"text-sm font-medium\">{t(\"contentManager.cover\")}</span>\n <div className=\"flex flex-wrap items-center gap-3\">\n {src ? <img src={src} alt=\"\" className=\"h-20 w-36 rounded-md border border-border object-cover\" /> : <span className=\"text-muted-foreground\">{t(\"contentManager.noCover\")}</span>}\n <Button type=\"button\" size=\"sm\" variant=\"outline\" disabled={save.pending} onClick={() => input.current?.click()}>\n {t(src ? \"pollEditor.replaceImage\" : \"contentManager.addCover\")}\n </Button>\n {v.cover?.image && (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" disabled={save.pending} onClick={() => pick(null)}>\n {t(\"pollEditor.removeImage\")}\n </Button>\n )}\n <input\n ref={input}\n type=\"file\"\n accept=\"image/*\"\n hidden\n aria-label={t(\"contentManager.cover\")}\n onChange={(e) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (f) pick(f);\n }}\n />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/**\n * A version's media: a video kind's source, poster and subtitles (by its\n * upload rules), else its upload folders. Uploads to a version that is not\n * live are added as they finish; a live one's wait for \"Add\".\n */\nfunction VersionMedia({ content, version, model, ...p }: Common & { content: Content; version: Version; model: ContentModel | null }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n const item = useMemo(() => ({ kind: content.kind, id: content.id, version: version.id }), [content.kind, content.id, version.id]);\n const r = useMediaRead(item, { editor: true, client: p.client });\n const languages = useMemo(() => (model?.languages ?? []).map((l) => ({ value: l, label: languageName(l) })), [model, languageName]);\n if (!r.read && r.loading) return <Skeleton className=\"h-24 w-full\" />;\n if (r.read?.uploads && videoPaths(r.read.uploads).source) return <VideoMediaEditor item={item} languages={languages} client={p.client} onError={p.onError} />;\n return <>\n <MediaFolderEditor item={item} commit={version.live ? \"manual\" : \"auto\"} label={t(\"contentEditor.media\")} client={p.client} onError={p.onError} />\n {model?.kinds[content.kind]?.presentation === \"reader\" && <PageReview content={content.id} version={version.id} client={p.client} onError={p.onError} />}\n </>;\n}\n\ntype Row = { title: string; start: string; end: string; release: string };\n\n/** A version's segments (chapters): page ranges with titles and release times. */\nexport function SegmentsEditor({ content, version, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const seed = () => version.segments.map((s) => ({ title: s.title ?? \"\", start: String(s.start), end: String(s.end), release: toLocalInput(s.release_at) }));\n const [rows, setRows] = useState<Row[]>(seed);\n // Seeded again when the stored segments change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => setRows(seed()), [JSON.stringify(version.segments)]);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const set = (i: number, patch: Partial<Row>) => {\n setSaved(false);\n setRows((r) => r.map((x, j) => (j === i ? { ...x, ...patch } : x)));\n };\n const valid = rows.every((r) => /^\\d+$/.test(r.start) && /^\\d+$/.test(r.end) && Number(r.end) > Number(r.start));\n return (\n <div className=\"grid gap-2\" data-ckui=\"segments-editor\">\n <h4 className=\"text-sm font-medium\">{t(\"contentEditor.segments\")}</h4>\n {rows.length === 0 && <p className=\"text-muted-foreground\">{t(\"contentEditor.noSegments\")}</p>}\n {rows.map((r, i) => (\n <div key={i} className=\"flex flex-wrap items-center gap-2\" data-ckui=\"segment-row\">\n <span className=\"w-6 text-xs text-muted-foreground tabular-nums\">{i + 1}</span>\n <Input className=\"h-8 w-40\" aria-label={t(\"contentEditor.segmentTitle\", { n: i + 1 })} placeholder={t(\"contentEditor.segmentTitlePlaceholder\")} value={r.title} onChange={(e) => set(i, { title: e.target.value })} />\n <Input className=\"h-8 w-20\" type=\"number\" min={0} aria-label={t(\"contentEditor.segmentStart\", { n: i + 1 })} value={r.start} onChange={(e) => set(i, { start: e.target.value })} />\n <span aria-hidden>–</span>\n <Input className=\"h-8 w-20\" type=\"number\" min={1} aria-label={t(\"contentEditor.segmentEnd\", { n: i + 1 })} value={r.end} onChange={(e) => set(i, { end: e.target.value })} />\n <Input className=\"h-8 w-48\" type=\"datetime-local\" aria-label={t(\"contentEditor.segmentRelease\", { n: i + 1 })} value={r.release} onChange={(e) => set(i, { release: e.target.value })} />\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" onClick={() => setRows((x) => x.filter((_, j) => j !== i))}>\n {t(\"common.remove\")}\n </Button>\n </div>\n ))}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n const last = rows.at(-1);\n const start = last ? Number(last.end) || 0 : 0;\n setRows((x) => [...x, { title: \"\", start: String(start), end: String(start + 1), release: \"\" }]);\n }}\n >\n {t(\"contentEditor.addSegment\")}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={save.pending || !valid}\n onClick={() => {\n setSaved(false);\n const segments: Segment[] = rows.map((r, i) => ({ position: i + 1, title: r.title.trim() || undefined, start: Number(r.start), end: Number(r.end), release_at: fromLocalInput(r.release), released: false }));\n void save.run(() => client.contents.setSegments(content.id, version.id, segments)).then((d) => d && setSaved(true));\n }}\n >\n {t(\"contentEditor.saveSegments\")}\n </Button>\n <Saved show={saved} />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/** Every editor section of an existing content: details, access and price, versions, groups. */\nexport function ContentSections({ content, ...p }: Common & { content: Content; media?: boolean; className?: string; management?: boolean }) {\n const languageName = useLanguageName();\n const versions = useMemo(() => content.versions.map((v) => ({ id: v.id, label: versionLabel(v, languageName, p.labels) })), [content.versions, languageName, p.labels]);\n const { spec } = useKind(content.kind, p.client);\n return (\n <div className={cn(\"grid gap-6\", p.className)} data-ckui=\"content-sections\">\n <ContentDetailsEditor content={content} {...p} />\n <AccessEditor content={content} {...p} />\n <VersionsEditor content={content} {...p} />\n {!!spec?.entities?.length && (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui=\"content-groups\">\n <MembershipEditor management={p.management} content={content.id} contentKind={content.kind} versions={spec.versions.hidden ? undefined : versions} labels={p.labels} client={p.client} onError={p.onError} />\n </section>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"editors.js","names":[],"sources":["../../../src/components/content/editors.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode, type SetStateAction } from \"react\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { fromLocalInput, parseAttributes, toLocalInput } from \"../../client/group-fields.js\";\nimport type { Content, ContentModel, Listing, Rule, Segment, Version } from \"../../client/generated/wire.js\";\nimport { useLanguageName, useMessages } from \"../../i18n/context.js\";\nimport { useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useKinds } from \"../../react/groups.js\";\nimport { useMediaRead } from \"../../react/read.js\";\nimport { usePresets } from \"../../react/public.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Input } from \"#ckui/ui/input\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { ReaderManifestEditor } from \"../admin/reader-manifest.js\";\nimport { PageReview } from \"../admin/page-review.js\";\nimport { VideoMediaEditor, videoPaths } from \"../admin/media-item-panel.js\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { MediaFolderEditor } from \"../media-folder-editor.js\";\nimport { SortableList } from \"../sortable-list.js\";\nimport { ErrorLine, useAction } from \"../social/parts.js\";\nimport { GroupPicker, labelOf, useGroupNames, type Labels } from \"../groups/parts.js\";\nimport { AttributeFields, formOf } from \"../groups/fields.js\";\nimport { MembershipEditor } from \"../groups/memberships.js\";\nimport { useDraft } from \"../../react/use-draft.js\";\nimport { useEditorSaveTask, readerMediaReady } from \"./editor-save.js\";\nimport { OfferFields } from \"./offer-fields.js\";\n\ninterface Common {\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n labels?: Labels;\n}\n\nconst NONE = \"__none__\";\nconst LISTINGS: readonly Listing[] = [\"listed\", \"members\", \"unlisted\"];\nconst COMMENTS = [\"open\", \"closed\", \"hidden\"] as const;\ntype Comments = (typeof COMMENTS)[number];\nconst LEVELS: readonly Rule[\"level\"][] = [\"public\", \"tier\", \"ppv\", \"group\", \"group_ppv\"];\nconst grouped = (l: Rule[\"level\"]) => l === \"group\" || l === \"group_ppv\";\n\nfunction Section({ title, ckui, children }: { title: ReactNode; ckui: string; children: ReactNode }) {\n return (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui={ckui}>\n <h3 className=\"font-medium\">{title}</h3>\n {children}\n </section>\n );\n}\n\nfunction Saved({ show }: { show: boolean }) {\n const { t } = useMessages();\n return show ? (\n <span role=\"status\" className=\"text-muted-foreground\">\n {t(\"contentEditor.saved\")}\n </span>\n ) : null;\n}\n\n/** The content model's kind, when it loaded. */\nfunction useKind(kind: string, client?: ContentKitClient): { model: ContentModel | null; spec: ContentModel[\"kinds\"][string] | undefined } {\n const { kinds } = useKinds({ client });\n return { model: kinds, spec: kinds?.kinds[kind] };\n}\n\n\nfunction useEditorKey(id: string, client: ContentKitClient, scope: string) {\n const [identity, setIdentity] = useState({ id, client, scope, key: 0 });\n if (identity.id !== id || identity.client !== client || identity.scope !== scope) {\n const next = { id, client, scope, key: identity.key + 1 };\n setIdentity(next);\n return next.key;\n }\n return identity.key;\n}\n\nfunction useEditorReload(content: Content, own?: ContentKitClient) {\n const { client, store, scope, language } = useContentScope(own);\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n return async () => {\n const fresh = await client.contents.get(content.id, language ?? content.language);\n let latest = fresh;\n if (mounted.current) store.patch<Content | null>(\n (tag) => tag.type === \"content\" && tag.id === content.id && (tag.readScope ?? \"{}\") === scope,\n (current) => {\n if (current && current.revision > latest.revision) latest = current;\n return latest;\n },\n );\n return latest;\n };\n}\n\n/** Listing and the kind's declared attributes. */\nexport function ContentDetailsEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <ContentDetailsForm key={key} {...p} client={client} />;\n}\n\nfunction ContentDetailsForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { spec } = useKind(content.kind, p.client);\n const declared = useMemo(() => spec?.attributes ?? {}, [spec]);\n const fields = useDraft(useMemo(() => ({ listing: content.listing, comments: content.comments }), [content.listing, content.comments]));\n const attrs = useDraft(useMemo(() => formOf(declared, content.attributes), [declared, content.attributes]));\n const { listing, comments } = fields.value;\n const reload = useEditorReload(content, p.client);\n const [invalid, setInvalid] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.details\")} ckui=\"content-details\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setInvalid(null);\n setSaved(false);\n let attributes: Record<string, unknown>;\n try {\n attributes = parseAttributes(declared, attrs.value);\n } catch (err) {\n return setInvalid((err as Error).message);\n }\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(() => client.contents.update(content.id, { listing, comments, attributes, revision: content.revision })).then((d) => {\n if (!d) return;\n const cleanFields = settleFields({ listing: d.listing, comments: d.comments });\n const cleanAttrs = settleAttrs(formOf(declared, d.attributes));\n setSaved(cleanFields && cleanAttrs);\n });\n }}\n >\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.listing\")}</Label>\n <Select value={listing} onValueChange={(v) => { fields.edit((f) => ({ ...f, listing: v as Listing })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.listing\")}>\n <SelectValue>{(v: string) => t(`contentEditor.listing_${v as Listing}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LISTINGS.map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.listing_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.comments\")}</Label>\n <Select value={comments} onValueChange={(v) => { fields.edit((f) => ({ ...f, comments: v as Comments })); setSaved(false); }}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.comments\")}>\n <SelectValue>{(v: string) => t(`contentEditor.comments_${v as Comments}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {COMMENTS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`contentEditor.comments_${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <AttributeFields declared={declared} form={attrs.value} onChange={(n, v) => { attrs.edit((a) => ({ ...a, [n]: v })); setSaved(false); }} labels={p.labels} />\n {invalid && <ErrorLine>{invalid}</ErrorLine>}\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settleFields = fields.checkpoint(), settleAttrs = attrs.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settleFields({ listing: d.listing, comments: d.comments });\n settleAttrs(formOf(declared, d.attributes));\n setInvalid(null);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n </Section>\n );\n}\n\n/** A rule's form: level, tiers, group (the content's owner group by default), the preview its kind has and when it turns free. */\nexport function RuleFields({ value, onChange, model, kind, owner, labels, client }: { value: Rule; onChange: (r: Rule) => void; model: ContentModel | null; kind: string; owner?: string; labels?: Labels; client: ContentKitClient }) {\n const { t } = useMessages();\n const id = useId();\n const tiers = model?.tiers ?? [];\n const spec = model?.kinds[kind];\n const groupKinds = Object.entries(model?.entity_kinds ?? {})\n .filter(([, g]) => g.sellable || g.auth_scope)\n .map(([k]) => k);\n // Picked once the model has loaded: its first group kind until one is chosen.\n const [chosenKind, setGroupKind] = useState<string>();\n const groupKind = chosenKind ?? groupKinds[0] ?? \"\";\n const named = useGroupNames(value.group_id ? [value.group_id] : [], { client });\n const group = value.group_id ? named.get(value.group_id) : undefined;\n const set = (patch: Partial<Rule>) => onChange({ ...value, ...patch });\n const pages = spec?.presentation === \"reader\";\n const segments = !!spec?.segments;\n return (\n <div className=\"grid gap-3\" data-ckui=\"rule-fields\">\n <div className=\"grid gap-1.5 sm:max-w-xs\">\n <Label>{t(\"contentEditor.access\")}</Label>\n <Select\n value={value.level}\n onValueChange={(v) => {\n const level = v as Rule[\"level\"];\n onChange({ level, group_id: grouped(level) ? value.group_id || owner : undefined, preview: value.preview, free_after: value.free_after });\n }}\n >\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.access\")}>\n <SelectValue>{(v: string) => t(`contentEditor.level_${v as Rule[\"level\"]}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {LEVELS.filter((l) => (l !== \"tier\" || tiers.length) && (!l.startsWith(\"group\") || groupKinds.length)).map((l) => (\n <SelectItem key={l} value={l}>\n {t(`contentEditor.level_${l}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {value.level === \"tier\" && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.tiers\")}</legend>\n {tiers.map((tier) => (\n <label key={tier} className=\"flex items-center gap-2\">\n <Switch\n checked={value.tiers?.includes(tier) ?? false}\n onCheckedChange={(on) => set({ tiers: on ? [...(value.tiers ?? []), tier] : (value.tiers ?? []).filter((x) => x !== tier) })}\n aria-label={labelOf(labels, tier)}\n />\n {labelOf(labels, tier)}\n </label>\n ))}\n </fieldset>\n )}\n {grouped(value.level) && (\n <div className=\"flex flex-wrap items-end gap-2\">\n {group || value.group_id ? (\n <span className=\"rounded-md border border-border px-2 py-0.5\" data-ckui=\"rule-group\">\n {group ? group.name || group.slug : value.group_id}\n </span>\n ) : null}\n {groupKinds.length > 1 && (\n <Select value={groupKind} onValueChange={(v) => setGroupKind(String(v))}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupEditor.edgeKind\")}>\n <SelectValue>{(v: string) => labelOf(labels, v)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {groupKinds.map((k) => (\n <SelectItem key={k} value={k}>\n {labelOf(labels, k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n {groupKind && <GroupPicker key={groupKind} kind={groupKind} label={t(\"contentEditor.group\")} client={client} onPick={(g) => set({ group_id: g.id })} />}\n </div>\n )}\n {value.level !== \"public\" && (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {pages && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-pages`}>{t(\"contentEditor.previewPages\")}</Label>\n <Input\n id={`${id}-pages`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.pages ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, pages: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n {segments && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-segments`}>{t(\"contentEditor.previewSegments\")}</Label>\n <Input\n id={`${id}-segments`}\n className=\"h-8\"\n type=\"number\"\n min={0}\n value={value.preview?.segments ?? \"\"}\n onChange={(e) => set({ preview: { ...value.preview, segments: e.target.value ? Math.max(0, Math.trunc(Number(e.target.value))) : undefined } })}\n />\n </div>\n )}\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-free`}>{t(\"contentEditor.freeAfter\")}</Label>\n <Input id={`${id}-free`} className=\"h-8\" type=\"datetime-local\" value={toLocalInput(value.free_after)} onChange={(e) => set({ free_after: fromLocalInput(e.target.value) })} />\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/** A rule the server takes: a group level names its group. */\nexport const complete = (r: Rule) => !grouped(r.level) || !!r.group_id;\n\n/** A rule as stored: empty previews and absent fields left out. */\nexport function cleanRule(r: Rule): Rule {\n const preview = r.preview && (r.preview.pages || r.preview.segments) ? { pages: r.preview.pages || undefined, segments: r.preview.segments || undefined } : undefined;\n return {\n level: r.level,\n tiers: r.level === \"tier\" ? r.tiers : undefined,\n group_id: r.level === \"group\" || r.level === \"group_ppv\" ? r.group_id : undefined,\n preview: r.level === \"public\" ? undefined : preview,\n free_after: r.level === \"public\" ? undefined : r.free_after,\n };\n}\n\n/** Who may open the content and what it sells for. */\nexport function AccessEditor(p: Common & { content: Content }) {\n const { client, scope } = useContentScope(p.client);\n const key = useEditorKey(p.content.id, client, scope);\n return <AccessForm key={key} {...p} client={client} />;\n}\n\nfunction AccessForm({ content, ...p }: Common & { content: Content }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { model } = useKind(content.kind, p.client);\n const rule = useDraft(content.access);\n const reload = useEditorReload(content, p.client);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n return (\n <Section title={t(\"contentEditor.accessTitle\")} ckui=\"access-editor\">\n <form\n className=\"grid gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n setSaved(false);\n const settle = rule.checkpoint();\n void save.run(() => client.contents.update(content.id, { access: cleanRule(rule.value), revision: content.revision })).then((d) => d && setSaved(settle(d.access)));\n }}\n >\n <RuleFields value={rule.value} onChange={(r) => { rule.edit(r); setSaved(false); }} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />\n <ErrorLine error={save.error} />\n <div className=\"flex items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !complete(rule.value)}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={save.pending} onClick={() => {\n const settle = rule.checkpoint();\n void save.run(reload).then((d) => {\n if (!d) return;\n settle(d.access);\n setSaved(false);\n });\n }}>{t(\"common.cancel\")}</Button>\n <Saved show={saved} />\n </div>\n </form>\n <OfferFields\n offer={content.offer}\n pending={offer.pending}\n onSell={(terms) => offer.run(() => client.offers.sell({ content: content.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id }))}\n />\n <ErrorLine error={offer.error} />\n </Section>\n );\n}\n\n/** A version's name in the editor: its label, else its languages and traits. */\nexport function versionLabel(v: Version, languageName: (l: string) => string, labels?: Labels): string {\n return v.label || [...v.languages.map(languageName), ...v.traits.map((x) => labelOf(labels, x))].join(\" · \");\n}\n\n/**\n * A content's versions: order, languages, traits, label, state and\n * schedule, an access override and its own offer, segments (chapters) and\n * the version's media folder; add and delete. A kind whose one version is\n * hidden shows only that version's segments and media.\n */\nexport function VersionsEditor({ content, media = true, activeVersion, ...p }: Common & { content: Content; media?: boolean; activeVersion?: string }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const languageName = useLanguageName();\n const { model, spec } = useKind(content.kind, p.client);\n const order = useAction(\"content.save\", p.onError);\n const add = useAction(\"content.save\", p.onError);\n const [open, setOpen] = useState<string | null>(null);\n const [opened, setOpened] = useState<string[]>([]);\n const reveal = (id: string) => { setOpen(id); setOpened((ids) => ids.includes(id) ? ids : [...ids,id]); };\n useEffect(() => { if (activeVersion) { setOpen(activeVersion); setOpened((ids)=>ids.includes(activeVersion)?ids:[...ids,activeVersion]); } }, [activeVersion]);\n useEditorSaveTask(`versions:${content.id}`, {label:t(\"contentEditor.versions\"),dirty:false,pending:order.pending||add.pending,valid:true,save:async()=>true});\n const versions = useMemo(() => [...content.versions].sort((a, b) => a.position - b.position), [content.versions]);\n if (!spec) return null;\n if (spec.versions.hidden) {\n const only = versions[0];\n if (!only || (!media && !spec.segments)) return null;\n return (\n <Section title={t(\"contentEditor.media\")} ckui=\"version-media\">\n {spec.segments && <SegmentsEditor content={content} version={only} {...p} />}\n {media && <VersionMedia content={content} version={only} model={model} {...p} />}\n </Section>\n );\n }\n const languages = model?.languages ?? [];\n return (\n <Section title={t(\"contentEditor.versions\")} ckui=\"versions-editor\">\n <SortableList\n items={versions}\n id={(v) => v.id}\n name={(v) => versionLabel(v, languageName, p.labels)}\n label={t(\"contentEditor.versions\")}\n disabled={order.pending || versions.length < 2}\n onMove={(from, to) => {\n const ids = versions.map((v) => v.id);\n const [moved] = ids.splice(from, 1);\n ids.splice(to, 0, moved!);\n void order.run(() => client.contents.orderVersions(content.id, ids));\n }}\n >\n {(v, handle) => (\n <div className=\"grid gap-2 rounded-md border border-border p-2\" data-ckui=\"version-row\" data-version={v.id}>\n <div className=\"flex flex-wrap items-center gap-2\">\n {versions.length > 1 && handle}\n <span className=\"min-w-0 flex-1 font-medium break-words\">{versionLabel(v, languageName, p.labels)}</span>\n <Badge variant={v.live ? \"default\" : \"outline\"}>{t(v.live ? \"contentEditor.live\" : v.state === \"draft\" ? \"contentManager.draft\" : \"contentManager.scheduled\")}</Badge>\n {v.access && <Badge variant=\"secondary\">{t(`contentEditor.level_${v.access.level}`)}</Badge>}\n {v.pages ? <span className=\"text-xs text-muted-foreground\">{t(\"contentEditor.pageCount\", { count: v.pages })}</span> : null}\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" aria-expanded={open === v.id} onClick={() => open === v.id ? setOpen(null) : reveal(v.id)}>\n {t(open === v.id ? \"contentEditor.close\" : \"contentEditor.edit\")}\n </Button>\n </div>\n {opened.includes(v.id) && <div hidden={open !== v.id}><VersionForm content={content} version={v} model={model} media={media} {...p} /></div>}\n </div>\n )}\n </SortableList>\n <ErrorLine error={order.error} />\n <AddVersion\n languages={languages}\n many={spec?.versions.languages === \"many\"}\n pending={add.pending}\n // A new version is a draft: open it for its media.\n onAdd={(input) => void add.run(() => client.contents.addVersion(content.id, input)).then((v) => v && reveal(v.id))}\n />\n <ErrorLine error={add.error} />\n </Section>\n );\n}\n\nfunction LanguageFields({ languages, value, many, onChange }: { languages: readonly string[]; value: readonly string[]; many: boolean; onChange: (v: string[]) => void }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n if (!many)\n return (\n <Select value={value[0] ?? NONE} onValueChange={(v) => onChange(v === NONE ? [] : [String(v)])}>\n <SelectTrigger size=\"sm\" aria-label={t(\"contentEditor.versionLanguage\")}>\n <SelectValue>{(v: string) => (v === NONE ? t(\"contentEditor.chooseLanguage\") : languageName(v))}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {languageName(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n return (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.versionLanguages\")}</legend>\n {languages.map((l) => (\n <label key={l} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={value.includes(l)} onCheckedChange={(on) => onChange(on ? [...value, l] : value.filter((x) => x !== l))} aria-label={languageName(l)} />\n {languageName(l)}\n </label>\n ))}\n </fieldset>\n );\n}\n\nfunction AddVersion({ languages, many, pending, onAdd }: { languages: readonly string[]; many: boolean; pending: boolean; onAdd: (v: { languages: string[] }) => void }) {\n const { t } = useMessages();\n const [langs, setLangs] = useState<string[]>([]);\n return (\n <div className=\"flex flex-wrap items-center gap-2\" data-ckui=\"add-version\">\n <LanguageFields languages={languages} value={langs} many={many} onChange={setLangs} />\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={pending || !langs.length}\n onClick={() => {\n onAdd({ languages: langs });\n setLangs([]);\n }}\n >\n {t(\"contentEditor.addVersion\")}\n </Button>\n </div>\n );\n}\n\nfunction VersionForm({ content, version: v, model, media, ...p }: Common & { content: Content; version: Version; model: ContentModel | null; media: boolean }) {\n const { t } = useMessages();\n const id = useId();\n const client = useContentKitClient(p.client);\n const spec = model?.kinds[content.kind];\n const seed = useCallback((v: Version) => ({langs:v.languages,traits:v.traits,label:v.label??\"\",draft:v.state===\"draft\",at:toLocalInput(v.publish_at),own:!!v.access,rule:v.access??content.access}),[content.access]);\n const fields = useDraft(useMemo(()=>seed(v),[seed,v]));\n const {langs,traits,label,draft,at,own,rule}=fields.value;\n const edit=(patch:Partial<typeof fields.value>)=>{fields.edit((old)=>({...old,...patch}));setSaved(false);};\n const [invalid,setInvalid]=useState<string|null>(null);\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const remove = useAction(\"content.save\", p.onError);\n const offer = useAction(\"offer.save\", p.onError);\n const valid=langs.length>0&&(!own||complete(rule));\n const submit=async()=>{\n if(!valid)return false;\n setInvalid(null);setSaved(false);\n if(spec?.presentation===\"reader\"&&v.state===\"draft\"&&!draft&&!(await readerMediaReady(client,{kind:content.kind,id:content.id,version:v.id}))){setInvalid(t(\"readerEditor.filesNotReady\"));return false;}\n const settle=fields.checkpoint();\n const out=await save.run(()=>client.contents.updateVersion(content.id,v.id,{languages:langs,traits,label:label.trim(),state:draft?\"draft\":\"published\",publish_at:fromLocalInput(at),...(own?{access:cleanRule(rule)}:{clear_access:!!v.access})}));\n if(!out)return false;\n const clean=settle(seed(out));setSaved(clean);return clean;\n };\n useEditorSaveTask(`version:${v.id}`,{label:t(\"contentEditor.versions\"),dirty:fields.dirty.length>0,pending:save.pending||remove.pending,valid,save:submit,order:10});\n return (\n <div className=\"grid gap-4 pt-2\">\n <form className=\"grid gap-3\" onSubmit={(event)=>{event.preventDefault();void submit();}}>\n <LanguageFields languages={model?.languages ?? []} value={langs} many={spec?.versions.languages === \"many\"} onChange={(langs)=>edit({langs})} />\n {!!spec?.versions.traits?.length && (\n <fieldset className=\"flex flex-wrap gap-3\">\n <legend className=\"sr-only\">{t(\"contentEditor.traits\")}</legend>\n {spec.versions.traits.map((x) => (\n <label key={x} className=\"flex items-center gap-1.5\">\n <Switch size=\"sm\" checked={traits.includes(x)} onCheckedChange={(on) => edit({traits:on ? [...traits, x] : traits.filter((y) => y !== x)})} aria-label={labelOf(p.labels, x)} />\n {labelOf(p.labels, x)}\n </label>\n ))}\n </fieldset>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-label`}>{t(\"contentEditor.versionLabel\")}</Label>\n <Input id={`${id}-label`} className=\"h-8\" value={label} onChange={(e)=>edit({label:e.target.value})} />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor={`${id}-at`}>{t(\"contentEditor.versionPublishAt\")}</Label>\n <Input id={`${id}-at`} className=\"h-8\" type=\"datetime-local\" value={at} onChange={(e)=>edit({at:e.target.value})} />\n </div>\n </div>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={draft} onCheckedChange={(draft)=>edit({draft})} />\n {t(\"contentEditor.versionDraft\")}\n </label>\n <label className=\"flex items-center gap-2\">\n <Switch size=\"sm\" checked={own} onCheckedChange={(own)=>edit({own})} />\n {t(\"contentEditor.ownAccess\")}\n </label>\n {own && <RuleFields value={rule} onChange={(rule)=>edit({rule})} model={model} kind={content.kind} owner={content.owner_group_id} labels={p.labels} client={client} />}\n {invalid&&<ErrorLine>{invalid}</ErrorLine>}\n <ErrorLine error={save.error} />\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button type=\"submit\" size=\"sm\" disabled={save.pending || !langs.length || (own && !complete(rule))}>\n {save.pending ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n <Saved show={saved} />\n <Button type=\"button\" size=\"sm\" variant=\"destructive\" className=\"ms-auto\" disabled={remove.pending} onClick={() => void remove.run(() => client.contents.removeVersion(content.id, v.id))}>\n {t(\"contentEditor.deleteVersion\")}\n </Button>\n </div>\n <ErrorLine error={remove.error} />\n </form>\n <OfferFields\n offer={v.offer}\n pending={offer.pending}\n onSell={(terms) => offer.run(() => client.offers.sell({ content: content.id, version: v.id }, terms))}\n onWithdraw={() => void offer.run(() => client.offers.withdraw({ content: content.id, version: v.id }))}\n />\n <ErrorLine error={offer.error} />\n {spec?.segments && <SegmentsEditor content={content} version={v} {...p} />}\n {media && <VersionCover content={content} version={v} {...p} />}\n {media && <VersionMedia content={content} version={v} model={model} {...p} />}\n {media && spec?.presentation === \"reader\" && <ReaderManifestEditor content={content.id} version={v.id} client={p.client} onError={p.onError} />}\n </div>\n );\n}\n\n/**\n * A version's own cover, where its kind has covers: the cover upload its\n * editors selected, else its first. Versions share no files.\n */\nexport function VersionCover({ content, version: v, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const { presets } = usePresets({ client });\n const save = useAction(\"content.save\", p.onError);\n const input = useRef<HTMLInputElement>(null);\n const [fresh, setFresh] = useState<string | null>(null);\n useEffect(() => () => void (fresh && URL.revokeObjectURL(fresh)), [fresh]);\n if (!presets.some((r) => r.kind === content.kind && r.name === \"cover\")) return null;\n const src = fresh ?? v.cover?.url;\n const pick = (file: File | null) =>\n void save.run(async () => {\n if (!file) {\n setFresh(null);\n return client.contents.setCover(content.id, v.id, null);\n }\n const ref = { kind: content.kind, id: content.id, version: v.id };\n const up = await client.media.uploadNamed(ref, file, { path: await client.media.presetPath(content.kind, \"cover\", file) });\n const saved = await client.contents.setCover(content.id, v.id, up.name);\n if (typeof URL.createObjectURL === \"function\") setFresh(URL.createObjectURL(file));\n return saved;\n });\n return (\n <div className=\"grid gap-1.5\" data-ckui=\"version-cover\">\n <span className=\"text-sm font-medium\">{t(\"contentManager.cover\")}</span>\n <div className=\"flex flex-wrap items-center gap-3\">\n {src ? <img src={src} alt=\"\" className=\"h-20 w-36 rounded-md border border-border object-cover\" /> : <span className=\"text-muted-foreground\">{t(\"contentManager.noCover\")}</span>}\n <Button type=\"button\" size=\"sm\" variant=\"outline\" disabled={save.pending} onClick={() => input.current?.click()}>\n {t(src ? \"pollEditor.replaceImage\" : \"contentManager.addCover\")}\n </Button>\n {v.cover?.image && (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" disabled={save.pending} onClick={() => pick(null)}>\n {t(\"pollEditor.removeImage\")}\n </Button>\n )}\n <input\n ref={input}\n type=\"file\"\n accept=\"image/*\"\n hidden\n aria-label={t(\"contentManager.cover\")}\n onChange={(e) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (f) pick(f);\n }}\n />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/**\n * A version's media: a video kind's source, poster and subtitles (by its\n * upload rules), else its upload folders. Uploads to a version that is not\n * live are added as they finish; a live one's wait for \"Add\".\n */\nfunction VersionMedia({ content, version, model, ...p }: Common & { content: Content; version: Version; model: ContentModel | null }) {\n const { t } = useMessages();\n const languageName = useLanguageName();\n const item = useMemo(() => ({ kind: content.kind, id: content.id, version: version.id }), [content.kind, content.id, version.id]);\n const r = useMediaRead(item, { editor: true, client: p.client });\n const languages = useMemo(() => (model?.languages ?? []).map((l) => ({ value: l, label: languageName(l) })), [model, languageName]);\n if (!r.read && r.loading) return <Skeleton className=\"h-24 w-full\" />;\n if (r.read?.uploads && videoPaths(r.read.uploads).source) return <VideoMediaEditor item={item} languages={languages} client={p.client} onError={p.onError} />;\n return <>\n <MediaFolderEditor item={item} commit={version.live ? \"manual\" : \"auto\"} label={t(\"contentEditor.media\")} client={p.client} onError={p.onError} />\n {model?.kinds[content.kind]?.presentation === \"reader\" && <PageReview content={content.id} version={version.id} client={p.client} onError={p.onError} />}\n </>;\n}\n\ntype Row = { title: string; start: string; end: string; release: string };\nconst segmentRows=(version:Version):Row[]=>version.segments.map((s)=>({title:s.title??\"\",start:String(s.start),end:String(s.end),release:toLocalInput(s.release_at)}));\n\n/** A version's segments (chapters): page ranges with titles and release times. */\nexport function SegmentsEditor({ content, version, ...p }: Common & { content: Content; version: Version }) {\n const { t } = useMessages();\n const client = useContentKitClient(p.client);\n const fields=useDraft(useMemo(()=>({rows:segmentRows(version)}),[version]));\n const rows=fields.value.rows;\n const setRows=(next:SetStateAction<Row[]>)=>fields.edit((old)=>({rows:typeof next===\"function\"?next(old.rows):next}));\n const [saved, setSaved] = useState(false);\n const save = useAction(\"content.save\", p.onError);\n const set = (i: number, patch: Partial<Row>) => {\n setSaved(false);\n setRows((r) => r.map((x, j) => (j === i ? { ...x, ...patch } : x)));\n };\n const valid = rows.every((r) => /^\\d+$/.test(r.start) && /^\\d+$/.test(r.end) && Number(r.end) > Number(r.start));\n const submit=async()=>{\n if(!valid)return false;\n setSaved(false);const settle=fields.checkpoint();\n const segments:Segment[]=rows.map((r,i)=>({position:i+1,title:r.title.trim()||undefined,start:Number(r.start),end:Number(r.end),release_at:fromLocalInput(r.release),released:false}));\n const out=await save.run(()=>client.contents.setSegments(content.id,version.id,segments));\n if(!out)return false;const clean=settle({rows:segmentRows(out)});setSaved(clean);return clean;\n };\n useEditorSaveTask(`segments:${version.id}`,{label:t(\"contentEditor.segments\"),dirty:fields.dirty.length>0,pending:save.pending,valid,save:submit,order:20});\n return (\n <div className=\"grid gap-2\" data-ckui=\"segments-editor\">\n <h4 className=\"text-sm font-medium\">{t(\"contentEditor.segments\")}</h4>\n {rows.length === 0 && <p className=\"text-muted-foreground\">{t(\"contentEditor.noSegments\")}</p>}\n {rows.map((r, i) => (\n <div key={i} className=\"flex flex-wrap items-center gap-2\" data-ckui=\"segment-row\">\n <span className=\"w-6 text-xs text-muted-foreground tabular-nums\">{i + 1}</span>\n <Input className=\"h-8 w-40\" aria-label={t(\"contentEditor.segmentTitle\", { n: i + 1 })} placeholder={t(\"contentEditor.segmentTitlePlaceholder\")} value={r.title} onChange={(e) => set(i, { title: e.target.value })} />\n <Input className=\"h-8 w-20\" type=\"number\" min={0} aria-label={t(\"contentEditor.segmentStart\", { n: i + 1 })} value={r.start} onChange={(e) => set(i, { start: e.target.value })} />\n <span aria-hidden>–</span>\n <Input className=\"h-8 w-20\" type=\"number\" min={1} aria-label={t(\"contentEditor.segmentEnd\", { n: i + 1 })} value={r.end} onChange={(e) => set(i, { end: e.target.value })} />\n <Input className=\"h-8 w-48\" type=\"datetime-local\" aria-label={t(\"contentEditor.segmentRelease\", { n: i + 1 })} value={r.release} onChange={(e) => set(i, { release: e.target.value })} />\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" onClick={() => setRows((x) => x.filter((_, j) => j !== i))}>\n {t(\"common.remove\")}\n </Button>\n </div>\n ))}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n const last = rows.at(-1);\n const start = last ? Number(last.end) || 0 : 0;\n setRows((x) => [...x, { title: \"\", start: String(start), end: String(start + 1), release: \"\" }]);\n }}\n >\n {t(\"contentEditor.addSegment\")}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={save.pending || !valid}\n onClick={()=>void submit()}\n >\n {t(\"contentEditor.saveSegments\")}\n </Button>\n <Saved show={saved} />\n </div>\n <ErrorLine error={save.error} />\n </div>\n );\n}\n\n/** Every editor section of an existing content: details, access and price, versions, groups. */\nexport function ContentSections({ content, ...p }: Common & { content: Content; media?: boolean; className?: string; management?: boolean }) {\n const languageName = useLanguageName();\n const versions = useMemo(() => content.versions.map((v) => ({ id: v.id, label: versionLabel(v, languageName, p.labels) })), [content.versions, languageName, p.labels]);\n const { spec } = useKind(content.kind, p.client);\n return (\n <div className={cn(\"grid gap-6\", p.className)} data-ckui=\"content-sections\">\n <ContentDetailsEditor content={content} {...p} />\n <AccessEditor content={content} {...p} />\n <VersionsEditor content={content} {...p} />\n {!!spec?.entities?.length && (\n <section className=\"grid gap-3 border-t border-border pt-4\" data-ckui=\"content-groups\">\n <MembershipEditor management={p.management} content={content.id} contentKind={content.kind} versions={spec.versions.hidden ? undefined : versions} labels={p.labels} client={p.client} onError={p.onError} />\n </section>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MineQuery } from '../../client/content/favorites.js';
|
|
2
|
+
import { CardListProps } from './grid.js';
|
|
3
|
+
/** Favorite contents, with the same filtering, paid previews and pagination as public lists. */
|
|
4
|
+
export declare function ContentFavorites({ query, ...p }: CardListProps & {
|
|
5
|
+
query?: Omit<MineQuery, "target">;
|
|
6
|
+
}): import('react').JSX.Element;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useMyFavorites as e } from "../../react/discovery.js";
|
|
2
|
+
import { CardGrid as t, cardListMode as n } from "./grid.js";
|
|
3
|
+
import { useMemo as r } from "react";
|
|
4
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/content/favorites.tsx
|
|
6
|
+
function a({ query: a = {}, ...o }) {
|
|
7
|
+
let s = r(() => ({
|
|
8
|
+
...a,
|
|
9
|
+
target: "contents",
|
|
10
|
+
mode: n(o.locked, a.mode),
|
|
11
|
+
summary: a.summary ?? !0,
|
|
12
|
+
limit: a.limit ?? o.pageSize
|
|
13
|
+
}), [
|
|
14
|
+
a,
|
|
15
|
+
o.pageSize,
|
|
16
|
+
o.locked
|
|
17
|
+
]), c = e(s, { client: o.client }), l = r(() => c.items.flatMap((e) => e.content ? [e.content] : []), [c.items]);
|
|
18
|
+
return /* @__PURE__ */ i(t, {
|
|
19
|
+
surface: "favorites",
|
|
20
|
+
...o,
|
|
21
|
+
list: {
|
|
22
|
+
...c,
|
|
23
|
+
items: l
|
|
24
|
+
},
|
|
25
|
+
render: JSON.stringify(s),
|
|
26
|
+
filterKinds: s.kind ? [s.kind] : void 0,
|
|
27
|
+
filterLanguage: s.display_language ?? s.language
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { a as ContentFavorites };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=favorites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"favorites.js","names":[],"sources":["../../../src/components/content/favorites.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { MineQuery } from \"../../client/content/favorites.js\";\nimport { useMyFavorites } from \"../../react/discovery.js\";\nimport { CardGrid, cardListMode, type CardListProps } from \"./grid.js\";\n\n/** Favorite contents, with the same filtering, paid previews and pagination as public lists. */\nexport function ContentFavorites({ query = {}, ...p }: CardListProps & { query?: Omit<MineQuery, \"target\"> }) {\n const q = useMemo(\n () => ({ ...query, target: \"contents\" as const, mode: cardListMode(p.locked, query.mode), summary: query.summary ?? true, limit: query.limit ?? p.pageSize }),\n [query, p.pageSize, p.locked],\n );\n const favorites = useMyFavorites(q, { client: p.client });\n const items = useMemo(() => favorites.items.flatMap((item) => (item.content ? [item.content] : [])), [favorites.items]);\n return (\n <CardGrid\n surface=\"favorites\"\n {...p}\n list={{ ...favorites, items }}\n render={JSON.stringify(q)}\n filterKinds={q.kind ? [q.kind] : undefined}\n filterLanguage={q.display_language ?? q.language}\n />\n );\n}\n"],"mappings":";;;;;AAMA,SAAgB,EAAiB,EAAE,WAAQ,CAAC,GAAG,GAAG,KAA4D;CAC5G,IAAM,IAAI,SACD;EAAE,GAAG;EAAO,QAAQ;EAAqB,MAAM,EAAa,EAAE,QAAQ,EAAM,IAAI;EAAG,SAAS,EAAM,WAAW;EAAM,OAAO,EAAM,SAAS,EAAE;CAAS,IAC3J;EAAC;EAAO,EAAE;EAAU,EAAE;CAAM,CAC9B,GACM,IAAY,EAAe,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,GAClD,IAAQ,QAAc,EAAU,MAAM,SAAS,MAAU,EAAK,UAAU,CAAC,EAAK,OAAO,IAAI,CAAC,CAAE,GAAG,CAAC,EAAU,KAAK,CAAC;CACtH,OACE,kBAAC,GAAD;EACE,SAAQ;EACR,GAAI;EACJ,MAAM;GAAE,GAAG;GAAW;EAAM;EAC5B,QAAQ,KAAK,UAAU,CAAC;EACxB,aAAa,EAAE,OAAO,CAAC,EAAE,IAAI,IAAI,KAAA;EACjC,gBAAgB,EAAE,oBAAoB,EAAE;CACzC,CAAA;AAEL"}
|
|
@@ -2,28 +2,32 @@ import { useMessages as e } from "../../i18n/context.js";
|
|
|
2
2
|
import { AppearanceContext as t } from "../../scope.js";
|
|
3
3
|
import { Dialog as n, DialogContent as r, DialogDescription as i, DialogHeader as a, DialogTitle as o } from "../../ui/dialog.js";
|
|
4
4
|
import { ContentFilterSettings as s } from "./filters.js";
|
|
5
|
-
import { useContext as c } from "react";
|
|
6
|
-
import { jsx as
|
|
5
|
+
import { useContext as c, useState as l } from "react";
|
|
6
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/content/filter-dialog.tsx
|
|
8
|
-
function
|
|
9
|
-
let { t:
|
|
10
|
-
return
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
function f({ open: f, onOpenChange: p, description: m, returnFocus: h, ...g }) {
|
|
9
|
+
let { t: _ } = e(), v = c(t), [y, b] = l({ open: !1 }), x = y;
|
|
10
|
+
return y.open !== f && (x = {
|
|
11
|
+
open: f,
|
|
12
|
+
container: f ? h?.()?.closest("dialog[open]") ?? void 0 : y.container
|
|
13
|
+
}, b(x)), /* @__PURE__ */ u(t.Provider, {
|
|
14
|
+
value: g.appearance ?? v,
|
|
15
|
+
children: /* @__PURE__ */ u(n, {
|
|
16
|
+
open: f,
|
|
17
|
+
onOpenChange: (e) => p(e),
|
|
18
|
+
children: /* @__PURE__ */ d(r, {
|
|
19
|
+
finalFocus: h,
|
|
20
|
+
portalContainer: x.container,
|
|
17
21
|
className: "max-h-[calc(100dvh-2rem)] overflow-y-auto",
|
|
18
|
-
children: [/* @__PURE__ */
|
|
19
|
-
...
|
|
20
|
-
includeDeleted:
|
|
22
|
+
children: [/* @__PURE__ */ d(a, { children: [/* @__PURE__ */ u(o, { children: _("readerSettings.filterTitle") }), /* @__PURE__ */ u(i, { children: m ?? _("readerSettings.filterDescription") })] }), /* @__PURE__ */ u(s, {
|
|
23
|
+
...g,
|
|
24
|
+
includeDeleted: g.includeDeleted ?? !1
|
|
21
25
|
})]
|
|
22
26
|
})
|
|
23
27
|
})
|
|
24
28
|
});
|
|
25
29
|
}
|
|
26
30
|
//#endregion
|
|
27
|
-
export {
|
|
31
|
+
export { f as ContentFilterDialog };
|
|
28
32
|
|
|
29
33
|
//# sourceMappingURL=filter-dialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-dialog.js","names":[],"sources":["../../../src/components/content/filter-dialog.tsx"],"sourcesContent":["import { useContext, type ReactNode } from \"react\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { AppearanceContext } from \"../../scope.js\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"#ckui/ui/dialog\";\nimport { ContentFilterSettings, type ContentFilterSettingsProps } from \"./filters.js\";\n\nexport interface ContentFilterDialogProps extends ContentFilterSettingsProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n description?: ReactNode;\n /** A stable focus target when a preference change removes the opening tile. */\n returnFocus?: () => HTMLElement | null;\n}\n\n/** The same filter controls as ReaderSettings, without another language picker. */\nexport function ContentFilterDialog({ open, onOpenChange, description, returnFocus, ...settings }: ContentFilterDialogProps) {\n const { t } = useMessages();\n const inheritedAppearance = useContext(AppearanceContext);\n return <AppearanceContext.Provider value={settings.appearance ?? inheritedAppearance}>\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent
|
|
1
|
+
{"version":3,"file":"filter-dialog.js","names":[],"sources":["../../../src/components/content/filter-dialog.tsx"],"sourcesContent":["import { useContext, useState, type ReactNode } from \"react\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { AppearanceContext } from \"../../scope.js\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"#ckui/ui/dialog\";\nimport { ContentFilterSettings, type ContentFilterSettingsProps } from \"./filters.js\";\n\nexport interface ContentFilterDialogProps extends ContentFilterSettingsProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n description?: ReactNode;\n /** A stable focus target when a preference change removes the opening tile. */\n returnFocus?: () => HTMLElement | null;\n}\n\n/** The same filter controls as ReaderSettings, without another language picker. */\nexport function ContentFilterDialog({ open, onOpenChange, description, returnFocus, ...settings }: ContentFilterDialogProps) {\n const { t } = useMessages();\n const inheritedAppearance = useContext(AppearanceContext);\n // Native modal dialogs live above body portals. Keep the opening surface\n // through preference reloads, even when they remove the triggering tile.\n const [portal, setPortal] = useState<{ open: boolean; container?: HTMLDialogElement }>({ open: false });\n let placement = portal;\n if (portal.open !== open) {\n placement = { open, container: open ? returnFocus?.()?.closest<HTMLDialogElement>(\"dialog[open]\") ?? undefined : portal.container };\n setPortal(placement);\n }\n return <AppearanceContext.Provider value={settings.appearance ?? inheritedAppearance}>\n <Dialog open={open} onOpenChange={(next) => onOpenChange(next)}>\n <DialogContent\n finalFocus={returnFocus}\n portalContainer={placement.container}\n className=\"max-h-[calc(100dvh-2rem)] overflow-y-auto\"\n >\n <DialogHeader>\n <DialogTitle>{t(\"readerSettings.filterTitle\")}</DialogTitle>\n <DialogDescription>{description ?? t(\"readerSettings.filterDescription\")}</DialogDescription>\n </DialogHeader>\n <ContentFilterSettings {...settings} includeDeleted={settings.includeDeleted ?? false} />\n </DialogContent>\n </Dialog>\n </AppearanceContext.Provider>;\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,EAAoB,EAAE,SAAM,iBAAc,gBAAa,gBAAa,GAAG,KAAsC;CAC3H,IAAM,EAAE,SAAM,EAAY,GACpB,IAAsB,EAAW,CAAiB,GAGlD,CAAC,GAAQ,KAAa,EAA2D,EAAE,MAAM,GAAM,CAAC,GAClG,IAAY;CAKhB,OAJI,EAAO,SAAS,MAClB,IAAY;EAAE;EAAM,WAAW,IAAO,IAAc,CAAC,EAAE,QAA2B,cAAc,KAAK,KAAA,IAAY,EAAO;CAAU,GAClI,EAAU,CAAS,IAEd,kBAAC,EAAkB,UAAnB;EAA4B,OAAO,EAAS,cAAc;EAC/D,UAAA,kBAAC,GAAD;GAAc;GAAM,eAAe,MAAS,EAAa,CAAI;GAC3D,UAAA,kBAAC,GAAD;IACE,YAAY;IACZ,iBAAiB,EAAU;IAC3B,WAAU;IAHZ,UAAA,CAKE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAc,EAAE,4BAA4B,EAAe,CAAA,GAC3D,kBAAC,GAAD,EAAA,UAAoB,KAAe,EAAE,kCAAkC,EAAqB,CAAA,CAChF,EAAA,CAAA,GACd,kBAAC,GAAD;KAAuB,GAAI;KAAU,gBAAgB,EAAS,kBAAkB;IAAQ,CAAA,CAC3E;;EACT,CAAA;CACkB,CAAA;AAC9B"}
|
|
@@ -16,6 +16,8 @@ export interface ContentFilterSettingsProps {
|
|
|
16
16
|
language?: string;
|
|
17
17
|
/** Currently excluded matches in this listing/day; omitted shows no counts. */
|
|
18
18
|
counts?: readonly ContentFilterCount[];
|
|
19
|
+
/** Counts cover a bounded candidate set, so each displayed count is a lower bound. */
|
|
20
|
+
countsLowerBound?: boolean;
|
|
19
21
|
/** Offer listing deleted content the reader holds. Default true. */
|
|
20
22
|
includeDeleted?: boolean;
|
|
21
23
|
client?: ContentKitClient;
|
|
@@ -41,7 +41,11 @@ function v(r) {
|
|
|
41
41
|
className: "min-w-0 flex-1",
|
|
42
42
|
children: [e.entity.name || e.entity.slug, r.counts !== void 0 && /* @__PURE__ */ g("span", {
|
|
43
43
|
className: "tabular-nums",
|
|
44
|
-
children: [
|
|
44
|
+
children: [
|
|
45
|
+
": ",
|
|
46
|
+
r.countsLowerBound ? "≥ " : "",
|
|
47
|
+
new Intl.NumberFormat(d.language).format(r.counts.filter((t) => t.entity.id === e.entity.id).reduce((e, t) => e + t.count, 0))
|
|
48
|
+
]
|
|
45
49
|
})]
|
|
46
50
|
})]
|
|
47
51
|
}, e.entity.id))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filters.js","names":[],"sources":["../../../src/components/content/filters.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useId } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { GroupCard } from \"../../client/generated/wire.js\";\nimport type { ReleaseDatesQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useContentFilters, useReleaseDates } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\n\n/** Counts for one concrete listing selection, aggregated by entity.\n * Only rows offered by the current domain's filter inventory are displayed. */\nexport interface ContentFilterCount {\n entity: Pick<GroupCard, \"id\">;\n count: number;\n}\n\nexport interface ContentFilterSettingsProps {\n /** Listing context; shows shared controls when any kind is in applies_to. */\n kinds?: readonly string[];\n /** Entity names in this language; default the provider's. */\n language?: string;\n /** Currently excluded matches in this listing/day; omitted shows no counts. */\n counts?: readonly ContentFilterCount[];\n /** Offer listing deleted content the reader holds. Default true. */\n includeDeleted?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** Show or hide configured content for this browser or signed-in account. */\nexport function ContentFilterSettings(p: ContentFilterSettingsProps) {\n const m = useMessages();\n const { t } = m;\n const id = useId();\n const ctx = useContext(ContentKitContext);\n const f = useContentFilters({ language: p.language, client: p.client });\n const save = useAction(\"filters.save\", p.onError);\n const root = (children: React.ReactNode) => (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"content-filters\">\n {children}\n </ContentKitUiRoot>\n );\n if (!f.filters) {\n if (f.error) return root(<ErrorLine>{contentError(m, f.error)}</ErrorLine>);\n return root(<Skeleton className=\"h-24 w-full\" />);\n }\n const filters = f.filters;\n const rows = !p.kinds || p.kinds.some((kind) => filters.applies_to.includes(kind)) ? filters.filters : [];\n if (!rows.length && p.includeDeleted === false) return null;\n return root(\n <>\n {rows.length > 0 && (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {rows.map((x) => (\n <li key={x.entity.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-slug={x.entity.slug} data-visible={x.visible}>\n <Switch id={`${id}-${x.entity.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(x.entity.id, v))} />\n <Label htmlFor={`${id}-${x.entity.id}`} className=\"min-w-0 flex-1\">\n {x.entity.name || x.entity.slug}\n {p.counts !== undefined && (\n <span className=\"tabular-nums\">: {new Intl.NumberFormat(m.language).format(p.counts.filter((entry) => entry.entity.id === x.entity.id).reduce((n, entry) => n + entry.count, 0))}</span>\n )}\n </Label>\n </li>\n ))}\n </ul>\n )}\n {p.includeDeleted !== false && ctx?.viewer !== null && (\n <div className=\"flex items-center gap-3\">\n <Switch id={`${id}-deleted`} checked={filters.include_deleted} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setIncludeDeleted(v))} />\n <Label htmlFor={`${id}-deleted`}>{t(\"contents.includeDeleted\")}</Label>\n </div>\n )}\n <ErrorLine error={save.error} />\n </>,\n );\n}\n\nexport interface ReleaseDateIndexProps {\n /** Which contents count: the listing's filters. */\n query?: ReleaseDatesQuery;\n /** The bucket chosen (a day YYYY-MM-DD or month YYYY-MM): list with released_on set to it. */\n selected?: string;\n onSelect?: (date: string) => void;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** The release date index: per month or day, newest first, how many contents and how many free. */\nexport function ReleaseDateIndex({ query = {}, selected, onSelect, client, className, appearance }: ReleaseDateIndexProps) {\n const m = useMessages();\n const { t } = m;\n const dates = useReleaseDates(query, { client });\n const label = (date: string) => {\n const [y, mo, d] = date.split(\"-\").map(Number);\n const at = new Date(Date.UTC(y!, (mo ?? 1) - 1, d ?? 1));\n return new Intl.DateTimeFormat(m.language, d ? { dateStyle: \"medium\", timeZone: \"UTC\" } : { year: \"numeric\", month: \"long\", timeZone: \"UTC\" }).format(at);\n };\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 text-sm\", className)} data-ckui=\"release-dates\">\n {dates.loading && !dates.items.length ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : dates.error && !dates.items.length ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, dates.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={dates.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n ) : !dates.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"contents.noDates\")}</p>\n ) : (\n <ul className=\"grid gap-1\">\n {dates.items.map((d) => (\n <li key={d.date}>\n <button\n type=\"button\"\n aria-pressed={selected === d.date}\n className={cn(\"flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted\", selected === d.date && \"bg-muted font-medium\")}\n onClick={() => onSelect?.(d.date)}\n data-ckui=\"release-date\"\n data-date={d.date}\n >\n <span>{label(d.date)}</span>\n <span className=\"text-xs text-muted-foreground tabular-nums\">\n {m.plural(\"contents.items\", d.count)}\n {d.free < d.count && ` · ${m.plural(\"contents.free\", d.free)}`}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {dates.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {dates.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, dates.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {dates.loadingMore ? t(\"contents.loading\") : dates.error ? t(\"common.retry\") : t(\"contents.loadMore\")}\n </Button>\n </div>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filters.js","names":[],"sources":["../../../src/components/content/filters.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useId } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { GroupCard } from \"../../client/generated/wire.js\";\nimport type { ReleaseDatesQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useContentFilters, useReleaseDates } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\n\n/** Counts for one concrete listing selection, aggregated by entity.\n * Only rows offered by the current domain's filter inventory are displayed. */\nexport interface ContentFilterCount {\n entity: Pick<GroupCard, \"id\">;\n count: number;\n}\n\nexport interface ContentFilterSettingsProps {\n /** Listing context; shows shared controls when any kind is in applies_to. */\n kinds?: readonly string[];\n /** Entity names in this language; default the provider's. */\n language?: string;\n /** Currently excluded matches in this listing/day; omitted shows no counts. */\n counts?: readonly ContentFilterCount[];\n /** Counts cover a bounded candidate set, so each displayed count is a lower bound. */\n countsLowerBound?: boolean;\n /** Offer listing deleted content the reader holds. Default true. */\n includeDeleted?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** Show or hide configured content for this browser or signed-in account. */\nexport function ContentFilterSettings(p: ContentFilterSettingsProps) {\n const m = useMessages();\n const { t } = m;\n const id = useId();\n const ctx = useContext(ContentKitContext);\n const f = useContentFilters({ language: p.language, client: p.client });\n const save = useAction(\"filters.save\", p.onError);\n const root = (children: React.ReactNode) => (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"content-filters\">\n {children}\n </ContentKitUiRoot>\n );\n if (!f.filters) {\n if (f.error) return root(<ErrorLine>{contentError(m, f.error)}</ErrorLine>);\n return root(<Skeleton className=\"h-24 w-full\" />);\n }\n const filters = f.filters;\n const rows = !p.kinds || p.kinds.some((kind) => filters.applies_to.includes(kind)) ? filters.filters : [];\n if (!rows.length && p.includeDeleted === false) return null;\n return root(\n <>\n {rows.length > 0 && (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {rows.map((x) => (\n <li key={x.entity.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-slug={x.entity.slug} data-visible={x.visible}>\n <Switch id={`${id}-${x.entity.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(x.entity.id, v))} />\n <Label htmlFor={`${id}-${x.entity.id}`} className=\"min-w-0 flex-1\">\n {x.entity.name || x.entity.slug}\n {p.counts !== undefined && (\n <span className=\"tabular-nums\">: {p.countsLowerBound ? \"≥ \" : \"\"}{new Intl.NumberFormat(m.language).format(p.counts.filter((entry) => entry.entity.id === x.entity.id).reduce((n, entry) => n + entry.count, 0))}</span>\n )}\n </Label>\n </li>\n ))}\n </ul>\n )}\n {p.includeDeleted !== false && ctx?.viewer !== null && (\n <div className=\"flex items-center gap-3\">\n <Switch id={`${id}-deleted`} checked={filters.include_deleted} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setIncludeDeleted(v))} />\n <Label htmlFor={`${id}-deleted`}>{t(\"contents.includeDeleted\")}</Label>\n </div>\n )}\n <ErrorLine error={save.error} />\n </>,\n );\n}\n\nexport interface ReleaseDateIndexProps {\n /** Which contents count: the listing's filters. */\n query?: ReleaseDatesQuery;\n /** The bucket chosen (a day YYYY-MM-DD or month YYYY-MM): list with released_on set to it. */\n selected?: string;\n onSelect?: (date: string) => void;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** The release date index: per month or day, newest first, how many contents and how many free. */\nexport function ReleaseDateIndex({ query = {}, selected, onSelect, client, className, appearance }: ReleaseDateIndexProps) {\n const m = useMessages();\n const { t } = m;\n const dates = useReleaseDates(query, { client });\n const label = (date: string) => {\n const [y, mo, d] = date.split(\"-\").map(Number);\n const at = new Date(Date.UTC(y!, (mo ?? 1) - 1, d ?? 1));\n return new Intl.DateTimeFormat(m.language, d ? { dateStyle: \"medium\", timeZone: \"UTC\" } : { year: \"numeric\", month: \"long\", timeZone: \"UTC\" }).format(at);\n };\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 text-sm\", className)} data-ckui=\"release-dates\">\n {dates.loading && !dates.items.length ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : dates.error && !dates.items.length ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, dates.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={dates.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n ) : !dates.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"contents.noDates\")}</p>\n ) : (\n <ul className=\"grid gap-1\">\n {dates.items.map((d) => (\n <li key={d.date}>\n <button\n type=\"button\"\n aria-pressed={selected === d.date}\n className={cn(\"flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted\", selected === d.date && \"bg-muted font-medium\")}\n onClick={() => onSelect?.(d.date)}\n data-ckui=\"release-date\"\n data-date={d.date}\n >\n <span>{label(d.date)}</span>\n <span className=\"text-xs text-muted-foreground tabular-nums\">\n {m.plural(\"contents.items\", d.count)}\n {d.free < d.count && ` · ${m.plural(\"contents.free\", d.free)}`}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {dates.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {dates.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, dates.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {dates.loadingMore ? t(\"contents.loading\") : dates.error ? t(\"common.retry\") : t(\"contents.loadMore\")}\n </Button>\n </div>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
|