Added welcome screen

This commit is contained in:
Mustafa Buyukcelebi 2020-07-25 19:18:08 +03:00
parent aa5a24a6d2
commit 68d0d984f6
12 changed files with 306 additions and 8 deletions

View File

@ -661,4 +661,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 84e32ce5543427579b8c72d77fd175fe29268d92 PODFILE CHECKSUM: 84e32ce5543427579b8c72d77fd175fe29268d92
COCOAPODS: 1.9.3 COCOAPODS: 1.8.4

View File

@ -73,6 +73,7 @@
"react-native-image-zoom-viewer": "^2.2.27", "react-native-image-zoom-viewer": "^2.2.27",
"react-native-keyboard-aware-scroll-view": "^0.9.1", "react-native-keyboard-aware-scroll-view": "^0.9.1",
"react-native-linear-gradient": "^2.4.2", "react-native-linear-gradient": "^2.4.2",
"react-native-modal": "^11.5.6",
"react-native-modal-dropdown": "esteemapp/react-native-modal-dropdown", "react-native-modal-dropdown": "esteemapp/react-native-modal-dropdown",
"react-native-modal-translucent": "^5.0.0", "react-native-modal-translucent": "^5.0.0",
"react-native-navigation-bar-color": "^1.0.0", "react-native-navigation-bar-color": "^1.0.0",

View File

@ -107,6 +107,15 @@ export const removeAllUserData = async () => {
} }
}; };
export const removeAllSCAccounts = async () => {
try {
await setItemToStorage(SC_ACCOUNTS, []);
return true;
} catch (error) {
return error;
}
};
export const setDraftPost = async (fields, username) => { export const setDraftPost = async (fields, username) => {
try { try {
let draft = await getItemFromStorage(DRAFT_SCHEMA); let draft = await getItemFromStorage(DRAFT_SCHEMA);
@ -593,6 +602,18 @@ export const getSCAccount = async (username) => {
} }
}; };
export const getAllSCAccounts = async () => {
try {
const scAccountStr = await getItemFromStorage(SC_ACCOUNTS);
if (scAccountStr && scAccountStr.length > 0) {
return scAccountStr;
}
return [];
} catch (error) {
return error;
}
};
export const removeSCAccount = async (username) => { export const removeSCAccount = async (username) => {
try { try {
let scAccount = await getItemFromStorage(SC_ACCOUNTS); let scAccount = await getItemFromStorage(SC_ACCOUNTS);
@ -621,3 +642,33 @@ export const getStorageType = async () => {
return error; return error;
} }
}; };
export const getVersionForWelcomeModal = async () => {
try {
const application = await getItemFromStorage(APPLICATION_SCHEMA);
if (application.versionForWelcomeModal) {
return application.versionForWelcomeModal;
}
return 0;
} catch (error) {
return error;
}
};
export const setVersionForWelcomeModal = async (version) => {
try {
const application = await getItemFromStorage(APPLICATION_SCHEMA);
if (application) {
application.versionForWelcomeModal = version;
await setItemToStorage(APPLICATION_SCHEMA, application);
return application;
}
const applicationData = {
versionForWelcomeModal: version,
};
await setItemToStorage(APPLICATION_SCHEMA, { ...applicationData });
return applicationData;
} catch (error) {
return error;
}
};

View File

@ -3,6 +3,7 @@ import {
ADD_OTHER_ACCOUNT, ADD_OTHER_ACCOUNT,
FETCH_ACCOUNT_FAIL, FETCH_ACCOUNT_FAIL,
REMOVE_OTHER_ACCOUNT, REMOVE_OTHER_ACCOUNT,
REMOVE_ALL_OTHER_ACCOUNT,
SET_GLOBAL_PROPS, SET_GLOBAL_PROPS,
UPDATE_CURRENT_ACCOUNT, UPDATE_CURRENT_ACCOUNT,
UPDATE_UNREAD_ACTIVITY_COUNT, UPDATE_UNREAD_ACTIVITY_COUNT,
@ -41,6 +42,10 @@ export const removeOtherAccount = (data) => ({
payload: data, payload: data,
}); });
export const removeAllOtherAccount = () => ({
type: REMOVE_ALL_OTHER_ACCOUNT,
});
export const setGlobalProps = (data) => ({ export const setGlobalProps = (data) => ({
type: SET_GLOBAL_PROPS, type: SET_GLOBAL_PROPS,
payload: data, payload: data,

View File

@ -38,6 +38,7 @@ export const ADD_OTHER_ACCOUNT = 'ADD_OTHER_ACCOUNT';
export const FETCH_ACCOUNT_FAIL = 'FETCH_ACCOUNT_FAIL'; export const FETCH_ACCOUNT_FAIL = 'FETCH_ACCOUNT_FAIL';
export const FETCHING_ACCOUNT = 'FETCHING_ACCOUNT'; export const FETCHING_ACCOUNT = 'FETCHING_ACCOUNT';
export const REMOVE_OTHER_ACCOUNT = 'REMOVE_OTHER_ACCOUNT'; export const REMOVE_OTHER_ACCOUNT = 'REMOVE_OTHER_ACCOUNT';
export const REMOVE_ALL_OTHER_ACCOUNT = 'REMOVE_ALL_OTHER_ACCOUNT';
export const UPDATE_CURRENT_ACCOUNT = 'UPDATE_CURRENT_ACCOUNT'; export const UPDATE_CURRENT_ACCOUNT = 'UPDATE_CURRENT_ACCOUNT';
export const UPDATE_UNREAD_ACTIVITY_COUNT = 'UPDATE_UNREAD_ACTIVITY_COUNT'; export const UPDATE_UNREAD_ACTIVITY_COUNT = 'UPDATE_UNREAD_ACTIVITY_COUNT';
export const SET_PIN_CODE = 'SET_PIN_CODE'; export const SET_PIN_CODE = 'SET_PIN_CODE';

View File

@ -7,6 +7,7 @@ import {
UPDATE_CURRENT_ACCOUNT, UPDATE_CURRENT_ACCOUNT,
UPDATE_UNREAD_ACTIVITY_COUNT, UPDATE_UNREAD_ACTIVITY_COUNT,
REMOVE_OTHER_ACCOUNT, REMOVE_OTHER_ACCOUNT,
REMOVE_ALL_OTHER_ACCOUNT,
LOGOUT_FAIL, LOGOUT_FAIL,
SET_GLOBAL_PROPS, SET_GLOBAL_PROPS,
} from '../constants/constants'; } from '../constants/constants';
@ -63,6 +64,12 @@ export default function (state = initialState, action) {
otherAccounts: state.otherAccounts.filter((item) => item.username !== action.payload), otherAccounts: state.otherAccounts.filter((item) => item.username !== action.payload),
}; };
case REMOVE_ALL_OTHER_ACCOUNT:
return {
...state,
otherAccounts: [],
};
case UPDATE_CURRENT_ACCOUNT: case UPDATE_CURRENT_ACCOUNT:
return { return {
...state, ...state,

View File

@ -16,6 +16,7 @@ import {
} from 'react-native-dark-mode'; } from 'react-native-dark-mode';
import messaging from '@react-native-firebase/messaging'; import messaging from '@react-native-firebase/messaging';
import PushNotification from 'react-native-push-notification'; import PushNotification from 'react-native-push-notification';
import VersionNumber from 'react-native-version-number';
// Constants // Constants
import AUTH_TYPE from '../../../constants/authType'; import AUTH_TYPE from '../../../constants/authType';
@ -34,6 +35,10 @@ import {
setAuthStatus, setAuthStatus,
removeSCAccount, removeSCAccount,
setExistUser, setExistUser,
getVersionForWelcomeModal,
setVersionForWelcomeModal,
getAllSCAccounts,
removeAllSCAccounts,
} from '../../../realm/realm'; } from '../../../realm/realm';
import { getUser, getPost } from '../../../providers/steem/dsteem'; import { getUser, getPost } from '../../../providers/steem/dsteem';
import { switchAccount } from '../../../providers/steem/auth'; import { switchAccount } from '../../../providers/steem/auth';
@ -47,6 +52,7 @@ import {
updateUnreadActivityCount, updateUnreadActivityCount,
removeOtherAccount, removeOtherAccount,
fetchGlobalProperties, fetchGlobalProperties,
removeAllOtherAccount,
} from '../../../redux/actions/accountAction'; } from '../../../redux/actions/accountAction';
import { import {
activeApplication, activeApplication,
@ -87,6 +93,7 @@ export const setPreviousAppState = () => {
let firebaseOnNotificationOpenedAppListener = null; let firebaseOnNotificationOpenedAppListener = null;
let firebaseOnMessageListener = null; let firebaseOnMessageListener = null;
let scAccounts = [];
class ApplicationContainer extends Component { class ApplicationContainer extends Component {
constructor(props) { constructor(props) {
@ -97,11 +104,14 @@ class ApplicationContainer extends Component {
isIos: Platform.OS !== 'android', isIos: Platform.OS !== 'android',
isThemeReady: false, isThemeReady: false,
appState: AppState.currentState, appState: AppState.currentState,
showWelcomeModal: false,
}; };
} }
componentDidMount = () => { componentDidMount = () => {
const { isIos } = this.state; const { isIos } = this.state;
const { appVersion } = VersionNumber;
this._setNetworkListener(); this._setNetworkListener();
Linking.addEventListener('url', this._handleOpenURL); Linking.addEventListener('url', this._handleOpenURL);
@ -123,6 +133,15 @@ class ApplicationContainer extends Component {
this._createPushListener(); this._createPushListener();
if (!isIos) BackHandler.addEventListener('hardwareBackPress', this._onBackPress); if (!isIos) BackHandler.addEventListener('hardwareBackPress', this._onBackPress);
getVersionForWelcomeModal().then((version) => {
if (version < parseFloat(appVersion)) {
this.setState({ showWelcomeModal: true });
getAllSCAccounts().then((accounts) => {
scAccounts = accounts;
});
}
});
}; };
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
@ -644,6 +663,41 @@ class ApplicationContainer extends Component {
dispatch(updateCurrentAccount(_currentAccount)); dispatch(updateCurrentAccount(_currentAccount));
}; };
_handleWelcomeModalButtonPress = () => {
const { dispatch, otherAccounts } = this.props;
const { appVersion } = VersionNumber;
const accountsWithoutSC = otherAccounts.filter(
(account) => !scAccounts.includes(account.username),
);
// setVersionForWelcomeModal(appVersion);
if (scAccounts.length > 0) {
scAccounts.forEach((el) => {
dispatch(removeOtherAccount(el.username));
});
removeAllSCAccounts().then(() => {
if (accountsWithoutSC.length > 0) {
this._switchAccount(accountsWithoutSC(0));
} else {
dispatch(updateCurrentAccount({}));
dispatch(login(false));
removePinCode();
setAuthStatus({ isLoggedIn: false });
setExistUser(false);
dispatch(removeAllOtherAccount());
dispatch(logoutDone());
}
navigate({ routeName: ROUTES.SCREENS.LOGIN });
this.setState({ showWelcomeModal: false });
});
} else {
this.setState({ showWelcomeModal: false });
}
};
UNSAFE_componentWillReceiveProps(nextProps) { UNSAFE_componentWillReceiveProps(nextProps) {
const { const {
isDarkTheme: _isDarkTheme, isDarkTheme: _isDarkTheme,
@ -698,7 +752,7 @@ class ApplicationContainer extends Component {
isPinCodeRequire, isPinCodeRequire,
rcOffer, rcOffer,
} = this.props; } = this.props;
const { isRenderRequire, isReady, isThemeReady } = this.state; const { isRenderRequire, isReady, isThemeReady, showWelcomeModal } = this.state;
return ( return (
children && children &&
@ -712,6 +766,8 @@ class ApplicationContainer extends Component {
locale: selectedLanguage, locale: selectedLanguage,
rcOffer, rcOffer,
toastNotification, toastNotification,
showWelcomeModal,
handleWelcomeModalButtonPress: this._handleWelcomeModalButtonPress,
}) })
); );
} }

View File

@ -1,9 +1,11 @@
import React, { Fragment, useEffect, useState } from 'react'; import React, { Fragment, useEffect, useState } from 'react';
import { Text } from 'react-native';
import SplashScreen from 'react-native-splash-screen'; import SplashScreen from 'react-native-splash-screen';
import ApplicationScreen from './screen/applicationScreen';
import ApplicationContainer from './container/applicationContainer';
import Launch from '../launch'; import ApplicationContainer from './container/applicationContainer';
import WelcomeScreen from './screen/welcomeScreen';
import ApplicationScreen from './screen/applicationScreen';
import LaunchScreen from '../launch';
import { Modal } from '../../components'; import { Modal } from '../../components';
import { PinCode } from '../pinCode'; import { PinCode } from '../pinCode';
@ -31,7 +33,11 @@ const Application = () => {
locale, locale,
rcOffer, rcOffer,
toastNotification, toastNotification,
showWelcomeModal,
handleWelcomeModalButtonPress,
}) => { }) => {
const _isAppReady = !showAnimation && isReady && isRenderRequire && isThemeReady;
console.log('_isAppReady :>> ', _isAppReady);
return ( return (
<Fragment> <Fragment>
<Modal <Modal
@ -42,6 +48,19 @@ const Application = () => {
> >
<PinCode /> <PinCode />
</Modal> </Modal>
<Modal
isOpen={!isPinCodeRequire && showWelcomeModal && _isAppReady}
isFullScreen
swipeToClose={false}
backButtonClose={false}
handleOnModalClose={() => console.log('handleOnModalClose :>> ')}
onDismiss={() => console.log('onDismiss :>> ')}
onRequestClose={() => {
console.log('onRequestClose :>> ');
}}
>
<WelcomeScreen handleButtonPress={handleWelcomeModalButtonPress} />
</Modal>
{isThemeReady && isRenderRequire && ( {isThemeReady && isRenderRequire && (
<ApplicationScreen <ApplicationScreen
isConnected={isConnected} isConnected={isConnected}
@ -52,7 +71,7 @@ const Application = () => {
rcOffer={rcOffer} rcOffer={rcOffer}
/> />
)} )}
{(showAnimation || !isReady || !isRenderRequire || !isThemeReady) && <Launch />} {!_isAppReady && <LaunchScreen />}
</Fragment> </Fragment>
); );
}} }}

View File

@ -1,9 +1,10 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { StatusBar, Platform, View, Alert } from 'react-native'; import { StatusBar, Platform, View, Alert, Text, Modal, TouchableHighlight } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet'; import EStyleSheet from 'react-native-extended-stylesheet';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createAppContainer } from 'react-navigation'; import { createAppContainer } from 'react-navigation';
import { injectIntl } from 'react-intl'; import { injectIntl } from 'react-intl';
import VersionNumber from 'react-native-version-number';
import AppNavitation from '../../../navigation/routes'; import AppNavitation from '../../../navigation/routes';
import { setTopLevelNavigator, navigate } from '../../../navigation/service'; import { setTopLevelNavigator, navigate } from '../../../navigation/service';
@ -13,6 +14,7 @@ import {
toastNotification as toastNotificationAction, toastNotification as toastNotificationAction,
setRcOffer, setRcOffer,
} from '../../../redux/actions/uiAction'; } from '../../../redux/actions/uiAction';
import { getVersionForWelcomeModal } from '../../../realm/realm';
import ROUTES from '../../../constants/routeNames'; import ROUTES from '../../../constants/routeNames';
@ -30,9 +32,20 @@ class ApplicationScreen extends Component {
super(props); super(props);
this.state = { this.state = {
isShowToastNotification: false, isShowToastNotification: false,
showWelcomeModal: false,
}; };
} }
componentDidMount() {
const { appVersion } = VersionNumber;
getVersionForWelcomeModal().then((version) => {
if (version < parseFloat(appVersion)) {
this.setState({ showWelcomeModal: true });
}
});
}
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
const { rcOffer, dispatch, intl } = this.props; const { rcOffer, dispatch, intl } = this.props;
const { rcOffer: rcOfferPrev } = prevProps; const { rcOffer: rcOfferPrev } = prevProps;
@ -88,7 +101,7 @@ class ApplicationScreen extends Component {
render() { render() {
const { isConnected, isDarkTheme, toastNotification, isReady } = this.props; const { isConnected, isDarkTheme, toastNotification, isReady } = this.props;
const { isShowToastNotification } = this.state; const { isShowToastNotification, showWelcomeModal } = this.state;
const barStyle = isDarkTheme ? 'light-content' : 'dark-content'; const barStyle = isDarkTheme ? 'light-content' : 'dark-content';
const barColor = isDarkTheme ? '#1e2835' : '#fff'; const barColor = isDarkTheme ? '#1e2835' : '#fff';
@ -106,6 +119,32 @@ class ApplicationScreen extends Component {
setTopLevelNavigator(navigatorRef); setTopLevelNavigator(navigatorRef);
}} }}
/> />
<Modal
animationType="slide"
visible={false}
presentationStyle="pageSheet"
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}
>
<View
style={{
backgroundColor: 'white',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text>Hello World!</Text>
<TouchableHighlight
onPress={() => {
this.setState({ showWelcomeModal: !showWelcomeModal });
}}
>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</Modal>
</Fragment> </Fragment>
{isShowToastNotification && ( {isShowToastNotification && (

View File

@ -0,0 +1,71 @@
import React from 'react';
import { Text, Image, View } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import { Icon, MainButton } from '../../../components';
import styles from './welcomeStyles';
const WelcomeScreen = ({ handleButtonPress }) => {
return (
<View style={styles.container}>
<Image
style={{ width: 205, height: 200, alignSelf: 'center' }}
source={require('../../../assets/ecency-logo.png')}
/>
<View>
<Text style={styles.welcomeText}>Welcome to</Text>
<Text style={styles.ecencyText}>Ecency</Text>
</View>
<View style={styles.sectionRow}>
<Icon
iconType="SimpleLineIcons"
name="question"
color={EStyleSheet.value('$primaryBlue')}
size={60}
/>
<View>
<Text style={styles.sectionTitle}>Lorem ipsum dolor</Text>
<Text style={styles.sectionText}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer a tellus eget arcu
</Text>
</View>
</View>
<View style={styles.sectionRow}>
<Icon
iconType="SimpleLineIcons"
name="question"
color={EStyleSheet.value('$primaryBlue')}
size={60}
/>
<View>
<Text style={styles.sectionTitle}>Lorem ipsum dolor</Text>
<Text style={styles.sectionText}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer a tellus eget arcu
</Text>
</View>
</View>
<View style={styles.sectionRow}>
<Icon
iconType="SimpleLineIcons"
name="question"
color={EStyleSheet.value('$primaryBlue')}
size={60}
/>
<View>
<Text style={styles.sectionTitle}>Lorem ipsum dolor</Text>
<Text style={styles.sectionText}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer a tellus eget arcu
</Text>
</View>
</View>
<MainButton
onPress={handleButtonPress}
style={{ alignSelf: 'center', paddingHorizontal: 30 }}
text="Start to Ecency"
/>
</View>
);
};
export default WelcomeScreen;

View File

@ -0,0 +1,33 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
flex: 1,
justifyContent: 'space-between',
paddingVertical: '5%',
paddingHorizontal: 40,
},
welcomeText: {
fontSize: 34,
},
ecencyText: {
fontSize: 34,
color: '$primaryBlue',
},
sectionRow: {
flexDirection: 'row',
},
sectionTitle: {
fontSize: 17,
fontWeight: '600',
marginLeft: 10,
},
sectionText: {
fontSize: 15,
marginLeft: 10,
marginRight: 45,
},
flex1: {
flex: 1,
},
});

View File

@ -7427,6 +7427,13 @@ react-native-actionsheet@esteemapp/react-native-actionsheet:
version "2.4.2" version "2.4.2"
resolved "https://codeload.github.com/esteemapp/react-native-actionsheet/tar.gz/c74540db08a4c2049ee9c8a8077b5c476b536e2c" resolved "https://codeload.github.com/esteemapp/react-native-actionsheet/tar.gz/c74540db08a4c2049ee9c8a8077b5c476b536e2c"
react-native-animatable@1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/react-native-animatable/-/react-native-animatable-1.3.3.tgz#a13a4af8258e3bb14d0a9d839917e9bb9274ec8a"
integrity sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==
dependencies:
prop-types "^15.7.2"
react-native-autoheight-webview@^1.3.4, react-native-autoheight-webview@^1.4.1: react-native-autoheight-webview@^1.3.4, react-native-autoheight-webview@^1.4.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/react-native-autoheight-webview/-/react-native-autoheight-webview-1.5.1.tgz#67cbfb672212d93dedecf723d1914cbc40287545" resolved "https://registry.yarnpkg.com/react-native-autoheight-webview/-/react-native-autoheight-webview-1.5.1.tgz#67cbfb672212d93dedecf723d1914cbc40287545"
@ -7540,6 +7547,14 @@ react-native-modal-translucent@^5.0.0:
resolved "https://registry.yarnpkg.com/react-native-modal-translucent/-/react-native-modal-translucent-5.0.0.tgz#8b35cfa4189dce776c77a925b00ad19d965bd0a2" resolved "https://registry.yarnpkg.com/react-native-modal-translucent/-/react-native-modal-translucent-5.0.0.tgz#8b35cfa4189dce776c77a925b00ad19d965bd0a2"
integrity sha512-xhJAlq4uCE7jPEIPxGS1WNiRIm5DCrZEO3SF88moTOm6b4/wfFEANf+lMsVkQf9b9dsQ6Em4nq4uAoejtbHb2A== integrity sha512-xhJAlq4uCE7jPEIPxGS1WNiRIm5DCrZEO3SF88moTOm6b4/wfFEANf+lMsVkQf9b9dsQ6Em4nq4uAoejtbHb2A==
react-native-modal@^11.5.6:
version "11.5.6"
resolved "https://registry.yarnpkg.com/react-native-modal/-/react-native-modal-11.5.6.tgz#bb25a78c35a5e24f45de060e5f64284397d38a87"
integrity sha512-APGNfbvgC4hXbJqcSADu79GLoMKIHUmgR3fDQ7rCGZNBypkStSP8imZ4PKK/OzIZZfjGU9aP49jhMgGbhY9KHA==
dependencies:
prop-types "^15.6.2"
react-native-animatable "1.3.3"
react-native-navigation-bar-color@^1.0.0: react-native-navigation-bar-color@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/react-native-navigation-bar-color/-/react-native-navigation-bar-color-1.0.0.tgz#04ff752a58049af93ceea9ccf266b8d3fbc6514a" resolved "https://registry.yarnpkg.com/react-native-navigation-bar-color/-/react-native-navigation-bar-color-1.0.0.tgz#04ff752a58049af93ceea9ccf266b8d3fbc6514a"