Profile: supports webfinger

* timelines: add emptyTimeline
This commit is contained in:
thislight 2025-01-02 18:11:35 +08:00
parent f860baa376
commit 7153a1fec1
No known key found for this signature in database
GPG key ID: FCFE5192241CCD4E
2 changed files with 96 additions and 14 deletions

View file

@ -248,6 +248,64 @@ export type TimelineResource<R> = [
{ refetch(info?: TimelineFetchDirection): void },
];
export const emptyTimeline = {
list() {
return emptyTimeline;
},
setDirection() {
return emptyTimeline;
},
async next(): Promise<IteratorResult<any, undefined>> {
return {
value: undefined,
done: true,
};
},
getDirection(): TimelineFetchDirection {
return "next";
},
clone() {
return emptyTimeline;
},
async return(): Promise<IteratorResult<any, undefined>> {
return {
value: undefined,
done: true,
};
},
async throw(e?: unknown) {
throw e;
},
async *values() {},
async *[Symbol.asyncIterator](): AsyncIterator<any[], undefined> {
return undefined;
},
async then<TNext, ENext>(
onresolve?: null | ((value: any[]) => TNext | PromiseLike<TNext>),
onrejected?: null | ((reason: unknown) => ENext | PromiseLike<ENext>),
) {
try {
if (!onresolve) {
throw new TypeError("no onresolve");
}
return await onresolve([]);
} catch (reason) {
if (!onrejected) {
throw reason;
}
return await onrejected(reason);
}
},
};
/**
* Create auto managed timeline controls.
*

View file

@ -47,7 +47,11 @@ import { useSessionForAcctStr } from "../masto/clients";
import { resolveCustomEmoji } from "../masto/toot";
import { FastAverageColor } from "fast-average-color";
import { useWindowSize } from "@solid-primitives/resize-observer";
import { createTimeline, createTimelineSnapshot } from "../masto/timelines";
import {
createTimeline,
createTimelineSnapshot,
emptyTimeline,
} from "../masto/timelines";
import TootList from "../timelines/TootList";
import { createTimeSource, TimeSourceProvider } from "~platform/timesrc";
import TootFilterButton from "./TootFilterButton";
@ -102,6 +106,9 @@ const Profile: Component = () => {
const [profileUncaught] = createResource(
() => [session().client, params.id] as const,
async ([client, id]) => {
if (id.startsWith("@")) {
return await client.v1.accounts.lookup({ acct: id.slice(1) });
}
return await client.v1.accounts.$select(id).fetch();
},
);
@ -114,6 +121,15 @@ const Profile: Component = () => {
}
};
const profileAcctId = () => {
if (params.id.startsWith("@")) {
// Webfinger
return profile()?.id;
} else {
return params.id;
}
};
const isCurrentSessionProfile = () => {
return (session().account as Account).inf?.url === profile()?.url;
};
@ -125,26 +141,33 @@ const Profile: Component = () => {
original: true,
});
const recentTimeline = () => {
const id = profileAcctId();
if (id) {
return session().client.v1.accounts.$select(id).statuses;
} else {
return emptyTimeline;
}
};
const [recentToots, recentTootChunk, { refetch: refetchRecentToots }] =
createTimeline(
() => session().client.v1.accounts.$select(params.id).statuses,
() => {
createTimeline(recentTimeline, () => {
const { boost, reply } = recentTootFilter();
return { limit: 20, excludeReblogs: !boost, excludeReplies: !reply };
},
);
});
const [pinnedToots, pinnedTootChunk] = createTimelineSnapshot(
() => session().client.v1.accounts.$select(params.id).statuses,
recentTimeline,
() => {
return { limit: 20, pinned: true };
},
);
const [relationshipUncaught, { mutate: mutateRelationship }] = createResource(
() => [session(), params.id] as const,
() => [session(), profileAcctId()] as const,
async ([sess, id]) => {
if (!sess.account) return; // No account, no relation
if (!sess.account || !id) return; // No account, no relation
const relations = await session().client.v1.accounts.relationships.fetch({
id: [id],
});
@ -177,16 +200,17 @@ const Profile: Component = () => {
const toggleSubscribeHome = async (event: Event) => {
const client = session().client;
if (!session().account) return;
const acctId = profileAcctId();
if (!session().account || !acctId) return;
const isSubscribed = relationship()?.following ?? false;
mutateRelationship((x) => Object.assign({ following: !isSubscribed }, x));
subscribeMenuState.onClose(event);
if (isSubscribed) {
const nrel = await client.v1.accounts.$select(params.id).unfollow();
const nrel = await client.v1.accounts.$select(acctId).unfollow();
mutateRelationship(nrel);
} else {
const nrel = await client.v1.accounts.$select(params.id).follow();
const nrel = await client.v1.accounts.$select(acctId).follow();
mutateRelationship(nrel);
}
};