StackedRouter: new router simulates app behaviour #45

Merged
Rubicon merged 18 commits from stacky into master 2024-11-18 10:35:30 +00:00
3 changed files with 44 additions and 108 deletions
Showing only changes of commit f0dadebfb6 - Show all commits

View file

@ -3,11 +3,9 @@ import {
Show,
onMount,
type ParentComponent,
children,
Suspense,
createRenderEffect,
} from "solid-js";
import { useDocumentTitle } from "../utils";
import { type mastodon } from "masto";
import Scaffold from "../material/Scaffold";
import {
AppBar,
@ -23,17 +21,11 @@ import ProfileMenuButton from "./ProfileMenuButton";
import Tabs from "../material/Tabs";
import Tab from "../material/Tab";
import { makeEventListener } from "@solid-primitives/event-listener";
import BottomSheet, {
HERO as BOTTOM_SHEET_HERO,
} from "../material/BottomSheet";
import { $settings } from "../settings/stores";
import { useStore } from "@nanostores/solid";
import { HeroSourceProvider, type HeroSource } from "../platform/anim";
import { setCache as setTootBottomSheetCache } from "./TootBottomSheet";
import TrendTimelinePanel from "./TrendTimelinePanel";
import TimelinePanel from "./TimelinePanel";
import { useSessions } from "../masto/clients";
import { useNavigator } from "../platform/StackedRouter";
const Home: ParentComponent = (props) => {
let panelList: HTMLDivElement;
@ -43,29 +35,17 @@ const Home: ParentComponent = (props) => {
const settings$ = useStore($settings);
const profiles = useSessions();
const profile = () => {
const all = profiles();
if (all.length > 0) {
return all[0].account.inf;
}
};
const client = () => {
const all = profiles();
return all?.[0]?.client;
};
const {pop, push} = useNavigator();
const [heroSrc, setHeroSrc] = createSignal<HeroSource>({});
const [panelOffset, setPanelOffset] = createSignal(0);
const prefetching = () => !settings$().prefetchTootsDisabled;
const [currentFocusOn, setCurrentFocusOn] = createSignal<HTMLElement[]>([]);
const [focusRange, setFocusRange] = createSignal([0, 0] as readonly [
number,
number,
]);
const child = children(() => props.children);
let scrollEventLockReleased = true;
const recalculateTabIndicator = () => {
@ -102,17 +82,17 @@ const Home: ParentComponent = (props) => {
}
};
const requestRecalculateTabIndicator = () => {
if (scrollEventLockReleased) {
requestAnimationFrame(recalculateTabIndicator);
}
};
createRenderEffect(() => {
makeEventListener(window, "resize", requestRecalculateTabIndicator);
});
onMount(() => {
makeEventListener(panelList, "scroll", () => {
if (scrollEventLockReleased) {
requestAnimationFrame(recalculateTabIndicator);
}
});
makeEventListener(window, "resize", () => {
if (scrollEventLockReleased) {
requestAnimationFrame(recalculateTabIndicator);
}
});
requestAnimationFrame(recalculateTabIndicator);
});
@ -135,30 +115,6 @@ const Home: ParentComponent = (props) => {
}
};
const openFullScreenToot = (
toot: mastodon.v1.Status,
srcElement?: HTMLElement,
reply?: boolean,
) => {
const p = profiles()[0];
const inf = p.account.inf ?? profile();
if (!inf) {
console.warn("no account info?");
return;
}
setHeroSrc((x) =>
Object.assign({}, x, { [BOTTOM_SHEET_HERO]: srcElement }),
);
const acct = `${inf.username}@${p.account.site}`;
setTootBottomSheetCache(acct, toot);
push(`/${encodeURIComponent(acct)}/toot/${toot.id}`, {
state: reply
? {
tootReply: true,
}
: undefined,
});
};
css`
.tab-panel {
@ -209,7 +165,7 @@ const Home: ParentComponent = (props) => {
class="responsive"
sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
>
<Tabs onFocusChanged={setCurrentFocusOn} offset={panelOffset()}>
<Tabs>
<Tab focus={isTabFocus(0)} onClick={[onTabClick, 0]}>
Home
</Tab>
@ -239,48 +195,40 @@ const Home: ParentComponent = (props) => {
</AppBar>
}
>
<HeroSourceProvider value={[heroSrc, setHeroSrc]}>
<TimeSourceProvider value={now}>
<Show when={!!client()}>
<div class="panel-list" ref={panelList!}>
<div class="tab-panel">
<div>
<TimelinePanel
client={client()}
name="home"
prefetch={prefetching()}
openFullScreenToot={openFullScreenToot}
/>
</div>
<TimeSourceProvider value={now}>
<Show when={!!client()}>
<div
class="panel-list"
ref={panelList!}
onScroll={requestRecalculateTabIndicator}
>
<div class="tab-panel">
<div>
<TimelinePanel
client={client()}
name="home"
prefetch={prefetching()}
/>
</div>
<div class="tab-panel">
<div>
<TrendTimelinePanel
client={client()}
openFullScreenToot={openFullScreenToot}
/>
</div>
</div>
<div class="tab-panel">
<div>
<TimelinePanel
client={client()}
name="public"
prefetch={prefetching()}
openFullScreenToot={openFullScreenToot}
/>
</div>
</div>
<div></div>
</div>
</Show>
</TimeSourceProvider>
<Suspense>
<BottomSheet open={!!child()} onClose={() => pop(1)}>
{child()}
</BottomSheet>
</Suspense>
</HeroSourceProvider>
<div class="tab-panel">
<div>
<TrendTimelinePanel client={client()} />
</div>
</div>
<div class="tab-panel">
<div>
<TimelinePanel
client={client()}
name="public"
prefetch={prefetching()}
/>
</div>
</div>
<div></div>
</div>
</Show>
</TimeSourceProvider>
</Scaffold>
</>
);

View file

@ -20,12 +20,6 @@ const TimelinePanel: Component<{
client: mastodon.rest.Client;
name: "home" | "public";
prefetch?: boolean;
openFullScreenToot: (
toot: mastodon.v1.Status,
srcElement?: HTMLElement,
reply?: boolean,
) => void;
}> = (props) => {
const [scrollLinked, setScrollLinked] = createSignal<HTMLElement>();

View file

@ -13,12 +13,6 @@ import TootList from "./TootList.jsx";
const TrendTimelinePanel: Component<{
client: mastodon.rest.Client;
openFullScreenToot: (
toot: mastodon.v1.Status,
srcElement?: HTMLElement,
reply?: boolean,
) => void;
}> = (props) => {
const [scrollLinked, setScrollLinked] = createSignal<HTMLElement>();
const [tl, snapshot, { refetch: refetchTimeline }] = createTimelineSnapshot(