.
This commit is contained in:
parent
d8f2407ddf
commit
9689bfcc18
23 changed files with 1815 additions and 955 deletions
|
|
@ -2,14 +2,31 @@ import { useCallback, useEffect, useState } from 'react';
|
|||
import type { UrlState } from './types';
|
||||
import { decodeState, encodeState } from './url-state';
|
||||
|
||||
/** The fragment is the durable source of truth. No local storage or server state. */
|
||||
const readLocation = () => decodeState(window.location.search || window.location.hash);
|
||||
const queryUrl = (query: string) => `${window.location.pathname}${query}`;
|
||||
|
||||
/** Readable query parameters are the durable source of truth. */
|
||||
export function useProject() {
|
||||
const [loaded, setLoaded] = useState(() => decodeState(window.location.hash));
|
||||
const [loaded, setLoaded] = useState(readLocation);
|
||||
useEffect(() => {
|
||||
const restore = () => setLoaded(decodeState(window.location.hash));
|
||||
const restore = () => {
|
||||
const next = readLocation();
|
||||
if (!next.error) {
|
||||
try {
|
||||
// Canonicalize editable queries and migrate existing fragment links
|
||||
// without creating an extra entry in browser history.
|
||||
const query = encodeState(next.state);
|
||||
if (query !== window.location.search || window.location.hash)
|
||||
window.history.replaceState(null, '', queryUrl(query));
|
||||
} catch (error) {
|
||||
next.error = error instanceof Error ? error.message : 'This plan could not be saved.';
|
||||
}
|
||||
}
|
||||
setLoaded(next);
|
||||
};
|
||||
window.addEventListener('hashchange', restore);
|
||||
window.addEventListener('popstate', restore);
|
||||
if (!window.location.hash) window.history.replaceState(null, '', encodeState(loaded.state));
|
||||
restore();
|
||||
return () => {
|
||||
window.removeEventListener('hashchange', restore);
|
||||
window.removeEventListener('popstate', restore);
|
||||
|
|
@ -19,10 +36,10 @@ export function useProject() {
|
|||
setLoaded((current) => {
|
||||
const next = transform(current.state);
|
||||
try {
|
||||
const hash = encodeState(next);
|
||||
if (hash !== window.location.hash)
|
||||
window.history[milestone ? 'pushState' : 'replaceState'](null, '', hash);
|
||||
const canonical = decodeState(hash).state;
|
||||
const query = encodeState(next);
|
||||
if (query !== window.location.search || window.location.hash)
|
||||
window.history[milestone ? 'pushState' : 'replaceState'](null, '', queryUrl(query));
|
||||
const canonical = decodeState(query).state;
|
||||
if (next.project === current.state.project) canonical.project = current.state.project;
|
||||
return { state: canonical, error: null };
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue