Profile: supports webfinger
* timelines: add emptyTimeline
This commit is contained in:
parent
f860baa376
commit
7153a1fec1
2 changed files with 96 additions and 14 deletions
|
@ -248,6 +248,64 @@ export type TimelineResource<R> = [
|
||||||
{ refetch(info?: TimelineFetchDirection): void },
|
{ 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.
|
* Create auto managed timeline controls.
|
||||||
*
|
*
|
||||||
|
|
|
@ -47,7 +47,11 @@ import { useSessionForAcctStr } from "../masto/clients";
|
||||||
import { resolveCustomEmoji } from "../masto/toot";
|
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 { createTimeline, createTimelineSnapshot } from "../masto/timelines";
|
import {
|
||||||
|
createTimeline,
|
||||||
|
createTimelineSnapshot,
|
||||||
|
emptyTimeline,
|
||||||
|
} 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";
|
||||||
|
@ -102,6 +106,9 @@ const Profile: Component = () => {
|
||||||
const [profileUncaught] = createResource(
|
const [profileUncaught] = createResource(
|
||||||
() => [session().client, params.id] as const,
|
() => [session().client, params.id] as const,
|
||||||
async ([client, id]) => {
|
async ([client, id]) => {
|
||||||
|
if (id.startsWith("@")) {
|
||||||
|
return await client.v1.accounts.lookup({ acct: id.slice(1) });
|
||||||
|
}
|
||||||
return await client.v1.accounts.$select(id).fetch();
|
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 = () => {
|
const isCurrentSessionProfile = () => {
|
||||||
return (session().account as Account).inf?.url === profile()?.url;
|
return (session().account as Account).inf?.url === profile()?.url;
|
||||||
};
|
};
|
||||||
|
@ -125,26 +141,33 @@ const Profile: Component = () => {
|
||||||
original: true,
|
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 }] =
|
const [recentToots, recentTootChunk, { refetch: refetchRecentToots }] =
|
||||||
createTimeline(
|
createTimeline(recentTimeline, () => {
|
||||||
() => session().client.v1.accounts.$select(params.id).statuses,
|
|
||||||
() => {
|
|
||||||
const { boost, reply } = recentTootFilter();
|
const { boost, reply } = recentTootFilter();
|
||||||
return { limit: 20, excludeReblogs: !boost, excludeReplies: !reply };
|
return { limit: 20, excludeReblogs: !boost, excludeReplies: !reply };
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const [pinnedToots, pinnedTootChunk] = createTimelineSnapshot(
|
const [pinnedToots, pinnedTootChunk] = createTimelineSnapshot(
|
||||||
() => session().client.v1.accounts.$select(params.id).statuses,
|
recentTimeline,
|
||||||
() => {
|
() => {
|
||||||
return { limit: 20, pinned: true };
|
return { limit: 20, pinned: true };
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const [relationshipUncaught, { mutate: mutateRelationship }] = createResource(
|
const [relationshipUncaught, { mutate: mutateRelationship }] = createResource(
|
||||||
() => [session(), params.id] as const,
|
() => [session(), profileAcctId()] as const,
|
||||||
async ([sess, id]) => {
|
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({
|
const relations = await session().client.v1.accounts.relationships.fetch({
|
||||||
id: [id],
|
id: [id],
|
||||||
});
|
});
|
||||||
|
@ -177,16 +200,17 @@ const Profile: Component = () => {
|
||||||
|
|
||||||
const toggleSubscribeHome = async (event: Event) => {
|
const toggleSubscribeHome = async (event: Event) => {
|
||||||
const client = session().client;
|
const client = session().client;
|
||||||
if (!session().account) return;
|
const acctId = profileAcctId();
|
||||||
|
if (!session().account || !acctId) return;
|
||||||
const isSubscribed = relationship()?.following ?? false;
|
const isSubscribed = relationship()?.following ?? false;
|
||||||
mutateRelationship((x) => Object.assign({ following: !isSubscribed }, x));
|
mutateRelationship((x) => Object.assign({ following: !isSubscribed }, x));
|
||||||
subscribeMenuState.onClose(event);
|
subscribeMenuState.onClose(event);
|
||||||
|
|
||||||
if (isSubscribed) {
|
if (isSubscribed) {
|
||||||
const nrel = await client.v1.accounts.$select(params.id).unfollow();
|
const nrel = await client.v1.accounts.$select(acctId).unfollow();
|
||||||
mutateRelationship(nrel);
|
mutateRelationship(nrel);
|
||||||
} else {
|
} else {
|
||||||
const nrel = await client.v1.accounts.$select(params.id).follow();
|
const nrel = await client.v1.accounts.$select(acctId).follow();
|
||||||
mutateRelationship(nrel);
|
mutateRelationship(nrel);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue