diff --git a/docs/HEROUI_MIGRATION.md b/docs/HEROUI_MIGRATION.md index a84272eb..0a1cca7c 100644 --- a/docs/HEROUI_MIGRATION.md +++ b/docs/HEROUI_MIGRATION.md @@ -37,8 +37,11 @@ toolbars, consistent spacing, and restrained selection colors. Advanced controls live behind a per-section switch; changing views preserves project values. Background types and other exclusive choices use TagGroup. The header follows native fullscreen state and keeps project titles centered at narrow widths. Floating layers keep one -surface instead of nesting cards and shadows. Timeline colors follow the theme -and retain the distinction between clip types. The recorder keeps its compact +surface instead of nesting cards and shadows. Timeline blocks retain the original +Recordly palette in both themes. Inspector controls use compact 12–13px text and +32–36px controls, with 14px section titles. Image and video wallpaper grids share +a plus tile for importing and a small remove control on custom tiles, revealed +on hover or keyboard focus. The recorder keeps its compact desktop layout. The adapters in `src/components/ui` translate existing Recordly state/callback @@ -64,7 +67,8 @@ Browser tests use an explicit mocked Electron bridge and a generated six-second video fixture; they never start a real screen recording. They cover control callbacks and keyboard behavior, modal focus, export settings, presets, cropping, annotation formatting/undo, project menus, recorder popovers, countdown and update -windows, theme switching, Advanced state, color editing, and header/playback +windows, theme switching, Advanced state, color editing, wallpaper uploads and +keyboard/hover removal, and header/playback alignment from 800–1440px with and without macOS window controls. Screenshots and failure traces go to the ignored `test-results/` directory. diff --git a/src/components/ui/choice-group.tsx b/src/components/ui/choice-group.tsx index e6edc166..d43e858f 100644 --- a/src/components/ui/choice-group.tsx +++ b/src/components/ui/choice-group.tsx @@ -20,7 +20,7 @@ export function ChoiceGroup({ }) { return ( {children} diff --git a/src/components/ui/color-picker.tsx b/src/components/ui/color-picker.tsx index 5f8d90d5..71c65923 100644 --- a/src/components/ui/color-picker.tsx +++ b/src/components/ui/color-picker.tsx @@ -58,7 +58,7 @@ export function ColorControl({ - -
- {customImages.map((imageUrl, idx) => { - const isSelected = getWallpaperTileState(imageUrl); - return renderWallpaperImageTile(imageUrl, isSelected, { - key: `custom-${idx}`, - ariaLabel: isVideoWallpaperSource(imageUrl) - ? (imageUrl.split(/[\\/]/).pop() ?? - tSettings( - "background.video", - "Video background", - )) - : undefined, - title: isVideoWallpaperSource(imageUrl) - ? imageUrl.split(/[\\/]/).pop() - : undefined, - onClick: () => onWallpaperChange(imageUrl), - children: ( - - ), - }); - })} - - {imageWallpaperTiles.map((tile) => { - const isSelected = getWallpaperTileState( - tile.value, - tile.previewUrl, - ); - return renderWallpaperImageTile( - tile.previewUrl, - isSelected, - { - key: tile.key, - ariaLabel: tile.label, - title: tile.label, - onClick: () => onWallpaperChange(tile.value), - }, - ); - })} -
- - ) : backgroundTab === "video" ? ( -
- - -
- {customImages - .filter(isVideoWallpaperSource) - .map((videoUrl, idx) => { - const isSelected = getWallpaperTileState(videoUrl); - return renderWallpaperImageTile( - videoUrl, - isSelected, - { - key: `custom-video-${idx}`, - ariaLabel: - videoUrl.split(/[\\/]/).pop() ?? - "Video background", - title: videoUrl.split(/[\\/]/).pop(), - onClick: () => onWallpaperChange(videoUrl), - children: ( - - ), - }, - ); - })} - - {videoWallpaperTiles.map((wallpaper) => { - const isSelected = getWallpaperTileState( - wallpaper.value, - wallpaper.previewUrl, - ); - return renderWallpaperImageTile( - wallpaper.previewUrl, - isSelected, - { - key: wallpaper.key, - ariaLabel: wallpaper.label, - title: wallpaper.label, - onClick: () => - onWallpaperChange(wallpaper.value), - }, - ); - })} -
-
+ fileInputRef.current?.click() + : handleVideoUpload + } + onSelect={onWallpaperChange} + onRemove={handleRemoveCustomImage} + isSelected={getWallpaperTileState} + items={[ + ...customImages + .filter( + (url) => + isVideoWallpaperSource(url) === + (backgroundTab === "video"), + ) + .map((url, index) => ({ + key: `custom-${index}`, + value: url, + previewUrl: url, + label: isVideoWallpaperSource(url) + ? (url.split(/[\\/]/).pop() ?? + "Custom video wallpaper") + : `${tSettings("background.customWallpaper", "Custom wallpaper")} ${index + 1}`, + removable: true, + })), + ...(backgroundTab === "image" + ? imageWallpaperTiles + : videoWallpaperTiles), + ]} + /> + ) : backgroundTab === "color" ? (
@@ -2165,6 +2007,8 @@ export function SettingsPanel({
{tSettings("captions.generation", "Generation")} @@ -2201,7 +2045,7 @@ export function SettingsPanel({ value={autoCaptionSettings.language || "auto"} onValueChange={(value) => updateAutoCaptionSettings({ language: value })} > - + @@ -2216,7 +2060,7 @@ export function SettingsPanel({
{whisperModelDownloadStatus === "downloading" ? ( - @@ -2225,7 +2069,7 @@ export function SettingsPanel({ type="button" variant="outline" onClick={onDeleteWhisperSmallModel} - className="h-10 w-full px-4 text-sm" + className="h-9 w-full px-4 text-sm" > {tSettings("captions.deleteModel", "Delete Model")} @@ -2233,7 +2077,7 @@ export function SettingsPanel({ @@ -2243,7 +2087,7 @@ export function SettingsPanel({ variant="outline" onClick={onClearAutoCaptions} disabled={captionCueCount === 0} - className="h-10 w-full px-4 text-sm" + className="h-9 w-full px-4 text-sm" > {tSettings("captions.clearFull", "Clear Captions")} @@ -2254,7 +2098,7 @@ export function SettingsPanel({ type="button" onClick={onGenerateAutoCaptions} disabled={isGeneratingCaptions || !whisperModelPath} - className="h-10 w-full px-4 text-sm" + className="h-9 w-full px-4 text-sm" > {isGeneratingCaptions ? tSettings("captions.generating", "Generating...") @@ -2460,7 +2304,7 @@ export function SettingsPanel({
{t("common.app.language", "Language")}