mirror of
https://github.com/lux-tel/session-desktop.git
synced 2026-10-30 20:33:24 +00:00
76 lines
2.9 KiB
TypeScript
76 lines
2.9 KiB
TypeScript
import styled from 'styled-components';
|
|
import { SessionHtmlRenderer } from './SessionHTMLRenderer';
|
|
import {
|
|
formatMessageWithArgs,
|
|
GetMessageArgs,
|
|
MergedLocalizerTokens,
|
|
sanitizeArgs,
|
|
getRawMessage,
|
|
messageArgsToArgsOnly,
|
|
type ArgsFromToken,
|
|
type LocalizerHtmlTag,
|
|
} from '../../localization/localeTools';
|
|
import { getCrowdinLocale } from '../../util/i18n/shared';
|
|
|
|
/** An array of supported html tags to render if found in a string */
|
|
export const supportedFormattingTags = ['b', 'i', 'u', 's', 'br', 'span'];
|
|
/** NOTE: self-closing tags must also be listed in {@link supportedFormattingTags} */
|
|
const supportedSelfClosingFormattingTags = ['br'];
|
|
|
|
function createSupportedFormattingTagsRegex() {
|
|
return new RegExp(
|
|
`<(?:${supportedFormattingTags.join('|')})>.*?</(?:${supportedFormattingTags.join('|')})>|<(?:${supportedSelfClosingFormattingTags.join('|')})\\/>`,
|
|
'g'
|
|
);
|
|
}
|
|
|
|
const StyledHtmlRenderer = styled.span`
|
|
* > span {
|
|
color: var(--renderer-span-primary-color);
|
|
}
|
|
|
|
* > span[role='img'] {
|
|
font-family: var(--font-icon);
|
|
vertical-align: top;
|
|
}
|
|
`;
|
|
|
|
export type WithAsTag = { asTag?: LocalizerHtmlTag };
|
|
export type WithClassName = { className?: string };
|
|
|
|
/**
|
|
* Retrieve a localized message string, substituting dynamic parts where necessary and formatting it as HTML if necessary.
|
|
*
|
|
* @param props.token - The token identifying the message to retrieve and an optional record of substitution variables and their replacement values.
|
|
* @param props.args - An optional record of substitution variables and their replacement values. This is required if the string has dynamic parts.
|
|
* @param props.as - An optional HTML tag to render the component as. Defaults to a fragment, unless the string contains html tags. In that case, it will render as HTML in a div tag.
|
|
*
|
|
* @returns The localized message string with substitutions and formatting applied.
|
|
*/
|
|
export const Localizer = <T extends MergedLocalizerTokens>(
|
|
props: GetMessageArgs<T> & WithAsTag & WithClassName
|
|
) => {
|
|
const args = messageArgsToArgsOnly(props);
|
|
|
|
let rawString: string = getRawMessage<T>(getCrowdinLocale(), props);
|
|
|
|
const containsFormattingTags = createSupportedFormattingTagsRegex().test(rawString);
|
|
const cleanArgs = args && containsFormattingTags ? sanitizeArgs(args) : args;
|
|
|
|
const containsIcons = !!(cleanArgs && Object.keys(cleanArgs).includes('icon'));
|
|
if (containsIcons && (cleanArgs as any).icon) {
|
|
rawString = rawString.replaceAll(/\{icon}/g, `<span role='img'>{icon}</span>`);
|
|
}
|
|
|
|
const i18nString = formatMessageWithArgs(rawString, cleanArgs as ArgsFromToken<T>);
|
|
|
|
return containsFormattingTags || containsIcons ? (
|
|
/** If the string contains a relevant formatting tag, render it as HTML */
|
|
<StyledHtmlRenderer>
|
|
<SessionHtmlRenderer tag={props.asTag} html={i18nString} className={props.className} />
|
|
</StyledHtmlRenderer>
|
|
) : (
|
|
i18nString
|
|
);
|
|
};
|