feat(quick-260921-pi9): Bilderrahmen-Widget - Diashow mit Grossansicht, Bildverwaltung in den Einstellungen
- picture-frame-config.ts: Eintragstyp als Vereinigung (upload | url) in EINER geordneten Liste, resolvePictureFrameConfig laesst alles ausser https weg (T-PI9-07), Intervall 0 oder 5..3600 s, pickNextIndex (Zufall nie dasselbe) - dashboard-images-api.ts: Upload als FormData-Feld image ohne eigenen Content-Type, 413 -> deutsche Meldung, Proxy-Pfad fuer <img src> - PictureFrameWidget: Leerzustand, <img referrerPolicy=no-referrer> (Browser laedt Fremdbilder, Server nie), object-contain/cover, Unterschrift-Streifen, Wechsel per Timer mit Raeumung, kaputte Bilder verlassen den Umlauf, Grossansicht nur ausserhalb des Bearbeitungsmodus mit Fokus-Rueckgabe und Pause des Wechsels; im Bearbeitungsmodus kein Knopf (Karte bleibt Griff) - PictureFrameConfigForm im WidgetSettingsPanel: Ausschnitt, Intervall, Reihenfolge, Liste mit Vorschau/Unterschrift/Pfeilen/Entfernen (Upload wird auch serverseitig geloescht), Datei hochladen, https-Adresse hinzufuegen - Registry (4x4 min, 8x8 Vorgabe), Katalog, Seite, Uebersetzungen de/en (widgets.pictureFrame, 28 Schluessel), bestehende Tests auf acht Typen Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import type { ComponentType } from 'react';
|
||||
* calculator/favorites/stopwatch: Phase 8 additions (der fruehere
|
||||
* Einzel-Schnellzugriffs-Typ wurde in quick-260916-iex entfernt — Favoriten
|
||||
* decken den Fall ab).
|
||||
* picture-frame: Bilderrahmen (quick-260921-pi9).
|
||||
*/
|
||||
export type WidgetType =
|
||||
| 'clock'
|
||||
@@ -14,7 +15,8 @@ export type WidgetType =
|
||||
| 'note'
|
||||
| 'calculator'
|
||||
| 'favorites'
|
||||
| 'stopwatch';
|
||||
| 'stopwatch'
|
||||
| 'picture-frame';
|
||||
|
||||
/**
|
||||
* Props contract that every widget component must accept.
|
||||
@@ -53,6 +55,10 @@ export const WIDGET_CONSTRAINTS: Record<
|
||||
calculator: { minW: 3, minH: 10, defaultW: 6, defaultH: 10 },
|
||||
favorites: { minW: 3, minH: 3, defaultW: 6, defaultH: 10 },
|
||||
stopwatch: { minW: 4, minH: 3, defaultW: 6, defaultH: 6 },
|
||||
// quick-260921-pi9: ein Bild braucht Flaeche — 8x8 ist ein Quadrat von der
|
||||
// Groesse einer halben Notiz (6x8 -> 8x8), 4x4 die kleinste Kachel, in der
|
||||
// Bild und Unterschrift-Streifen noch erkennbar sind.
|
||||
'picture-frame': { minW: 4, minH: 4, defaultW: 8, defaultH: 8 },
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -248,6 +254,28 @@ function StopwatchIcon({ className }: { className?: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
function PictureFrameIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className={className}
|
||||
>
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" />
|
||||
<circle cx="8.5" cy="8.5" r="1.5" />
|
||||
<polyline points="21 15 16 10 5 21" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registry of all widget types. Used by the widget catalog modal
|
||||
* and the grid renderer to look up components and constraints.
|
||||
@@ -309,6 +337,14 @@ export const WIDGET_REGISTRY: Record<WidgetType, WidgetDefinition> = {
|
||||
...WIDGET_CONSTRAINTS.stopwatch,
|
||||
component: PlaceholderWidget, // Replaced via wireStopwatchWidget()
|
||||
},
|
||||
'picture-frame': {
|
||||
type: 'picture-frame',
|
||||
nameKey: 'pictureFrame.name',
|
||||
descriptionKey: 'pictureFrame.description',
|
||||
icon: PictureFrameIcon,
|
||||
...WIDGET_CONSTRAINTS['picture-frame'],
|
||||
component: PlaceholderWidget, // Replaced via wirePictureFrameWidget()
|
||||
},
|
||||
};
|
||||
|
||||
// Wire actual widget components lazily to avoid circular deps
|
||||
@@ -370,3 +406,11 @@ export function wireStopwatchWidget(component: ComponentType<WidgetProps>) {
|
||||
stopwatchWired = true;
|
||||
}
|
||||
}
|
||||
|
||||
let pictureFrameWired = false;
|
||||
export function wirePictureFrameWidget(component: ComponentType<WidgetProps>) {
|
||||
if (!pictureFrameWired) {
|
||||
WIDGET_REGISTRY['picture-frame'].component = component;
|
||||
pictureFrameWired = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user