Compare commits
No commits in common. "e7410c729679af7744170990d0e87eb0d0242e0c" and "f4c0104d4832772048a553c3d31032358996d567" have entirely different histories.
e7410c7296
...
f4c0104d48
9 changed files with 56 additions and 135 deletions
|
@ -7,7 +7,6 @@ import {
|
||||||
createEffect,
|
createEffect,
|
||||||
createResource,
|
createResource,
|
||||||
untrack,
|
untrack,
|
||||||
type Resource,
|
|
||||||
type ResourceFetcherInfo,
|
type ResourceFetcherInfo,
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { createStore } from "solid-js/store";
|
import { createStore } from "solid-js/store";
|
||||||
|
@ -20,7 +19,7 @@ type TimelineParamsOf<T> = T extends Timeline<infer P> ? P : never;
|
||||||
|
|
||||||
export function createTimelineControlsForArray(
|
export function createTimelineControlsForArray(
|
||||||
status: () => mastodon.v1.Status[] | undefined,
|
status: () => mastodon.v1.Status[] | undefined,
|
||||||
): TimelineControls {
|
) {
|
||||||
const lookup = new ReactiveMap<string, TreeNode<mastodon.v1.Status>>();
|
const lookup = new ReactiveMap<string, TreeNode<mastodon.v1.Status>>();
|
||||||
|
|
||||||
const [threads, setThreads] = createStore([] as mastodon.v1.Status["id"][]);
|
const [threads, setThreads] = createStore([] as mastodon.v1.Status["id"][]);
|
||||||
|
@ -85,14 +84,11 @@ export function createTimelineControlsForArray(
|
||||||
|
|
||||||
export function createTimelineSnapshot<
|
export function createTimelineSnapshot<
|
||||||
T extends Timeline<mastodon.DefaultPaginationParams>,
|
T extends Timeline<mastodon.DefaultPaginationParams>,
|
||||||
>(
|
>(timeline: Accessor<T>, limit: Accessor<number>) {
|
||||||
timeline: Accessor<T>,
|
|
||||||
params: Accessor<TimelineParamsOf<T>>,
|
|
||||||
): TimelineResource<mastodon.v1.Status[] | undefined> {
|
|
||||||
const [shot, { refetch }] = createResource(
|
const [shot, { refetch }] = createResource(
|
||||||
() => [timeline(), params()] as const,
|
() => [timeline(), limit()] as const,
|
||||||
async ([tl, limit]) => {
|
async ([tl, limit]) => {
|
||||||
const ls = await tl.list(limit).next();
|
const ls = await tl.list({ limit }).next();
|
||||||
return ls.value;
|
return ls.value;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -202,51 +198,9 @@ function createTimelineChunk<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TimelineControls = {
|
|
||||||
/**
|
|
||||||
* The threads.
|
|
||||||
*
|
|
||||||
* The identifiers here is the most-bottom toot id in the thread.
|
|
||||||
*
|
|
||||||
* @see You can use {@link TimelineControls.get} and {@link TimelineControls.getPath} to resolve them if
|
|
||||||
* the context is needed.
|
|
||||||
*/
|
|
||||||
list: readonly mastodon.v1.Status["id"][];
|
|
||||||
/**
|
|
||||||
* Get the single node.
|
|
||||||
*/
|
|
||||||
get(id: string): TreeNode<mastodon.v1.Status> | undefined;
|
|
||||||
/**
|
|
||||||
* Collect the path from the node to the most-top node.
|
|
||||||
*/
|
|
||||||
getPath(id: string): TreeNode<mastodon.v1.Status>[] | undefined;
|
|
||||||
/**
|
|
||||||
* Set the node value.
|
|
||||||
*/
|
|
||||||
set(id: string, value: mastodon.v1.Status): void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TimelineResource<
|
|
||||||
R,
|
|
||||||
> = [
|
|
||||||
TimelineControls,
|
|
||||||
Resource<R>,
|
|
||||||
{ refetch(info?: TimelineFetchDirection): void },
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create auto managed timeline controls.
|
|
||||||
*
|
|
||||||
* The error from the resource is not thrown in the
|
|
||||||
* {@link TimelineControls.list} and {@link TimelineControls}.get*.
|
|
||||||
* Use the second value from {@link TimelineResource} to catch the error.
|
|
||||||
*/
|
|
||||||
export function createTimeline<
|
export function createTimeline<
|
||||||
T extends Timeline<mastodon.DefaultPaginationParams>,
|
T extends Timeline<mastodon.DefaultPaginationParams>,
|
||||||
>(
|
>(timeline: Accessor<T>, params: Accessor<TimelineParamsOf<T>>) {
|
||||||
timeline: Accessor<T>,
|
|
||||||
params: Accessor<TimelineParamsOf<T>>,
|
|
||||||
): TimelineResource<TimelineChunk<TimelineParamsOf<T>> | undefined> {
|
|
||||||
const lookup = new ReactiveMap<string, TreeNode<mastodon.v1.Status>>();
|
const lookup = new ReactiveMap<string, TreeNode<mastodon.v1.Status>>();
|
||||||
const [threads, setThreads] = createStore([] as mastodon.v1.Status["id"][]);
|
const [threads, setThreads] = createStore([] as mastodon.v1.Status["id"][]);
|
||||||
|
|
||||||
|
|
|
@ -82,27 +82,25 @@
|
||||||
--tutu-color-error-on-surface: #d32f2f;
|
--tutu-color-error-on-surface: #d32f2f;
|
||||||
--tutu-color-inactive-on-surface: #757575;
|
--tutu-color-inactive-on-surface: #757575;
|
||||||
|
|
||||||
--tutu-color-shadow: rgba(0, 0, 0, 0.15);
|
--tutu-shadow-e1: 0px 1px 2px 0px #9e9e9e;
|
||||||
|
|
||||||
--tutu-shadow-e1: 0px 1px 2px 0px var(--tutu-color-shadow);
|
|
||||||
/* Switch */
|
/* Switch */
|
||||||
--tutu-shadow-e2: 0px 2px 4px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e2: 0px 2px 4px 0px #9e9e9e;
|
||||||
/* (Resting) cards, raised button, quick entry / search bar */
|
/* (Resting) cards, raised button, quick entry / search bar */
|
||||||
--tutu-shadow-e3: 0px 3px 6px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e3: 0px 3px 6px 0px #9e9e9e;
|
||||||
/* Refresh indicator, quick entry / search bar (scrolled) */
|
/* Refresh indicator, quick entry / search bar (scrolled) */
|
||||||
--tutu-shadow-e4: 0px 4px 8px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e4: 0px 4px 8px 0px #9e9e9e;
|
||||||
/* App bar */
|
/* App bar */
|
||||||
--tutu-shadow-e6: 0px 6px 12px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e6: 0px 6px 12px 0px #9e9e9e;
|
||||||
/* Snack bar, FAB (resting) */
|
/* Snack bar, FAB (resting) */
|
||||||
--tutu-shadow-e8: 0px 8px 16px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e8: 0px 8px 16px 0px #9e9e9e;
|
||||||
/* Menu, (picked-up) cards, (pressed) raise button */
|
/* Menu, (picked-up) cards, (pressed) raise button */
|
||||||
--tutu-shadow-e9: 0px 9px 18px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e9: 0px 9px 18px 0px #9e9e9e;
|
||||||
/* Submenu (+1dp for each submenu) */
|
/* Submenu (+1dp for each submenu) */
|
||||||
--tutu-shadow-e12: 0px 12px 24px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e12: 0px 12px 24px 0px #9e9e9e;
|
||||||
/* (pressed) FAB */
|
/* (pressed) FAB */
|
||||||
--tutu-shadow-e16: 0px 16px 32px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e16: 0px 16px 32px 0px #9e9e9e;
|
||||||
/* Nav drawer, right drawer, modal bottom sheet */
|
/* Nav drawer, right drawer, modal bottom sheet */
|
||||||
--tutu-shadow-e24: 0px 24px 48px 0px var(--tutu-color-shadow);
|
--tutu-shadow-e24: 0px 24px 48px 0px #9e9e9e;
|
||||||
/* Dialog, picker */
|
/* Dialog, picker */
|
||||||
|
|
||||||
--tutu-anim-curve-std: cubic-bezier(0.4, 0, 0.2, 1);
|
--tutu-anim-curve-std: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
|
|
@ -39,7 +39,7 @@ import { resolveCustomEmoji } from "../masto/toot";
|
||||||
import { FastAverageColor } from "fast-average-color";
|
import { FastAverageColor } from "fast-average-color";
|
||||||
import { useWindowSize } from "@solid-primitives/resize-observer";
|
import { useWindowSize } from "@solid-primitives/resize-observer";
|
||||||
import { css } from "solid-styled";
|
import { css } from "solid-styled";
|
||||||
import { createTimeline, createTimelineSnapshot } from "../masto/timelines";
|
import { createTimeline } from "../masto/timelines";
|
||||||
import TootList from "../timelines/TootList";
|
import TootList from "../timelines/TootList";
|
||||||
import { createTimeSource, TimeSourceProvider } from "../platform/timesrc";
|
import { createTimeSource, TimeSourceProvider } from "../platform/timesrc";
|
||||||
import TootFilterButton from "./TootFilterButton";
|
import TootFilterButton from "./TootFilterButton";
|
||||||
|
@ -91,7 +91,6 @@ const Profile: Component = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const [recentTootFilter, setRecentTootFilter] = createSignal({
|
const [recentTootFilter, setRecentTootFilter] = createSignal({
|
||||||
pinned: true,
|
|
||||||
boost: false,
|
boost: false,
|
||||||
reply: true,
|
reply: true,
|
||||||
original: true,
|
original: true,
|
||||||
|
@ -106,13 +105,6 @@ const Profile: Component = () => {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const [pinnedToots, pinnedTootChunk] = createTimelineSnapshot(
|
|
||||||
() => session().client.v1.accounts.$select(params.id).statuses,
|
|
||||||
() => {
|
|
||||||
return { limit: 20, pinned: true };
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const bannerImg = () => profile()?.header;
|
const bannerImg = () => profile()?.header;
|
||||||
const avatarImg = () => profile()?.avatar;
|
const avatarImg = () => profile()?.avatar;
|
||||||
const displayName = () =>
|
const displayName = () =>
|
||||||
|
@ -120,10 +112,6 @@ const Profile: Component = () => {
|
||||||
const fullUsername = () => (profile()?.acct ? `@${profile()!.acct!}` : ""); // TODO: full user name
|
const fullUsername = () => (profile()?.acct ? `@${profile()!.acct!}` : ""); // TODO: full user name
|
||||||
const description = () => profile()?.note;
|
const description = () => profile()?.note;
|
||||||
|
|
||||||
const isTootListLoading = () =>
|
|
||||||
recentTootChunk.loading ||
|
|
||||||
(recentTootFilter().pinned && pinnedTootChunk.loading);
|
|
||||||
|
|
||||||
css`
|
css`
|
||||||
.intro {
|
.intro {
|
||||||
background-color: var(--tutu-color-surface-d);
|
background-color: var(--tutu-color-surface-d);
|
||||||
|
@ -189,22 +177,6 @@ const Profile: Component = () => {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toot-list-toolbar {
|
|
||||||
position: sticky;
|
|
||||||
top: var(--scaffold-topbar-height);
|
|
||||||
z-index: calc(var(--tutu-zidx-nav, 1) - 1);
|
|
||||||
background: var(--tutu-color-surface);
|
|
||||||
border-bottom: 1px solid var(--tutu-color-surface-d);
|
|
||||||
contain: content;
|
|
||||||
/* TODO: box-shadow is needed here (same as app bar, e6).
|
|
||||||
There is no good way to detect if the sticky is "sticked" -
|
|
||||||
so let's leave it for future.
|
|
||||||
|
|
||||||
For now we use a trick to make it looks better.
|
|
||||||
*/
|
|
||||||
box-shadow: 0px -2px 4px 0px var(--tutu-color-shadow);
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -384,10 +356,9 @@ const Profile: Component = () => {
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="toot-list-toolbar">
|
<div>
|
||||||
<TootFilterButton
|
<TootFilterButton
|
||||||
options={{
|
options={{
|
||||||
pinned: "Pinneds",
|
|
||||||
boost: "Boosts",
|
boost: "Boosts",
|
||||||
reply: "Replies",
|
reply: "Replies",
|
||||||
original: "Originals",
|
original: "Originals",
|
||||||
|
@ -399,14 +370,6 @@ const Profile: Component = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TimeSourceProvider value={time}>
|
<TimeSourceProvider value={time}>
|
||||||
<Show when={recentTootFilter().pinned}>
|
|
||||||
<TootList
|
|
||||||
threads={pinnedToots.list}
|
|
||||||
onUnknownThread={pinnedToots.getPath}
|
|
||||||
onChangeToot={pinnedToots.set}
|
|
||||||
/>
|
|
||||||
<Divider />
|
|
||||||
</Show>
|
|
||||||
<TootList
|
<TootList
|
||||||
threads={recentToots.list}
|
threads={recentToots.list}
|
||||||
onUnknownThread={recentToots.getPath}
|
onUnknownThread={recentToots.getPath}
|
||||||
|
@ -426,9 +389,9 @@ const Profile: Component = () => {
|
||||||
size="large"
|
size="large"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={[refetchRecentToots, "prev"]}
|
onClick={[refetchRecentToots, "prev"]}
|
||||||
disabled={isTootListLoading()}
|
disabled={recentTootChunk.loading}
|
||||||
>
|
>
|
||||||
<Show when={isTootListLoading()} fallback={<ExpandMore />}>
|
<Show when={recentTootChunk.loading} fallback={<ExpandMore />}>
|
||||||
<CircularProgress sx={{ width: "24px", height: "24px" }} />
|
<CircularProgress sx={{ width: "24px", height: "24px" }} />
|
||||||
</Show>
|
</Show>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { useLocation, useNavigate, useParams } from "@solidjs/router";
|
import { useLocation, useNavigate, useParams } from "@solidjs/router";
|
||||||
import {
|
import {
|
||||||
catchError,
|
|
||||||
createEffect,
|
createEffect,
|
||||||
createRenderEffect,
|
createRenderEffect,
|
||||||
createResource,
|
createResource,
|
||||||
|
@ -43,6 +42,7 @@ function getCache(acct: string, id: string) {
|
||||||
const TootBottomSheet: Component = (props) => {
|
const TootBottomSheet: Component = (props) => {
|
||||||
const params = useParams<{ acct: string; id: string }>();
|
const params = useParams<{ acct: string; id: string }>();
|
||||||
const location = useLocation<{
|
const location = useLocation<{
|
||||||
|
tootBottomSheetPushedCount?: number;
|
||||||
tootReply?: boolean;
|
tootReply?: boolean;
|
||||||
}>();
|
}>();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -51,6 +51,10 @@ const TootBottomSheet: Component = (props) => {
|
||||||
const acctText = () => decodeURIComponent(params.acct);
|
const acctText = () => decodeURIComponent(params.acct);
|
||||||
const session = useSessionForAcctStr(acctText);
|
const session = useSessionForAcctStr(acctText);
|
||||||
|
|
||||||
|
const pushedCount = () => {
|
||||||
|
return location.state?.tootBottomSheetPushedCount || 0;
|
||||||
|
};
|
||||||
|
|
||||||
const [remoteToot, { mutate: setRemoteToot }] = createResource(
|
const [remoteToot, { mutate: setRemoteToot }] = createResource(
|
||||||
() => [session().client, params.id] as const,
|
() => [session().client, params.id] as const,
|
||||||
async ([client, id]) => {
|
async ([client, id]) => {
|
||||||
|
@ -58,9 +62,7 @@ const TootBottomSheet: Component = (props) => {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const toot = () => catchError(remoteToot, (error) => {
|
const toot = () => remoteToot() ?? getCache(acctText(), params.id);
|
||||||
console.error(error)
|
|
||||||
}) ?? getCache(acctText(), params.id);
|
|
||||||
|
|
||||||
createEffect((lastTootId?: string) => {
|
createEffect((lastTootId?: string) => {
|
||||||
const tootId = toot()?.id;
|
const tootId = toot()?.id;
|
||||||
|
@ -76,18 +78,12 @@ const TootBottomSheet: Component = (props) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const [tootContextErrorUncaught, { refetch: refetchContext }] =
|
const [tootContext, { refetch: refetchContext }] = createResource(
|
||||||
createResource(
|
() => [session().client, params.id] as const,
|
||||||
() => [session().client, params.id] as const,
|
async ([client, id]) => {
|
||||||
async ([client, id]) => {
|
return await client.v1.statuses.$select(id).context.fetch();
|
||||||
return await client.v1.statuses.$select(id).context.fetch();
|
},
|
||||||
},
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const tootContext = () =>
|
|
||||||
catchError(tootContextErrorUncaught, (error) => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
const ancestors = createTimelineControlsForArray(
|
const ancestors = createTimelineControlsForArray(
|
||||||
() => tootContext()?.ancestors,
|
() => tootContext()?.ancestors,
|
||||||
|
@ -164,6 +160,19 @@ const TootBottomSheet: Component = (props) => {
|
||||||
setRemoteToot(result);
|
setRemoteToot(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const switchContext = (status: mastodon.v1.Status) => {
|
||||||
|
if (isInTyping()) {
|
||||||
|
setInTyping(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCache(params.acct, status);
|
||||||
|
navigate(`/${params.acct}/toot/${status.id}`, {
|
||||||
|
state: {
|
||||||
|
tootBottomSheetPushedCount: pushedCount() + 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const defaultMentions = () => {
|
const defaultMentions = () => {
|
||||||
const tootAcct = remoteToot()?.reblog?.account ?? remoteToot()?.account;
|
const tootAcct = remoteToot()?.reblog?.account ?? remoteToot()?.account;
|
||||||
if (!tootAcct) {
|
if (!tootAcct) {
|
||||||
|
@ -237,7 +246,7 @@ const TootBottomSheet: Component = (props) => {
|
||||||
sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
|
sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
|
||||||
>
|
>
|
||||||
<IconButton color="inherit" onClick={[navigate, -1]} disableRipple>
|
<IconButton color="inherit" onClick={[navigate, -1]} disableRipple>
|
||||||
<CloseIcon />
|
{pushedCount() > 0 ? <BackIcon /> : <CloseIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Title component="div" class="name" use:solid-styled>
|
<Title component="div" class="name" use:solid-styled>
|
||||||
<span
|
<span
|
||||||
|
@ -293,7 +302,7 @@ const TootBottomSheet: Component = (props) => {
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={tootContextErrorUncaught.loading}>
|
<Show when={tootContext.loading}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { findElementActionable } from "./RegularToot";
|
||||||
|
|
||||||
const TootList: Component<{
|
const TootList: Component<{
|
||||||
ref?: Ref<HTMLDivElement>;
|
ref?: Ref<HTMLDivElement>;
|
||||||
threads: readonly string[];
|
threads: string[];
|
||||||
onUnknownThread: (id: string) => { value: mastodon.v1.Status }[] | undefined;
|
onUnknownThread: (id: string) => { value: mastodon.v1.Status }[] | undefined;
|
||||||
onChangeToot: (id: string, value: mastodon.v1.Status) => void;
|
onChangeToot: (id: string, value: mastodon.v1.Status) => void;
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
|
|
|
@ -28,7 +28,7 @@ const TrendTimelinePanel: Component<{
|
||||||
const [timeline, snapshot, { refetch: refetchTimeline }] =
|
const [timeline, snapshot, { refetch: refetchTimeline }] =
|
||||||
createTimelineSnapshot(
|
createTimelineSnapshot(
|
||||||
() => props.client.v1.trends.statuses,
|
() => props.client.v1.trends.statuses,
|
||||||
() => ({ limit: 120 }),
|
() => 120,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -40,7 +40,7 @@ const TrendTimelinePanel: Component<{
|
||||||
<PullDownToRefresh
|
<PullDownToRefresh
|
||||||
linkedElement={scrollLinked()}
|
linkedElement={scrollLinked()}
|
||||||
loading={snapshot.loading}
|
loading={snapshot.loading}
|
||||||
onRefresh={() => refetchTimeline("next")}
|
onRefresh={() => refetchTimeline({ direction: "new" })}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
ref={(e) =>
|
ref={(e) =>
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
.BoostIcon {
|
.icon__boost {
|
||||||
display: inline-flex;
|
padding: 0;
|
||||||
|
display: inline-block;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-color: green;
|
|
||||||
padding: 0.125em;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
> svg {
|
> :global(svg) {
|
||||||
color: white;
|
color: green;
|
||||||
font-size: 1em;
|
font-size: 1rem;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ import "./BoostIcon.css";
|
||||||
const BoostIcon: Component<JSX.HTMLElementTags["i"]> = (props) => {
|
const BoostIcon: Component<JSX.HTMLElementTags["i"]> = (props) => {
|
||||||
const [managed, rest] = splitProps(props, ["class"]);
|
const [managed, rest] = splitProps(props, ["class"]);
|
||||||
return (
|
return (
|
||||||
<i class={["BoostIcon", managed.class].join(" ")} {...rest}>
|
<i class={["icon__boost", managed.class].join(" ")} {...rest}>
|
||||||
<Repeat />
|
<Repeat />
|
||||||
</i>
|
</i>
|
||||||
);
|
);
|
||||||
|
|
|
@ -222,7 +222,6 @@
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: auto 1fr auto;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tootAttachmentGrp {
|
.tootAttachmentGrp {
|
||||||
|
|
Loading…
Reference in a new issue