113 lines
2.5 KiB
TypeScript
113 lines
2.5 KiB
TypeScript
import { graphemeLength, Post, PostReference } from "@skyware/bot";
|
|
import * as yaml from "js-yaml";
|
|
import bot from "../bot";
|
|
import { muted_threads } from "../db/schema";
|
|
import { eq } from "drizzle-orm";
|
|
import db from "../db";
|
|
import * as c from "../constants";
|
|
|
|
/*
|
|
Traversal
|
|
*/
|
|
export async function traverseThread(post: Post): Promise<Post[]> {
|
|
const thread: Post[] = [
|
|
post,
|
|
];
|
|
let currentPost: Post | undefined = post;
|
|
let parentCount = 0;
|
|
|
|
while (
|
|
currentPost && parentCount < c.MAX_THREAD_DEPTH
|
|
) {
|
|
const parentPost = await currentPost.fetchParent();
|
|
|
|
if (parentPost) {
|
|
thread.push(parentPost);
|
|
currentPost = parentPost;
|
|
} else {
|
|
break;
|
|
}
|
|
parentCount++;
|
|
}
|
|
|
|
return thread.reverse();
|
|
}
|
|
|
|
export function parseThread(thread: Post[]) {
|
|
return yaml.dump({
|
|
uri: thread[0]!.uri,
|
|
posts: thread.map((post) => ({
|
|
author: `${post.author.displayName} (${post.author.handle})`,
|
|
text: post.text,
|
|
})),
|
|
});
|
|
}
|
|
|
|
/*
|
|
Split Responses
|
|
*/
|
|
export function exceedsGraphemes(content: string) {
|
|
return graphemeLength(content) > c.MAX_GRAPHEMES;
|
|
}
|
|
|
|
export function splitResponse(text: string): string[] {
|
|
const words = text.split(" ");
|
|
const chunks: string[] = [];
|
|
let currentChunk = "";
|
|
|
|
for (const word of words) {
|
|
if (currentChunk.length + word.length + 1 < c.MAX_GRAPHEMES - 10) {
|
|
currentChunk += ` ${word}`;
|
|
} else {
|
|
chunks.push(currentChunk.trim());
|
|
currentChunk = word;
|
|
}
|
|
}
|
|
|
|
if (currentChunk.trim()) {
|
|
chunks.push(currentChunk.trim());
|
|
}
|
|
|
|
const total = chunks.length;
|
|
if (total <= 1) return [text];
|
|
|
|
return chunks.map((chunk, i) => `(${i + 1}/${total}) ${chunk}`);
|
|
}
|
|
|
|
export async function multipartResponse(content: string, post?: Post) {
|
|
const parts = splitResponse(content).filter((p) => p.trim().length > 0);
|
|
|
|
let latest: PostReference;
|
|
let rootUri: string;
|
|
|
|
if (post) {
|
|
rootUri = (post as any).rootUri ?? (post as any).uri;
|
|
latest = await post.reply({ text: parts[0]! });
|
|
} else {
|
|
latest = await bot.post({ text: parts[0]! });
|
|
rootUri = latest.uri;
|
|
}
|
|
|
|
for (const text of parts.slice(1)) {
|
|
latest = await latest.reply({ text });
|
|
}
|
|
|
|
return rootUri;
|
|
}
|
|
|
|
/*
|
|
Misc.
|
|
*/
|
|
export async function isThreadMuted(post: Post): Promise<boolean> {
|
|
const root = post.root || post;
|
|
if (!root) return false;
|
|
|
|
console.log("Found root: ", root.text);
|
|
|
|
const [mute] = await db
|
|
.select()
|
|
.from(muted_threads)
|
|
.where(eq(muted_threads.uri, root.uri));
|
|
|
|
return mute !== undefined;
|
|
}
|