Navigate to the last visited route #112

Merged
akinwale merged 2 commits from save-last-route into master 2020-01-20 21:40:18 +01:00
6 changed files with 29 additions and 26 deletions

View file

@ -10,6 +10,7 @@
"__": true "__": true
}, },
"rules": { "rules": {
"no-console": 2,
"no-multi-spaces": 0, "no-multi-spaces": 0,
"new-cap": 0, "new-cap": 0,
"prefer-promise-reject-errors": 0, "prefer-promise-reject-errors": 0,

View file

@ -95,6 +95,7 @@ const compressor = createCompressor();
const authFilter = createFilter('auth', ['authToken']); const authFilter = createFilter('auth', ['authToken']);
const blockedFilter = createFilter('blocked', ['blockedChannels']); const blockedFilter = createFilter('blocked', ['blockedChannels']);
const contentFilter = createFilter('content', ['positions']); const contentFilter = createFilter('content', ['positions']);
const drawerFilter = createFilter('drawer', ['lastRouteInStack']);
const saveClaimsFilter = createFilter('claims', ['claimsByUri']); const saveClaimsFilter = createFilter('claims', ['claimsByUri']);
const subscriptionsFilter = createFilter('subscriptions', ['enabledChannelNotifications', 'subscriptions', 'latest']); const subscriptionsFilter = createFilter('subscriptions', ['enabledChannelNotifications', 'subscriptions', 'latest']);
const settingsFilter = createFilter('settings', ['clientSettings']); const settingsFilter = createFilter('settings', ['clientSettings']);
@ -102,12 +103,13 @@ const tagsFilter = createFilter('tags', ['followedTags']);
const walletFilter = createFilter('wallet', ['receiveAddress']); const walletFilter = createFilter('wallet', ['receiveAddress']);
const v4PersistOptions = { const v4PersistOptions = {
whitelist: ['auth', 'blocked', 'claims', 'content', 'subscriptions', 'settings', 'tags', 'wallet'], whitelist: ['auth', 'blocked', 'claims', 'drawer', 'content', 'subscriptions', 'settings', 'tags', 'wallet'],
// Order is important. Needs to be compressed last or other transforms can't // Order is important. Needs to be compressed last or other transforms can't
// read the data // read the data
transforms: [ transforms: [
authFilter, authFilter,
blockedFilter, blockedFilter,
drawerFilter,
saveClaimsFilter, saveClaimsFilter,
subscriptionsFilter, subscriptionsFilter,
settingsFilter, settingsFilter,

View file

@ -14,11 +14,13 @@ import {
selectEmailToVerify, selectEmailToVerify,
} from 'lbryinc'; } from 'lbryinc';
import { doSetClientSetting } from 'redux/actions/settings'; import { doSetClientSetting } from 'redux/actions/settings';
import { selectLastRouteInStack } from 'redux/selectors/drawer';
import SplashScreen from './view'; import SplashScreen from './view';
const select = state => ({ const select = state => ({
user: selectUser(state), user: selectUser(state),
emailToVerify: selectEmailToVerify(state), emailToVerify: selectEmailToVerify(state),
lastRouteInStack: selectLastRouteInStack(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Lbry, doPreferenceGet } from 'lbry-redux'; import { Lbry, doPreferenceGet, isURIValid } from 'lbry-redux';
import { Lbryio } from 'lbryinc'; import { Lbryio } from 'lbryinc';
import { ActivityIndicator, DeviceEventEmitter, Linking, NativeModules, Platform, Text, View } from 'react-native'; import { ActivityIndicator, DeviceEventEmitter, Linking, NativeModules, Platform, Text, View } from 'react-native';
import { NavigationActions, StackActions } from 'react-navigation'; import { NavigationActions, StackActions } from 'react-navigation';
@ -11,7 +11,7 @@ import Button from 'component/button';
import ProgressBar from 'component/progressBar'; import ProgressBar from 'component/progressBar';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Colors from 'styles/colors'; import Colors from 'styles/colors';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import Constants, { DrawerRoutes } from 'constants'; // eslint-disable-line node/no-deprecated-api
import splashStyle from 'styles/splash'; import splashStyle from 'styles/splash';
import RNFS from 'react-native-fs'; import RNFS from 'react-native-fs';
@ -43,7 +43,7 @@ class SplashScreen extends React.PureComponent {
} }
navigateToMain = () => { navigateToMain = () => {
const { navigation, notify, verifyUserEmail, verifyUserEmailFailure } = this.props; const { lastRouteInStack, navigation, notify, verifyUserEmail, verifyUserEmailFailure } = this.props;
const resetAction = StackActions.reset({ const resetAction = StackActions.reset({
index: 0, index: 0,
actions: [NavigationActions.navigate({ routeName: 'Main' })], actions: [NavigationActions.navigate({ routeName: 'Main' })],
@ -55,29 +55,14 @@ class SplashScreen extends React.PureComponent {
? navigation.state.params.launchUrl ? navigation.state.params.launchUrl
: this.state.launchUrl; : this.state.launchUrl;
if (launchUrl) { if (launchUrl) {
if (launchUrl.startsWith('lbry://?verify=')) {
let verification = {};
try {
verification = JSON.parse(atob(launchUrl.substring(15)));
} catch (error) {
console.log(error);
}
if (verification.token && verification.recaptcha) {
AsyncStorage.setItem(Constants.KEY_SHOULD_VERIFY_EMAIL, 'true');
try {
verifyUserEmail(verification.token, verification.recaptcha);
} catch (error) {
const message = __('Invalid Verification Token');
verifyUserEmailFailure(message);
notify({ message });
}
} else {
notify({
message: __('Invalid Verification URI'),
});
}
} else {
navigateToUri(navigation, transformUrl(launchUrl)); navigateToUri(navigation, transformUrl(launchUrl));
} else if (lastRouteInStack) {
// no launch url, check if there's a last route in stack to navigate to.
const { route, params } = lastRouteInStack;
if (!DrawerRoutes.includes(route) && isURIValid(route)) {
navigateToUri(navigation, route);
} else {
navigation.navigate({ routeName: route, params });
} }
} }
}; };

View file

@ -3,6 +3,7 @@ import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
const reducers = {}; const reducers = {};
const defaultState = { const defaultState = {
stack: [{ route: Constants.DRAWER_ROUTE_DISCOVER, params: {} }], // Discover is always the first drawer route stack: [{ route: Constants.DRAWER_ROUTE_DISCOVER, params: {} }], // Discover is always the first drawer route
lastRouteInStack: {},
playerVisible: false, playerVisible: false,
playerVisibleByUri: {}, playerVisibleByUri: {},
currentRoute: null, currentRoute: null,
@ -42,23 +43,30 @@ reducers[Constants.ACTION_PUSH_DRAWER_STACK] = (state, action) => {
canPushStack = false; canPushStack = false;
} }
let lastRouteInStack;
if (canPushStack) { if (canPushStack) {
newStack.push({ route: routeName, params }); newStack.push({ route: routeName, params });
// save the route
lastRouteInStack = { route: routeName, params };
} }
return { return {
...state, ...state,
stack: newStack, stack: newStack,
lastRouteInStack,
}; };
}; };
reducers[Constants.ACTION_POP_DRAWER_STACK] = (state, action) => { reducers[Constants.ACTION_POP_DRAWER_STACK] = (state, action) => {
// We don't want to pop the Discover route, since it's always expected to be the first // We don't want to pop the Discover route, since it's always expected to be the first
const newStack = state.stack.length === 1 ? state.stack.slice() : state.stack.slice(0, state.stack.length - 1); const newStack = state.stack.length === 1 ? state.stack.slice() : state.stack.slice(0, state.stack.length - 1);
const lastRouteInStack = newStack && newStack.length > 0 ? newStack[newStack.length - 1] : null;
return { return {
...state, ...state,
stack: newStack, stack: newStack,
lastRouteInStack,
}; };
}; };

View file

@ -34,6 +34,11 @@ export const selectLastDrawerRoute = createSelector(
}, },
); );
export const selectLastRouteInStack = createSelector(
selectState,
state => state.lastRouteInStack,
);
export const selectCurrentRoute = createSelector( export const selectCurrentRoute = createSelector(
selectState, selectState,
state => state.currentRoute, state => state.currentRoute,