Skip to content

Commit

Permalink
Merge branch 'main' into feature/ramp-deeplink-handler
Browse files Browse the repository at this point in the history
  • Loading branch information
wachunei authored Apr 22, 2024
2 parents b437bb2 + 87309d1 commit 5de1023
Show file tree
Hide file tree
Showing 59 changed files with 1,661 additions and 222 deletions.
7 changes: 7 additions & 0 deletions app/actions/notification/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,10 @@ export function removeNotVisibleNotifications() {
type: 'REMOVE_NOT_VISIBLE_NOTIFICATIONS',
};
}

export function updateNotificationStatus(notificationsSettings) {
return {
type: 'UPDATE_NOTIFICATION_STATUS',
notificationsSettings,
};
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { NotificationsKindTypes } from '../../../../../../util/notifications';
import { NotificationTypes } from '../../../../../../util/notifications';
import { IconName, IconSize } from '../../../../Icons/Icon/Icon.types';

// Internal dependencies.
import { BadgeNotificationsProps } from './BadgeNotifications.types';

// Test IDs
export const BADGE_NOTIFICATIONS_TEST_ID = 'badge-notifications';
export const TEST_NOTIFICATIONS_ACTION = NotificationsKindTypes.transaction;
export const TEST_NOTIFICATIONS_ACTION = NotificationTypes.TRANSACTION;
export const TEST_RNOTIFICATIONS_ICON_NAME = IconName.Send2;

// Defaults
export const DEFAULT_BADGENOTIFICATIONS_NOTIFICATIONSICON_SIZE = IconSize.Md;

export const SAMPLE_BADGENOTIFICATIONS_PROPS: BadgeNotificationsProps = {
name: TEST_NOTIFICATIONS_ACTION,
iconName: TEST_RNOTIFICATIONS_ICON_NAME,
};
50 changes: 50 additions & 0 deletions app/components/Nav/Main/MainNavigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import AdvancedSettings from '../../Views/Settings/AdvancedSettings';
import SecuritySettings from '../../Views/Settings/SecuritySettings';
import ExperimentalSettings from '../../Views/Settings/ExperimentalSettings';
import NetworksSettings from '../../Views/Settings/NetworksSettings';
import NotificationsSettings from '../../Views/Settings/NotificationsSettings';
import OptIn from '../../Views/Notifications/OptIn';
import AppInformation from '../../Views/Settings/AppInformation';
import Contacts from '../../Views/Settings/Contacts';
import Wallet from '../../Views/Wallet';
Expand Down Expand Up @@ -226,6 +228,22 @@ const SnapsSettingsStack = () => (
);
///: END:ONLY_INCLUDE_IF

const NotificationsOptInStack = () => (
<Stack.Navigator initialRouteName={Routes.NOTIFICATIONS.OPT_IN}>
<Stack.Screen
mode={'modal'}
name={Routes.NOTIFICATIONS.OPT_IN}
component={OptIn}
options={{ headerShown: false }}
/>
<Stack.Screen
name={Routes.SETTINGS.NOTIFICATIONS}
component={NotificationsSettings}
options={NotificationsSettings.navigationOptions}
/>
</Stack.Navigator>
);

const SettingsFlow = () => (
<Stack.Navigator initialRouteName={'Settings'}>
<Stack.Screen
Expand Down Expand Up @@ -318,6 +336,11 @@ const SettingsFlow = () => (
component={EnterPasswordSimple}
options={EnterPasswordSimple.navigationOptions}
/>
<Stack.Screen
name={Routes.SETTINGS.NOTIFICATIONS}
component={NotificationsSettings}
options={NotificationsSettings.navigationOptions}
/>
{
///: BEGIN:ONLY_INCLUDE_IF(snaps)
}
Expand Down Expand Up @@ -555,6 +578,27 @@ const PaymentRequestView = () => (
</Stack.Navigator>
);

const NotificationsModeView = (props) => (
<Stack.Navigator>
<Stack.Screen
name={Routes.SETTINGS.NOTIFICATIONS}
component={NotificationsSettings}
options={NotificationsSettings.navigationOptions}
/>
<Stack.Screen
mode={'modal'}
name="NotificationsOptIn"
component={OptIn}
options={OptIn.navigationOptions}
/>
<Stack.Screen
name="ContactForm"
component={ContactForm}
options={ContactForm.navigationOptions}
/>
</Stack.Navigator>
);

const Swaps = () => (
<Stack.Navigator>
<Stack.Screen
Expand Down Expand Up @@ -658,6 +702,7 @@ const MainNavigator = () => (
<Stack.Screen name="OfflineModeView" component={OfflineModeView} />
<Stack.Screen name={Routes.QR_SCANNER} component={QrScanner} />
<Stack.Screen name="PaymentRequestView" component={PaymentRequestView} />
<Stack.Screen name="NotificationsView" component={NotificationsModeView} />
<Stack.Screen name={Routes.RAMP.BUY}>
{() => <RampRoutes rampType={RampType.BUY} />}
</Stack.Screen>
Expand All @@ -678,6 +723,11 @@ const MainNavigator = () => (
// eslint-disable-next-line react-native/no-inline-styles
headerStyle={{ borderBottomWidth: 0 }}
/>
<Stack.Screen
name={Routes.NOTIFICATIONS.OPT_IN_STACK}
component={NotificationsOptInStack}
options={NotificationsOptInStack.navigationOptions}
/>
</Stack.Navigator>
);

Expand Down
41 changes: 32 additions & 9 deletions app/components/UI/Navbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,16 @@ const styles = StyleSheet.create({
paddingVertical: Device.isAndroid() ? 14 : 8,
},
infoButton: {
paddingRight: Device.isAndroid() ? 22 : 18,
marginTop: 5,
},
disabled: {
opacity: 0.3,
},
leftButtonContainer: {
marginRight: Device.isAndroid() ? 22 : 12,
flexDirection: 'row',
alignItems: 'flex-end',
},
optinHeaderLeft: {
flexDirection: 'row',
alignItems: 'center',
Expand Down Expand Up @@ -893,6 +897,7 @@ export function getWalletNavbarOptions(
onPressTitle,
navigation,
themeColors,
isNotificationEnabled,
) {
const innerStyles = StyleSheet.create({
headerStyle: {
Expand Down Expand Up @@ -961,6 +966,14 @@ export function getWalletNavbarOptions(
trackEvent(MetaMetricsEvents.WALLET_QR_SCANNER);
}

function handleNotificationOnPress() {
if (isNotificationEnabled) {
// [ATTENTION]: will navigate to Notifications screen. Notifications screen will be implemented on a diff PR.
} else {
navigation.navigate(Routes.NOTIFICATIONS.OPT_IN_STACK);
}
}

return {
headerTitle: () => (
<View style={innerStyles.headerTitle}>
Expand All @@ -981,14 +994,24 @@ export function getWalletNavbarOptions(
/>
),
headerRight: () => (
<ButtonIcon
variant={ButtonIconVariants.Primary}
onPress={openQRScanner}
iconName={IconName.Scan}
style={styles.infoButton}
size={IconSize.Xl}
testID={WalletViewSelectorsIDs.WALLET_SCAN_BUTTON}
/>
<View style={styles.leftButtonContainer}>
<ButtonIcon
variant={ButtonIconVariants.Primary}
onPress={handleNotificationOnPress}
iconName={IconName.Notification}
style={styles.infoButton}
size={IconSize.Xl}
testID={WalletViewSelectorsIDs.WALLET_NOTIFICATIONS_BUTTON}
/>
<ButtonIcon
variant={ButtonIconVariants.Primary}
onPress={openQRScanner}
iconName={IconName.Scan}
style={styles.infoButton}
size={IconSize.Xl}
testID={WalletViewSelectorsIDs.WALLET_SCAN_BUTTON}
/>
</View>
),
headerStyle: innerStyles.headerStyle,
headerTintColor: themeColors.primary.default,
Expand Down
7 changes: 1 addition & 6 deletions app/components/UI/NavbarTitle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Networks, { getDecimalChainId } from '../../../util/networks';
import { strings } from '../../../../locales/i18n';
import Device from '../../../util/device';
import { ThemeContext, mockTheme } from '../../../util/theme';
import { NAVBAR_TITLE_NETWORKS_TEXT } from '../../../../wdio/screen-objects/testIDs/Screens/WalletScreen-testIds';
import Routes from '../../../constants/navigation/Routes';
import { MetaMetricsEvents } from '../../../core/Analytics';
import { withNavigation } from '@react-navigation/compat';
Expand Down Expand Up @@ -171,11 +170,7 @@ class NavbarTitle extends PureComponent {
color ? { backgroundColor: color } : styles.otherNetworkIcon,
]}
/>
<Text
numberOfLines={1}
style={styles.networkName}
testID={NAVBAR_TITLE_NETWORKS_TEXT}
>
<Text numberOfLines={1} style={styles.networkName}>
{name}
</Text>
</View>
Expand Down

This file was deleted.

124 changes: 124 additions & 0 deletions app/components/Views/Notifications/OptIn/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React, { useState } from 'react';
import { Image, View, Linking } from 'react-native';
import { useFocusEffect, useNavigation } from '@react-navigation/native';

import Button, {
ButtonVariants,
} from '../../../../component-library/components/Buttons/Button';
import { strings } from '../../../../../locales/i18n';
import Text, {
TextColor,
TextVariant,
} from '../../../../component-library/components/Texts/Text';
import { useTheme } from '../../../../util/theme';
import EnableNotificationsCardPlaceholder from '../../../../images/enableNotificationsCard.png';
import { createStyles } from './styles';
import Routes from '../../../../constants/navigation/Routes';
import { CONSENSYS_PRIVACY_POLICY } from '../../../../constants/urls';
import { useSelector } from 'react-redux';
import { mmStorage } from '../../../../util/notifications';
import { STORAGE_IDS } from '../../../../util/notifications/settings/storage/constants';

const OptIn = () => {
const theme = useTheme();
const styles = createStyles(theme);
const navigation = useNavigation();
const isNotificationEnabled = useSelector(
(state: any) => state.notification?.notificationsSettings?.isEnabled,
);
const [promptCount, setPromptCount] = useState(0);

const navigateToNotificationsSettings = () => {
navigation.navigate(Routes.SETTINGS.NOTIFICATIONS);
};

const navigateToMainWallet = () => {
!isNotificationEnabled &&
mmStorage.saveLocal(
STORAGE_IDS.PUSH_NOTIFICATIONS_PROMPT_COUNT,
promptCount,
);
navigation.navigate(Routes.WALLET_VIEW);
};

const goToLearnMore = () => {
Linking.openURL(CONSENSYS_PRIVACY_POLICY);
};

useFocusEffect(() => {
if (isNotificationEnabled) {
navigateToMainWallet();
} else {
const count = mmStorage.getLocal(
STORAGE_IDS.PUSH_NOTIFICATIONS_PROMPT_COUNT,
);
const times = count + 1 || 1;

setPromptCount(times);
}
});

return (
<View style={styles.wrapper}>
<Text
variant={TextVariant.HeadingMD}
color={TextColor.Default}
style={styles.textTitle}
>
{strings('notifications.activation_card.title')}
</Text>
<View style={styles.card}>
<Image
source={EnableNotificationsCardPlaceholder}
style={styles.image}
/>
</View>
<Text
variant={TextVariant.BodyMD}
color={TextColor.Alternative}
style={styles.textSpace}
>
{strings('notifications.activation_card.description_1')}
</Text>

<Text
variant={TextVariant.BodyMD}
color={TextColor.Alternative}
style={styles.textSpace}
>
{strings('notifications.activation_card.description_2')}
<Text
variant={TextVariant.BodyMD}
color={TextColor.Info}
onPress={goToLearnMore}
>
{strings('notifications.activation_card.learn_more')}
</Text>
</Text>

<Text variant={TextVariant.BodyMD} color={TextColor.Alternative}>
{strings('notifications.activation_card.manage_preferences_1')}
<Text variant={TextVariant.BodyMDBold} color={TextColor.Alternative}>
{strings('notifications.activation_card.manage_preferences_2')}
</Text>
</Text>

<View style={styles.btnContainer}>
<Button
variant={ButtonVariants.Secondary}
label={strings('notifications.activation_card.cancel')}
onPress={navigateToMainWallet}
style={styles.ctaBtn}
/>
<Button
variant={ButtonVariants.Primary}
label={strings('notifications.activation_card.cta')}
onPress={navigateToNotificationsSettings}
style={styles.ctaBtn}
/>
</View>
</View>
);
};

export default OptIn;
51 changes: 51 additions & 0 deletions app/components/Views/Notifications/OptIn/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* eslint-disable import/prefer-default-export */
import { StyleSheet } from 'react-native';
import type { Theme } from '@metamask/design-tokens';
import Device from '../../../../util/device';
import scaling from '../../../../util/scaling';

const HEIGHT = scaling.scale(240);

export const createStyles = ({ colors }: Theme) =>
StyleSheet.create({
wrapper: {
flex: 1,
alignItems: 'flex-start',
backgroundColor: colors.background.default,
paddingTop: 40,
paddingHorizontal: 16,
},
card: {
height: HEIGHT,
width: Device.getDeviceWidth() - 32,
alignSelf: 'center',
borderRadius: 12,
overflow: 'hidden',
marginBottom: 16,
},
image: {
resizeMode: 'cover',
height: HEIGHT,
width: Device.getDeviceWidth() - 32,
},
btnContainer: {
bottom: 0,
position: 'absolute',
flexDirection: 'row',
justifyContent: 'space-between',
alignSelf: 'center',
marginBottom: 16,
},
ctaBtn: {
margin: 4,
width: '48%',
alignSelf: 'center',
},
textSpace: {
marginBottom: 16,
},
textTitle: {
marginBottom: 16,
alignSelf: 'center',
},
});
Loading

0 comments on commit 5de1023

Please sign in to comment.