* add ~platform/DocumentTitle * add titles for some pages
This commit is contained in:
parent
1115135380
commit
1c8a3f0bbb
12 changed files with 843 additions and 823 deletions
|
@ -8,13 +8,13 @@ import {
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { acceptAccountViaAuthCode } from "./stores";
|
import { acceptAccountViaAuthCode } from "./stores";
|
||||||
import { $settings } from "../settings/stores";
|
import { $settings } from "../settings/stores";
|
||||||
import { useDocumentTitle } from "../utils";
|
|
||||||
import cards from "~material/cards.module.css";
|
import cards from "~material/cards.module.css";
|
||||||
import { LinearProgress } from "@suid/material";
|
import { LinearProgress } from "@suid/material";
|
||||||
import Img from "~material/Img";
|
import Img from "~material/Img";
|
||||||
import { createRestAPIClient } from "masto";
|
import { createRestAPIClient } from "masto";
|
||||||
import { Title } from "~material/typography";
|
import { Title } from "~material/typography";
|
||||||
import { useNavigator } from "~platform/StackedRouter";
|
import { useNavigator } from "~platform/StackedRouter";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
type OAuth2CallbackParams = {
|
type OAuth2CallbackParams = {
|
||||||
code?: string;
|
code?: string;
|
||||||
|
@ -27,13 +27,12 @@ const MastodonOAuth2Callback: Component = () => {
|
||||||
const titleId = createUniqueId();
|
const titleId = createUniqueId();
|
||||||
const [params] = useSearchParams<OAuth2CallbackParams>();
|
const [params] = useSearchParams<OAuth2CallbackParams>();
|
||||||
const { push: navigate } = useNavigator();
|
const { push: navigate } = useNavigator();
|
||||||
const setDocumentTitle = useDocumentTitle("Back from Mastodon...");
|
|
||||||
const [siteImg, setSiteImg] = createSignal<{
|
const [siteImg, setSiteImg] = createSignal<{
|
||||||
src: string;
|
src: string;
|
||||||
srcset?: string;
|
srcset?: string;
|
||||||
blurhash: string;
|
blurhash: string;
|
||||||
}>();
|
}>();
|
||||||
const [siteTitle, setSiteTitle] = createSignal("the Mastodon server");
|
const [siteTitle, setSiteTitle] = createSignal("Mastodon");
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const onGoingOAuth2Process = $settings.get().onGoingOAuth2Process;
|
const onGoingOAuth2Process = $settings.get().onGoingOAuth2Process;
|
||||||
|
@ -42,7 +41,6 @@ const MastodonOAuth2Callback: Component = () => {
|
||||||
url: onGoingOAuth2Process,
|
url: onGoingOAuth2Process,
|
||||||
});
|
});
|
||||||
const ins = await client.v2.instance.fetch();
|
const ins = await client.v2.instance.fetch();
|
||||||
setDocumentTitle(`Back from ${ins.title}...`);
|
|
||||||
setSiteTitle(ins.title);
|
setSiteTitle(ins.title);
|
||||||
|
|
||||||
const srcset = [];
|
const srcset = [];
|
||||||
|
@ -93,6 +91,8 @@ const MastodonOAuth2Callback: Component = () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<DocumentTitle>Back from {siteTitle()}</DocumentTitle>
|
||||||
<div class={cards.layoutCentered}>
|
<div class={cards.layoutCentered}>
|
||||||
<div class={cards.card} aria-busy="true" aria-describedby={progressId}>
|
<div class={cards.card} aria-busy="true" aria-describedby={progressId}>
|
||||||
<LinearProgress
|
<LinearProgress
|
||||||
|
@ -129,6 +129,7 @@ const MastodonOAuth2Callback: Component = () => {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import {
|
||||||
Component,
|
Component,
|
||||||
Show,
|
Show,
|
||||||
createEffect,
|
createEffect,
|
||||||
createSelector,
|
|
||||||
createSignal,
|
createSignal,
|
||||||
createUniqueId,
|
createUniqueId,
|
||||||
onMount,
|
onMount,
|
||||||
|
@ -10,15 +9,14 @@ import {
|
||||||
import cards from "~material/cards.module.css";
|
import cards from "~material/cards.module.css";
|
||||||
import TextField from "~material/TextField.js";
|
import TextField from "~material/TextField.js";
|
||||||
import Button from "~material/Button.js";
|
import Button from "~material/Button.js";
|
||||||
import { useDocumentTitle } from "../utils";
|
|
||||||
import { Title } from "~material/typography";
|
import { Title } from "~material/typography";
|
||||||
import { css } from "solid-styled";
|
|
||||||
import { LinearProgress } from "@suid/material";
|
import { LinearProgress } from "@suid/material";
|
||||||
import { createRestAPIClient } from "masto";
|
import { createRestAPIClient } from "masto";
|
||||||
import { getOrRegisterApp } from "./stores";
|
import { getOrRegisterApp } from "./stores";
|
||||||
import { useSearchParams } from "@solidjs/router";
|
import { useSearchParams } from "@solidjs/router";
|
||||||
import { $settings } from "../settings/stores";
|
import { $settings } from "../settings/stores";
|
||||||
import "./SignIn.css";
|
import "./SignIn.css";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
type ErrorParams = {
|
type ErrorParams = {
|
||||||
error: string;
|
error: string;
|
||||||
|
@ -36,8 +34,6 @@ const SignIn: Component = () => {
|
||||||
const [serverUrlError, setServerUrlError] = createSignal(false);
|
const [serverUrlError, setServerUrlError] = createSignal(false);
|
||||||
const [targetSiteTitle, setTargetSiteTitle] = createSignal("");
|
const [targetSiteTitle, setTargetSiteTitle] = createSignal("");
|
||||||
|
|
||||||
useDocumentTitle("Sign In");
|
|
||||||
|
|
||||||
const serverUrl = () => {
|
const serverUrl = () => {
|
||||||
const url = rawServerUrl();
|
const url = rawServerUrl();
|
||||||
if (url.length === 0 || /^%w:/.test(url)) {
|
if (url.length === 0 || /^%w:/.test(url)) {
|
||||||
|
@ -115,6 +111,8 @@ const SignIn: Component = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<DocumentTitle>Sign In</DocumentTitle>
|
||||||
<main class="SignIn">
|
<main class="SignIn">
|
||||||
<Show when={params.error || params.errorDescription}>
|
<Show when={params.error || params.errorDescription}>
|
||||||
<div class={cards.card} style={{ "margin-bottom": "20px" }}>
|
<div class={cards.card} style={{ "margin-bottom": "20px" }}>
|
||||||
|
@ -164,6 +162,7 @@ const SignIn: Component = () => {
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,12 @@ import {
|
||||||
splitProps,
|
splitProps,
|
||||||
Component,
|
Component,
|
||||||
createSignal,
|
createSignal,
|
||||||
createEffect,
|
|
||||||
onMount,
|
onMount,
|
||||||
createRenderEffect,
|
createRenderEffect,
|
||||||
Show,
|
Show,
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { css } from "solid-styled";
|
import { css } from "solid-styled";
|
||||||
import { decode } from "blurhash";
|
import { decode } from "blurhash";
|
||||||
import { mergeClass } from "../utils";
|
|
||||||
|
|
||||||
type ImgProps = {
|
type ImgProps = {
|
||||||
blurhash?: string;
|
blurhash?: string;
|
||||||
|
@ -24,6 +22,7 @@ const Img: Component<ImgProps> = (props) => {
|
||||||
"blurhash",
|
"blurhash",
|
||||||
"keepBlur",
|
"keepBlur",
|
||||||
"class",
|
"class",
|
||||||
|
"classList",
|
||||||
"style",
|
"style",
|
||||||
]);
|
]);
|
||||||
const [isImgLoaded, setIsImgLoaded] = createSignal(false);
|
const [isImgLoaded, setIsImgLoaded] = createSignal(false);
|
||||||
|
@ -61,21 +60,21 @@ const Img: Component<ImgProps> = (props) => {
|
||||||
const onImgLoaded = () => {
|
const onImgLoaded = () => {
|
||||||
setIsImgLoaded(true);
|
setIsImgLoaded(true);
|
||||||
setImgSize({
|
setImgSize({
|
||||||
width: imgE.width,
|
width: imgE!.width,
|
||||||
height: imgE.height,
|
height: imgE!.height,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMetadataLoaded = () => {
|
const onMetadataLoaded = () => {
|
||||||
setImgSize({
|
setImgSize({
|
||||||
width: imgE.width,
|
width: imgE!.width,
|
||||||
height: imgE.height,
|
height: imgE!.height,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
setImgSize((x) => {
|
setImgSize((x) => {
|
||||||
const parent = imgE.parentElement;
|
const parent = imgE!.parentElement;
|
||||||
if (!parent) return x;
|
if (!parent) return x;
|
||||||
return x
|
return x
|
||||||
? x
|
? x
|
||||||
|
@ -87,7 +86,14 @@ const Img: Component<ImgProps> = (props) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={mergeClass(managed.class, "img-root")} style={managed.style}>
|
<div
|
||||||
|
classList={{
|
||||||
|
...managed.classList,
|
||||||
|
[managed.class ?? ""]: true,
|
||||||
|
"img-root": true,
|
||||||
|
}}
|
||||||
|
style={managed.style}
|
||||||
|
>
|
||||||
<Show when={managed.blurhash}>
|
<Show when={managed.blurhash}>
|
||||||
<canvas
|
<canvas
|
||||||
ref={(canvas) => {
|
ref={(canvas) => {
|
||||||
|
|
22
src/platform/DocumentTitle.tsx
Normal file
22
src/platform/DocumentTitle.tsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { children, createRenderEffect, onCleanup, type JSX } from "solid-js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Document title.
|
||||||
|
*
|
||||||
|
* The `children` must be plain text.
|
||||||
|
*/
|
||||||
|
export default function (props: { children?: JSX.Element }) {
|
||||||
|
let otitle: string | undefined;
|
||||||
|
|
||||||
|
createRenderEffect(() => (otitle = document.title));
|
||||||
|
|
||||||
|
const title = children(() => props.children);
|
||||||
|
|
||||||
|
createRenderEffect(
|
||||||
|
() => (document.title = (title.toArray() as string[]).join("")),
|
||||||
|
);
|
||||||
|
|
||||||
|
onCleanup(() => (document.title = otitle!));
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}
|
|
@ -65,6 +65,7 @@ import {
|
||||||
} from "../timelines/toots/ItemSelectionProvider";
|
} from "../timelines/toots/ItemSelectionProvider";
|
||||||
import AppTopBar from "~material/AppTopBar";
|
import AppTopBar from "~material/AppTopBar";
|
||||||
import type { Account } from "../accounts/stores";
|
import type { Account } from "../accounts/stores";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
const Profile: Component = () => {
|
const Profile: Component = () => {
|
||||||
const { pop } = useNavigator();
|
const { pop } = useNavigator();
|
||||||
|
@ -216,6 +217,8 @@ const Profile: Component = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<DocumentTitle>{profile()?.displayName ?? "Someone"}</DocumentTitle>
|
||||||
<Scaffold
|
<Scaffold
|
||||||
topbar={
|
topbar={
|
||||||
<AppTopBar
|
<AppTopBar
|
||||||
|
@ -389,7 +392,9 @@ const Profile: Component = () => {
|
||||||
aria-label={`${relationship()?.following ? "Unfollow" : "Follow"} on your home timeline`}
|
aria-label={`${relationship()?.following ? "Unfollow" : "Follow"} on your home timeline`}
|
||||||
>
|
>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar src={(session().account as Account).inf?.avatar}></Avatar>
|
<Avatar
|
||||||
|
src={(session().account as Account).inf?.avatar}
|
||||||
|
></Avatar>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
secondary={
|
secondary={
|
||||||
|
@ -565,6 +570,7 @@ const Profile: Component = () => {
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</Scaffold>
|
</Scaffold>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { useStore } from "@nanostores/solid";
|
||||||
import { $settings } from "./stores";
|
import { $settings } from "./stores";
|
||||||
import { useNavigator } from "~platform/StackedRouter";
|
import { useNavigator } from "~platform/StackedRouter";
|
||||||
import AppTopBar from "~material/AppTopBar";
|
import AppTopBar from "~material/AppTopBar";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
const ChooseLang: Component = () => {
|
const ChooseLang: Component = () => {
|
||||||
const { pop } = useNavigator();
|
const { pop } = useNavigator();
|
||||||
|
@ -53,6 +54,8 @@ const ChooseLang: Component = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<DocumentTitle>{t("Choose Language")}</DocumentTitle>
|
||||||
<Scaffold
|
<Scaffold
|
||||||
topbar={
|
topbar={
|
||||||
<AppTopBar>
|
<AppTopBar>
|
||||||
|
@ -114,6 +117,7 @@ const ChooseLang: Component = () => {
|
||||||
</List>
|
</List>
|
||||||
</List>
|
</List>
|
||||||
</Scaffold>
|
</Scaffold>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,10 @@ import { useStore } from "@nanostores/solid";
|
||||||
import { $settings } from "./stores";
|
import { $settings } from "./stores";
|
||||||
import { useNavigator } from "~platform/StackedRouter";
|
import { useNavigator } from "~platform/StackedRouter";
|
||||||
import AppTopBar from "~material/AppTopBar";
|
import AppTopBar from "~material/AppTopBar";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
const Motions: Component = () => {
|
const Motions: Component = () => {
|
||||||
const {pop} = useNavigator();
|
const { pop } = useNavigator();
|
||||||
const [t] = createTranslator(
|
const [t] = createTranslator(
|
||||||
(code) =>
|
(code) =>
|
||||||
import(`./i18n/${code}.json`) as Promise<{
|
import(`./i18n/${code}.json`) as Promise<{
|
||||||
|
@ -30,6 +31,8 @@ const Motions: Component = () => {
|
||||||
);
|
);
|
||||||
const settings = useStore($settings);
|
const settings = useStore($settings);
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<DocumentTitle>{t("motions")}</DocumentTitle>
|
||||||
<Scaffold
|
<Scaffold
|
||||||
topbar={
|
topbar={
|
||||||
<AppTopBar>
|
<AppTopBar>
|
||||||
|
@ -79,6 +82,7 @@ const Motions: Component = () => {
|
||||||
</li>
|
</li>
|
||||||
</List>
|
</List>
|
||||||
</Scaffold>
|
</Scaffold>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { $settings } from "./stores";
|
||||||
import { useStore } from "@nanostores/solid";
|
import { useStore } from "@nanostores/solid";
|
||||||
import { useNavigator } from "~platform/StackedRouter";
|
import { useNavigator } from "~platform/StackedRouter";
|
||||||
import AppTopBar from "~material/AppTopBar";
|
import AppTopBar from "~material/AppTopBar";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
const ChooseRegion: Component = () => {
|
const ChooseRegion: Component = () => {
|
||||||
const { pop } = useNavigator();
|
const { pop } = useNavigator();
|
||||||
|
@ -48,6 +49,8 @@ const ChooseRegion: Component = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<DocumentTitle>{t("Choose Region")}</DocumentTitle>
|
||||||
<Scaffold
|
<Scaffold
|
||||||
topbar={
|
topbar={
|
||||||
<AppTopBar>
|
<AppTopBar>
|
||||||
|
@ -101,6 +104,7 @@ const ChooseRegion: Component = () => {
|
||||||
</List>
|
</List>
|
||||||
</List>
|
</List>
|
||||||
</Scaffold>
|
</Scaffold>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ import { makeAcctText, useSessions } from "../masto/clients.js";
|
||||||
import { useNavigator } from "~platform/StackedRouter.jsx";
|
import { useNavigator } from "~platform/StackedRouter.jsx";
|
||||||
import AppTopBar from "~material/AppTopBar.jsx";
|
import AppTopBar from "~material/AppTopBar.jsx";
|
||||||
import MastodonLogo from "./MastodonLogo.jsx";
|
import MastodonLogo from "./MastodonLogo.jsx";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle.jsx";
|
||||||
|
|
||||||
type Inset = {
|
type Inset = {
|
||||||
top?: number;
|
top?: number;
|
||||||
|
@ -197,6 +198,8 @@ const Settings: Component = () => {
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<DocumentTitle>{t("Settings")}</DocumentTitle>
|
||||||
<Scaffold
|
<Scaffold
|
||||||
topbar={
|
topbar={
|
||||||
<AppTopBar>
|
<AppTopBar>
|
||||||
|
@ -416,6 +419,7 @@ const Settings: Component = () => {
|
||||||
)}
|
)}
|
||||||
</List>
|
</List>
|
||||||
</Scaffold>
|
</Scaffold>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {
|
||||||
createEffect,
|
createEffect,
|
||||||
useTransition,
|
useTransition,
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { useDocumentTitle } from "../utils";
|
|
||||||
import Scaffold from "~material/Scaffold";
|
import Scaffold from "~material/Scaffold";
|
||||||
import {
|
import {
|
||||||
ListItemSecondaryAction,
|
ListItemSecondaryAction,
|
||||||
|
@ -30,6 +29,7 @@ import {
|
||||||
import AppTopBar from "~material/AppTopBar";
|
import AppTopBar from "~material/AppTopBar";
|
||||||
import { createTranslator } from "~platform/i18n";
|
import { createTranslator } from "~platform/i18n";
|
||||||
import { useWindowSize } from "@solid-primitives/resize-observer";
|
import { useWindowSize } from "@solid-primitives/resize-observer";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
type StringRes = Record<
|
type StringRes = Record<
|
||||||
"tabs.home" | "tabs.trending" | "tabs.public" | "set.prefetch-toots",
|
"tabs.home" | "tabs.trending" | "tabs.public" | "set.prefetch-toots",
|
||||||
|
@ -38,7 +38,6 @@ type StringRes = Record<
|
||||||
|
|
||||||
const Home: ParentComponent = (props) => {
|
const Home: ParentComponent = (props) => {
|
||||||
let panelList: HTMLDivElement;
|
let panelList: HTMLDivElement;
|
||||||
useDocumentTitle("Timelines");
|
|
||||||
const [t] = createTranslator(
|
const [t] = createTranslator(
|
||||||
(code) => import(`./i18n/${code}.json`) as Promise<{ default: StringRes }>,
|
(code) => import(`./i18n/${code}.json`) as Promise<{ default: StringRes }>,
|
||||||
);
|
);
|
||||||
|
@ -179,6 +178,7 @@ const Home: ParentComponent = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<DocumentTitle>Timelines</DocumentTitle>
|
||||||
<Scaffold
|
<Scaffold
|
||||||
topbar={
|
topbar={
|
||||||
<AppTopBar>
|
<AppTopBar>
|
||||||
|
|
|
@ -14,7 +14,6 @@ import cards from "~material/cards.module.css";
|
||||||
import { css } from "solid-styled";
|
import { css } from "solid-styled";
|
||||||
import { createTimeSource, TimeSourceProvider } from "~platform/timesrc";
|
import { createTimeSource, TimeSourceProvider } from "~platform/timesrc";
|
||||||
import TootComposer from "./TootComposer";
|
import TootComposer from "./TootComposer";
|
||||||
import { useDocumentTitle } from "../utils";
|
|
||||||
import { createTimelineControlsForArray } from "../masto/timelines";
|
import { createTimelineControlsForArray } from "../masto/timelines";
|
||||||
import TootList from "./TootList";
|
import TootList from "./TootList";
|
||||||
import "./TootBottomSheet.css";
|
import "./TootBottomSheet.css";
|
||||||
|
@ -26,6 +25,7 @@ import ItemSelectionProvider, {
|
||||||
import AppTopBar from "~material/AppTopBar";
|
import AppTopBar from "~material/AppTopBar";
|
||||||
import { fetchStatus } from "../masto/statuses";
|
import { fetchStatus } from "../masto/statuses";
|
||||||
import { type Account } from "../accounts/stores";
|
import { type Account } from "../accounts/stores";
|
||||||
|
import DocumentTitle from "~platform/DocumentTitle";
|
||||||
|
|
||||||
const TootBottomSheet: Component = (props) => {
|
const TootBottomSheet: Component = (props) => {
|
||||||
const params = useParams<{ acct: string; id: string }>();
|
const params = useParams<{ acct: string; id: string }>();
|
||||||
|
@ -65,11 +65,11 @@ const TootBottomSheet: Component = (props) => {
|
||||||
() => tootContext()?.descendants,
|
() => tootContext()?.descendants,
|
||||||
);
|
);
|
||||||
|
|
||||||
useDocumentTitle(() => {
|
const documentTitle = () => {
|
||||||
const t = toot()?.reblog ?? toot();
|
const t = toot()?.reblog ?? toot();
|
||||||
const name = t?.account.displayName ?? "Someone";
|
const name = t?.account.displayName ?? "Someone";
|
||||||
return `${name}'s toot`;
|
return `${name}'s toot`;
|
||||||
});
|
};
|
||||||
|
|
||||||
const tootDisplayName = () => {
|
const tootDisplayName = () => {
|
||||||
const t = toot()?.reblog ?? toot();
|
const t = toot()?.reblog ?? toot();
|
||||||
|
@ -163,6 +163,7 @@ const TootBottomSheet: Component = (props) => {
|
||||||
}
|
}
|
||||||
class="TootBottomSheet"
|
class="TootBottomSheet"
|
||||||
>
|
>
|
||||||
|
<DocumentTitle>{documentTitle()}</DocumentTitle>
|
||||||
<div class="Scrollable">
|
<div class="Scrollable">
|
||||||
<TimeSourceProvider value={time}>
|
<TimeSourceProvider value={time}>
|
||||||
<ItemSelectionProvider value={selectionState}>
|
<ItemSelectionProvider value={selectionState}>
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import {
|
|
||||||
createRenderEffect,
|
|
||||||
onCleanup,
|
|
||||||
type Accessor,
|
|
||||||
} from "solid-js";
|
|
||||||
|
|
||||||
export function useDocumentTitle(newTitle?: string | Accessor<string>) {
|
|
||||||
const capturedTitle = document.title;
|
|
||||||
|
|
||||||
createRenderEffect(() => {
|
|
||||||
if (newTitle)
|
|
||||||
document.title = typeof newTitle === "string" ? newTitle : newTitle();
|
|
||||||
});
|
|
||||||
|
|
||||||
onCleanup(() => {
|
|
||||||
document.title = capturedTitle;
|
|
||||||
});
|
|
||||||
|
|
||||||
return (x: ((x: string) => string) | string) =>
|
|
||||||
(document.title = typeof x === "string" ? x : x(document.title));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mergeClass(c1: string | undefined, c2: string | undefined) {
|
|
||||||
if (!c1) {
|
|
||||||
return c2;
|
|
||||||
}
|
|
||||||
if (!c2) {
|
|
||||||
return c1;
|
|
||||||
}
|
|
||||||
return [c1, c2].join(" ");
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue