From 84f17f2d984760cf454b72e1c4c5d1faaf9e525c Mon Sep 17 00:00:00 2001 From: Derock Date: Sat, 10 Feb 2024 14:20:20 -0500 Subject: [PATCH] fix missing keys, refactor out main component --- src/generator/index.tsx | 69 ++---------------------- src/generator/renderers/attachment.tsx | 4 +- src/generator/renderers/components.tsx | 2 +- src/generator/renderers/content.tsx | 4 +- src/generator/renderers/message.tsx | 14 +++-- src/generator/transcript.tsx | 74 ++++++++++++++++++++++++++ src/index.ts | 3 ++ tests/generate.ts | 1 - 8 files changed, 96 insertions(+), 75 deletions(-) create mode 100644 src/generator/transcript.tsx diff --git a/src/generator/index.tsx b/src/generator/index.tsx index ce401b8..14ae04c 100644 --- a/src/generator/index.tsx +++ b/src/generator/index.tsx @@ -1,15 +1,13 @@ -import { ChannelType, type Awaitable, type Channel, type Message, type Role, type User } from 'discord.js'; +import { type Awaitable, type Channel, type Message, type Role, type User } from 'discord.js'; import ReactDOMServer from 'react-dom/server'; -import React, { Suspense } from 'react'; -import { DiscordHeader, DiscordMessages } from '@derockdev/discord-components-react'; -import DiscordMessage from './renderers/message'; -import MessageContent, { RenderType } from './renderers/content'; +import React from 'react'; import { buildProfiles } from '../utils/buildProfiles'; import { revealSpoiler, scrollToMessage } from '../static/client'; import { readFileSync } from 'fs'; import path from 'path'; import { renderToString } from '@derockdev/discord-components-core/hydrate'; import { streamToString } from '../utils/utils'; +import DiscordMessages from './transcript'; // read the package.json file and get the @derockdev/discord-components-core version let discordComponentsVersion = '^3.6.1'; @@ -41,65 +39,6 @@ export type RenderMessageContext = { export default async function render({ messages, channel, callbacks, ...options }: RenderMessageContext) { const profiles = buildProfiles(messages); - const elements = ( - - {/* header */} - - {channel.isThread() ? ( - `Thread channel in ${channel.parent?.name ?? 'Unknown Channel'}` - ) : channel.isDMBased() ? ( - `Direct Messages` - ) : channel.isVoiceBased() ? ( - `Voice Text Channel for ${channel.name}` - ) : channel.type === ChannelType.GuildCategory ? ( - `Category Channel` - ) : 'topic' in channel && channel.topic ? ( - - ) : ( - `This is the start of #${channel.name} channel.` - )} - - - {/* body */} - - {messages.map((message) => ( - - ))} - - - {/* footer */} -
- {options.footerText - ? options.footerText - .replaceAll('{number}', messages.length.toString()) - .replace('{s}', messages.length > 1 ? 's' : '') - : `Exported ${messages.length} message${messages.length > 1 ? 's' : ''}.`}{' '} - {options.poweredBy ? ( - - Powered by{' '} - - discord-html-transcripts - - . - - ) : null} -
-
- ); - // NOTE: this renders a STATIC site with no interactivity // if interactivity is needed, switch to renderToPipeableStream and use hydrateRoot on client. const stream = ReactDOMServer.renderToStaticNodeStream( @@ -154,7 +93,7 @@ export default async function render({ messages, channel, callbacks, ...options minHeight: '100vh', }} > - {elements} + {/* Make sure the script runs after the DOM has loaded */} diff --git a/src/generator/renderers/attachment.tsx b/src/generator/renderers/attachment.tsx index eab488c..adfde25 100644 --- a/src/generator/renderers/attachment.tsx +++ b/src/generator/renderers/attachment.tsx @@ -16,8 +16,8 @@ export async function Attachments(props: { message: Message; context: RenderMess return ( - {props.message.attachments.map((attachment) => ( - + {props.message.attachments.map((attachment, id) => ( + ))} ); diff --git a/src/generator/renderers/components.tsx b/src/generator/renderers/components.tsx index 910a928..dd1065f 100644 --- a/src/generator/renderers/components.tsx +++ b/src/generator/renderers/components.tsx @@ -7,7 +7,7 @@ export default function ComponentRow({ row, id }: { row: ActionRow {row.components.map((component, id) => ( - + ))} ); diff --git a/src/generator/renderers/content.tsx b/src/generator/renderers/content.tsx index bbb6e80..b09ca69 100644 --- a/src/generator/renderers/content.tsx +++ b/src/generator/renderers/content.tsx @@ -77,8 +77,8 @@ async function MessageASTNodes({ if (Array.isArray(nodes)) { return ( <> - {nodes.map((node) => ( - + {nodes.map((node, i) => ( + ))} ); diff --git a/src/generator/renderers/message.tsx b/src/generator/renderers/message.tsx index 4db48b4..90f478f 100644 --- a/src/generator/renderers/message.tsx +++ b/src/generator/renderers/message.tsx @@ -1,7 +1,7 @@ import { DiscordAttachments, DiscordCommand, - DiscordMessage, + DiscordMessage as DiscordMessageComponent, DiscordReaction, DiscordReactions, DiscordThread, @@ -18,13 +18,19 @@ import { DiscordEmbed } from './embed'; import MessageReply from './reply'; import DiscordSystemMessage from './systemMessage'; -export default async function Message({ message, context }: { message: MessageType; context: RenderMessageContext }) { +export default async function DiscordMessage({ + message, + context, +}: { + message: MessageType; + context: RenderMessageContext; +}) { if (message.system) return ; const isCrosspost = message.reference && message.reference.guildId !== message.guild?.id; return ( - )} - + ); } diff --git a/src/generator/transcript.tsx b/src/generator/transcript.tsx new file mode 100644 index 0000000..c1d64e3 --- /dev/null +++ b/src/generator/transcript.tsx @@ -0,0 +1,74 @@ +import { DiscordHeader, DiscordMessages as DiscordMessagesComponent } from '@derockdev/discord-components-react'; +import { ChannelType } from 'discord.js'; +import React, { Suspense } from 'react'; +import type { RenderMessageContext } from '.'; +import MessageContent, { RenderType } from './renderers/content'; +import DiscordMessage from './renderers/message'; + +/** + * The core transcript component. + * Expects window.$discordMessage.profiles to be set for profile information. + * + * @param props Messages, channel details, callbacks, etc. + * @returns + */ +export default async function DiscordMessages({ messages, channel, callbacks, ...options }: RenderMessageContext) { + return ( + + {/* header */} + + {channel.isThread() ? ( + `Thread channel in ${channel.parent?.name ?? 'Unknown Channel'}` + ) : channel.isDMBased() ? ( + `Direct Messages` + ) : channel.isVoiceBased() ? ( + `Voice Text Channel for ${channel.name}` + ) : channel.type === ChannelType.GuildCategory ? ( + `Category Channel` + ) : 'topic' in channel && channel.topic ? ( + + ) : ( + `This is the start of #${channel.name} channel.` + )} + + + {/* body */} + + {messages.map((message) => ( + + ))} + + + {/* footer */} +
+ {options.footerText + ? options.footerText + .replaceAll('{number}', messages.length.toString()) + .replace('{s}', messages.length > 1 ? 's' : '') + : `Exported ${messages.length} message${messages.length > 1 ? 's' : ''}.`}{' '} + {options.poweredBy ? ( + + Powered by{' '} + + discord-html-transcripts + + . + + ) : null} +
+
+ ); +} diff --git a/src/index.ts b/src/index.ts index 9a3a7fd..dd39a2a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,9 @@ import { type ObjectType, } from './types'; +// re-export component for custom rendering +export { default as DiscordMessages } from './generator/transcript'; + // version check const versionPrefix = version.split('.')[0]; diff --git a/tests/generate.ts b/tests/generate.ts index 566d37c..6e3893e 100644 --- a/tests/generate.ts +++ b/tests/generate.ts @@ -17,7 +17,6 @@ client.on('ready', async () => { process.exit(1); } - console.log('Generating transcript for', channel); console.time('transcript'); const attachment = await createTranscript(channel); console.timeEnd('transcript');