~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
67 lines · 1.9 KB Raw History
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useState,
} from 'react';

const NavigationContext = createContext(() => {});

/**
 * Path routing over the History API. The site record serves index.html for
 * every unmatched path, so a reload or a shared link lands on the same screen a
 * click does.
 *
 * The query string is tracked alongside the path, because a space is addressed
 * by its AT-URI and that URI holds slashes. Carrying it as a parameter keeps
 * every screen a real, shareable page without encoding a path inside a path.
 */
export function useLocation() {
  const [href, setHref] = useState(
    () => window.location.pathname + window.location.search,
  );

  useEffect(() => {
    const onPop = () =>
      setHref(window.location.pathname + window.location.search);
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  const navigate = useCallback((next) => {
    window.history.pushState({}, '', next);
    setHref(next);
    window.scrollTo(0, 0);
  }, []);

  const url = new URL(href, window.location.origin);
  return { path: url.pathname, params: url.searchParams, navigate };
}

export function NavigationProvider({ navigate, children }) {
  return (
    <NavigationContext.Provider value={navigate}>
      {children}
    </NavigationContext.Provider>
  );
}

export function useNavigate() {
  return useContext(NavigationContext);
}

/**
 * The href for a screen: a path and the parameters that address what it shows.
 * @param {string} path
 * @param {Record<string, string|null|undefined>} params
 * @returns {string}
 */
export function href(path, params = {}) {
  const search = new URLSearchParams();
  for (const [key, value] of Object.entries(params)) {
    if (value) search.set(key, value);
  }
  const query = search.toString();
  return query ? `${path}?${query}` : path;
}