mirror of
https://github.com/priyanshujain/margin-calendar.git
synced 2026-10-04 20:17:04 +00:00
hold the hour it is now open through every strip, folds included
This commit is contained in:
1 parent
4b3ef9c62c
commit
9462b7920f
9 files changed
+186
-102
No files matched your search
+18
-45
@@ -20,15 +20,7 @@ import {
|
||||
type PointerEvent as ReactPointerEvent,
|
||||
} from "react";
|
||||
import { eventCreate, eventUpdate } from "../api/events";
|
||||
import {
|
||||
computeBounds,
|
||||
computeFit,
|
||||
timeToY,
|
||||
trimFolds,
|
||||
yToTime,
|
||||
type Bounds,
|
||||
type Fold,
|
||||
} from "../grid/fit";
|
||||
import { computeBounds, computeFit, timeToY, yToTime, type Bounds, type Fold } from "../grid/fit";
|
||||
import { loadBounds, saveBounds } from "../grid/folds";
|
||||
import { useCalendarView } from "../store/useCalendarView";
|
||||
import { notify } from "../store/useToast";
|
||||
@@ -52,9 +44,9 @@ import { GridGaps } from "./GridGaps";
|
||||
import { GridGhost } from "./GridGhost";
|
||||
import {
|
||||
MIN_EVENT_MINUTES,
|
||||
busyHours,
|
||||
clampMinutes,
|
||||
dayMinutes,
|
||||
heldHours,
|
||||
hourLabel,
|
||||
inBand,
|
||||
isVisible,
|
||||
@@ -240,21 +232,19 @@ export function GridView({ defaultCalendarId }: GridViewProps) {
|
||||
|
||||
const timed = useMemo(() => byDay.flat(), [byDay]);
|
||||
|
||||
// The hour the clock is in, when today is one of the columns.
|
||||
//
|
||||
// The axis is drawn from the events, and at nine in the evening the events are usually behind
|
||||
// you: the bounds end at six, the rest of the day is in the trailing strip, and the now line has
|
||||
// nowhere to land. So the hour you are in is taken into the bounds when it falls outside them.
|
||||
// One hour, and only the hour, so the axis gains a row rather than an evening.
|
||||
//
|
||||
// Keyed on the hour rather than the minute, because that is how often the answer changes. The
|
||||
// line itself moves every minute, on its own tick, in `GridNowLine`.
|
||||
// The hour the clock is in, when today is one of the columns. Keyed on the hour rather than the
|
||||
// minute, because that is how often the answer changes. The line itself moves every minute, on
|
||||
// its own tick, in `GridNowLine`.
|
||||
const hourStart = useHourStart();
|
||||
const nowBand = useMemo((): Bounds | null => {
|
||||
if (!days.includes(startOfDay(hourStart))) return null;
|
||||
const hour = new Date(hourStart).getHours();
|
||||
return { start: hour, end: hour + 1 };
|
||||
}, [days, hourStart]);
|
||||
const nowHour = useMemo(
|
||||
() => (days.includes(startOfDay(hourStart)) ? new Date(hourStart).getHours() : null),
|
||||
[days, hourStart],
|
||||
);
|
||||
|
||||
// The hours nothing may hide: every hour an event on screen covers, and the hour it is now, so
|
||||
// the now line always has a row to land in. They are carved out of every strip alike, the ones
|
||||
// outside the bounds and the ones you folded, and the bounds themselves stay the events' business.
|
||||
const held = useMemo(() => heldHours(timed, nowHour), [timed, nowHour]);
|
||||
|
||||
// Hysteresis needs the bounds it adopted last pass, so they live in a ref rather than in state:
|
||||
// paging a week must not reflow the axis, and a render loop through state would fight that.
|
||||
@@ -263,26 +253,9 @@ export function GridView({ defaultCalendarId }: GridViewProps) {
|
||||
const bounds = floor
|
||||
? { start: Math.min(auto.start, floor.start), end: Math.max(auto.end, floor.end) }
|
||||
: auto;
|
||||
// What the events and the user asked for is what the hysteresis remembers. The clock's hour is
|
||||
// a pin laid over the top of it every hour, so it never accumulates into the axis it pins.
|
||||
previous.current = bounds;
|
||||
// A fold hides empty hours. Any hour an event on screen covers is given back at full scale,
|
||||
// however it got there: typed into the palette, moved in the editor, or synced in from Google.
|
||||
const shown = trimFolds(folds, busyHours(timed));
|
||||
if (!nowBand) return computeFit({ bounds, folds: shown, viewportHeight: viewportH });
|
||||
|
||||
// Everything the widening reached over folds behind it. At half eleven at night the axis is
|
||||
// one row longer and one strip taller, rather than four rows of empty evening shorter.
|
||||
const reach: Fold[] = [
|
||||
{ start: nowBand.end, end: bounds.start },
|
||||
{ start: bounds.end, end: nowBand.start },
|
||||
];
|
||||
const axis = {
|
||||
start: Math.min(bounds.start, nowBand.start),
|
||||
end: Math.max(bounds.end, nowBand.end),
|
||||
};
|
||||
return computeFit({ bounds: axis, folds: [...shown, ...reach], viewportHeight: viewportH });
|
||||
}, [timed, folds, floor, viewportH, nowBand]);
|
||||
return computeFit({ bounds, folds, hold: held, viewportHeight: viewportH });
|
||||
}, [timed, folds, floor, viewportH, held]);
|
||||
|
||||
useEffect(() => {
|
||||
const signature = `${layout.bounds.start} ${layout.bounds.end}`;
|
||||
@@ -293,8 +266,8 @@ export function GridView({ defaultCalendarId }: GridViewProps) {
|
||||
|
||||
const publish = useGrid((s) => s.publish);
|
||||
useEffect(() => {
|
||||
if (viewportH > 0) publish(layout, days, timed);
|
||||
}, [publish, layout, days, timed, viewportH]);
|
||||
if (viewportH > 0) publish(layout, days, held);
|
||||
}, [publish, layout, days, held, viewportH]);
|
||||
|
||||
const todayMs = today();
|
||||
const todayIndex = days.findIndex((d) => d === todayMs);
|
||||
|
||||
Reference in new issue
Block a user