mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-28 07:37:43 +02:00
feat(shared-ui): unify ImmersiveModeToggle across Calendar, Contacts, and Todo apps
- Move ImmersiveModeToggle component from Calendar to shared-ui package - Add immersiveModeEnabled setting to Contacts and Todo settings stores - Update all three app layouts with F-key shortcut and conditional UI rendering - Consistent glass-pill styling on hover for toggle button 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a6d439360f
commit
893c6ef0fb
7 changed files with 246 additions and 121 deletions
|
|
@ -58,6 +58,10 @@ export interface TodoAppSettings {
|
|||
dailyGoal: number | null;
|
||||
/** Show productivity streak */
|
||||
showStreak: boolean;
|
||||
|
||||
// Immersive Mode
|
||||
/** Fullscreen mode - hides all UI elements */
|
||||
immersiveModeEnabled: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: TodoAppSettings = {
|
||||
|
|
@ -89,6 +93,9 @@ const DEFAULT_SETTINGS: TodoAppSettings = {
|
|||
pomodoroEnabled: false,
|
||||
dailyGoal: null,
|
||||
showStreak: false,
|
||||
|
||||
// Immersive Mode
|
||||
immersiveModeEnabled: false,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'todo-settings';
|
||||
|
|
@ -198,6 +205,19 @@ export const todoSettings = {
|
|||
return settings.showStreak;
|
||||
},
|
||||
|
||||
// Immersive Mode
|
||||
get immersiveModeEnabled() {
|
||||
return settings.immersiveModeEnabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle Immersive Mode (fullscreen, hide all UI)
|
||||
*/
|
||||
toggleImmersiveMode() {
|
||||
settings = { ...settings, immersiveModeEnabled: !settings.immersiveModeEnabled };
|
||||
saveSettings(settings);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize settings from localStorage
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { PillNavigation, QuickInputBar } from '@manacore/shared-ui';
|
||||
import { PillNavigation, QuickInputBar, ImmersiveModeToggle } from '@manacore/shared-ui';
|
||||
import {
|
||||
SplitPaneContainer,
|
||||
setSplitPanelContext,
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
} from '@manacore/shared-ui';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { userSettings } from '$lib/stores/user-settings.svelte';
|
||||
import { todoSettings } from '$lib/stores/settings.svelte';
|
||||
import { projectsStore } from '$lib/stores/projects.svelte';
|
||||
import { labelsStore } from '$lib/stores/labels.svelte';
|
||||
import { tasksStore } from '$lib/stores/tasks.svelte';
|
||||
|
|
@ -215,6 +216,18 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// F = Toggle Immersive Mode (no modifier keys)
|
||||
if (
|
||||
(event.key === 'f' || event.key === 'F') &&
|
||||
!event.ctrlKey &&
|
||||
!event.metaKey &&
|
||||
!event.shiftKey &&
|
||||
!event.altKey
|
||||
) {
|
||||
event.preventDefault();
|
||||
todoSettings.toggleImmersiveMode();
|
||||
}
|
||||
}
|
||||
|
||||
function handleModeChange(isSidebar: boolean) {
|
||||
|
|
@ -262,6 +275,9 @@
|
|||
// Initialize split-panel from URL/localStorage
|
||||
splitPanel.initialize();
|
||||
|
||||
// Initialize todo settings
|
||||
todoSettings.initialize();
|
||||
|
||||
// Load data
|
||||
await Promise.all([
|
||||
projectsStore.fetchProjects(),
|
||||
|
|
@ -328,66 +344,80 @@
|
|||
|
||||
<SplitPaneContainer>
|
||||
<div class="layout-container">
|
||||
<PillNavigation
|
||||
items={navItems}
|
||||
currentPath={$page.url.pathname}
|
||||
appName="Todo"
|
||||
homeRoute="/"
|
||||
onToggleTheme={handleToggleTheme}
|
||||
{isDark}
|
||||
{isSidebarMode}
|
||||
onModeChange={handleModeChange}
|
||||
{isCollapsed}
|
||||
onCollapsedChange={handleCollapsedChange}
|
||||
desktopPosition={userSettings.nav.desktopPosition}
|
||||
showThemeToggle={true}
|
||||
showThemeVariants={true}
|
||||
{themeVariantItems}
|
||||
{currentThemeVariantLabel}
|
||||
themeMode={theme.mode}
|
||||
onThemeModeChange={handleThemeModeChange}
|
||||
showLanguageSwitcher={true}
|
||||
{languageItems}
|
||||
{currentLanguageLabel}
|
||||
showLogout={authStore.isAuthenticated}
|
||||
onLogout={handleLogout}
|
||||
loginHref="/login"
|
||||
primaryColor="#8b5cf6"
|
||||
showAppSwitcher={true}
|
||||
{appItems}
|
||||
{userEmail}
|
||||
settingsHref="/settings"
|
||||
manaHref="/mana"
|
||||
profileHref="/profile"
|
||||
allAppsHref="/apps"
|
||||
onOpenInPanel={handleOpenInPanel}
|
||||
<!-- UI Elements (hidden in immersive mode) -->
|
||||
{#if !todoSettings.immersiveModeEnabled}
|
||||
<PillNavigation
|
||||
items={navItems}
|
||||
currentPath={$page.url.pathname}
|
||||
appName="Todo"
|
||||
homeRoute="/"
|
||||
onToggleTheme={handleToggleTheme}
|
||||
{isDark}
|
||||
{isSidebarMode}
|
||||
onModeChange={handleModeChange}
|
||||
{isCollapsed}
|
||||
onCollapsedChange={handleCollapsedChange}
|
||||
desktopPosition={userSettings.nav.desktopPosition}
|
||||
showThemeToggle={true}
|
||||
showThemeVariants={true}
|
||||
{themeVariantItems}
|
||||
{currentThemeVariantLabel}
|
||||
themeMode={theme.mode}
|
||||
onThemeModeChange={handleThemeModeChange}
|
||||
showLanguageSwitcher={true}
|
||||
{languageItems}
|
||||
{currentLanguageLabel}
|
||||
showLogout={authStore.isAuthenticated}
|
||||
onLogout={handleLogout}
|
||||
loginHref="/login"
|
||||
primaryColor="#8b5cf6"
|
||||
showAppSwitcher={true}
|
||||
{appItems}
|
||||
{userEmail}
|
||||
settingsHref="/settings"
|
||||
manaHref="/mana"
|
||||
profileHref="/profile"
|
||||
allAppsHref="/apps"
|
||||
onOpenInPanel={handleOpenInPanel}
|
||||
/>
|
||||
|
||||
<!-- Global Quick Input Bar -->
|
||||
<QuickInputBar
|
||||
onSearch={handleSearch}
|
||||
onSelect={handleSelect}
|
||||
{quickActions}
|
||||
placeholder="Neue Aufgabe oder suchen..."
|
||||
emptyText="Keine Aufgaben gefunden"
|
||||
searchingText="Suche..."
|
||||
onCreate={handleCreate}
|
||||
onParseCreate={handleParseCreate}
|
||||
createText="Erstellen"
|
||||
appIcon="todo"
|
||||
primaryColor="#8b5cf6"
|
||||
autoFocus={true}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<!-- Immersive Mode Toggle (always visible) -->
|
||||
<ImmersiveModeToggle
|
||||
isImmersive={todoSettings.immersiveModeEnabled}
|
||||
onToggle={() => todoSettings.toggleImmersiveMode()}
|
||||
/>
|
||||
|
||||
<main
|
||||
class="main-content bg-background"
|
||||
class:sidebar-mode={isSidebarMode && !isCollapsed}
|
||||
class:floating-mode={!isSidebarMode && !isCollapsed}
|
||||
class:immersive={todoSettings.immersiveModeEnabled}
|
||||
>
|
||||
<div class="content-wrapper" class:full-width={$page.url.pathname === '/kanban'}>
|
||||
<div
|
||||
class="content-wrapper"
|
||||
class:full-width={$page.url.pathname === '/kanban'}
|
||||
class:immersive={todoSettings.immersiveModeEnabled}
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Global Quick Input Bar -->
|
||||
<QuickInputBar
|
||||
onSearch={handleSearch}
|
||||
onSelect={handleSelect}
|
||||
{quickActions}
|
||||
placeholder="Neue Aufgabe oder suchen..."
|
||||
emptyText="Keine Aufgaben gefunden"
|
||||
searchingText="Suche..."
|
||||
onCreate={handleCreate}
|
||||
onParseCreate={handleParseCreate}
|
||||
createText="Erstellen"
|
||||
appIcon="todo"
|
||||
primaryColor="#8b5cf6"
|
||||
autoFocus={true}
|
||||
/>
|
||||
</div>
|
||||
</SplitPaneContainer>
|
||||
|
||||
|
|
@ -414,6 +444,19 @@
|
|||
padding-left: 180px;
|
||||
}
|
||||
|
||||
/* Immersive mode - fullscreen, no padding */
|
||||
.main-content.immersive {
|
||||
padding: 0 !important;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.content-wrapper.immersive {
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
max-width: 900px;
|
||||
margin-left: auto;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue