Media replaces Video, and the greyed-out Image
Two rows, one of them marked `soon`, for a distinction that was never the editor's to make. The path names a real file and what that file IS is a fact about it — the site reads it off the extension the way a gallery item always has. So the picker asks for a file and stops asking what kind. `video` is gone from what an editor can create and still legal in the database. Every row was migrated; one written by something older should still be editable rather than open nothing, which is why the edit path answers to both. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Handshake, Images, Mail, Type, Video, type LucideIcon } from 'lucide-react';
|
||||
import { Handshake, Image, Images, Mail, Type, type LucideIcon } from 'lucide-react';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||
|
||||
/**
|
||||
@@ -23,7 +23,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/u
|
||||
* A kind the server would accept and this has never heard of is not creatable anyway.
|
||||
*/
|
||||
|
||||
export type ComponentKind = 'free-text' | 'video' | 'gallery' | 'contact-form' | 'partners';
|
||||
export type ComponentKind = 'free-text' | 'media' | 'gallery' | 'contact-form' | 'partners';
|
||||
|
||||
type Choice = {
|
||||
kind: ComponentKind | null;
|
||||
@@ -42,8 +42,15 @@ type Choice = {
|
||||
*/
|
||||
const CHOICES: Choice[] = [
|
||||
{ kind: 'free-text', label: 'Text', hint: 'Words, headings and links', Icon: Type },
|
||||
{ kind: null, label: 'Image', hint: 'One picture from the media store', Icon: Images },
|
||||
{ kind: 'video', label: 'Video', hint: 'No controls, a poster, autoplay and loop', Icon: Video },
|
||||
/*
|
||||
One entry, either kind, because the block does not store which.
|
||||
|
||||
Image and Video were two rows — one of them greyed out as `soon` — and the distinction was never
|
||||
the editor's to make: the path names a real file and what that file IS is a fact about it. So the
|
||||
picker asks for a file and the site works out the rest, which is also what a gallery item has
|
||||
always done.
|
||||
*/
|
||||
{ kind: 'media', label: 'Media', hint: 'A photograph or a video, from the media store', Icon: Image },
|
||||
{ kind: 'gallery', label: 'Gallery', hint: 'A named set of media', Icon: Images },
|
||||
/*
|
||||
Two that place something the site already draws.
|
||||
|
||||
@@ -15,7 +15,7 @@ import { paintCanvas, type CanvasComponent, type CanvasSection } from '../canvas
|
||||
*/
|
||||
const LABELS: Record<string, string> = {
|
||||
'free-text': 'Text',
|
||||
video: 'Video',
|
||||
media: 'Media',
|
||||
gallery: 'Gallery',
|
||||
'contact-form': 'Contact form',
|
||||
partners: 'Partners',
|
||||
@@ -294,16 +294,19 @@ export const PageBuilderPanel = () => {
|
||||
setChoosing(null);
|
||||
// Each kind opens its own editor. A kind with no case here cannot be created, which is the point.
|
||||
if (kind === 'free-text') setEditing({ id: null, ...at, html: '' });
|
||||
if (kind === 'video') setPicking({ id: null, ...at });
|
||||
if (kind === 'media') setPicking({ id: null, ...at });
|
||||
if (kind === 'gallery') setChoosingGallery({ id: null, ...at, galleryId: null });
|
||||
if (PLACES_ONLY.includes(kind)) void createEmpty(kind, at);
|
||||
};
|
||||
|
||||
/*
|
||||
A video is a PATH, saved as soon as it is chosen.
|
||||
A media block is a PATH, saved as soon as it is chosen.
|
||||
|
||||
Free text needs a dialog because writing is a thing people do halfway; picking a file is one act
|
||||
with one outcome, so there is nothing to draft and nothing to cancel out of afterwards.
|
||||
|
||||
Photograph or video is not asked. The file already knows, and the site reads it off the extension
|
||||
the way a gallery item always has — a kind stored here would be a second answer able to disagree.
|
||||
*/
|
||||
const saveVideo = async (url: string) => {
|
||||
if (!page || !picking) return;
|
||||
@@ -312,7 +315,7 @@ export const PageBuilderPanel = () => {
|
||||
setError(null);
|
||||
try {
|
||||
if (picking.id === null) {
|
||||
await clientRef.current.post(base, { kind: 'video', column: picking.column, content: { url } });
|
||||
await clientRef.current.post(base, { kind: 'media', column: picking.column, content: { url } });
|
||||
} else {
|
||||
await clientRef.current.patch(`${base}/${picking.id}`, { content: { url } });
|
||||
}
|
||||
@@ -353,7 +356,9 @@ export const PageBuilderPanel = () => {
|
||||
|
||||
// Edit means whatever editing THIS kind means. The canvas draws one button; which door it opens is
|
||||
// decided here, where the kinds are known.
|
||||
if (component.kind === 'video') {
|
||||
// `video` too — no row holds it since the rename, but one written by something older should
|
||||
// still be editable rather than open nothing.
|
||||
if (component.kind === 'media' || component.kind === 'video') {
|
||||
setPicking({ id: component.id, sectionId: owner.id, column: component.column });
|
||||
return;
|
||||
}
|
||||
@@ -518,7 +523,7 @@ export const PageBuilderPanel = () => {
|
||||
open={picking !== null}
|
||||
onClose={() => setPicking(null)}
|
||||
onPick={(path) => void saveVideo(path)}
|
||||
title="Choose a video"
|
||||
title="Choose a photograph or a video"
|
||||
/>
|
||||
|
||||
<GalleryPicker
|
||||
|
||||
Reference in New Issue
Block a user