diff --git a/docs/optimizing.md b/docs/optimizing.md index 07f8e6f..920c157 100644 --- a/docs/optimizing.md +++ b/docs/optimizing.md @@ -33,7 +33,7 @@ Don't choose algorithm solely on the time complexity. GUI app needs smooth, not But it comes with cost. Modern browsers are already very smart on rendering. Using `contain`, you are trading onething off for another: - `layout` affects the reflow. This property usually won't make large change: mainline browsers already can incrementally reflow. -- `style` affects the style computation, is automatically enabled when using `container` property. Usually won't make large change too, unless you frequently change the styles (and/or your stylesheet is large and/or with complex selectors), containing the computation may help performance. +- `style` affacts the style computation, is automatically enabled when using `container` property. Usually won't make large change too, unless you frequently change the styles (and/or your stylesheet is large and/or with complex selectors). - `paint` affects the shading, the pixel-filling process. This is useful - the shading is resource-heavy - but the browser may need more buffers and more time to compose the final frame. - This containment may increase memory usage. - `size` says the size is not affected by outside elements and is defined. It hints the user agent can use the pre-defined size and/or cache the computed size (with `auto` keyword). diff --git a/src/profiles/Profile.tsx b/src/profiles/Profile.tsx index 5e1ad0c..cc29999 100644 --- a/src/profiles/Profile.tsx +++ b/src/profiles/Profile.tsx @@ -58,10 +58,6 @@ import Menu, { createManagedMenuState } from "~material/Menu"; import { share } from "~platform/share"; import "./Profile.css"; import { useNavigator } from "~platform/StackedRouter"; -import { - createSingluarItemSelection, - default as ItemSelectionProvider, -} from "../timelines/toots/ItemSelectionProvider"; const Profile: Component = () => { const { pop } = useNavigator(); @@ -74,7 +70,6 @@ const Profile: Component = () => { }>(); const windowSize = useWindowSize(); const time = createTimeSource(); - const [, selectionState] = createSingluarItemSelection(); const menuButId = createUniqueId(); const recentTootListId = createUniqueId(); @@ -504,26 +499,22 @@ const Profile: Component = () => { > - - - 0} - > - - - + + 0}> - - + + + +
{ let panelList: HTMLDivElement; useDocumentTitle("Timelines"); const now = createTimeSource(); - const [, selectionState] = createSingluarItemSelection( - undefined as string | undefined, - ); const settings$ = useStore($settings); @@ -122,6 +115,7 @@ const Home: ParentComponent = (props) => { } }; + css` .tab-panel { overflow: visible auto; @@ -201,42 +195,40 @@ const Home: ParentComponent = (props) => { } > - - - -
-
-
- -
+ + +
+
+
+
-
-
- -
-
-
-
- -
-
-
- - - +
+
+ +
+
+
+
+ +
+
+
+
+
+
); diff --git a/src/timelines/RegularToot.tsx b/src/timelines/RegularToot.tsx index 84c1c38..63ef7c1 100644 --- a/src/timelines/RegularToot.tsx +++ b/src/timelines/RegularToot.tsx @@ -4,6 +4,7 @@ import { type Component, type JSX, Show, + createRenderEffect, createSignal, type Setter, createContext, diff --git a/src/timelines/TootList.tsx b/src/timelines/TootList.tsx index 35986a5..b35dcce 100644 --- a/src/timelines/TootList.tsx +++ b/src/timelines/TootList.tsx @@ -7,7 +7,6 @@ import { Index, createMemo, For, - createUniqueId, } from "solid-js"; import { type mastodon } from "masto"; import { vibrate } from "~platform/hardware"; @@ -22,7 +21,6 @@ import cardStyle from "~material/cards.module.css"; import type { ThreadNode } from "../masto/timelines"; import { useNavigator } from "~platform/StackedRouter"; import { ANIM_CURVE_STD } from "~material/theme"; -import { useItemSelection } from "./toots/ItemSelectionProvider"; function durationOf(rect0: DOMRect, rect1: DOMRect) { const distancelt = Math.sqrt( @@ -47,9 +45,6 @@ function positionTootInThread(index: number, threadLength: number) { return "middle"; } -/** - * Full-feature toot list. - */ const TootList: Component<{ ref?: Ref; id?: string; @@ -58,7 +53,7 @@ const TootList: Component<{ onChangeToot: (id: string, value: mastodon.v1.Status) => void; }> = (props) => { const session = useDefaultSession(); - const [isExpanded, setExpanded] = useItemSelection(); + const [expandedThreadId, setExpandedThreadId] = createSignal(); const { push } = useNavigator(); const onBookmark = async (status: mastodon.v1.Status) => { @@ -195,7 +190,7 @@ const TootList: Component<{ event.currentTarget, ); - if (actionableElement && isExpanded(event.currentTarget.id)) { + if (actionableElement && checkIsExpended(status)) { if (actionableElement.dataset.action === "acct") { event.stopPropagation(); @@ -219,13 +214,18 @@ const TootList: Component<{ } // else if (!actionableElement || !checkIsExpended(status) || ) - if (!isExpanded(event.currentTarget.id)) { - setExpanded(event.currentTarget.id); + if (status.id !== expandedThreadId()) { + setExpandedThreadId((x) => (x ? undefined : status.id)); } else { openFullScreenToot(status, event.currentTarget as HTMLElement); } }; + const checkIsExpendedId = createSelector(expandedThreadId); + + const checkIsExpended = (status: mastodon.v1.Status) => + checkIsExpendedId(status.id); + const reply = ( status: mastodon.v1.Status, event: { currentTarget: HTMLElement }, @@ -234,7 +234,10 @@ const TootList: Component<{ openFullScreenToot(status, element, true); }; - const vote = async (status: mastodon.v1.Status, votes: readonly number[]) => { + const vote = async ( + status: mastodon.v1.Status, + votes: readonly number[] + ) => { const client = session()?.client; if (!client) return; @@ -268,15 +271,13 @@ const TootList: Component<{ return

Oops: {String(err)}

; }} > - +
{(threadId, threadIdx) => { @@ -290,13 +291,11 @@ const TootList: Component<{ {(threadNode, index) => { const status = () => threadNode().value; - const id = createUniqueId(); return ( 1 @@ -304,8 +303,8 @@ const TootList: Component<{ : undefined } class={cardStyle.card} - evaluated={isExpanded(id)} - actionable={isExpanded(id)} + evaluated={checkIsExpended(status())} + actionable={checkIsExpended(status())} onClick={[onItemClick, status()]} /> ); diff --git a/src/timelines/toots/ItemSelectionProvider.ts b/src/timelines/toots/ItemSelectionProvider.ts deleted file mode 100644 index e19e024..0000000 --- a/src/timelines/toots/ItemSelectionProvider.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - createContext, - createSelector, - createSignal, - useContext, - type Accessor, -} from "solid-js"; - -export type ItemSelectionState = [(value: T) => boolean, (value: T) => void]; - -const ItemSelectionContext = /* @__PURE__ */ createContext< - ItemSelectionState ->([() => false, () => undefined]); - -export function createSingluarItemSelection( - intial?: T, -): readonly [Accessor, ItemSelectionState] { - const [value, setValue] = createSignal(intial); - - const select = createSelector(value, (a, b) => - typeof b !== "undefined" ? a === b : false, - ); - - const toggle = (v: T | undefined) => { - setValue((o) => (o ? undefined : v)); - }; - - return [value, [select, toggle]]; -} - -export function useItemSelection() { - return useContext(ItemSelectionContext); -} - -export default ItemSelectionContext.Provider; diff --git a/src/timelines/toots/TootAuthorGroup.css b/src/timelines/toots/TootAuthorGroup.css index e52794f..1d62d16 100644 --- a/src/timelines/toots/TootAuthorGroup.css +++ b/src/timelines/toots/TootAuthorGroup.css @@ -10,7 +10,7 @@ } } -.TootAuthorGroup>.name-grp { +.TootAuthorGroup > .name-grp { display: grid; grid-template-columns: 1fr auto; color: var(--tutu-color-secondary-text-on-surface); @@ -22,16 +22,18 @@ >time { text-align: end; } + + &:hover { + > .name-primary { + text-decoration: underline; + } + } } -.RegularToot.expanded .TootAuthorGroup>.name-grp>.name-primary { - text-decoration: underline; -} - -.TootAuthorGroup>.name-grp>.name-primary { +.TootAuthorGroup > .name-grp > .name-primary { color: var(--tutu-color-on-surface); - >.acct-mark { + > .acct-mark { font-size: 1.2em; color: var(--tutu-color-secondary-text-on-surface); vertical-align: sub; @@ -39,7 +41,7 @@ } } -.TootAuthorGroup>.avatar { +.TootAuthorGroup > .avatar { width: calc(var(--toot-avatar-size, 40px) - 1px); aspect-ratio: 1/1; object-fit: contain;