tutu/src/masto/clients.ts
2024-07-22 21:57:04 +08:00

78 lines
1.8 KiB
TypeScript

import {
Accessor,
createContext,
createRenderEffect,
createResource,
Signal,
useContext,
} from "solid-js";
import { Account } from "../accounts/stores";
import { createRestAPIClient, mastodon } from "masto";
import { useLocation, useNavigate } from "@solidjs/router";
const restfulCache: Record<string, mastodon.rest.Client> = {};
export function createMastoClientFor(account: Account) {
const cacheKey = [account.site, account.accessToken].join("");
const cache = restfulCache[cacheKey];
if (cache) return cache;
const client = createRestAPIClient({
url: account.site,
accessToken: account.accessToken,
});
restfulCache[cacheKey] = client;
return client;
}
export function createUnauthorizedClient(site: string) {
const cache = restfulCache[site];
if (cache) return cache;
const client = createRestAPIClient({
url: site,
});
restfulCache[site] = client;
return client;
}
export function useInstance(client: Accessor<mastodon.rest.Client>) {
return createResource(client, async (client) => {
return await client.v2.instance.fetch();
});
}
export type Session = {
account: Account;
client: mastodon.rest.Client;
};
const Context = /* @__PURE__ */ createContext<Signal<Session[]>>();
export const Provider = Context.Provider;
export function useSessions() {
const [sessions] = useSessionsRw();
const navigate = useNavigate();
const location = useLocation();
createRenderEffect(() => {
if (sessions().length > 0) return;
navigate(
"/accounts/sign-in?back=" + encodeURIComponent(location.pathname),
{ replace: true },
);
});
return sessions;
}
function useSessionsRw() {
const store = useContext(Context);
if (!store) {
throw new TypeError("sessions are not provided");
}
return store;
}