Compare commits

..

4 commits

Author SHA1 Message Date
thislight
85cb7ad081
App: try fix gap at bottom on iOS standalone
All checks were successful
/ depoly (push) Successful in 1m17s
2024-11-10 22:29:49 +08:00
thislight
8066f699bd
TootBottomSheet: test scrollable 2024-11-10 21:39:54 +08:00
thislight
34dd95e959
Settings: fix safe area insets emulation 2024-11-10 21:23:03 +08:00
thislight
7e698ebe4c
bump to v1.1.0 2024-11-10 16:56:41 +08:00
5 changed files with 112 additions and 70 deletions

View file

@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package",
"name": "tutu",
"version": "1.0.8",
"version": "1.1.0",
"description": "",
"private": true,
"type": "module",

View file

@ -10,6 +10,11 @@
overscroll-behavior-block: none;
}
body, #root {
min-height: 100vh;
min-height: 100dvh;
}
.custom-emoji {
width: 1em;
}

View file

@ -98,7 +98,14 @@ const safeAreaInsets: Record<string, SafeAreaInsets> = {
let screenOrientationCallback: (() => void) | undefined;
function removeSafeAreaEmulation(root: HTMLElement) {
for (const name of ["top", "right", "bottom", "left"]) {
root.style.removeProperty(`--safe-area-inset-${name}`);
}
}
function applySafeAreaEmulation(root: HTMLElement, insets: Inset) {
removeSafeAreaEmulation(root);
for (const key of Object.keys(insets) as (keyof Inset)[]) {
const value = insets[key];
if (!value || value === 0) continue;
@ -109,19 +116,22 @@ function applySafeAreaEmulation(root: HTMLElement, insets: Inset) {
function setupSafeAreaEmulation(name: string) {
const insets = safeAreaInsets[name];
const root = document.querySelector(":root")! as HTMLElement;
if (!insets) {
if (screenOrientationCallback) {
window.screen.orientation.removeEventListener(
"change",
screenOrientationCallback,
);
screenOrientationCallback = undefined;
}
for (const name of ["top", "right", "bottom", "left"]) {
root.style.removeProperty(`--safe-area-inset-${name}`);
}
} else {
if (screenOrientationCallback) {
window.screen.orientation.removeEventListener(
"change",
screenOrientationCallback,
);
screenOrientationCallback = undefined;
}
removeSafeAreaEmulation(root);
if (insets) {
screenOrientationCallback = () => {
console.debug(
`safe area emulation target: ${window.screen.orientation.type}`,
);
if (window.screen.orientation.type === "portrait-primary") {
console.debug("safe area emulation: protrait");
applySafeAreaEmulation(root, insets.protrait);
@ -138,6 +148,16 @@ function setupSafeAreaEmulation(name: string) {
}
}
if (import.meta.hot) {
import.meta.hot.accept((mod) => {
if (!mod) return;
if (screenOrientationCallback) {
mod["screenOrientationCallback"] = screenOrientationCallback;
setTimeout(screenOrientationCallback, 0);
}
});
}
type Strings = {
["lang.auto"]: Template<{ detected: string }>;
} & Record<string, string | undefined>;

View file

@ -0,0 +1,18 @@
.TootBottomSheet {
overflow: hidden;
.Scrollable {
padding-bottom: var(--safe-area-inset-bottom, 0);
overflow-y: auto;
overscroll-behavior-y: contain;
max-height: calc(100vh - var(--scaffold-topbar-height, 0px));
max-height: calc(100dvh - var(--scaffold-topbar-height, 0px));
}
.progress-line {
display: flex;
justify-content: center;
margin-top: 12px;
margin-bottom: 12px;
}
}

View file

@ -11,9 +11,7 @@ import {
import Scaffold from "../material/Scaffold";
import { AppBar, CircularProgress, IconButton, Toolbar } from "@suid/material";
import { Title } from "../material/typography";
import {
Close as CloseIcon,
} from "@suid/icons-material";
import { Close as CloseIcon } from "@suid/icons-material";
import { useSessionForAcctStr } from "../masto/clients";
import { resolveCustomEmoji } from "../masto/toot";
import RegularToot, { findElementActionable } from "./RegularToot";
@ -26,6 +24,7 @@ import TootComposer from "./TootComposer";
import { useDocumentTitle } from "../utils";
import { createTimelineControlsForArray } from "../masto/timelines";
import TootList from "./TootList";
import "./TootBottomSheet.css";
let cachedEntry: [string, mastodon.v1.Status] | undefined;
@ -245,64 +244,64 @@ const TootBottomSheet: Component = (props) => {
</Toolbar>
</AppBar>
}
class="TootBottomSheet"
>
<TimeSourceProvider value={time}>
<TootList
threads={ancestors.list}
onUnknownThread={ancestors.getPath}
onChangeToot={ancestors.set}
/>
<article>
<Show when={toot()}>
<RegularToot
id={`toot-${toot()!.id}`}
class={cards.card}
style={{
"scroll-margin-top":
"calc(var(--scaffold-topbar-height) + 20px)",
}}
status={toot()!}
actionable={!!actSession()}
evaluated={true}
onBookmark={onBookmark}
onRetoot={onBoost}
onFavourite={onFav}
onClick={handleMainTootClick}
></RegularToot>
</Show>
</article>
<Show when={session()!.account}>
<TootComposer
mentions={defaultMentions()}
profile={session().account!}
replyToDisplayName={toot()?.account?.displayName || ""}
client={session().client}
onSent={() => refetchContext()}
inReplyToId={remoteToot()?.reblog?.id ?? remoteToot()?.id}
<div
class="Scrollable"
>
<TimeSourceProvider value={time}>
<TootList
threads={ancestors.list}
onUnknownThread={ancestors.getPath}
onChangeToot={ancestors.set}
/>
</Show>
<Show when={tootContextErrorUncaught.loading}>
<div
style={{
display: "flex",
"justify-content": "center",
"margin-block": "12px",
}}
>
<CircularProgress style="width: 1.5em; height: 1.5em;" />
</div>
</Show>
<article>
<Show when={toot()}>
<RegularToot
id={`toot-${toot()!.id}`}
class={cards.card}
style={{
"scroll-margin-top":
"calc(var(--scaffold-topbar-height) + 20px)",
}}
status={toot()!}
actionable={!!actSession()}
evaluated={true}
onBookmark={onBookmark}
onRetoot={onBoost}
onFavourite={onFav}
onClick={handleMainTootClick}
></RegularToot>
</Show>
</article>
<TootList
threads={descendants.list}
onUnknownThread={descendants.getPath}
onChangeToot={descendants.set}
/>
</TimeSourceProvider>
<div style={{ height: "var(--safe-area-inset-bottom, 0)" }}></div>
<Show when={session()!.account}>
<TootComposer
mentions={defaultMentions()}
profile={session().account!}
replyToDisplayName={toot()?.account?.displayName || ""}
client={session().client}
onSent={() => refetchContext()}
inReplyToId={remoteToot()?.reblog?.id ?? remoteToot()?.id}
/>
</Show>
<Show when={tootContextErrorUncaught.loading}>
<div
class="progress-line"
>
<CircularProgress style="width: 1.5em; height: 1.5em;" />
</div>
</Show>
<TootList
threads={descendants.list}
onUnknownThread={descendants.getPath}
onChangeToot={descendants.set}
/>
</TimeSourceProvider>
</div>
</Scaffold>
);
};