mirror of
https://github.com/priyanshujain/margin-calendar.git
synced 2026-10-02 11:07:04 +00:00
fix fold wakeup bug
This commit is contained in:
1 parent
9e7d3414d9
commit
c35202674d
5 files changed
+66
-26
No files matched your search
+14
-23
@@ -1,15 +1,15 @@
|
||||
// The wall clock, at the two granularities anything on the grid cares about: the minute the now
|
||||
// line moves on, and the hour the fit holds open around it.
|
||||
//
|
||||
// Both schedule off the clock rather than off an interval, so a tab that was asleep and a machine
|
||||
// that woke up catch up on the next tick instead of drifting further out every hour. A timer is
|
||||
// still a timer, though: one set before the lid closed can fire long after its wall-clock
|
||||
// deadline, and a hidden window's timers run late or not at all. So the window coming back, as a
|
||||
// focus or a visibility change, is read as a tick of its own.
|
||||
// Both are read off the clock once a minute rather than counted down to. A timer's deadline is
|
||||
// measured in time the machine spent awake, so one set for the top of the hour before the lid
|
||||
// closed is still waiting out the rest of that hour when it opens, however late it is by then.
|
||||
// Reading once a minute puts a minute on how far behind either can be; the window coming back, as
|
||||
// a focus or a visibility change, is read as a tick of its own so it is usually less.
|
||||
//
|
||||
// They are separate hooks because they are separate rerenders. The minute belongs to the one
|
||||
// component that draws the line; putting the fit on that tick would solve the whole axis sixty
|
||||
// times an hour to answer a question that changes once.
|
||||
// component that draws the line. The hour is read as often but only changes once an hour, and a
|
||||
// state set to the value it already holds rerenders nothing.
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -22,20 +22,12 @@ function hourStart(ms: number): number {
|
||||
return d.getTime();
|
||||
}
|
||||
|
||||
/** The next one. `setMinutes(60)` rolls the date over for us, daylight saving and all. */
|
||||
function nextHourStart(ms: number): number {
|
||||
const d = new Date(ms);
|
||||
d.setMinutes(60, 0, 0);
|
||||
return d.getTime();
|
||||
}
|
||||
|
||||
function useTick<T>(read: (now: number) => T, next: (now: number) => number): T {
|
||||
function useTick<T>(read: (now: number) => T): T {
|
||||
const [value, setValue] = useState(() => read(Date.now()));
|
||||
useEffect(() => {
|
||||
let timer = 0;
|
||||
const schedule = () => {
|
||||
const now = Date.now();
|
||||
timer = window.setTimeout(tick, Math.max(0, next(now) - now));
|
||||
timer = window.setTimeout(tick, MINUTE - (Date.now() % MINUTE));
|
||||
};
|
||||
const tick = () => {
|
||||
window.clearTimeout(timer);
|
||||
@@ -53,25 +45,24 @@ function useTick<T>(read: (now: number) => T, next: (now: number) => number): T
|
||||
document.removeEventListener("visibilitychange", woke);
|
||||
window.removeEventListener("focus", woke);
|
||||
};
|
||||
// Both callbacks are module-level functions in every caller, so there is nothing to rebind.
|
||||
}, [read, next]);
|
||||
// `read` is a module-level function in every caller, so there is nothing to rebind.
|
||||
}, [read]);
|
||||
return value;
|
||||
}
|
||||
|
||||
const now = (ms: number) => ms;
|
||||
const nextMinute = (ms: number) => ms + MINUTE - (ms % MINUTE);
|
||||
|
||||
/** Now, refreshed on every wall-clock minute. */
|
||||
export function useMinuteTick(): number {
|
||||
return useTick(now, nextMinute);
|
||||
return useTick(now);
|
||||
}
|
||||
|
||||
/**
|
||||
* The top of the hour it is now, refreshed when the clock turns over into the next one.
|
||||
* The top of the hour it is now, read every minute and changed once an hour.
|
||||
*
|
||||
* Returning the hour rather than the instant is what makes this cheap to depend on: the value is
|
||||
* identical for a whole hour, so a memo keyed on it recomputes once, when the answer changed.
|
||||
*/
|
||||
export function useHourStart(): number {
|
||||
return useTick(hourStart, nextHourStart);
|
||||
return useTick(hourStart);
|
||||
}
|
||||
Reference in new issue
Block a user