From ad7db8e86515df26f441112fa08013f25f9de5ce Mon Sep 17 00:00:00 2001 From: thislight Date: Sat, 23 Nov 2024 22:21:14 +0800 Subject: [PATCH 1/5] RegularToot: refactor, add env context --- src/timelines/RegularToot.tsx | 71 +++++++++---------- src/timelines/TootBottomSheet.tsx | 70 ++++++++++++++----- src/timelines/TootList.tsx | 94 +++++++++++++------------- src/timelines/toots/TootPoll.tsx | 42 ++++++------ src/timelines/toots/TootPollDialog.tsx | 10 ++- 5 files changed, 164 insertions(+), 123 deletions(-) diff --git a/src/timelines/RegularToot.tsx b/src/timelines/RegularToot.tsx index 68c0f72..3ddaeb3 100644 --- a/src/timelines/RegularToot.tsx +++ b/src/timelines/RegularToot.tsx @@ -7,6 +7,8 @@ import { createRenderEffect, createSignal, type Setter, + createContext, + useContext, } from "solid-js"; import tootStyle from "./toot.module.css"; import { formatRelative, parseISO } from "date-fns"; @@ -38,27 +40,38 @@ import BoostIcon from "./toots/BoostIcon"; import PreviewCard from "./toots/PreviewCard"; import TootPoll from "./toots/TootPoll"; -type TootActionGroupProps = { - onRetoot?: (value: T) => void; - onFavourite?: (value: T) => void; - onBookmark?: (value: T) => void; - onReply?: ( - value: T, +export type TootEnv = { + boost: (value: mastodon.v1.Status) => void; + favourite: (value: mastodon.v1.Status) => void; + bookmark: (value: mastodon.v1.Status) => void; + reply?: ( + value: mastodon.v1.Status, event: MouseEvent & { currentTarget: HTMLButtonElement }, ) => void; + vote: ( + status: mastodon.v1.Status, + votes: readonly number[], + ) => void | Promise; }; +const TootEnvContext = /* @__PURE__ */ createContext(); + +export const TootEnvProvider = TootEnvContext.Provider; + +export function useTootEnv() { + const env = useContext(TootEnvContext); + if (!env) { + throw new TypeError("environment not found, use TootEnvProvider to provide") + } + return env +} + type RegularTootProps = { status: mastodon.v1.Status; actionable?: boolean; evaluated?: boolean; thread?: "top" | "bottom" | "middle"; - - onVote?: (value: { - status: mastodon.v1.Status; - votes: readonly number[]; - }) => void | Promise; -} & TootActionGroupProps & +} & JSX.HTMLElementTags["article"]; function isolatedCallback(e: MouseEvent) { @@ -79,8 +92,9 @@ export function findRootToot(element: HTMLElement) { } function TootActionGroup( - props: TootActionGroupProps & { value: T }, + props: { value: T }, ) { + const {reply, boost, favourite, bookmark} = useTootEnv() let actGrpElement: HTMLDivElement; const toot = () => props.value; return ( @@ -89,10 +103,10 @@ function TootActionGroup( class={tootStyle.tootBottomActionGrp} onClick={isolatedCallback} > - + @@ -243,11 +257,10 @@ function onToggleReveal(setValue: Setter, event: Event) { */ const RegularToot: Component = (props) => { let rootRef: HTMLElement; - const [managed, managedActionGroup, pollProps, rest] = splitProps( + const {vote} = useTootEnv() + const [managed, rest] = splitProps( props, ["status", "lang", "class", "actionable", "evaluated", "thread"], - ["onRetoot", "onFavourite", "onBookmark", "onReply"], - ["onVote"], ); const now = useTimeSource(); const status = () => managed.status; @@ -361,18 +374,8 @@ const RegularToot: Component = (props) => { pollProps.onVote?.({ status: status(), votes })} + value={toot().poll!} + status={toot()} /> @@ -380,7 +383,7 @@ const RegularToot: Component = (props) => { class={cardStyle.cardNoPad} style={{ "margin-top": "8px" }} /> - + diff --git a/src/timelines/TootBottomSheet.tsx b/src/timelines/TootBottomSheet.tsx index d38d34f..09465db 100644 --- a/src/timelines/TootBottomSheet.tsx +++ b/src/timelines/TootBottomSheet.tsx @@ -13,7 +13,10 @@ import { Title } from "~material/typography"; import { Close as CloseIcon } from "@suid/icons-material"; import { useSessionForAcctStr } from "../masto/clients"; import { resolveCustomEmoji } from "../masto/toot"; -import RegularToot, { findElementActionable } from "./RegularToot"; +import RegularToot, { + findElementActionable, + TootEnvProvider, +} from "./RegularToot"; import type { mastodon } from "masto"; import cards from "~material/cards.module.css"; import { css } from "solid-styled"; @@ -169,6 +172,33 @@ const TootBottomSheet: Component = (props) => { return Array.from(new Set(values).keys()); }; + const vote = async (status: mastodon.v1.Status, votes: readonly number[]) => { + const client = session()?.client; + if (!client) return; + + const toot = status.reblog ?? status; + if (!toot.poll) return; + + const npoll = await client.v1.polls.$select(toot.poll.id).votes.create({ + choices: votes, + }); + + if (status.reblog) { + setRemoteToot({ + ...status, + reblog: { + ...status.reblog, + poll: npoll, + }, + }); + } else { + setRemoteToot({ + ...status, + poll: npoll, + }); + } + }; + const handleMainTootClick = ( event: MouseEvent & { currentTarget: HTMLElement }, ) => { @@ -255,23 +285,29 @@ const TootBottomSheet: Component = (props) => {
- + > + +
diff --git a/src/timelines/TootList.tsx b/src/timelines/TootList.tsx index e72c360..3408e0e 100644 --- a/src/timelines/TootList.tsx +++ b/src/timelines/TootList.tsx @@ -14,6 +14,7 @@ import { setCache as setTootBottomSheetCache } from "./TootBottomSheet"; import RegularToot, { findElementActionable, findRootToot, + TootEnvProvider, } from "./RegularToot"; import cardStyle from "~material/cards.module.css"; import type { ThreadNode } from "../masto/timelines"; @@ -232,13 +233,10 @@ const TootList: Component<{ openFullScreenToot(status, element, true); }; - const vote = async ({ - status, - votes, - }: { - status: mastodon.v1.Status; - votes: readonly number[]; - }) => { + const vote = async ( + status: mastodon.v1.Status, + votes: readonly number[] + ) => { const client = session()?.client; if (!client) return; @@ -263,7 +261,6 @@ const TootList: Component<{ poll: npoll, }); } - }; return ( @@ -273,49 +270,50 @@ const TootList: Component<{ return

Oops: {String(err)}

; }} > -
- - {(threadId, threadIdx) => { - const thread = createMemo(() => - props.onUnknownThread(threadId())?.reverse(), - ); + +
+ + {(threadId, threadIdx) => { + const thread = createMemo(() => + props.onUnknownThread(threadId())?.reverse(), + ); - const threadLength = () => thread()?.length ?? 0; + const threadLength = () => thread()?.length ?? 0; - return ( - - {(threadNode, index) => { - const status = () => threadNode().value; + return ( + + {(threadNode, index) => { + const status = () => threadNode().value; - return ( - 1 - ? positionTootInThread(index, threadLength()) - : undefined - } - class={cardStyle.card} - evaluated={checkIsExpended(status())} - actionable={checkIsExpended(status())} - onBookmark={onBookmark} - onRetoot={toggleBoost} - onFavourite={toggleFavourite} - onReply={reply} - onVote={vote} - onClick={[onItemClick, status()]} - /> - ); - }} - - ); - }} - -
+ return ( + 1 + ? positionTootInThread(index, threadLength()) + : undefined + } + class={cardStyle.card} + evaluated={checkIsExpended(status())} + actionable={checkIsExpended(status())} + onClick={[onItemClick, status()]} + /> + ); + }} +
+ ); + }} + +
+ ); }; diff --git a/src/timelines/toots/TootPoll.tsx b/src/timelines/toots/TootPoll.tsx index ce972b0..a148fcb 100644 --- a/src/timelines/toots/TootPoll.tsx +++ b/src/timelines/toots/TootPoll.tsx @@ -28,21 +28,17 @@ import { useTimeSource } from "~platform/timesrc"; import { useDateFnLocale } from "~platform/i18n"; import TootPollDialog from "./TootPollDialog"; import { ANIM_CURVE_STD } from "~material/theme"; +import { useTootEnv } from "../RegularToot"; type TootPollProps = { - options: Readonly; - multiple?: boolean; - votesCount: number; - expired?: boolean; - expiredAt?: Date; - voted?: boolean; - ownVotes?: readonly number[]; - - onVote(votes: readonly number[]): void | Promise; + value: mastodon.v1.Poll + status: mastodon.v1.Status }; const TootPoll: Component = (props) => { let list: HTMLUListElement; + const {vote}= useTootEnv() + const now = useTimeSource(); const dateFnLocale = useDateFnLocale(); const [mustShowResult, setMustShowResult] = createSignal(); @@ -50,24 +46,26 @@ const TootPoll: Component = (props) => { const [initialVote, setInitialVote] = createSignal(0); + const poll = () => props.value + const isShowResult = () => { const n = mustShowResult(); if (typeof n !== "undefined") { return n; } - return props.expired || props.voted; + return poll().expired || poll().voted; }; const isOwnVote = createSelector( - () => props.ownVotes, + () => poll().ownVotes, (idx: number, votes) => votes?.includes(idx) || false, ); const openVote = (i: number, event: Event) => { event.stopPropagation(); - if (props.expired || props.voted) { + if (poll().expired || poll().voted) { return; } @@ -100,13 +98,13 @@ const TootPoll: Component = (props) => { return (
- {props.votesCount} votes in total - + {poll().votesCount} votes in total + Poll is ended
- + {(option, index) => { return ( <> @@ -140,7 +138,7 @@ const TootPoll: Component = (props) => { = (props) => { - + - {isBefore(now(), props.expiredAt!) ? "Expire in" : "Expired"} + {isBefore(now(), poll().expiresAt!) ? "Expire in" : "Expired"} - - + - + diff --git a/src/timelines/TootList.tsx b/src/timelines/TootList.tsx index 3408e0e..b35dcce 100644 --- a/src/timelines/TootList.tsx +++ b/src/timelines/TootList.tsx @@ -6,6 +6,7 @@ import { createSelector, Index, createMemo, + For, } from "solid-js"; import { type mastodon } from "masto"; import { vibrate } from "~platform/hardware"; @@ -278,10 +279,10 @@ const TootList: Component<{ vote: vote }}>
- + {(threadId, threadIdx) => { const thread = createMemo(() => - props.onUnknownThread(threadId())?.reverse(), + props.onUnknownThread(threadId)?.reverse(), ); const threadLength = () => thread()?.length ?? 0; @@ -311,7 +312,7 @@ const TootList: Component<{ ); }} - +
diff --git a/src/timelines/toot.module.css b/src/timelines/toot.module.css index bb10964..1f68542 100644 --- a/src/timelines/toot.module.css +++ b/src/timelines/toot.module.css @@ -17,10 +17,6 @@ border-radius: 0; } - &>.toot { - box-shadow: none; - } - time { color: var(--tutu-color-secondary-text-on-surface); } @@ -89,41 +85,6 @@ background-color: var(--tutu-color-surface-d); } -.toot.compact { - display: grid; - grid-template-columns: auto 1fr; - gap: 8px; - row-gap: 0; - padding-block: var(--card-gut, 16px); - padding-inline: var(--card-pad, 16px); - - > :first-child { - grid-row: 1/3; - } - - > :last-child { - grid-column: 2 /3; - } -} - -.compactAuthorGroup { - display: flex; - gap: 8px; - align-items: center; - margin-bottom: 8px; - flex-flow: row wrap; - justify-content: flex-end; - - >.compactAuthorUsername { - color: var(--tutu-color-secondary-text-on-surface); - flex-grow: 1; - } - - >time { - color: var(--tutu-color-secondary-text-on-surface); - } -} - .tootRetootGrp { display: flex; gap: 0.25em; @@ -134,44 +95,3 @@ margin-right: 0.25em; } } - -.tootBottomActionGrp { - composes: cardGutSkip from "~material/cards.module.css"; - padding-block: calc((var(--card-gut) - 10px) / 2); - - animation: 225ms var(--tutu-anim-curve-std) tootBottomExpanding; - display: flex; - flex-flow: row wrap; - justify-content: space-evenly; - - >button { - color: var(--tutu-color-on-surface); - padding: 10px 8px; - - >svg { - font-size: 20px; - } - } -} - -.tootActionWithCount { - display: flex; - align-items: center; - gap: 8px; -} - -.tootAction { - display: flex; - align-items: center; - justify-content: center; -} - -@keyframes tootBottomExpanding { - 0% { - opacity: 0; - } - - 100% { - opacity: 1; - } -} \ No newline at end of file diff --git a/src/timelines/toots/TootActionGroup.css b/src/timelines/toots/TootActionGroup.css new file mode 100644 index 0000000..b82432c --- /dev/null +++ b/src/timelines/toots/TootActionGroup.css @@ -0,0 +1,41 @@ +.TootActionGroup { + padding-block: calc((var(--card-gut) - 10px) / 2); + contain: layout style; + + animation: 225ms var(--tutu-anim-curve-std) TootActionGroup_fade-in; + display: flex; + flex-flow: row wrap; + justify-content: space-evenly; + + >button { + color: var(--tutu-color-on-surface); + padding: 10px 8px; + + >svg { + font-size: 20px; + } + } + + >* { + display: flex; + align-items: center; + } + + >.with-count { + gap: 8px; + } + + >.plain { + justify-content: center; + } +} + +@keyframes TootActionGroup_fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} \ No newline at end of file diff --git a/src/timelines/toots/TootActionGroup.tsx b/src/timelines/toots/TootActionGroup.tsx new file mode 100644 index 0000000..fef75ef --- /dev/null +++ b/src/timelines/toots/TootActionGroup.tsx @@ -0,0 +1,89 @@ +import type { mastodon } from "masto"; +import { useTootEnv } from "../RegularToot"; +import { Button } from "@suid/material"; +import { Show } from "solid-js"; +import { + Bookmark, + BookmarkAddOutlined, + Repeat, + ReplyAll, + Share, + Star, + StarOutline, +} from "@suid/icons-material"; +import { canShare, share } from "~platform/share"; +import "./TootActionGroup.css"; + +async function shareContent(toot: mastodon.v1.Status) { + return await share({ + url: toot.url ?? undefined, + }); +} + +function isolatedCallback(e: MouseEvent) { + e.stopPropagation(); +} + +function TootActionGroup(props: { + value: T; + class?: string; +}) { + const { reply, boost, favourite, bookmark } = useTootEnv(); + let actGrpElement: HTMLDivElement; + const toot = () => props.value; + return ( +
+ + + + + + + + + + +
+ ); +} + +export default TootActionGroup; From 9fe86d12b0e9b81a70c8e3881a9040e0a84e4d0b Mon Sep 17 00:00:00 2001 From: thislight Date: Sat, 23 Nov 2024 23:36:51 +0800 Subject: [PATCH 3/5] i18n: optimize performance --- src/App.tsx | 23 +++++++-- src/platform/i18n.tsx | 111 ++++++++++++++++-------------------------- 2 files changed, 60 insertions(+), 74 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8f7ba44..e7ca588 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import { Route, Router } from "@solidjs/router"; +import { Route } from "@solidjs/router"; import { ThemeProvider } from "@suid/material"; import { Component, @@ -17,7 +17,12 @@ import { } from "./masto/clients.js"; import { $accounts, updateAcctInf } from "./accounts/stores.js"; import { useStore } from "@nanostores/solid"; -import { DateFnScope, useLanguage } from "./platform/i18n.jsx"; +import { + AppLocaleProvider, + createCurrentLanguage, + createCurrentRegion, + createDateFnLocaleResource, +} from "./platform/i18n.jsx"; import { useRegisterSW } from "virtual:pwa-register/solid"; import { isJSONRPCResult, @@ -67,7 +72,9 @@ const Routing: Component = () => { const App: Component = () => { const theme = useRootTheme(); const accts = useStore($accounts); - const lang = useLanguage(); + const lang = createCurrentLanguage(); + const region = createCurrentRegion(); + const dateFnLocale = createDateFnLocaleResource(region); const [serviceWorker, setServiceWorker] = createSignal< ServiceWorker | undefined >(undefined, { name: "serviceWorker" }); @@ -150,7 +157,13 @@ const App: Component = () => { }} > - + { - + ); diff --git a/src/platform/i18n.tsx b/src/platform/i18n.tsx index ade3868..b64b920 100644 --- a/src/platform/i18n.tsx +++ b/src/platform/i18n.tsx @@ -1,12 +1,12 @@ import { - ParentComponent, + catchError, createContext, createMemo, createResource, useContext, } from "solid-js"; import { match } from "@formatjs/intl-localematcher"; -import { Accessor, createEffect, createSignal } from "solid-js"; +import { Accessor } from "solid-js"; import { $settings } from "../settings/stores"; import { enGB } from "date-fns/locale/en-GB"; import { useStore } from "@nanostores/solid"; @@ -17,13 +17,6 @@ import { type Template, } from "@solid-primitives/i18n"; -async function synchronised( - name: string, - callback: () => Promise | void, -): Promise { - await navigator.locks.request(name, callback); -} - export const SUPPORTED_LANGS = ["en", "zh-Hans"] as const; export const SUPPORTED_REGIONS = ["en_US", "en_GB", "zh_CN"] as const; @@ -38,14 +31,6 @@ export function autoMatchLangTag() { return match(Array.from(navigator.languages), SUPPORTED_LANGS, DEFAULT_LANG); } -const DateFnLocaleCx = /* __@PURE__ */ createContext>( - () => enGB, -); - -const cachedDateFnLocale: Record = { - enGB, -}; - export function autoMatchRegion() { const specifiers = navigator.languages.map((x) => x.split("-")); @@ -70,7 +55,7 @@ export function autoMatchRegion() { return "en_GB"; } -export function useRegion() { +export function createCurrentRegion() { const appSettings = useStore($settings); return createMemo( @@ -100,53 +85,6 @@ async function importDateFnLocale(tag: string): Promise { } } -/** - * Provides runtime values and fetch dependencies for date-fns locale - */ -export const DateFnScope: ParentComponent = (props) => { - const [dateFnLocale, setDateFnLocale] = createSignal(enGB, { - name: "dateFnLocale", - }); - const region = useRegion(); - - createEffect(() => { - const dateFnLocaleName = region(); - - if (cachedDateFnLocale[dateFnLocaleName]) { - setDateFnLocale(cachedDateFnLocale[dateFnLocaleName]); - } else { - synchronised("i18n-wrapper-load-date-fns-locale", async () => { - if (cachedDateFnLocale[dateFnLocaleName]) { - setDateFnLocale(cachedDateFnLocale[dateFnLocaleName]); - return; - } - const target = `date-fns/locale/${dateFnLocaleName}`; - try { - const mod = await importDateFnLocale(dateFnLocaleName); - cachedDateFnLocale[dateFnLocaleName] = mod; - setDateFnLocale(mod); - } catch (reason) { - console.error( - { - act: "load-date-fns-locale", - stat: "failed", - reason, - target, - }, - "failed to load date-fns locale", - ); - } - }); - } - }); - - return ( - - {props.children} - - ); -}; - /** * Get the {@link Locale} object for date-fns. * @@ -155,11 +93,11 @@ export const DateFnScope: ParentComponent = (props) => { * @returns Accessor for Locale */ export function useDateFnLocale(): Accessor { - const cx = useContext(DateFnLocaleCx); - return cx; + const { dateFn } = useAppLocale(); + return dateFn; } -export function useLanguage() { +export function createCurrentLanguage() { const settings = useStore($settings); return () => settings().language || autoMatchLangTag(); } @@ -179,7 +117,7 @@ type MergedImportedModule = T extends [] export function createStringResource< T extends ImportFn | undefined>>[], >(...importFns: T) { - const language = useLanguage(); // TODO: this function costs to much, provide a global cache + const language = createCurrentLanguage(); const cache: Record> = {}; return createResource( @@ -209,3 +147,38 @@ export function createTranslator< return [translator(res[0], resolveTemplate), res] as const; } + +export type AppLocale = { + dateFn: () => Locale; + language: () => string; + region: () => string; +}; + +const AppLocaleContext = /* @__PURE__ */ createContext(); + +export const AppLocaleProvider = AppLocaleContext.Provider; + +export function useAppLocale() { + const l = useContext(AppLocaleContext); + if (!l) { + throw new TypeError("app locale not found"); + } + return l; +} + +export function createDateFnLocaleResource(region: () => string) { + const [localeUncaught] = createResource( + region, + async (region) => { + return await importDateFnLocale(region); + }, + { initialValue: enGB }, + ); + + return createMemo( + () => + catchError(localeUncaught, (reason) => { + console.error("fetch date-fns locale", reason); + }) ?? enGB, + ); +} From 6895367fada4e3f28327d7557317f3d23344c237 Mon Sep 17 00:00:00 2001 From: thislight Date: Sat, 23 Nov 2024 23:44:34 +0800 Subject: [PATCH 4/5] RegularToot: remove css module --- src/timelines/RegularToot.css | 78 +++++++++++++++++++++++++++++++++++ src/timelines/RegularToot.tsx | 76 +++++++--------------------------- src/timelines/toot.module.css | 45 -------------------- 3 files changed, 93 insertions(+), 106 deletions(-) create mode 100644 src/timelines/RegularToot.css diff --git a/src/timelines/RegularToot.css b/src/timelines/RegularToot.css new file mode 100644 index 0000000..d7a50c3 --- /dev/null +++ b/src/timelines/RegularToot.css @@ -0,0 +1,78 @@ +.RegularToot { + --card-pad: 16px; + --card-gut: 16px; + --toot-avatar-size: 40px; + margin-block: 0; + position: relative; + contain: layout style; + cursor: pointer; + + + transition: + margin-top 60ms var(--tutu-anim-curve-sharp), + margin-bottom 60ms var(--tutu-anim-curve-sharp), + height 60ms var(--tutu-anim-curve-sharp), + var(--tutu-transition-shadow); + border-radius: 0; + + time { + color: var(--tutu-color-secondary-text-on-surface); + } + + >.retoot-grp { + display: flex; + gap: 0.25em; + margin-bottom: 8px; + align-items: center; + + > :first-child { + margin-right: 0.25em; + } + } + + & .custom-emoji { + height: 1em; + object-fit: contain; + } + + &.expanded { + margin-block: 20px; + box-shadow: var(--tutu-shadow-e9); + } + + &.thread-top, + &.thread-mid, + &.thread-btm { + position: relative; + + &::before { + content: ""; + position: absolute; + left: 36px; + background-color: var(--tutu-color-secondary); + width: 2px; + display: block; + } + } + + &.thread-mid { + &::before { + top: 0; + bottom: 0; + } + } + + &.thread-top { + &::before { + top: 16px; + bottom: 0; + } + } + + &.thread-btm { + &::before { + top: 0; + height: 16px; + } + } +} diff --git a/src/timelines/RegularToot.tsx b/src/timelines/RegularToot.tsx index 48bc7cf..fd5c80d 100644 --- a/src/timelines/RegularToot.tsx +++ b/src/timelines/RegularToot.tsx @@ -14,11 +14,7 @@ import tootStyle from "./toot.module.css"; import { formatRelative } from "date-fns"; import Img from "~material/Img.js"; import { Body2 } from "~material/typography.js"; -import { css } from "solid-styled"; -import { - SmartToySharp, - Lock, -} from "@suid/icons-material"; +import { SmartToySharp, Lock } from "@suid/icons-material"; import { useTimeSource } from "~platform/timesrc.js"; import { resolveCustomEmoji } from "../masto/toot.js"; import { Divider } from "@suid/material"; @@ -30,7 +26,8 @@ import TootContent from "./toots/TootContent"; import BoostIcon from "./toots/BoostIcon"; import PreviewCard from "./toots/PreviewCard"; import TootPoll from "./toots/TootPoll"; -import TootActionGroup from "./toots/TootActionGroup.js" +import TootActionGroup from "./toots/TootActionGroup.js"; +import "./RegularToot.css"; export type TootEnv = { boost: (value: mastodon.v1.Status) => void; @@ -178,9 +175,9 @@ function onToggleReveal(setValue: Setter, event: Event) { * You can extract the intent from the attributes of the "actionable" element. * The action type is the dataset's `action`. */ -const RegularToot: Component = (props) => { +const RegularToot: Component = (oprops) => { let rootRef: HTMLElement; - const [managed, rest] = splitProps(props, [ + const [props, rest] = splitProps(oprops, [ "status", "lang", "class", @@ -189,71 +186,28 @@ const RegularToot: Component = (props) => { "thread", ]); const now = useTimeSource(); - const status = () => managed.status; + const status = () => props.status; const toot = () => status().reblog ?? status(); const session = useDefaultSession(); const [reveal, setReveal] = createSignal(false); - css` - .reply-sep { - margin-left: calc(var(--toot-avatar-size) + var(--card-pad) + 8px); - margin-block: 8px; - } - - .thread-top, - .thread-mid, - .thread-btm { - position: relative; - - &::before { - content: ""; - position: absolute; - left: 36px; - background-color: var(--tutu-color-secondary); - width: 2px; - display: block; - } - } - - .thread-mid { - &::before { - top: 0; - bottom: 0; - } - } - - .thread-top { - &::before { - top: 16px; - bottom: 0; - } - } - - .thread-btm { - &::before { - top: 0; - height: 16px; - } - } - `; - return ( <>
-
+
{ @@ -301,7 +255,7 @@ const RegularToot: Component = (props) => { - + :first-child { - margin-right: 0.25em; - } -} From 4c717a0cb7eb479dcd6d6c836d287bacb8d3354d Mon Sep 17 00:00:00 2001 From: thislight Date: Sat, 23 Nov 2024 23:47:52 +0800 Subject: [PATCH 5/5] TootComposer: use useAppLocale --- src/timelines/TootComposer.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/timelines/TootComposer.tsx b/src/timelines/TootComposer.tsx index 3c6b696..2895c67 100644 --- a/src/timelines/TootComposer.tsx +++ b/src/timelines/TootComposer.tsx @@ -42,7 +42,7 @@ import { import type { Account } from "../accounts/stores"; import "./TootComposer.css"; import BottomSheet from "~material/BottomSheet"; -import { useLanguage } from "~platform/i18n"; +import { useAppLocale } from "~platform/i18n"; import iso639_1 from "iso-639-1"; import ChooseTootLang from "./ChooseTootLang"; import type { mastodon } from "masto"; @@ -98,7 +98,8 @@ const TootVisibilityPickerDialog: Component<{ style={{ "border-top": "1px solid #ddd", background: "var(--tutu-color-surface)", - padding: "8px 16px calc(8px + var(--safe-area-inset-bottom, 0px))", + padding: + "8px 16px calc(8px + var(--safe-area-inset-bottom, 0px))", width: "100%", "text-align": "end", }} @@ -232,7 +233,7 @@ const TootComposer: Component<{ const [permPicker, setPermPicker] = createSignal(false); const [language, setLanguage] = createSignal("en"); const [langPickerOpen, setLangPickerOpen] = createSignal(false); - const appLanguage = useLanguage(); + const { language: appLanguage } = useAppLocale(); const [openMenu, menuState] = createManagedMenuState(); const randomPlaceholder = useRandomChoice(() => [