masto/timelines: now the params is general typed
This commit is contained in:
parent
a0cbf857a9
commit
6620e022bf
3 changed files with 29 additions and 38 deletions
|
@ -11,23 +11,15 @@ import {
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { createStore } from "solid-js/store";
|
import { createStore } from "solid-js/store";
|
||||||
|
|
||||||
type Timeline = {
|
type Timeline<T extends mastodon.DefaultPaginationParams> = {
|
||||||
list(params: {
|
list(params?: T): mastodon.Paginator<mastodon.v1.Status[], unknown>;
|
||||||
/** Return results older than this ID. */
|
|
||||||
readonly maxId?: string;
|
|
||||||
/** Return results newer than this ID. */
|
|
||||||
readonly sinceId?: string;
|
|
||||||
/** Get a list of items with ID greater than this value excluding this ID */
|
|
||||||
readonly minId?: string;
|
|
||||||
/** Maximum number of results to return per page. Defaults to 40. NOTE: Pagination is done with the Link header from the response. */
|
|
||||||
readonly limit?: number;
|
|
||||||
}): mastodon.Paginator<mastodon.v1.Status[], unknown>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createTimelineSnapshot(
|
type TimelineParamsOf<T> = T extends Timeline<infer P> ? P : never;
|
||||||
timeline: Accessor<Timeline>,
|
|
||||||
limit: Accessor<number>,
|
export function createTimelineSnapshot<
|
||||||
) {
|
T extends Timeline<mastodon.DefaultPaginationParams>,
|
||||||
|
>(timeline: Accessor<T>, limit: Accessor<number>) {
|
||||||
const [shot, { refetch }] = createResource(
|
const [shot, { refetch }] = createResource(
|
||||||
() => [timeline(), limit()] as const,
|
() => [timeline(), limit()] as const,
|
||||||
async ([tl, limit]) => {
|
async ([tl, limit]) => {
|
||||||
|
@ -80,13 +72,13 @@ export function createTimelineSnapshot(
|
||||||
|
|
||||||
export type TimelineFetchDirection = mastodon.Direction;
|
export type TimelineFetchDirection = mastodon.Direction;
|
||||||
|
|
||||||
export type TimelineChunk = {
|
export type TimelineChunk<T extends mastodon.DefaultPaginationParams> = {
|
||||||
tl: Timeline;
|
tl: Timeline<T>;
|
||||||
rebuilt: boolean;
|
rebuilt: boolean;
|
||||||
chunk: readonly mastodon.v1.Status[];
|
chunk: readonly mastodon.v1.Status[];
|
||||||
done?: boolean;
|
done?: boolean;
|
||||||
direction: TimelineFetchDirection;
|
direction: TimelineFetchDirection;
|
||||||
limit: number;
|
params: T;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TreeNode<T> = {
|
type TreeNode<T> = {
|
||||||
|
@ -108,21 +100,21 @@ function collectPath<T>(node: TreeNode<T>) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTimelineChunk(
|
function createTimelineChunk<T extends Timeline<mastodon.DefaultPaginationParams>>(
|
||||||
timeline: Accessor<Timeline>,
|
timeline: Accessor<T>,
|
||||||
limit: Accessor<number>,
|
params: Accessor<TimelineParamsOf<T>>,
|
||||||
) {
|
) {
|
||||||
let vpMaxId: string | undefined, vpMinId: string | undefined;
|
let vpMaxId: string | undefined, vpMinId: string | undefined;
|
||||||
|
|
||||||
const fetchExtendingPage = async (
|
const fetchExtendingPage = async (
|
||||||
tl: Timeline,
|
tl: T,
|
||||||
direction: TimelineFetchDirection,
|
direction: TimelineFetchDirection,
|
||||||
limit: number,
|
params: TimelineParamsOf<T>,
|
||||||
) => {
|
) => {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case "next": {
|
case "next": {
|
||||||
const page = await tl
|
const page = await tl
|
||||||
.list({ limit, sinceId: vpMaxId })
|
.list({ ...params, sinceId: vpMaxId })
|
||||||
.setDirection(direction)
|
.setDirection(direction)
|
||||||
.next();
|
.next();
|
||||||
if ((page.value?.length ?? 0) > 0) {
|
if ((page.value?.length ?? 0) > 0) {
|
||||||
|
@ -133,7 +125,7 @@ function createTimelineChunk(
|
||||||
|
|
||||||
case "prev": {
|
case "prev": {
|
||||||
const page = await tl
|
const page = await tl
|
||||||
.list({ limit, maxId: vpMinId })
|
.list({ ...params, maxId: vpMinId })
|
||||||
.setDirection(direction)
|
.setDirection(direction)
|
||||||
.next();
|
.next();
|
||||||
if ((page.value?.length ?? 0) > 0) {
|
if ((page.value?.length ?? 0) > 0) {
|
||||||
|
@ -145,11 +137,11 @@ function createTimelineChunk(
|
||||||
};
|
};
|
||||||
|
|
||||||
return createResource(
|
return createResource(
|
||||||
() => [timeline(), limit()] as const,
|
() => [timeline(), params()] as const,
|
||||||
async (
|
async (
|
||||||
[tl, limit],
|
[tl, params],
|
||||||
info: ResourceFetcherInfo<
|
info: ResourceFetcherInfo<
|
||||||
Readonly<TimelineChunk>,
|
Readonly<TimelineChunk<TimelineParamsOf<T>>>,
|
||||||
TimelineFetchDirection
|
TimelineFetchDirection
|
||||||
>,
|
>,
|
||||||
) => {
|
) => {
|
||||||
|
@ -160,27 +152,26 @@ function createTimelineChunk(
|
||||||
vpMaxId = undefined;
|
vpMaxId = undefined;
|
||||||
vpMinId = undefined;
|
vpMinId = undefined;
|
||||||
}
|
}
|
||||||
const posts = await fetchExtendingPage(tl, direction, limit);
|
const posts = await fetchExtendingPage(tl, direction, params);
|
||||||
return {
|
return {
|
||||||
tl,
|
tl,
|
||||||
rebuilt: rebuildTimeline,
|
rebuilt: rebuildTimeline,
|
||||||
chunk: posts.value ?? [],
|
chunk: posts.value ?? [],
|
||||||
done: posts.done,
|
done: posts.done,
|
||||||
direction,
|
direction,
|
||||||
limit,
|
params,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTimeline(
|
export function createTimeline<
|
||||||
timeline: Accessor<Timeline>,
|
T extends Timeline<mastodon.DefaultPaginationParams>,
|
||||||
limit: Accessor<number>,
|
>(timeline: Accessor<T>, params: Accessor<TimelineParamsOf<T>>) {
|
||||||
) {
|
|
||||||
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"][]);
|
||||||
|
|
||||||
const [chunk, { refetch }] = createTimelineChunk(timeline, limit);
|
const [chunk, { refetch }] = createTimelineChunk(timeline, params);
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const chk = catchError(chunk, (e) => console.error(e));
|
const chk = catchError(chunk, (e) => console.error(e));
|
||||||
|
|
|
@ -60,14 +60,14 @@ const Profile: Component = () => {
|
||||||
|
|
||||||
const [recentToots] = createTimeline(
|
const [recentToots] = createTimeline(
|
||||||
() => session().client.v1.accounts.$select(params.id).statuses,
|
() => session().client.v1.accounts.$select(params.id).statuses,
|
||||||
() => 20,
|
() => ({ limit: 20 }),
|
||||||
);
|
);
|
||||||
|
|
||||||
const bannerImg = () => profile()?.header;
|
const bannerImg = () => profile()?.header;
|
||||||
const avatarImg = () => profile()?.avatar;
|
const avatarImg = () => profile()?.avatar;
|
||||||
const displayName = () =>
|
const displayName = () =>
|
||||||
resolveCustomEmoji(profile()?.displayName || "", profile()?.emojis ?? []);
|
resolveCustomEmoji(profile()?.displayName || "", profile()?.emojis ?? []);
|
||||||
const fullUsername = () => `@${profile()?.acct ?? "..."}`; // TODO: full user name
|
const fullUsername = () => `@${profile()?.acct ?? ""}`; // TODO: full user name
|
||||||
const description = () => profile()?.note;
|
const description = () => profile()?.note;
|
||||||
|
|
||||||
css`
|
css`
|
||||||
|
|
|
@ -32,7 +32,7 @@ const TimelinePanel: Component<{
|
||||||
|
|
||||||
const [timeline, snapshot, { refetch: refetchTimeline }] = createTimeline(
|
const [timeline, snapshot, { refetch: refetchTimeline }] = createTimeline(
|
||||||
() => props.client.v1.timelines[props.name],
|
() => props.client.v1.timelines[props.name],
|
||||||
() => 20,
|
() => ({limit: 20}),
|
||||||
);
|
);
|
||||||
const [expandedThreadId, setExpandedThreadId] = createSignal<string>();
|
const [expandedThreadId, setExpandedThreadId] = createSignal<string>();
|
||||||
const [typing, setTyping] = createSignal(false);
|
const [typing, setTyping] = createSignal(false);
|
||||||
|
|
Loading…
Reference in a new issue