Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/animations/Searching_Fox.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Third party dependencies.
import { StyleSheet, TextStyle, Dimensions } from 'react-native';
import { StyleSheet, Dimensions, TextStyle, Platform } from 'react-native';
import { Theme } from '../../../../util/theme/models';
import { getFontFamily, TextVariant } from '../../Texts/Text';
import { typography } from '@metamask/design-tokens';
import { colors as commonColors } from '../../../../styles/common';

const screenHeight = Dimensions.get('window').height;
/**
Expand All @@ -12,9 +14,10 @@ const screenHeight = Dimensions.get('window').height;
* @param params.vars Inputs that the style sheet depends on.
* @returns StyleSheet object.
*/

const styleSheet = (params: { theme: Theme }) => {
const { theme } = params;
const { colors, typography } = theme;
const { colors } = theme;

return StyleSheet.create({
screen: {
Expand All @@ -23,8 +26,14 @@ const styleSheet = (params: { theme: Theme }) => {
modal: {
backgroundColor: colors.background.default,
borderRadius: 10,
padding: 16,
marginHorizontal: 16,
padding: 0,
paddingHorizontal: 16,
paddingTop: 16,
},
headerContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
headerText: {
color: colors.text.default,
Expand All @@ -33,10 +42,20 @@ const styleSheet = (params: { theme: Theme }) => {
textAlign: 'center',
marginBottom: 16,
},
bodyContainer: { height: screenHeight / 2 },
headerEmpty: {
width: 32,
height: 32,
},
bodyContainer: { height: screenHeight / 2, padding: 0 },
checkboxContainer: {
flexDirection: 'row',
marginTop: 16,
columnGap: 8,
marginRight: 16,
width: '90%',
borderTopWidth: 1,
borderColor: colors.border.muted,
paddingTop: 16,
},
checkboxText: {
marginLeft: 8,
Expand All @@ -50,26 +69,25 @@ const styleSheet = (params: { theme: Theme }) => {
width: '100%',
},
scrollToEndButton: {
width: 32,
height: 32,
borderRadius: 32 / 2,
backgroundColor: colors.background.default,
width: 40,
height: 40,
borderRadius: 40 / 2,
backgroundColor: commonColors.modalScrollButton,
justifyContent: 'center',
alignItems: 'center',
zIndex: 1,
zIndex: 10,
position: 'absolute',
bottom: 175,
right: 32,
borderWidth: 1,
borderColor: colors.primary.default,
boxShadow: `0px 3px 8px ${commonColors.modalScrollButton}`,
},
footerHelpText: {
marginTop: 16,
marginBottom: 4,
textAlign: 'center',
color: colors.text.alternative,
...(typography.sBodySM as TextStyle),
fontFamily: getFontFamily(TextVariant.BodySM),
marginBottom: Platform.OS === 'ios' ? 8 : 16,
},
});
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import ModalMandatory from './ModalMandatory';
import renderWithProvider from '../../../../util/test/renderWithProvider';
import { SafeAreaProvider } from 'react-native-safe-area-context';
const mockedNavigate = jest.fn();

jest.mock('@react-navigation/native', () => {
Expand All @@ -15,35 +16,39 @@ jest.mock('@react-navigation/native', () => {
describe('Mandatory Modal', () => {
it('should render correctly webview mandatory modal', () => {
const { toJSON } = renderWithProvider(
<ModalMandatory
route={{
params: {
headerTitle: 'test',
footerHelpText: 'test',
buttonText: 'test',
body: { source: 'WebView', uri: 'http://google.com' },
onAccept: () => null,
checkboxText: 'test',
},
}}
/>,
<SafeAreaProvider>
<ModalMandatory
route={{
params: {
headerTitle: 'test',
footerHelpText: 'test',
buttonText: 'test',
body: { source: 'WebView', uri: 'http://google.com' },
onAccept: () => null,
checkboxText: 'test',
},
}}
/>
</SafeAreaProvider>,
);
expect(toJSON).toMatchSnapshot();
});
it('should render correctly component mandatory modal', () => {
const { toJSON } = renderWithProvider(
<ModalMandatory
route={{
params: {
headerTitle: 'test',
footerHelpText: 'test',
buttonText: 'test',
body: { source: 'Node', component: () => <></> },
onAccept: () => null,
checkboxText: 'test',
},
}}
/>,
<SafeAreaProvider>
<ModalMandatory
route={{
params: {
headerTitle: 'test',
footerHelpText: 'test',
buttonText: 'test',
body: { source: 'Node', component: () => <></> },
onAccept: () => null,
checkboxText: 'test',
},
}}
/>
</SafeAreaProvider>,
);
expect(toJSON).toMatchSnapshot();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ import { WebView } from '@metamask/react-native-webview';

// External dependencies.
import ButtonPrimary from '../../Buttons/Button/variants/ButtonPrimary';
import Text from '../../Texts/Text';
import Text, { TextVariant, TextColor } from '../../Texts/Text';
import { useStyles } from '../../../hooks';
import { useTheme } from '../../../../util/theme';
import ReusableModal, {
ReusableModalRef,
} from '../../../../components/UI/ReusableModal';
import Checkbox from '../../../../component-library/components/Checkbox';
import { IconName } from '../../../../component-library/components/Icons/Icon';
import ButtonIcon from '../../../../component-library/components/Buttons/ButtonIcon';

// Internal dependencies
import {
WEBVIEW_SCROLL_END_EVENT,
Expand All @@ -34,12 +30,13 @@ import {
} from './ModalMandatory.types';
import stylesheet from './ModalMandatory.styles';
import { TermsOfUseModalSelectorsIDs } from '../../../../../e2e/selectors/Onboarding/TermsOfUseModal.selectors';
import BottomSheet, { BottomSheetRef } from '../../BottomSheets/BottomSheet';

const ModalMandatory = ({ route }: MandatoryModalProps) => {
const { colors } = useTheme();
const { styles } = useStyles(stylesheet, {});
const modalRef = useRef<ReusableModalRef>(null);
const webViewRef = useRef<WebView>(null);
const bottomSheetRef = useRef<BottomSheetRef>(null);

const [isWebViewLoaded, setIsWebViewLoaded] = useState<boolean>(false);
const [isScrollEnded, setIsScrollEnded] = useState<boolean>(false);
Expand Down Expand Up @@ -122,14 +119,29 @@ const ModalMandatory = ({ route }: MandatoryModalProps) => {
};
}, []);

const renderHeader = () => (
<Text style={styles.headerText}>{headerTitle}</Text>
);

const onPress = () => {
modalRef.current?.dismissModal(onAccept);
bottomSheetRef.current?.onCloseBottomSheet(onAccept);
};

const onClose = () => {
bottomSheetRef.current?.onCloseBottomSheet();
};

const renderHeader = () => (
<View style={styles.headerContainer}>
<View style={styles.headerEmpty} />
<Text variant={TextVariant.HeadingMD} color={TextColor.Default}>
{headerTitle}
</Text>
<ButtonIcon
testID={TermsOfUseModalSelectorsIDs.CLOSE_BUTTON}
onPress={onClose}
iconName={IconName.Close}
hitSlop={12}
/>
</View>
);

const onMessage = (event: { nativeEvent: { data: string } }) => {
if (event.nativeEvent.data === WEBVIEW_SCROLL_END_EVENT) {
setIsScrollEnded(true);
Expand All @@ -152,6 +164,7 @@ const ModalMandatory = ({ route }: MandatoryModalProps) => {
testID={TermsOfUseModalSelectorsIDs.SCROLL_ARROW_BUTTON}
onPress={scrollToEnd}
iconName={IconName.ArrowDown}
iconColor={colors.primary.default}
hitSlop={12}
/>
</View>
Expand Down Expand Up @@ -231,7 +244,7 @@ const ModalMandatory = ({ route }: MandatoryModalProps) => {
};

return (
<ReusableModal ref={modalRef} style={styles.screen} isInteractable={false}>
<BottomSheet ref={bottomSheetRef} shouldNavigateBack>
<View style={styles.modal} testID={containerTestId}>
{renderHeader()}
<View
Expand All @@ -247,7 +260,9 @@ const ModalMandatory = ({ route }: MandatoryModalProps) => {
testID={TermsOfUseModalSelectorsIDs.CHECKBOX}
>
<Checkbox onPress={handleSelect} isChecked={isCheckboxSelected} />
<Text style={styles.checkboxText}>{checkboxText}</Text>
<Text variant={TextVariant.BodySMMedium} color={TextColor.Default}>
{checkboxText}
</Text>
</TouchableOpacity>
<ButtonPrimary
label={buttonText}
Expand All @@ -265,10 +280,16 @@ const ModalMandatory = ({ route }: MandatoryModalProps) => {
/>
{isScrollToEndNeeded && renderScrollEndButton()}
{footerHelpText ? (
<Text style={styles.footerHelpText}>{footerHelpText}</Text>
<Text
style={styles.footerHelpText}
variant={TextVariant.BodySM}
color={TextColor.Alternative}
>
{footerHelpText}
</Text>
) : null}
</View>
</ReusableModal>
</BottomSheet>
);
};

Expand Down
58 changes: 51 additions & 7 deletions app/components/UI/Navbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -682,17 +682,61 @@ export function getOnboardingNavbarOptions(
*
* @returns {Object} - Corresponding navbar options containing headerTitle
*/
export function getTransparentOnboardingNavbarOptions(themeColors) {
export function getTransparentOnboardingNavbarOptions(
themeColors,
showLogo = true,
color,
darkColor = false,
) {
const innerStyles = StyleSheet.create({
headerStyle: {
backgroundColor: themeColors.background.default,
backgroundColor: color || themeColors.background.default,
shadowColor: importedColors.transparent,
elevation: 0,
},
metamaskName: {
width: 70,
height: 35,
tintColor: darkColor ? importedColors.btnBlack : themeColors.text.default,
},
});
return {
headerTitle: () =>
showLogo ? (
<View style={styles.metamaskNameTransparentWrapper}>
<Image
source={metamask_name}
style={innerStyles.metamaskName}
resizeMethod={'auto'}
/>
</View>
) : null,
headerLeft: () => <View />,
headerRight: () => <View />,
headerStyle: innerStyles.headerStyle,
};
}

/**
* Function that returns a Carousel navigation options for our onboarding screens.
*
* @returns {Object} - Corresponding navbar options containing headerTitle
* @param {Object} themeColors - The theme colors object
* @param {string} currentTabColor - The color of the current tab
*/
export function getOnboardingCarouselNavbarOptions(
themeColors,
currentTabColor,
) {
const innerStyles = StyleSheet.create({
headerStyle: {
backgroundColor: currentTabColor,
shadowColor: importedColors.transparent,
elevation: 0,
},
metamaskName: {
width: 70,
height: 35,
tintColor: themeColors.text.default,
},
});
return {
Expand All @@ -716,17 +760,16 @@ export function getTransparentOnboardingNavbarOptions(themeColors) {
*
* @returns {Object} - Corresponding navbar options containing headerTitle and a back button
*/
export function getTransparentBackOnboardingNavbarOptions(themeColors) {
export function getTransparentBackOnboardingNavbarOptions(themeColors, color) {
const innerStyles = StyleSheet.create({
headerStyle: {
backgroundColor: themeColors.background.default,
backgroundColor: color || themeColors.background.default,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would rename color to backgroundColor be more accurate?

shadowColor: importedColors.transparent,
elevation: 0,
},
metamaskName: {
width: 70,
height: 35,
tintColor: themeColors.text.default,
},
});
return {
Expand All @@ -739,8 +782,9 @@ export function getTransparentBackOnboardingNavbarOptions(themeColors) {
/>
</View>
),
headerBackTitle: strings('navigation.back'),
headerRight: () => <View />,
headerBackTitle: strings('navigation.back'),
headerLeft: () => <View />,
headerStyle: innerStyles.headerStyle,
headerTintColor: themeColors.primary.default,
};
Expand Down
Loading
Loading