feat(web): wallpaper system + sticky PageHeader

Wallpaper system with four sources (predefined images, CSS gradients,
custom uploads via mana-media, and theme default). Configurable per-scene
or globally, with overlay controls (blur + opacity) and hover preview.

Adds sticky prop to shared PageHeader component and applies it across
themes, settings, credits, subscription, help, and profile pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-12 16:00:03 +02:00
parent a9c51517eb
commit 8c2f9306e9
22 changed files with 1557 additions and 66 deletions

View file

@ -28,6 +28,16 @@ export type {
StartPageConfig,
WeekStartDay,
GeneralSettings,
// Wallpaper Types
WallpaperSource,
WallpaperSourceNone,
WallpaperSourcePredefined,
WallpaperSourceGenerated,
WallpaperSourceUpload,
WallpaperSolid,
WallpaperGradient,
WallpaperOverlay,
WallpaperConfig,
} from './types';
// User Settings Constants

View file

@ -182,6 +182,68 @@ export interface ThemeStore {
initialize: () => () => void;
}
// ============================================================================
// Wallpaper / Background Types
// ============================================================================
/** No wallpaper — the theme's default bg-background color shows through. */
export interface WallpaperSourceNone {
type: 'none';
}
/** A bundled, predefined wallpaper image (e.g. "ocean-1"). */
export interface WallpaperSourcePredefined {
type: 'predefined';
id: string;
}
/** Solid color background for generated wallpapers. */
export interface WallpaperSolid {
type: 'solid';
color: string;
}
/** Gradient background for generated wallpapers. */
export interface WallpaperGradient {
type: 'gradient';
colors: string[];
angle?: number;
}
/** A CSS gradient or solid color generated client-side. Only parameters are stored. */
export interface WallpaperSourceGenerated {
type: 'generated';
params: WallpaperSolid | WallpaperGradient;
}
/** A user-uploaded image served by mana-media / MinIO. */
export interface WallpaperSourceUpload {
type: 'upload';
mediaId: string;
url: string;
}
/** All wallpaper source types. */
export type WallpaperSource =
| WallpaperSourceNone
| WallpaperSourcePredefined
| WallpaperSourceGenerated
| WallpaperSourceUpload;
/** Overlay applied on top of the wallpaper for readability. */
export interface WallpaperOverlay {
/** Backdrop blur in px (020, default 0). */
blur?: number;
/** Semi-transparent overlay darkness (00.6, default 0). */
opacity?: number;
}
/** Complete wallpaper configuration. */
export interface WallpaperConfig {
source: WallpaperSource;
overlay?: WallpaperOverlay;
}
// ============================================================================
// Accessibility (A11y) Types
// ============================================================================
@ -322,6 +384,8 @@ export interface GlobalSettings {
general: GeneralSettings;
/** Recently used emojis (shared across all apps) - max 16 */
recentEmojis?: string[];
/** Global wallpaper / background config (can be overridden per scene) */
wallpaper?: WallpaperConfig;
}
/**

View file

@ -267,6 +267,7 @@ export function createUserSettingsStore(config: UserSettingsStoreConfig): UserSe
},
},
recentEmojis: settings.recentEmojis ?? globalSettings.recentEmojis,
wallpaper: settings.wallpaper !== undefined ? settings.wallpaper : globalSettings.wallpaper,
};
saveToStorage();