Skip to content

Commit

Permalink
Handle nested translations correctly.
Browse files Browse the repository at this point in the history
This means translations in the `extra` property of PlainText,
or in the `with` property of Translated,
will be handled correctly.
  • Loading branch information
retrixe committed Aug 11, 2022
1 parent 3c53937 commit 32e77e3
Showing 1 changed file with 33 additions and 37 deletions.
70 changes: 33 additions & 37 deletions src/minecraft/chatToJsx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ export interface BaseChat {
obfuscated?: boolean
underlined?: boolean
strikethrough?: boolean
// TODO: This should be MinecraftChat, so translateChat should be
// called in flattenExtraComponents when the extra is translatable.
extra?: PlainTextChat[]
extra?: MinecraftChat[]
insertion?: string
clickEvent?: ClickEvent
hoverEvent?: HoverEvent
Expand All @@ -69,8 +67,7 @@ export interface PlainTextChat extends BaseChat {
text?: string
}

export interface TranslatedChat {
// TODO: This should extend BaseChat, so this should apply to child withs.
export interface TranslatedChat extends BaseChat {
translate: string
with: MinecraftChat[]
}
Expand Down Expand Up @@ -155,7 +152,32 @@ const trimLines = (s: string) =>
.join('\n')
: s.trimLeft() // LOW-TODO: This is problematic, temporary workaround until this can be refined.

const flattenExtraComponents = (chat: PlainTextChat): PlainTextChat[] => {
const isTranslatedChat = (chat: MinecraftChat): chat is TranslatedChat =>
typeof (chat as TranslatedChat).translate === 'string'

const translateChat = (chat: TranslatedChat): PlainTextChat => {
const { translate, with: tw, ...c } = chat
const translation = translations[translate]
?.split('%s')
?.flatMap((text, index) => {
let insert = tw && tw[index]
if (!insert) return { text }
else if (typeof insert === 'string') insert = { text: insert }
else if (isTranslatedChat(insert)) insert = translateChat(insert)
return [{ text }, insert]
})
if (!translation) {
return { text: `[EnderChat] Unknown translation ${translate}.` }
}
return {
...c,
extra: Array.isArray(c.extra) ? [...translation, ...c.extra] : translation
}
}

const flattenComponents = (chat: MinecraftChat): PlainTextChat[] => {
if (typeof chat === 'string') return parseColorCodes(chat)
else if (isTranslatedChat(chat)) chat = translateChat(chat)
const { extra, ...c } = chat
const arr =
c.text && hasColorCodes(c.text)
Expand All @@ -164,39 +186,13 @@ const flattenExtraComponents = (chat: PlainTextChat): PlainTextChat[] => {
? [c]
: []
if (!extra) return arr
const flattenedExtra = extra.flatMap(e =>
flattenExtraComponents({ ...c, ...e })
)
const flattenedExtra = extra.flatMap(e => {
if (typeof e === 'string') e = { text: e } // Colour codes will be parsed in the next step.
return flattenComponents({ ...c, ...e })
})
return [...arr, ...flattenedExtra]
}

const translateChat = (chat: TranslatedChat): PlainTextChat[] => {
if (!chat.with) chat.with = []
const translation = translations[chat.translate]
?.split('%s')
?.map((text, index) => {
let insert = chat.with[index] ? [chat.with[index]] : []
if (typeof insert[0] === 'string') insert = [{ text: insert[0] }]
else if (insert[0] && (insert[0] as TranslatedChat).translate) {
insert = translateChat(insert[0] as TranslatedChat)
}
return [{ text }, ...insert] as PlainTextChat[]
})
?.flat()
if (!translation) {
return [{ text: `[EnderChat] Unknown translation ${chat.translate}.` }]
} else return translation
}

const flattenTranslateComponents = (chat: MinecraftChat): PlainTextChat[] => {
if (typeof chat === 'string') return parseColorCodes(chat)
else if ((chat as TranslatedChat).translate) {
return translateChat(chat as TranslatedChat)
} else {
return flattenExtraComponents(chat as PlainTextChat)
}
}

const parseChatToJsx = (
chat: MinecraftChat,
Component: React.ComponentType<TextProps>,
Expand All @@ -205,7 +201,7 @@ const parseChatToJsx = (
componentProps?: {},
trim = false
) => {
const flat = flattenTranslateComponents(chat)
const flat = flattenComponents(chat)
return (
<Component {...componentProps}>
{flat.map((c, i) => {
Expand Down

0 comments on commit 32e77e3

Please sign in to comment.