firefish/packages/sw/src/scripts/operations.ts

121 lines
3.1 KiB
TypeScript
Raw Normal View History

2023-07-20 04:17:05 +09:00
/*
* Operations
*
*/
2023-10-10 23:28:06 +09:00
import * as firefish from "firefish-js";
2023-07-20 04:17:05 +09:00
import type { SwMessage, SwMessageOrderType } from "@/types";
import { getAccountFromId } from "@/scripts/get-account-from-id";
import { getUrlWithLoginId } from "@/scripts/login-id";
2023-10-10 23:28:06 +09:00
export const cli = new firefish.api.APIClient({
2023-07-20 04:17:05 +09:00
origin,
fetch: (...args): Promise<Response> => fetch(...args),
});
export async function api<
2023-10-10 23:28:06 +09:00
E extends keyof firefish.Endpoints,
O extends firefish.Endpoints[E]["req"],
2023-07-20 04:17:05 +09:00
>(
endpoint: E,
userId?: string,
options?: O,
): Promise<void | ReturnType<typeof cli.request<E, O>>> {
let account: { token: string; id: string } | void;
if (userId) {
account = await getAccountFromId(userId);
if (!account) return;
}
return cli.request(endpoint, options, account?.token);
}
// mark-all-as-read送出を1秒間隔に制限する
const readBlockingStatus = new Map<string, boolean>();
export function sendMarkAllAsRead(
userId: string,
): Promise<null | undefined | void> {
if (readBlockingStatus.get(userId)) return Promise.resolve();
readBlockingStatus.set(userId, true);
return new Promise((resolve) => {
setTimeout(() => {
readBlockingStatus.set(userId, false);
api("notifications/mark-all-as-read", userId).then(resolve, resolve);
}, 1000);
});
}
// rendered acctからユーザーを開く
export function openUser(
acct: string,
loginId?: string,
): ReturnType<typeof openClient> {
return openClient("push", `/@${acct}`, loginId, { acct });
}
// noteIdからートを開く
export function openNote(
noteId: string,
loginId?: string,
): ReturnType<typeof openClient> {
return openClient("push", `/notes/${noteId}`, loginId, { noteId });
}
// noteIdからートを開く
export function openAntenna(
antennaId: string,
loginId: string,
): ReturnType<typeof openClient> {
return openClient("push", `/timeline/antenna/${antennaId}`, loginId, {
antennaId,
});
}
// post-formのオプションから投稿フォームを開く
export async function openPost(
options: {
initialText?: string;
2023-10-10 23:28:06 +09:00
reply?: firefish.entities.Note;
renote?: firefish.entities.Note;
2023-07-20 04:17:05 +09:00
},
loginId?: string,
): ReturnType<typeof openClient> {
// クエリを作成しておく
const url = "/share";
const query = new URLSearchParams();
if (options.initialText) query.set("text", options.initialText);
if (options.reply) query.set("replyId", options.reply.id);
if (options.renote) query.set("renoteId", options.renote.id);
return openClient("post", `${url}?${query}`, loginId, { options });
}
export async function openClient(
order: SwMessageOrderType,
url: string,
loginId?: string,
query: Record<string, SwMessage[string]> = {},
): Promise<WindowClient | null> {
const client = await findClient();
if (client) {
client.postMessage({
type: "order",
...query,
order,
loginId,
url,
} satisfies SwMessage);
return client;
}
return self.clients.openWindow(getUrlWithLoginId(url, loginId!));
}
export async function findClient(): Promise<WindowClient | null> {
const clients = await globalThis.clients.matchAll({
type: "window",
});
return clients.find((c) => !new URL(c.url).searchParams.has("zen")) ?? null;
}