mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:01:08 +02:00
🚸 feat(calendar): auto-scroll to current hour and hide tasks by default
- Hide tasks in calendar by default on app load (not persisted from sessions) - Auto-scroll to current hour when loading DayView, WeekView, MultiDayView - Center current hour in viewport for immediate visibility - Exclude task/sidebar settings from cloud sync to ensure clean initial state
This commit is contained in:
parent
bba696e241
commit
2200ed64e8
4 changed files with 94 additions and 3 deletions
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { viewStore } from '$lib/stores/view.svelte';
|
||||
import { eventsStore } from '$lib/stores/events.svelte';
|
||||
import { calendarsStore } from '$lib/stores/calendars.svelte';
|
||||
|
|
@ -124,6 +125,30 @@
|
|||
let dragPreviewHeight = $state(0);
|
||||
let dayColumnRef = $state<HTMLElement | null>(null);
|
||||
|
||||
// Scroll to current hour on mount
|
||||
onMount(() => {
|
||||
const scrollContainer = dayColumnRef?.parentElement;
|
||||
if (!scrollContainer) return;
|
||||
|
||||
// Use CSS variable for hour height (default 48px)
|
||||
const hourHeight =
|
||||
parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--hour-height')) ||
|
||||
48;
|
||||
const currentHour = new Date().getHours();
|
||||
const viewportHeight = scrollContainer.clientHeight;
|
||||
|
||||
// Calculate scroll position to center current hour in viewport
|
||||
// Account for firstVisibleHour (if hour filtering is enabled)
|
||||
const effectiveHour = Math.max(0, currentHour - firstVisibleHour);
|
||||
const scrollPosition = effectiveHour * hourHeight - viewportHeight / 2 + hourHeight / 2;
|
||||
|
||||
// Scroll to position (instant, not smooth, for initial load)
|
||||
scrollContainer.scrollTo({
|
||||
top: Math.max(0, scrollPosition),
|
||||
behavior: 'instant',
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Resize State
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { viewStore } from '$lib/stores/view.svelte';
|
||||
import { eventsStore } from '$lib/stores/events.svelte';
|
||||
import { calendarsStore } from '$lib/stores/calendars.svelte';
|
||||
|
|
@ -147,6 +148,30 @@
|
|||
// Reference to the days container for position calculations
|
||||
let daysContainerEl: HTMLDivElement;
|
||||
|
||||
// Scroll to current hour on mount
|
||||
onMount(() => {
|
||||
const scrollContainer = daysContainerEl?.parentElement;
|
||||
if (!scrollContainer) return;
|
||||
|
||||
// Use CSS variable for hour height (default 48px)
|
||||
const hourHeight =
|
||||
parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--hour-height')) ||
|
||||
48;
|
||||
const currentHour = new Date().getHours();
|
||||
const viewportHeight = scrollContainer.clientHeight;
|
||||
|
||||
// Calculate scroll position to center current hour in viewport
|
||||
// Account for firstVisibleHour (if hour filtering is enabled)
|
||||
const effectiveHour = Math.max(0, currentHour - firstVisibleHour);
|
||||
const scrollPosition = effectiveHour * hourHeight - viewportHeight / 2 + hourHeight / 2;
|
||||
|
||||
// Scroll to position (instant, not smooth, for initial load)
|
||||
scrollContainer.scrollTo({
|
||||
top: Math.max(0, scrollPosition),
|
||||
behavior: 'instant',
|
||||
});
|
||||
});
|
||||
|
||||
function getEventsForDay(day: Date): CalendarEvent[] {
|
||||
return getVisibleTimedEvents(
|
||||
eventsStore.getEventsForDay(day),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { viewStore } from '$lib/stores/view.svelte';
|
||||
import { eventsStore } from '$lib/stores/events.svelte';
|
||||
import { calendarsStore } from '$lib/stores/calendars.svelte';
|
||||
|
|
@ -147,6 +148,32 @@
|
|||
// Reference to the days container for position calculations
|
||||
let daysContainerEl: HTMLDivElement;
|
||||
|
||||
// Reference to the time grid (scroll container)
|
||||
let timeGridEl: HTMLDivElement;
|
||||
|
||||
// Scroll to current hour on mount
|
||||
onMount(() => {
|
||||
if (!timeGridEl) return;
|
||||
|
||||
// Use CSS variable for hour height (default 48px)
|
||||
const hourHeight =
|
||||
parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--hour-height')) ||
|
||||
48;
|
||||
const currentHour = new Date().getHours();
|
||||
const viewportHeight = timeGridEl.clientHeight;
|
||||
|
||||
// Calculate scroll position to center current hour in viewport
|
||||
// Account for firstVisibleHour (if hour filtering is enabled)
|
||||
const effectiveHour = Math.max(0, currentHour - firstVisibleHour);
|
||||
const scrollPosition = effectiveHour * hourHeight - viewportHeight / 2 + hourHeight / 2;
|
||||
|
||||
// Scroll to position (instant, not smooth, for initial load)
|
||||
timeGridEl.scrollTo({
|
||||
top: Math.max(0, scrollPosition),
|
||||
behavior: 'instant',
|
||||
});
|
||||
});
|
||||
|
||||
// Birthday Popover (using composable)
|
||||
const birthdayPopover = useBirthdayPopover();
|
||||
|
||||
|
|
@ -933,7 +960,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Time grid -->
|
||||
<div class="time-grid scrollbar-thin">
|
||||
<div class="time-grid scrollbar-thin" bind:this={timeGridEl}>
|
||||
<!-- Time column -->
|
||||
<div class="time-column">
|
||||
{#each hours as hour}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ const DEFAULT_SETTINGS: CalendarAppSettings = {
|
|||
showBirthdays: true,
|
||||
showBirthdayAge: true,
|
||||
showTasksInCalendar: false,
|
||||
sidebarCollapsed: false,
|
||||
sidebarCollapsed: true,
|
||||
quickViewPillViews: ['week', 'month', 'agenda'],
|
||||
customDayCount: 30,
|
||||
defaultEventDuration: 60,
|
||||
|
|
@ -131,6 +131,13 @@ const baseStore = createAppSettingsStore<CalendarAppSettings>(
|
|||
}
|
||||
);
|
||||
|
||||
// Always start with tasks/sidebar hidden when the app loads
|
||||
// (don't persist this from previous sessions)
|
||||
if (browser) {
|
||||
baseStore.set('showTasksInCalendar', false);
|
||||
baseStore.set('sidebarCollapsed', true);
|
||||
}
|
||||
|
||||
// Load settings from cloud
|
||||
function loadFromCloud(): Partial<CalendarAppSettings> | null {
|
||||
if (!userSettings.loaded) return null;
|
||||
|
|
@ -266,7 +273,14 @@ export const settingsStore = {
|
|||
if (!initialSyncDone) {
|
||||
const cloudSettings = loadFromCloud();
|
||||
if (cloudSettings && Object.keys(cloudSettings).length > 0) {
|
||||
baseStore.update(cloudSettings);
|
||||
// Exclude showTasksInCalendar and sidebarCollapsed from cloud sync
|
||||
// - always start with tasks hidden and sidebar collapsed
|
||||
const {
|
||||
showTasksInCalendar: _,
|
||||
sidebarCollapsed: __,
|
||||
...settingsWithoutTasks
|
||||
} = cloudSettings;
|
||||
baseStore.update(settingsWithoutTasks);
|
||||
} else {
|
||||
syncToCloud(baseStore.settings);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue