mattermost-mobile-upstream/app/components/syntax_highlight/index.tsx
Elias Nahum b6fc85385e
Migrate from RNN to Expo router (#9402)
* Expo-Router partial migration

* Full migration to ExpoRouter

* i18n

* add tests

* Merge branch 'main' into expo-router

* align package-lock.json

* i18n

* feedback review

* feedback review

* android 16kb patch

* Refactored emoji picker keyboard using a state machine

* set android launch_screen in drawables instead of layout

* no conditional hooks

* remove duplicate call in test

* address feedback

* fix tests and address more feedback

* small corrections

* small corrections

* small corrections

* fix draft test

* fix draft test 2

* remove navigateToScreen in draff test

* fix nit in draft test

* remove doc file

* Feedback review

* fix snapshots

* improve test coverage

* fix i18n

* Upgrade t o RN 0.83, other dependencies and new architecture (#9737)

* library hardware-keyboard android new arch support fix

* library rnshare android new arch support fix

* library rnutils android new arch support fix

* library secure-pdf-viewer add new arch support

* Enable new arch on iOS and Android

* update emm and network client with new-arch

* update intune to use new-arch

* performance improvements

* fix tests

* fixes post input on new-arch

* fix android emoji picker

* remove doc

* run tests in parallel

* upgrade to React Native 0.83.9, Expo 55, React 19, and New Architecture

Bumps core dependencies to their latest versions:
- React Native 0.77.3 → 0.83.9 (New Architecture enabled)
- React 18.3.1 → 19.2.5
- Expo SDK 52 → 55
- TypeScript 5.8.3 → 6.0.3
- Node.js 22.16.0 → 24.15.0
- react-native-reanimated 3.17.3 → 4.3.0
- Various other dependency upgrades

Migrates iOS AppDelegate from Objective-C to Swift, updates Android
build tooling and Gradle wrapper, refreshes all patches and font
assets, and adapts app code, tests, and CI workflows throughout for
API changes introduced by these upgrades.

* remove unecessary dismissKeyboard in notifications

* feedback review

* update intune to use new-arch

* update @mattermost deps

* missing i18n string

* additional fixes

* update fastlane
2026-05-13 17:44:55 +08:00

92 lines
2.9 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useMemo} from 'react';
import {StyleSheet, View} from 'react-native';
import SyntaxHighlighter from 'react-syntax-highlighter';
import {githubGist as github, monokai, solarizedDark, solarizedLight} from 'react-syntax-highlighter/dist/cjs/styles/hljs';
import {useTheme} from '@context/theme';
import CodeHighlightRenderer from './renderer';
import type {SyntaxHiglightProps} from '@typings/components/syntax_highlight';
const codeTheme: Record<string, any> = {
github,
monokai,
'solarized-dark': solarizedDark,
'solarized-light': solarizedLight,
};
const styles = StyleSheet.create({
preTag: {
padding: 5,
width: '100%',
},
flex: {
flex: 1,
},
});
function getMaximumLineLength(code: string) {
return code.split('\n').reduce((prev, v) => Math.max(prev, v.length), 0);
}
const MAXIMUM_CODE_LINE_LENGTH = 300;
const Highlighter = ({code, language, textStyle, selectable = false}: SyntaxHiglightProps) => {
const theme = useTheme();
const style = codeTheme[theme.codeTheme] || github;
const preTagStyle = useMemo(() => [
styles.preTag,
selectable && styles.flex,
{backgroundColor: style.hljs.background || theme.centerChannelBg},
],
[theme, selectable, style]);
const maximumLineLength = useMemo(() => getMaximumLineLength(code), [code]);
const languageToUse = maximumLineLength > MAXIMUM_CODE_LINE_LENGTH ? 'text' : language;
const showLineNumbers = useMemo(() => code.split('\n').length > 1, [code]);
const nativeRenderer = useCallback(({rows, stylesheet}: rendererProps) => {
const digits = rows.length.toString().length;
return (
<CodeHighlightRenderer
digits={digits}
rows={rows}
stylesheet={stylesheet}
defaultColor={style.hljs.color || theme.centerChannelColor}
fontFamily={textStyle.fontFamily || 'monospace'}
fontSize={textStyle.fontSize}
selectable={selectable}
selectionColor={theme.onlineIndicator}
/>
);
}, [style.hljs.color, theme.centerChannelColor, theme.onlineIndicator, textStyle.fontFamily, textStyle.fontSize, selectable]);
const preTag = useCallback((info: any) => (
<View
style={preTagStyle}
>
{info.children}
</View>
), [preTagStyle]);
return (
<SyntaxHighlighter
style={style}
language={languageToUse}
horizontal={true}
showLineNumbers={showLineNumbers}
renderer={nativeRenderer}
PreTag={preTag}
CodeTag={View}
wrapLines={true}
>
{code}
</SyntaxHighlighter>
);
};
export default Highlighter;