diff --git a/src/generator/index.tsx b/src/generator/index.tsx index bd7c329..5ce2f3e 100644 --- a/src/generator/index.tsx +++ b/src/generator/index.tsx @@ -9,6 +9,7 @@ import { revealSpoiler, scrollToMessage } from '../static/client'; import { readFileSync } from 'fs'; import path from 'path'; import { renderToString } from '@derockdev/discord-components-core/hydrate'; +import type { Language } from '../languages'; // read the package.json file and get the @derockdev/discord-components-core version let discordComponentsVersion = '^3.6.1'; @@ -35,6 +36,8 @@ export type RenderMessageContext = { saveImages: boolean; favicon: 'guild' | string; hydrate: boolean; + + language: Language; }; export default async function renderMessages({ messages, channel, callbacks, ...options }: RenderMessageContext) { diff --git a/src/generator/renderers/reply.tsx b/src/generator/renderers/reply.tsx index a880822..5b3421a 100644 --- a/src/generator/renderers/reply.tsx +++ b/src/generator/renderers/reply.tsx @@ -33,10 +33,10 @@ export default async function renderReply(message: Message, context: RenderMessa {await renderContent(referencedMessage.content, { ...context, type: RenderType.REPLY })} - ) : isCommand ? ( - Click to see command. ) : ( - Click to see attachment. + + {context.language.format(isCommand ? 'reply.command' : 'reply.attachment')} + )} ); diff --git a/src/index.ts b/src/index.ts index b3250c1..157ae3d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ import { type GenerateFromMessagesOptions, type ObjectType, } from './types'; +import { Language } from './languages'; // version check const versionPrefix = version.split('.')[0]; @@ -51,6 +52,7 @@ export async function generateFromMessages = T extends Array + ? '' + : T extends object + ? { + [K in keyof T]: T[K] extends object ? `${K & string}.${DotNotation}` : K & string; + }[keyof T] + : T & string; + +/** + * A class to handle language strings + */ +export class Language { + private readonly language: LanguageType; + + constructor(public readonly languageName: Languages) { + if (languageName in languages) { + this.language = languages[languageName]; + } + + console.warn(`[discord-html-transcripts] Language "${languageName}" not found, defaulting to "en-US".`); + this.language = languages['en-US']; + } + + /** + * Return a formatted string with the given language path (e.g. `reply.command`) + * @param path The path to the string + * @param args The arguments to pass to the string + */ + public format(path: DotNotation, ...args: unknown[]): string { + let lang = this.language; + const keys = path.split('.'); + + // traverse the language object + for (const key of keys) { + if (key in lang) { + // @ts-expect-error - key narrowing for ts not implemented (issue #43284) + lang = lang[key]; + } else { + if (this.languageName === 'en-US') { + throw new Error(`[discord-html-transcripts] Language path "${path}" not found.`); + } + + return new Language('en-US').format(path, ...args); + } + } + + // if array, choose a random element + if (Array.isArray(lang)) { + lang = lang[Math.floor(Math.random() * lang.length)]; + } + + return format(lang, ...args); + } +} diff --git a/src/languages/types.ts b/src/languages/types.ts new file mode 100644 index 0000000..8e17fe3 --- /dev/null +++ b/src/languages/types.ts @@ -0,0 +1,19 @@ +/** + * Common language type + */ +export type Language = { + reply: { + command: string; + attachment: string; + }; + + system: { + joinMessages: string[]; + messagePinned: string; + }; + + // /** + // * Server boosts + // */ + // boosts +}; diff --git a/src/types.ts b/src/types.ts index f97516c..9d8f773 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,6 @@ import type { AttachmentBuilder } from 'discord.js'; import type { RenderMessageContext } from './generator'; +import type { Languages } from './languages'; export type AttachmentTypes = 'audio' | 'video' | 'image' | 'file'; @@ -64,6 +65,12 @@ export type GenerateFromMessagesOptions = Partial<{ * @default false - the returned html will be hydrated client-side */ hydrate: boolean; + + /** + * The language to use, e.g. 'en-US'. See documentation for list of supported languages. + * @default 'en-US' + */ + language: Languages; }>; export type CreateTranscriptOptions = Partial<