diff --git a/src/routes/blog/post/announcing-threads/+page.markdoc b/src/routes/blog/post/announcing-threads/+page.markdoc index 2c252acb71..c7caa18bb6 100644 --- a/src/routes/blog/post/announcing-threads/+page.markdoc +++ b/src/routes/blog/post/announcing-threads/+page.markdoc @@ -13,7 +13,7 @@ featured: false Introducing Threads. A complete overview of all questions ever asked and answered on the Appwrite Discord Server. Now, you can get an answer to your question immediately without awaiting a response or having to search the server. ## Helping you move faster -Imagine you're deep into building your dream application with Appwrite, and suddenly, you hit a roadblock – a puzzling bug or a tricky configuration issue. At times like these, your go-to support is the Appwrite [Discord server](appwrite.io/discord), your connection to the developer community and all its wisdom +Imagine you're deep into building your dream application with Appwrite, and suddenly, you hit a roadblock – a puzzling bug or a tricky configuration issue. At times like these, your go-to support is the Appwrite [Discord server](https://appwrite.io/discord), your connection to the developer community and all its wisdom Discord servers like ours are invaluable spaces where developers gather to share experiences, ask questions, and find solutions. But here's the challenge: valuable answers often get buried in endless message threads, making finding what you need feel like searching for a needle in a haystack. Costing you valuable time you could rather spend building. diff --git a/src/routes/changelog/entry/[entry]/+page.ts b/src/routes/changelog/entry/[entry]/+page.ts index 3f348c40bb..f1a5fd260b 100644 --- a/src/routes/changelog/entry/[entry]/+page.ts +++ b/src/routes/changelog/entry/[entry]/+page.ts @@ -3,26 +3,25 @@ import { getAllChangelogEntries } from '../../utils.js'; import type { EntryGenerator } from './$types.js'; export const entries: EntryGenerator = async () => { - const entries = await getAllChangelogEntries(); - return entries.map((entry) => { - return { - entry: entry.slug - } - }); -} - -export const load = async ({ params, }) => { - const entries = await getAllChangelogEntries(); - const entry = entries.find((entry) => { - return entry.filepath.includes(params.entry); - }); + const entries = await getAllChangelogEntries(); + return entries.map((entry) => { + return { + entry: entry.slug + }; + }); +}; - if (!entry) { - throw error(404, 'Not found') - } +export const load = async ({ params }) => { + const entries = await getAllChangelogEntries(); + const entry = entries.find((entry) => { + return entry.slug === params.entry; + }); - return { - ...entry - } + if (!entry) { + throw error(404, 'Not found'); + } -}; \ No newline at end of file + return { + ...entry + }; +}; diff --git a/src/routes/changelog/utils.ts b/src/routes/changelog/utils.ts index b313f22e79..3aae41539f 100644 --- a/src/routes/changelog/utils.ts +++ b/src/routes/changelog/utils.ts @@ -14,7 +14,7 @@ export const getAllChangelogEntries = async () => { let entries = Object.entries(entriesGlob).map(([filepath, component]) => { const typedComponent = component as ChangelogComponent; const { frontmatter } = typedComponent; - const slug = filepath.replace(/\.markdoc$/, '').replace('(entries)/', ''); + const slug = filepath.replace(/\.markdoc$/, '').replace('./(entries)/', ''); const href = `/changelog/entry/${slug}`; return { ...frontmatter, component: typedComponent.default, filepath, href, slug }; diff --git a/src/routes/threads/[id]/+page.server.ts b/src/routes/threads/[id]/+page.server.ts index 1985134c2d..46552c52cd 100644 --- a/src/routes/threads/[id]/+page.server.ts +++ b/src/routes/threads/[id]/+page.server.ts @@ -1,7 +1,16 @@ import { error } from '@sveltejs/kit'; -import { getRelatedThreads, getThread, getThreadMessages } from '../helpers.js'; +import { getRelatedThreads, getThread, getThreadMessages, iterateAllThreads } from '../helpers.js'; -export const prerender = false; +export const prerender = true; + +export const entries = async () => { + const ids = []; + for await (const thread of iterateAllThreads()) { + ids.push({ id: thread.$id }); + } + + return ids; +}; export const load = async ({ params }) => { const id = params.id; @@ -14,7 +23,7 @@ export const load = async ({ params }) => { return { ...thread, related, - messages, + messages }; } catch (e) { throw error(404, 'Thread not found'); diff --git a/src/routes/threads/[id]/HtmlRenderer.svelte b/src/routes/threads/[id]/HtmlRenderer.svelte new file mode 100644 index 0000000000..9c5f956f91 --- /dev/null +++ b/src/routes/threads/[id]/HtmlRenderer.svelte @@ -0,0 +1,5 @@ + + +{text} \ No newline at end of file diff --git a/src/routes/threads/[id]/MessageCard.svelte b/src/routes/threads/[id]/MessageCard.svelte index 75b5a190a3..04636bd2f2 100644 --- a/src/routes/threads/[id]/MessageCard.svelte +++ b/src/routes/threads/[id]/MessageCard.svelte @@ -3,6 +3,7 @@ import type { DiscordMessage } from '../types'; import CodeRenderer from './CodeRenderer.svelte'; import LinkRenderer from './LinkRenderer.svelte'; + import HtmlRenderer from './HtmlRenderer.svelte'; export let message: DiscordMessage; @@ -39,7 +40,8 @@ source={message.message} renderers={{ code: CodeRenderer, - link: LinkRenderer + link: LinkRenderer, + html: HtmlRenderer }} /> diff --git a/src/routes/threads/helpers.ts b/src/routes/threads/helpers.ts index 079c494187..eee199dc4a 100644 --- a/src/routes/threads/helpers.ts +++ b/src/routes/threads/helpers.ts @@ -67,12 +67,10 @@ export function filterThreads({ q, threads: threadDocs, tags, allTags }: FilterT type GetThreadsArgs = Omit; export async function getThreads({ q, tags, allTags }: GetThreadsArgs) { - let query = [ - q ? Query.search('search_meta', q) : undefined - ]; - + let query = [q ? Query.search('search_meta', q) : undefined]; + tags = tags?.filter(Boolean).map((tag) => tag.toLowerCase()) ?? []; - + if (tags.length > 0) { query = [...query, Query.search('tags', tags.join(','))]; } @@ -112,4 +110,26 @@ export async function getThreadMessages(threadId: string) { return (data.documents as unknown as DiscordMessage[]).sort( (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime() ); -} \ No newline at end of file +} + +export async function* iterateAllThreads() { + let offset = 0; + const limit = 100; + while (true) { + const data = await databases.listDocuments( + PUBLIC_APPWRITE_DB_MAIN_ID, + PUBLIC_APPWRITE_COL_THREADS_ID, + [Query.offset(offset), Query.limit(limit)] + ); + + if (data.documents.length === 0) { + break; + } + + for (const thread of data.documents) { + yield thread; + } + + offset += limit; + } +} diff --git a/svelte.config.js b/svelte.config.js index 472fd466a2..db6be85734 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -55,7 +55,7 @@ const config = { $markdoc: './src/markdoc' }, prerender: { - handleHttpError: 'warn' + concurrency: 64 } } };