From 88d62e0a4b2ef673c1187206d75e3ee31b3189ed Mon Sep 17 00:00:00 2001 From: Cal Leung Date: Wed, 8 Jun 2022 13:02:21 -0700 Subject: [PATCH] Update WhatsNewModal to parse template --- app/components/UI/WhatsNewModal/index.js | 260 +++++++++++------- .../UI/WhatsNewModal/whatsNewList.ts | 33 +-- 2 files changed, 170 insertions(+), 123 deletions(-) diff --git a/app/components/UI/WhatsNewModal/index.js b/app/components/UI/WhatsNewModal/index.js index 1091250e291..a5daefb94ce 100644 --- a/app/components/UI/WhatsNewModal/index.js +++ b/app/components/UI/WhatsNewModal/index.js @@ -5,9 +5,9 @@ import { Text, TouchableOpacity, ScrollView, - TouchableWithoutFeedback, Image, InteractionManager, + TouchableWithoutFeedback, } from 'react-native'; import { useNavigationState } from '@react-navigation/native'; import ActionModal from '../ActionModal'; @@ -23,37 +23,62 @@ import { WHATS_NEW_APP_VERSION_SEEN, } from '../../../constants/storage'; import compareVersions from 'compare-versions'; -import scaling from '../../../util/scaling'; import PropTypes from 'prop-types'; import { findRouteNameFromNavigatorState } from '../../../util/general'; +import StyledButton from '../StyledButton'; import { useAppThemeFromContext, mockTheme } from '../../../util/theme'; +const modalMargin = 24; +const modalPadding = 24; +const screenWidth = Device.getDeviceWidth(); +const screenHeight = Device.getDeviceHeight(); +const slideItemWidth = screenWidth - modalMargin * 2; +const maxSlideItemHeight = screenHeight - 200; +const slideImageWidth = slideItemWidth - modalPadding * 2; +const imageAspectRatio = 128 / 264; +const slideImageHeight = slideImageWidth * imageAspectRatio; const createStyles = (colors) => StyleSheet.create({ wrapper: { marginTop: 24, - maxHeight: Device.getDeviceHeight() - 200, flex: 1, + overflow: 'hidden', }, - button: { + slideContent: { + maxHeight: maxSlideItemHeight, + }, + slideItemContainer: { + flex: 1, + width: slideItemWidth, + paddingHorizontal: modalPadding, + paddingBottom: 16, + }, + progessContainer: { + flexDirection: 'row', + alignSelf: 'center', marginTop: 16, - borderColor: colors.primary.default, - borderWidth: 1, - borderRadius: 50, - padding: 12, - paddingHorizontal: 34, + marginBottom: 8, }, - buttonText: { - color: colors.primary.default, - textAlign: 'center', - ...fontStyles.normal, + slideCircle: { + width: 8, + height: 8, + borderRadius: 8 / 2, + backgroundColor: colors.icon.default, + opacity: 0.4, + marginHorizontal: 8, + }, + slideSolidCircle: { + opacity: 1, + }, + button: { + marginTop: 8, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', - marginBottom: 24, - paddingHorizontal: 24, + marginBottom: 20, + paddingHorizontal: modalPadding, }, headerCenterAux: { flex: 1, @@ -67,40 +92,29 @@ const createStyles = (colors) => fontSize: 18, color: colors.text.default, }, - newFeatureImageContainer: { + slideImageContainer: { flexDirection: 'row', - flex: 1, borderRadius: 10, marginBottom: 24, }, - newFeatureImage: { + slideImage: { flex: 1, borderRadius: 10, - width: scaling.scale(280, { baseModel: 1 }), - height: scaling.scale(128, { baseModel: 1 }), + width: slideImageWidth, + height: slideImageHeight, }, - newFeatureTitle: { + slideTitle: { ...fontStyles.bold, fontSize: 16, marginBottom: 12, - textAlign: 'center', color: colors.text.default, }, - newFeatureText: { + slideDescription: { ...fontStyles.normal, fontSize: 14, lineHeight: 20, - textAlign: 'center', color: colors.text.default, - marginBottom: 12, - }, - buttonContainer: { - flexDirection: 'row', - justifyContent: 'center', - }, - featureContainer: { - marginBottom: 25, - paddingHorizontal: 24, + marginBottom: 24, }, }); @@ -108,6 +122,8 @@ const WhatsNewModal = (props) => { const [featuresToShow, setFeaturesToShow] = useState(null); const [show, setShow] = useState(false); const routes = useNavigationState((state) => state.routes); + const slideIds = [0, 1]; + const [currentSlide, setCurrentSlide] = useState(slideIds[0]); const { colors } = useAppThemeFromContext() || mockTheme; const styles = createStyles(colors); @@ -121,44 +137,39 @@ const WhatsNewModal = (props) => { const lastAppVersion = await AsyncStorage.getItem(LAST_APP_VERSION); const isUpdate = !!lastAppVersion && currentAppVersion !== lastAppVersion; - let showFeatures = []; - - whatsNew.forEach((feature) => { - const seen = - !!whatsNewAppVersionSeen && - compareVersions.compare( - whatsNewAppVersionSeen, - feature.minAppVersion, - '>=', - ); + const seen = + !!whatsNewAppVersionSeen && + compareVersions.compare( + whatsNewAppVersionSeen, + whatsNew.minAppVersion, + '>=', + ); - if (seen) return; + if (seen) return; - if (feature.onlyUpdates) { - const updatingCorrect = feature.onlyUpdates && isUpdate; + if (whatsNew.onlyUpdates) { + const updatingCorrect = whatsNew.onlyUpdates && isUpdate; - if (!updatingCorrect) return; + if (!updatingCorrect) return; - const lastVersionCorrect = compareVersions.compare( - lastAppVersion, - feature.maxLastAppVersion, - '<', - ); + const lastVersionCorrect = compareVersions.compare( + lastAppVersion, + whatsNew.maxLastAppVersion, + '<', + ); - if (!lastVersionCorrect) return; - } + if (!lastVersionCorrect) return; + } - const versionCorrect = compareVersions.compare( - currentAppVersion, - feature.minAppVersion, - '>=', - ); + const versionCorrect = compareVersions.compare( + currentAppVersion, + whatsNew.minAppVersion, + '>=', + ); - if (!versionCorrect) return; + if (!versionCorrect) return; - showFeatures = [...showFeatures, ...feature.features]; - }); - if (showFeatures.length) setFeaturesToShow(showFeatures); + if (whatsNew.slides.length) setFeaturesToShow(true); }; shouldShow(); }, []); @@ -169,13 +180,13 @@ const WhatsNewModal = (props) => { await AsyncStorage.setItem(WHATS_NEW_APP_VERSION_SEEN, version); }; - const callButton = (feature) => { + const callButton = (onPress) => { closeModal(); - feature.buttonPress && feature.buttonPress(props); + onPress(props); }; useEffect(() => { - if (props.enabled && !!featuresToShow) { + if (props.enabled && featuresToShow) { const route = findRouteNameFromNavigatorState(routes); if (route === 'WalletView') { InteractionManager.runAfterInteractions(() => { @@ -187,6 +198,66 @@ const WhatsNewModal = (props) => { } }, [featuresToShow, props.enabled, routes]); + const renderSlideElement = (elementInfo) => { + switch (elementInfo.type) { + case 'title': + return (element = ( + {elementInfo.title} + )); + case 'description': + return (element = ( + {elementInfo.description} + )); + case 'image': + return ( + + + + ); + case 'button': + return ( + + callButton(elementInfo.onPress)} + > + {elementInfo.buttonText} + + + ); + } + return null; + }; + + const renderSlide = (slideInfo, index) => { + const key = `slide-info-${index}`; + return ( + + + + {slideInfo.map((elementInfo, elIndex) => { + const elKey = `${key}-${elIndex}`; + return {renderSlideElement(elementInfo)}; + })} + + + + ); + }; + + const onScrollEnd = (e) => { + const xOffset = e.nativeEvent.contentOffset.x; + const slideIndex = Math.round(xOffset / screenWidth); + if (currentSlide === slideIndex) { + return; + } + setCurrentSlide(slideIndex); + }; + return ( { - {!!featuresToShow && ( - - - - {featuresToShow.map((feature, index) => ( - - - - - - - {feature.title} - - {feature.text} - - callButton(feature)} - > - - {feature.buttonText} - - - - - ))} - - - + {featuresToShow && ( + + + {whatsNew.slides.map(renderSlide)} + + + {slideIds.map((id) => ( + + ))} + + )} diff --git a/app/components/UI/WhatsNewModal/whatsNewList.ts b/app/components/UI/WhatsNewModal/whatsNewList.ts index b6e95bb04e8..fa6fb04f4d0 100644 --- a/app/components/UI/WhatsNewModal/whatsNewList.ts +++ b/app/components/UI/WhatsNewModal/whatsNewList.ts @@ -1,25 +1,10 @@ -import { strings } from '../../../../locales/i18n'; +/* eslint-disable import/prefer-default-export */ +import { WhatsNew } from './types'; -export const whatsNew = [ - { - // All users that have <1.0.7 and are updating to >=1.0.7 should see - onlyUpdates: true, // Only users who updated the app will see this, not newly installs - maxLastAppVersion: '1.0.7', // Only users who had a previous version <1.0.7 version will see this - minAppVersion: '1.0.7', // Only users who updated to a version >= 1.0.7 will see this - features: [ - { - title: strings('whats_new.feature_security_settings_title'), - text: strings('whats_new.feature_security_settings_text'), - buttonText: strings('whats_new.feature_security_settings_button'), - buttonPress: (props) => - props.navigation.navigate('SettingsView', { - screen: 'SettingsFlow', - params: { screen: 'SecuritySettings' }, - }), - image: require('../../../images/whats-new-security.png'), // eslint-disable-line - }, - ], - }, -]; - -export default whatsNew; +export const whatsNew: WhatsNew = { + // All users that have <1.0.7 and are updating to >=1.0.7 should see + onlyUpdates: true, // Only users who updated the app will see this, not newly installs + maxLastAppVersion: '1.0.7', // Only users who had a previous version <1.0.7 version will see this + minAppVersion: '1.0.7', // Only users who updated to a version >= 1.0.7 will see this + slides: [[], [], []], +};