Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
227
mutation.ts5.81 kB
import { uniqueId } from "lodash"; import { useEffect, useRef } from "react"; import { Arguments, MutatorCallback, useSWRConfig } from "swr"; import { postDelete, postReactAdd, postReactRemove, postUpdate, } from "@/api/openapi-client/posts"; import { replyCreate } from "@/api/openapi-client/replies"; import { getThreadGetKey, threadUpdate } from "@/api/openapi-client/threads"; import { Identifier, PostMutableProps, React, Reply, ReplyInitialProps, Thread, ThreadGetParams, ThreadGetResponse, ThreadReference, } from "@/api/openapi-schema"; import { useSession } from "@/auth"; export function useThreadMutations(thread: ThreadReference) { const sessionInitial = useSession(); const sessionRef = useRef(sessionInitial); useEffect(() => { sessionRef.current = sessionInitial; }, [sessionInitial]); const { mutate } = useSWRConfig(); const threadGetKey = getThreadGetKey(thread.slug); const key = (key: Arguments) => { if (!Array.isArray(key)) return false; const path = key[0]; const params = key.length > 1 ? (key[1] as ThreadGetParams) : undefined; const pathMatch = path === threadGetKey[0]; if (!pathMatch) return false; const paramsMatch = params?.page === threadGetKey[1]?.page; const match = pathMatch && paramsMatch; return match; }; const createReply = async (reply: ReplyInitialProps) => { const mutator: MutatorCallback<ThreadGetResponse> = (data) => { const session = sessionRef.current; if (!data || !session) return; const newReply = { id: uniqueId("optimistic_reply_"), createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), title: thread.title, author: session, assets: [], collections: { has_collected: false, in_collections: 0 }, likes: { likes: 0, liked: false }, reacts: [], body_links: [], slug: thread.slug, root_id: thread.id, root_slug: thread.slug, ...reply, } satisfies Reply; const newData: Thread = { ...data, replies: { ...data.replies, replies: [...data.replies.replies, newReply], }, }; return newData; }; await mutate(key, mutator, { revalidate: false, }); await replyCreate(thread.slug, reply); }; const updateReply = async (id: Identifier, updated: PostMutableProps) => { const mutator: MutatorCallback<ThreadGetResponse> = (data) => { if (!data) return; const newData = { ...data, replies: { ...data.replies, replies: data.replies.replies.map((reply) => reply.id === id ? { ...reply, ...updated } : reply, ), }, }; return newData; }; await mutate(key, mutator, { revalidate: false, }); await postUpdate(id, updated); }; const deleteReply = async (id: Identifier) => { const mutator = (data?: ThreadGetResponse) => { if (!data) return; const newData: ThreadGetResponse = { ...data, replies: { ...data.replies, replies: data.replies.replies.filter((reply) => reply.id !== id), }, }; return newData; }; await mutate(key, mutator, { revalidate: false, }); await postDelete(id); }; const reactionAdd = async (replyID: Identifier, emoji: string) => { const session = sessionRef.current; if (!session) return; const mutator: MutatorCallback<ThreadGetResponse> = (data) => { if (!data) return; const newData = { ...data, replies: { ...data.replies, replies: data.replies.replies.map((reply) => { if (reply.id !== replyID) { return reply; } const newReact = { id: uniqueId("optimistic_reply_update_"), emoji, author: session, } satisfies React; const reacts = [...reply.reacts, newReact]; return { ...reply, reacts, }; }), }, }; return newData; }; await mutate(key, mutator, { revalidate: false, }); await postReactAdd(replyID, { emoji }); }; const reactionRemove = async (replyID: Identifier, reactID: Identifier) => { const session = sessionRef.current; if (!session) return; const mutator: MutatorCallback<ThreadGetResponse> = (data) => { if (!data) return; const newData = { ...data, replies: { ...data.replies, replies: data.replies.replies.map((reply) => { if (reply.id !== replyID) { return reply; } const reacts = reply.reacts.filter((react) => react.id !== reactID); return { ...reply, reacts, }; }), }, }; return newData; }; await mutate(key, mutator, { revalidate: false, }); await postReactRemove(replyID, reactID); }; const updateCategory = async (categoryID: Identifier) => { const mutator: MutatorCallback<ThreadGetResponse> = (data) => { if (!data) return; const newData = { ...data, category_id: categoryID, }; return newData; }; await mutate(key, mutator, { revalidate: false, }); await threadUpdate(thread.slug, { category: categoryID }); }; const revalidate = async (after?: number) => { setTimeout(() => { mutate(key); }, after); }; return { createReply, updateReply, deleteReply, reactionAdd, reactionRemove, updateCategory, revalidate, }; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server