* Handle biometric authentication * jailbreak/root detection and biometric small fixes * remove server from initializeSecurityManager and fix loginEntry * Add screen capture prevention and other small fixes * added unit tests to SecurityManager * added shielded nativeID to protect views * use MobilePreventScreenCapture instead of MobileAllowScreenshots in config type definition * Apply Swizzle for screen capture on iOS * Apply patch to bottom sheet to prevent screen captures * fix ios sendReply * Fix SDWebImage swizzle to use the correct session * Fix potential crash on Android when using hardware keyboard * rename patch for network library to remove warning * add temp emm reference * fix initializeSecurityManager tests * fix translations * use siteName for jailbreak detection when connecting to a new server * fix i18n typo * do not query the entire config from the db only the required fields * migrate manage_apps to use defineMessages * use TestHelper.wait in tests * use defineMessages for security manager * fix missing else statement for gm_to_channel * created a TestHelper function to mockQuery and replace as jest.Mock with jest.mocked * fix unit tests * fix unit tests (again) and include setting the test environment to UTC * Fix keyboard disappearing on iOS * update react-native-emm
149 lines
4.7 KiB
TypeScript
149 lines
4.7 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import React, {useCallback, useMemo, useState} from 'react';
|
|
import {ScrollView, View, type StyleProp, type ViewStyle} from 'react-native';
|
|
|
|
import AutocompleteSelector from '@components/autocomplete_selector';
|
|
import {Preferences} from '@constants';
|
|
import {CustomThemeProvider} from '@context/theme';
|
|
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
|
|
import SecurityManager from '@managers/security_manager';
|
|
import {popTopScreen} from '@screens/navigation';
|
|
|
|
import ButtonComponentLibrary from './button.cl';
|
|
|
|
import type {AvailableScreens} from '@typings/screens/navigation';
|
|
|
|
const componentMap = {
|
|
Button: ButtonComponentLibrary,
|
|
};
|
|
|
|
type ComponentName = keyof typeof componentMap
|
|
const defaultComponent = Object.keys(componentMap)[0] as ComponentName;
|
|
const componentOptions = Object.keys(componentMap).map((v) => ({
|
|
value: v,
|
|
text: v,
|
|
}));
|
|
|
|
type ThemeName = keyof typeof Preferences.THEMES;
|
|
const defaultTheme = Object.keys(Preferences.THEMES)[0] as ThemeName;
|
|
const themeOptions = Object.keys(Preferences.THEMES).map((v) => ({
|
|
value: v,
|
|
text: v,
|
|
}));
|
|
|
|
type BackgroundType = 'center' | 'sidebar';
|
|
const backgroundOptions = [{
|
|
value: 'center',
|
|
text: 'Center channel',
|
|
}, {
|
|
value: 'sidebar',
|
|
text: 'Sidebar background',
|
|
}];
|
|
|
|
type Props = {
|
|
componentId: AvailableScreens;
|
|
};
|
|
|
|
const ComponentLibrary = ({componentId}: Props) => {
|
|
const [selectedComponent, setSelectedComponent] = useState<ComponentName>(defaultComponent);
|
|
const onSelectComponent = useCallback((value: SelectedDialogOption) => {
|
|
if (!value) {
|
|
setSelectedComponent(defaultComponent);
|
|
return;
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
setSelectedComponent(value[0].value as ComponentName);
|
|
return;
|
|
}
|
|
setSelectedComponent(value.value as ComponentName);
|
|
}, []);
|
|
|
|
const [selectedTheme, setSelectedTheme] = useState(defaultTheme);
|
|
const onSelectTheme = useCallback((value: SelectedDialogOption) => {
|
|
if (!value) {
|
|
setSelectedTheme(defaultTheme);
|
|
return;
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
setSelectedTheme(value[0].value as ThemeName);
|
|
return;
|
|
}
|
|
setSelectedTheme(value.value as ThemeName);
|
|
}, []);
|
|
|
|
const [selectedBackground, setSelectedBackground] = useState<BackgroundType>('center');
|
|
const onSelectBackground = useCallback((value: SelectedDialogOption) => {
|
|
if (!value) {
|
|
setSelectedBackground('center');
|
|
return;
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
setSelectedBackground(value[0].value as BackgroundType);
|
|
return;
|
|
}
|
|
setSelectedBackground(value.value as BackgroundType);
|
|
}, []);
|
|
|
|
const backgroundStyle: StyleProp<ViewStyle> = useMemo(() => {
|
|
const theme = Preferences.THEMES[selectedTheme];
|
|
switch (selectedBackground) {
|
|
case 'center':
|
|
return {
|
|
backgroundColor: theme.centerChannelBg,
|
|
};
|
|
case 'sidebar':
|
|
default:
|
|
return {
|
|
backgroundColor: theme.sidebarBg,
|
|
};
|
|
}
|
|
}, [selectedBackground, selectedTheme]);
|
|
|
|
const close = useCallback(() => {
|
|
popTopScreen(componentId);
|
|
}, [componentId]);
|
|
|
|
useAndroidHardwareBackHandler(componentId, close);
|
|
|
|
const SelectedComponent = componentMap[selectedComponent];
|
|
return (
|
|
<ScrollView
|
|
style={{margin: 10}}
|
|
nativeID={SecurityManager.getShieldScreenId(componentId)}
|
|
>
|
|
<AutocompleteSelector
|
|
testID='selectedComponent'
|
|
label='Component'
|
|
onSelected={onSelectComponent}
|
|
selected={selectedComponent}
|
|
options={componentOptions}
|
|
/>
|
|
<AutocompleteSelector
|
|
testID='selectedTheme'
|
|
label='Theme'
|
|
onSelected={onSelectTheme}
|
|
selected={selectedTheme}
|
|
options={themeOptions}
|
|
/>
|
|
<AutocompleteSelector
|
|
testID='selectedBackground'
|
|
label='Background'
|
|
onSelected={onSelectBackground}
|
|
selected={selectedBackground}
|
|
options={backgroundOptions}
|
|
/>
|
|
<View style={backgroundStyle}>
|
|
<CustomThemeProvider theme={Preferences.THEMES[selectedTheme]}>
|
|
<SelectedComponent/>
|
|
</CustomThemeProvider>
|
|
</View>
|
|
</ScrollView>
|
|
);
|
|
};
|
|
|
|
export default ComponentLibrary;
|