BottomSheet: first attempt for animation

This commit is contained in:
thislight 2024-08-12 17:25:03 +08:00
parent 1c0a83dbab
commit 2d7b931ef8
No known key found for this signature in database
GPG key ID: A50F9451AC56A63E
13 changed files with 196 additions and 20 deletions

View file

@ -34,16 +34,25 @@ import Tab from "../material/Tab";
import { Create as CreateTootIcon } from "@suid/icons-material";
import { useTimeline } from "../masto/timelines";
import { makeEventListener } from "@solid-primitives/event-listener";
import BottomSheet from "../material/BottomSheet";
import BottomSheet, {
HERO as BOTTOM_SHEET_HERO,
} from "../material/BottomSheet";
import { $settings } from "../settings/stores";
import { useStore } from "@nanostores/solid";
import { vibrate } from "../platform/hardware";
import PullDownToRefresh from "./PullDownToRefresh";
import { HeroSourceProvider, type HeroSource } from "../platform/anim";
import { useNavigate } from "@solidjs/router";
const TimelinePanel: Component<{
client: mastodon.rest.Client;
name: "home" | "public" | "trends";
prefetch?: boolean;
openFullScreenToot: (
toot: mastodon.v1.Status,
srcElement?: HTMLElement,
) => void;
}> = (props) => {
const [scrollLinked, setScrollLinked] = createSignal<HTMLElement>();
const [
@ -125,18 +134,22 @@ const TimelinePanel: Component<{
>
<For each={timeline}>
{(item, index) => {
let element: HTMLElement | undefined;
return (
<TootThread
ref={element}
status={item}
onBoost={(...args) => onBoost(index(), ...args)}
onBookmark={(...args) => onBookmark(index(), ...args)}
client={props.client}
expanded={item.id === expandedThreadId() ? 1 : 0}
onExpandChange={() =>
setExpandedThreadId(
item.id !== expandedThreadId() ? item.id : undefined,
)
}
onExpandChange={(x) => {
if (item.id !== expandedThreadId()) {
setExpandedThreadId(item.id);
} else if (x === 2){
props.openFullScreenToot(item, element);
}
}}
/>
);
}}
@ -185,7 +198,9 @@ const Home: ParentComponent = (props) => {
const sessions = useSessions();
const client = () => sessions()[0].client;
const [profile] = useAcctProfile(client);
const navigate = useNavigate();
const [heroSrc, setHeroSrc] = createSignal<HeroSource>({});
const [panelOffset, setPanelOffset] = createSignal(0);
const prefetching = () => !settings$().prefetchTootsDisabled;
const [currentFocusOn, setCurrentFocusOn] = createSignal<HTMLElement[]>([]);
@ -259,6 +274,22 @@ const Home: ParentComponent = (props) => {
}
};
const openFullScreenToot = (
toot: mastodon.v1.Status,
srcElement?: HTMLElement,
) => {
const p = sessions()[0];
const inf = p.account.inf ?? profile();
if (!inf) {
console.warn('no account info?')
return;
}
const rect = srcElement?.getBoundingClientRect();
setHeroSrc((x) => Object.assign({}, x, { [BOTTOM_SHEET_HERO]: rect }));
const acct = `${inf.username}@${p.account.site}`;
navigate(`/${encodeURIComponent(acct)}/${toot.id}`);
};
css`
.tab-panel {
overflow: visible auto;
@ -344,6 +375,7 @@ const Home: ParentComponent = (props) => {
client={client()}
name="home"
prefetch={prefetching()}
openFullScreenToot={openFullScreenToot}
/>
</div>
</div>
@ -353,6 +385,7 @@ const Home: ParentComponent = (props) => {
client={client()}
name="trends"
prefetch={prefetching()}
openFullScreenToot={openFullScreenToot}
/>
</div>
</div>
@ -362,13 +395,16 @@ const Home: ParentComponent = (props) => {
client={client()}
name="public"
prefetch={prefetching()}
openFullScreenToot={openFullScreenToot}
/>
</div>
</div>
<div></div>
</div>
</TimeSourceProvider>
<BottomSheet open={!!child()}>{child()}</BottomSheet>
<HeroSourceProvider value={[heroSrc, setHeroSrc]}>
<BottomSheet open={!!child()}>{child()}</BottomSheet>
</HeroSourceProvider>
</Scaffold>
</>
);

View file

@ -15,8 +15,6 @@ import {
untrack,
} from "solid-js";
import { css } from "solid-styled";
import { useHeroSource } from "../platform/anim";
import { Portal } from "solid-js/web";
import { createStore } from "solid-js/store";
import { IconButton, Toolbar } from "@suid/material";
import { ArrowLeft, ArrowRight, Close } from "@suid/icons-material";
@ -42,8 +40,6 @@ function clamp(input: number, min: number, max: number) {
const MediaViewer: ParentComponent<MediaViewerProps> = (props) => {
let rootRef: HTMLDialogElement;
const heroSource = useHeroSource();
const heroSourceEl = () => heroSource()[MEDIA_VIEWER_HEROSRC];
type State = {
ref?: HTMLElement;
media: mastodon.v1.MediaAttachment;

View file

@ -1,7 +1,23 @@
import { useParams } from "@solidjs/router";
import type { Component } from "solid-js";
import Scaffold from "../material/Scaffold";
import TootThread from "./TootThread";
import { AppBar, Toolbar } from "@suid/material";
import { Title } from "../material/typography";
const TootBottomSheet: Component = (props) => {
return <></>;
const params = useParams()
return <Scaffold
topbar={
<AppBar position="static">
<Toolbar variant="dense" sx={{paddingTop: "var(--safe-area-inset-top, 0px)"}}>
<Title>A Toot</Title>
</Toolbar>
</AppBar>
}
>
<p>{params.acct}/{params.id}</p>
</Scaffold>;
};
export default TootBottomSheet;

View file

@ -1,5 +1,5 @@
import type { mastodon } from "masto";
import { Show, createResource, createSignal, type Component } from "solid-js";
import { Show, createResource, createSignal, type Component, type Ref } from "solid-js";
import CompactToot from "./CompactToot";
import { useTimeSource } from "../platform/timesrc";
import RegularToot from "./RegularToot";
@ -7,6 +7,7 @@ import cardStyle from "../material/cards.module.css";
import { css } from "solid-styled";
type TootThreadProps = {
ref?: Ref<HTMLElement>,
status: mastodon.v1.Status;
client: mastodon.rest.Client;
expanded?: 0 | 1 | 2;
@ -70,6 +71,7 @@ const TootThread: Component<TootThreadProps> = (props) => {
return (
<article
ref={props.ref}
classList={{ "thread-line": !!inReplyTo(), expanded: expanded() > 0 }}
onClick={() => props.onExpandChange?.(nextExpandLevel[expanded()])}
>