pi-mono/apps/p2/plugins/web-shell/web.tsx
Mario Zechner 05dc8d239d feat: add apps/p2 (imported from pi-private at 7dadff697)
p2 (Pi Mobile on Chord v2) moves from pi-private into pi as one commit. Root scripts that loop all workspaces
use --if-present; npm test, ./test.sh and the release script cover packages/* only (p2: cd apps/p2 && npm test);
sync-versions also updates apps' workspace pins.
2026-11-03 13:39:06 +00:00

53 lines
1.3 KiB
TypeScript

// App layout: the sidebar and main slots, the drawer on phones, Back/Forward navigation.
import { contribute, defineFacet } from "@p2/app/v1";
import {
AppLayout,
ComposerState,
closeLayers,
getNavigation,
NavigationContext,
NewSessionState,
Slots,
startNavigation,
} from "@p2/app/v1/web";
import { useEffect } from "react";
function App() {
const nav = getNavigation();
useEffect(() => startNavigation(), []);
useEffect(() => {
const wide = window.matchMedia("(min-width: 900px)");
const change = () => {
if (wide.matches && nav.route.layers.at(-1)?.kind === "drawer") closeLayers();
};
change();
wide.addEventListener("change", change);
const key = (event: KeyboardEvent) => {
if (event.key === "Escape" && !event.defaultPrevented && nav.route.layers.at(-1)?.kind === "drawer") {
event.preventDefault();
closeLayers();
}
};
window.addEventListener("keydown", key);
return () => {
wide.removeEventListener("change", change);
window.removeEventListener("keydown", key);
};
}, [nav]);
return (
<NavigationContext.Provider value={nav}>
<NewSessionState>
<ComposerState>
<AppLayout />
</ComposerState>
</NewSessionState>
</NavigationContext.Provider>
);
}
export default defineFacet((host) => {
contribute(host, "p2.web-shell", (self) => {
self.contribute(Slots, { app: App });
});
});