better back button navigation handling (#408)

* better back button navigation handling
* add console=plain option to gradlew
This commit is contained in:
Akinwale Ariwodola 2019-01-21 14:35:11 +01:00 committed by GitHub
parent 53bfba0320
commit ec928c943d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 284 additions and 90 deletions

77
app/package-lock.json generated
View file

@ -2509,9 +2509,9 @@
} }
}, },
"create-react-context": { "create-react-context": {
"version": "0.2.3", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz", "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz",
"integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==", "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==",
"requires": { "requires": {
"fbjs": "^0.8.0", "fbjs": "^0.8.0",
"gud": "^1.0.0" "gud": "^1.0.0"
@ -5161,9 +5161,9 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
}, },
"query-string": { "query-string": {
"version": "6.1.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.1.0.tgz", "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.2.0.tgz",
"integrity": "sha512-pNB/Gr8SA8ff8KpUFM36o/WFAlthgaThka5bV19AD9PNTH20Pwq5Zxodif2YyHwrctp6SkL4GqlOot0qR/wGaw==", "integrity": "sha512-5wupExkIt8RYL4h/FE+WTg3JHk62e6fFPWtAZA9J5IWK1PfTfKkMS93HBUHcFpeYi9KsY5pFbh+ldvEyaz5MyA==",
"requires": { "requires": {
"decode-uri-component": "^0.2.0", "decode-uri-component": "^0.2.0",
"strict-uri-encode": "^2.0.0" "strict-uri-encode": "^2.0.0"
@ -5247,6 +5247,11 @@
} }
} }
}, },
"react-is": {
"version": "16.7.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.7.0.tgz",
"integrity": "sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g=="
},
"react-lifecycles-compat": { "react-lifecycles-compat": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
@ -5441,13 +5446,18 @@
} }
}, },
"react-native-safe-area-view": { "react-native-safe-area-view": {
"version": "0.9.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.9.0.tgz", "resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.11.0.tgz",
"integrity": "sha512-y792ScHMzvgwquxL869S9CER4dwiFu/TuCiXdy0xBtygmScMK4eWonnUT65LvOrsSSdr8o6XEK1mbI51h6ozvQ==", "integrity": "sha512-N3nElaahu1Me2ltnfc9acpgt1znm6pi8DSadKy79kvdzKwvVIzw0IXueA/Hjr51eCW1BsfNw7D1SgBT9U6qEkA==",
"requires": { "requires": {
"hoist-non-react-statics": "^2.3.1" "hoist-non-react-statics": "^2.3.1"
} }
}, },
"react-native-screens": {
"version": "1.0.0-alpha.22",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-1.0.0-alpha.22.tgz",
"integrity": "sha512-kSyAt0AeVU6N7ZonfV6dP6iZF8B7Bce+tk3eujXhzBGsLg0VSLnU7uE9VqJF0xdQrHR91ZjGgVMieo/8df9KTA=="
},
"react-native-tab-view": { "react-native-tab-view": {
"version": "0.0.77", "version": "0.0.77",
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-0.0.77.tgz", "resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-0.0.77.tgz",
@ -5504,21 +5514,23 @@
} }
}, },
"react-navigation": { "react-navigation": {
"version": "2.12.1", "version": "2.18.3",
"resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-2.12.1.tgz", "resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-2.18.3.tgz",
"integrity": "sha512-C+do+STPvvd/5LbaDhrZyf1P8tCeffttdlHyIRe1NgGg8Nj93FZHWOThi2hnmEZ75kXsS/JGxox4DDPqYVAxeQ==", "integrity": "sha512-/5KGMG1Oj5LN/x/7AKF0MWrpX9Qe29307RxEsMCiRT/A4jCYT0DPY99Bl7ZAGtROxExEy3rwTfTrtvpIT+CU7A==",
"requires": { "requires": {
"clamp": "^1.0.1", "clamp": "^1.0.1",
"create-react-context": "^0.2.1", "create-react-context": "0.2.2",
"hoist-non-react-statics": "^2.2.0", "hoist-non-react-statics": "^2.2.0",
"path-to-regexp": "^1.7.0", "path-to-regexp": "^1.7.0",
"query-string": "^6.1.0", "query-string": "^6.1.0",
"react-is": "^16.5.2",
"react-lifecycles-compat": "^3", "react-lifecycles-compat": "^3",
"react-native-safe-area-view": "^0.9.0", "react-native-safe-area-view": "0.11.0",
"react-native-screens": "^1.0.0-alpha.11",
"react-navigation-deprecated-tab-navigator": "1.3.0", "react-navigation-deprecated-tab-navigator": "1.3.0",
"react-navigation-drawer": "0.5.0", "react-navigation-drawer": "0.5.0",
"react-navigation-stack": "0.2.3", "react-navigation-stack": "0.7.0",
"react-navigation-tabs": "0.6.0" "react-navigation-tabs": "0.8.4"
} }
}, },
"react-navigation-deprecated-tab-navigator": { "react-navigation-deprecated-tab-navigator": {
@ -5538,42 +5550,33 @@
} }
}, },
"react-navigation-redux-helpers": { "react-navigation-redux-helpers": {
"version": "2.0.5", "version": "2.0.9",
"resolved": "https://registry.npmjs.org/react-navigation-redux-helpers/-/react-navigation-redux-helpers-2.0.5.tgz", "resolved": "https://registry.npmjs.org/react-navigation-redux-helpers/-/react-navigation-redux-helpers-2.0.9.tgz",
"integrity": "sha512-oxDpPqmXdzUJJ32ef8NY6Cu9XDJNO4DU91p0+ZgleEfaZwec9t2ua6sKwQyOfdWQPDwbJAxiXfZIAe3ao5MG6Q==", "integrity": "sha512-V1eyQ22T1znZeaou38f/JBp5DUV5X2T4hVVSlsjh8dk2unkWhaugzvrgFMF80Mzg1gH4rVE1yADyI9hzuwbbSw==",
"requires": { "requires": {
"invariant": "^2.2.2" "invariant": "^2.2.2"
} }
}, },
"react-navigation-stack": { "react-navigation-stack": {
"version": "0.2.3", "version": "0.7.0",
"resolved": "https://registry.npmjs.org/react-navigation-stack/-/react-navigation-stack-0.2.3.tgz", "resolved": "https://registry.npmjs.org/react-navigation-stack/-/react-navigation-stack-0.7.0.tgz",
"integrity": "sha512-xjVqiI/ztcQt45jxQ3vfO8Lr+9bVq+0J/lRhMdZCvCDwiyOVuB64wx7qPNJW16pnBBLiI5h6H7uhWE3rAT0r/w==" "integrity": "sha512-3Tbb/SsustBrM9R/qaI6XuOfyqYMVbwkeHFC8NbU890vB0aKZvjAtioWLZ18e/4LgbiOCmoTdp37z3gkGDyNDQ=="
}, },
"react-navigation-tabs": { "react-navigation-tabs": {
"version": "0.6.0", "version": "0.8.4",
"resolved": "https://registry.npmjs.org/react-navigation-tabs/-/react-navigation-tabs-0.6.0.tgz", "resolved": "https://registry.npmjs.org/react-navigation-tabs/-/react-navigation-tabs-0.8.4.tgz",
"integrity": "sha512-Ax1rujJ51R1Jrz7b5bHUAIgsYC1VrFws+d3hxlPy5dXG84iJdV5dnDFRvdQMDDfDZc+NDx2a223lAYsc3p2+XA==", "integrity": "sha512-CbS3xIVJVtpu+AYslv0PMLmjddJFVtU3XAhSJ9XnMrKLUJNmnQdW/L0w/Gp5qcBEF9h6bgsY3CoTtp7I6bqyOQ==",
"requires": { "requires": {
"hoist-non-react-statics": "^2.5.0", "hoist-non-react-statics": "^2.5.0",
"prop-types": "^15.6.1", "prop-types": "^15.6.1",
"react-lifecycles-compat": "^3.0.4", "react-lifecycles-compat": "^3.0.4",
"react-native-safe-area-view": "^0.7.0",
"react-native-tab-view": "^1.0.0" "react-native-tab-view": "^1.0.0"
}, },
"dependencies": { "dependencies": {
"react-native-safe-area-view": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.7.0.tgz",
"integrity": "sha512-SjLdW/Th0WVMhyngH4O6yC21S+O4U4AAG3QxBr7fZ2ftgjXSpKbDHAhEpxBdFwei6HsnsC2h9oYMtPpaW9nfGg==",
"requires": {
"hoist-non-react-statics": "^2.3.1"
}
},
"react-native-tab-view": { "react-native-tab-view": {
"version": "1.0.2", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-1.0.2.tgz", "resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-1.3.1.tgz",
"integrity": "sha512-x8I43V1X7/AyMnIwnqJGMU54LqQRlV6vJ9irbls9asA/axdHIdxagPIV6Jx1ttFe/bPKhFwXL+lRYdYxGyUlWg==", "integrity": "sha512-QNt6VkEW8SP1UJ7yjD5P4bOTWwHQfoIMD5CqnA06pcubdNwHR1NmjiNZsVnIvp5wAEVbW6yTHjLXOh1fzab4xg==",
"requires": { "requires": {
"prop-types": "^15.6.1" "prop-types": "^15.6.1"
} }

View file

@ -21,8 +21,8 @@
"react-native-phone-input": "lbryio/react-native-phone-input", "react-native-phone-input": "lbryio/react-native-phone-input",
"react-native-vector-icons": "^5.0.0", "react-native-vector-icons": "^5.0.0",
"react-native-video": "lbryio/react-native-video#exoplayer-lbry-android", "react-native-video": "lbryio/react-native-video#exoplayer-lbry-android",
"react-navigation": "^2.12.1", "react-navigation": "^2.18.3",
"react-navigation-redux-helpers": "^2.0.5", "react-navigation-redux-helpers": "^2.0.9",
"react-redux": "^5.0.3", "react-redux": "^5.0.3",
"redux": "^3.6.0", "redux": "^3.6.0",
"redux-logger": "3.0.6", "redux-logger": "3.0.6",

View file

@ -33,7 +33,9 @@ import {
TextInput, TextInput,
ToastAndroid ToastAndroid
} from 'react-native'; } from 'react-native';
import { doDeleteCompleteBlobs } from '../redux/actions/file'; import { doPopDrawerStack } from 'redux/actions/drawer';
import { doDeleteCompleteBlobs } from 'redux/actions/file';
import { selectDrawerStack } from 'redux/selectors/drawer';
import { SETTINGS, doDismissToast, doToast, selectToast } from 'lbry-redux'; import { SETTINGS, doDismissToast, doToast, selectToast } from 'lbry-redux';
import { import {
doUserEmailVerify, doUserEmailVerify,
@ -43,16 +45,16 @@ import {
selectEmailVerifyErrorMessage, selectEmailVerifyErrorMessage,
selectUser selectUser
} from 'lbryinc'; } from 'lbryinc';
import { makeSelectClientSetting } from '../redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import { decode as atob } from 'base-64'; import { decode as atob } from 'base-64';
import { dispatchNavigateToUri } from '../utils/helper'; import { dispatchNavigateBack, dispatchNavigateToUri } from 'utils/helper';
import Colors from '../styles/colors'; import Colors from 'styles/colors';
import Constants from '../constants'; import Constants from 'constants';
import Icon from 'react-native-vector-icons/FontAwesome5'; import Icon from 'react-native-vector-icons/FontAwesome5';
import NavigationButton from '../component/navigationButton'; import NavigationButton from 'component/navigationButton';
import discoverStyle from '../styles/discover'; import discoverStyle from 'styles/discover';
import searchStyle from '../styles/search'; import searchStyle from 'styles/search';
import SearchRightHeaderIcon from '../component/searchRightHeaderIcon'; import SearchRightHeaderIcon from 'component/searchRightHeaderIcon';
const menuNavigationButton = (navigation) => <NavigationButton const menuNavigationButton = (navigation) => <NavigationButton
name="bars" name="bars"
@ -72,15 +74,13 @@ const discoverStack = createStackNavigator({
}, },
File: { File: {
screen: FilePage, screen: FilePage,
navigationOptions: { navigationOptions: ({ navigation }) => ({
header: null, header: null
drawerLockMode: 'locked-closed' })
}
}, },
Search: { Search: {
screen: SearchPage, screen: SearchPage,
navigationOptions: ({ navigation }) => ({ navigationOptions: ({ navigation }) => ({
drawerLockMode: 'locked-closed',
headerTitleStyle: discoverStyle.titleText headerTitleStyle: discoverStyle.titleText
}) })
} }
@ -88,6 +88,17 @@ const discoverStack = createStackNavigator({
headerMode: 'screen' headerMode: 'screen'
}); });
discoverStack.navigationOptions = ({ navigation }) => {
let drawerLockMode = 'unlocked';
if (navigation.state.index > 0) {
drawerLockMode = 'locked-closed';
}
return {
drawerLockMode
};
};
const trendingStack = createStackNavigator({ const trendingStack = createStackNavigator({
Trending: { Trending: {
screen: TrendingPage, screen: TrendingPage,
@ -232,7 +243,7 @@ class AppWithNavigationState extends React.Component {
componentWillMount() { componentWillMount() {
AppState.addEventListener('change', this._handleAppStateChange); AppState.addEventListener('change', this._handleAppStateChange);
BackHandler.addEventListener('hardwareBackPress', function() { BackHandler.addEventListener('hardwareBackPress', function() {
const { dispatch, nav } = this.props; const { dispatch, nav, drawerStack, popDrawerStack } = this.props;
// There should be a better way to check this // There should be a better way to check this
if (nav.routes.length > 0) { if (nav.routes.length > 0) {
if (nav.routes[0].routeName === 'Main') { if (nav.routes[0].routeName === 'Main') {
@ -241,7 +252,7 @@ class AppWithNavigationState extends React.Component {
mainRoute.routes[0].index > 0 /* Discover stack index */ || mainRoute.routes[0].index > 0 /* Discover stack index */ ||
mainRoute.routes[4].index > 0 /* Wallet stack index */ || mainRoute.routes[4].index > 0 /* Wallet stack index */ ||
mainRoute.index >= 5 /* Settings and About screens */) { mainRoute.index >= 5 /* Settings and About screens */) {
dispatch(NavigationActions.back()); dispatchNavigateBack(dispatch, nav, drawerStack, doPopDrawerStack);
return true; return true;
} }
} }
@ -374,6 +385,7 @@ const mapStateToProps = state => ({
keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state), keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state),
nav: state.nav, nav: state.nav,
toast: selectToast(state), toast: selectToast(state),
drawerStack: selectDrawerStack(state),
emailToVerify: selectEmailToVerify(state), emailToVerify: selectEmailToVerify(state),
emailVerifyPending: selectEmailVerifyIsPending(state), emailVerifyPending: selectEmailVerifyIsPending(state),
emailVerifyErrorMessage: selectEmailVerifyErrorMessage(state), emailVerifyErrorMessage: selectEmailVerifyErrorMessage(state),

View file

@ -7,10 +7,33 @@ const Constants = {
ACTION_DELETE_COMPLETED_BLOBS: "DELETE_COMPLETED_BLOBS", ACTION_DELETE_COMPLETED_BLOBS: "DELETE_COMPLETED_BLOBS",
ACTION_FIRST_RUN_PAGE_CHANGED: "FIRST_RUN_PAGE_CHANGED", ACTION_FIRST_RUN_PAGE_CHANGED: "FIRST_RUN_PAGE_CHANGED",
PAGE_REWARDS: 'rewards', ACTION_PUSH_DRAWER_STACK: "PUSH_DRAWER_STACK",
PAGE_SETTINGS: 'settings', ACTION_POP_DRAWER_STACK: "POP_DRAWER_STACK",
PAGE_TRENDING: 'trending',
PAGE_WALLET: 'wallet' PAGE_REWARDS: "rewards",
PAGE_SETTINGS: "settings",
PAGE_TRENDING: "trending",
PAGE_WALLET: "wallet",
DRAWER_ROUTE_DISCOVER: "Discover",
DRAWER_ROUTE_TRENDING: "Trending",
DRAWER_ROUTE_SUBSCRIPTIONS: "Subscriptions",
DRAWER_ROUTE_MY_LBRY: "Downloads",
DRAWER_ROUTE_REWARDS: "Rewards",
DRAWER_ROUTE_WALLET: "Wallet",
DRAWER_ROUTE_SETTINGS: "Settings",
DRAWER_ROUTE_ABOUT: "About"
}; };
export default Constants; export default Constants;
export const DrawerRoutes = [
Constants.DRAWER_ROUTE_DISCOVER,
Constants.DRAWER_ROUTE_TRENDING,
Constants.DRAWER_ROUTE_SUBSCRIPTIONS,
Constants.DRAWER_ROUTE_MY_LBRY,
Constants.DRAWER_ROUTE_REWARDS,
Constants.DRAWER_ROUTE_WALLET,
Constants.DRAWER_ROUTE_SETTINGS,
Constants.DRAWER_ROUTE_ABOUT
];

View file

@ -22,14 +22,15 @@ import {
import { authReducer, rewardsReducer, subscriptionsReducer, userReducer } from 'lbryinc'; import { authReducer, rewardsReducer, subscriptionsReducer, userReducer } from 'lbryinc';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import { createLogger } from 'redux-logger'; import { createLogger } from 'redux-logger';
import { AppNavigator } from './component/AppNavigator'; import { AppNavigator } from 'component/AppNavigator';
import { persistStore, autoRehydrate } from 'redux-persist'; import { persistStore, autoRehydrate } from 'redux-persist';
import AppWithNavigationState, { reactNavigationMiddleware } from './component/AppNavigator'; import AppWithNavigationState, { reactNavigationMiddleware } from './component/AppNavigator';
import FilesystemStorage from 'redux-persist-filesystem-storage'; import FilesystemStorage from 'redux-persist-filesystem-storage';
import createCompressor from 'redux-persist-transform-compress'; import createCompressor from 'redux-persist-transform-compress';
import createFilter from 'redux-persist-transform-filter'; import createFilter from 'redux-persist-transform-filter';
import moment from 'moment'; import moment from 'moment';
import settingsReducer from './redux/reducers/settings'; import drawerReducer from 'redux/reducers/drawer';
import settingsReducer from 'redux/reducers/settings';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
const globalExceptionHandler = (error, isFatal) => { const globalExceptionHandler = (error, isFatal) => {
@ -81,6 +82,7 @@ const reducers = combineReducers({
blacklist: blacklistReducer, blacklist: blacklistReducer,
claims: claimsReducer, claims: claimsReducer,
costInfo: costInfoReducer, costInfo: costInfoReducer,
drawer: drawerReducer,
fileInfo: fileInfoReducer, fileInfo: fileInfoReducer,
nav: navigatorReducer, nav: navigatorReducer,
notifications: notificationsReducer, notifications: notificationsReducer,

View file

@ -1,16 +1,22 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doToast } from 'lbry-redux'; import { doToast } from 'lbry-redux';
import { doFetchAccessToken, selectAccessToken, selectUserEmail } from 'lbryinc'; import { doFetchAccessToken, selectAccessToken, selectUserEmail } from 'lbryinc';
import { doPushDrawerStack, doPopDrawerStack } from 'redux/actions/drawer';
import { selectDrawerStack } from 'redux/selectors/drawer';
import AboutPage from './view'; import AboutPage from './view';
import Constants from 'constants';
const select = state => ({ const select = state => ({
accessToken: selectAccessToken(state), accessToken: selectAccessToken(state),
userEmail: selectUserEmail(state), userEmail: selectUserEmail(state),
drawerStack: selectDrawerStack(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
fetchAccessToken: () => dispatch(doFetchAccessToken()), fetchAccessToken: () => dispatch(doFetchAccessToken()),
notify: data => dispatch(doToast(data)), notify: data => dispatch(doToast(data)),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_ABOUT)),
popDrawerStack: () => dispatch(doPopDrawerStack()),
}); });
export default connect(select, perform)(AboutPage); export default connect(select, perform)(AboutPage);

View file

@ -13,6 +13,7 @@ class AboutPage extends React.PureComponent {
}; };
componentDidMount() { componentDidMount() {
this.props.pushDrawerStack();
if (NativeModules.VersionInfo) { if (NativeModules.VersionInfo) {
NativeModules.VersionInfo.getAppVersion().then(version => { NativeModules.VersionInfo.getAppVersion().then(version => {
this.setState({appVersion: version}); this.setState({appVersion: version});
@ -33,14 +34,14 @@ class AboutPage extends React.PureComponent {
} }
render() { render() {
const { accessToken, navigation, notify, userEmail } = this.props; const { accessToken, drawerStack, navigation, notify, popDrawerStack, userEmail } = this.props;
const loading = 'Loading...'; const loading = 'Loading...';
const ver = this.state.versionInfo ? this.state.versionInfo : null; const ver = this.state.versionInfo ? this.state.versionInfo : null;
return ( return (
<View style={aboutStyle.container}> <View style={aboutStyle.container}>
<PageHeader title={"About LBRY"} <PageHeader title={"About LBRY"}
onBackPressed={() => navigation.goBack(navigation.state.key)} /> onBackPressed={() => navigateBack(navigation, drawerStack, popDrawerStack)} />
<ScrollView style={aboutStyle.scrollContainer}> <ScrollView style={aboutStyle.scrollContainer}>
<Text style={aboutStyle.title}>Content Freedom</Text> <Text style={aboutStyle.title}>Content Freedom</Text>
<Text style={aboutStyle.paragraph}> <Text style={aboutStyle.paragraph}>

View file

@ -7,11 +7,14 @@ import {
makeSelectFetchingChannelClaims, makeSelectFetchingChannelClaims,
makeSelectTotalPagesForChannel makeSelectTotalPagesForChannel
} from 'lbry-redux'; } from 'lbry-redux';
import { doPopDrawerStack } from 'redux/actions/drawer';
import { selectDrawerStack } from 'redux/selectors/drawer';
import ChannelPage from './view'; import ChannelPage from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
claimsInChannel: makeSelectClaimsInChannelForCurrentPageState(props.uri)(state), claimsInChannel: makeSelectClaimsInChannelForCurrentPageState(props.uri)(state),
drawerStack: selectDrawerStack(state),
fetching: makeSelectFetchingChannelClaims(props.uri)(state), fetching: makeSelectFetchingChannelClaims(props.uri)(state),
totalPages: makeSelectTotalPagesForChannel(props.uri, 10)(state), // Update to use a default PAGE_SIZE constant totalPages: makeSelectTotalPagesForChannel(props.uri, 10)(state), // Update to use a default PAGE_SIZE constant
}); });
@ -19,6 +22,7 @@ const select = (state, props) => ({
const perform = dispatch => ({ const perform = dispatch => ({
fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)), fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)),
fetchClaimCount: uri => dispatch(doFetchClaimCountByChannel(uri)), fetchClaimCount: uri => dispatch(doFetchClaimCountByChannel(uri)),
popDrawerStack: () => dispatch(doPopDrawerStack())
}); });
export default connect(select, perform)(ChannelPage); export default connect(select, perform)(ChannelPage);

View file

@ -1,6 +1,7 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import { ActivityIndicator, Text, View } from 'react-native'; import { ActivityIndicator, Text, View } from 'react-native';
import { navigateBack } from 'utils/helper';
import Colors from 'styles/colors'; import Colors from 'styles/colors';
import Button from 'component/button'; import Button from 'component/button';
import FileList from 'component/fileList'; import FileList from 'component/fileList';
@ -41,7 +42,16 @@ class ChannelPage extends React.PureComponent {
} }
render() { render() {
const { fetching, claimsInChannel, claim, navigation, totalPages, uri } = this.props; const {
fetching,
claimsInChannel,
claim,
navigation,
totalPages,
uri,
drawerStack,
popDrawerStack
} = this.props;
const { name, permanent_url: permanentUrl } = claim; const { name, permanent_url: permanentUrl } = claim;
let contentList; let contentList;
@ -69,7 +79,7 @@ class ChannelPage extends React.PureComponent {
return ( return (
<View style={channelPageStyle.container}> <View style={channelPageStyle.container}>
<PageHeader title={name} onBackPressed={() => navigation.goBack(navigation.state.key)} /> <PageHeader title={name} onBackPressed={() => navigateBack(navigation, drawerStack, popDrawerStack)} />
{contentList} {contentList}
{(totalPages > 1) && {(totalPages > 1) &&
<View style={channelPageStyle.pageButtons}> <View style={channelPageStyle.pageButtons}>

View file

@ -5,6 +5,8 @@ import {
selectMyClaimsWithoutChannels, selectMyClaimsWithoutChannels,
selectIsFetchingFileList, selectIsFetchingFileList,
} from 'lbry-redux'; } from 'lbry-redux';
import { doPushDrawerStack } from 'redux/actions/drawer';
import Constants from 'constants';
import DownloadsPage from './view'; import DownloadsPage from './view';
const select = (state) => ({ const select = (state) => ({
@ -15,6 +17,7 @@ const select = (state) => ({
const perform = dispatch => ({ const perform = dispatch => ({
fileList: () => dispatch(doFileList()), fileList: () => dispatch(doFileList()),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_MY_LBRY))
}); });
export default connect(select, perform)(DownloadsPage); export default connect(select, perform)(DownloadsPage);

View file

@ -25,7 +25,9 @@ class DownloadsPage extends React.PureComponent {
}; };
componentDidMount() { componentDidMount() {
this.props.fileList(); const { fileList, pushDrawerStack } = this.props;
pushDrawerStack();
fileList();
} }
render() { render() {

View file

@ -9,6 +9,8 @@ import {
selectUser, selectUser,
} from 'lbryinc'; } from 'lbryinc';
import { doToast } from 'lbry-redux'; import { doToast } from 'lbry-redux';
import { doPushDrawerStack } from 'redux/actions/drawer';
import Constants from 'constants';
import RewardsPage from './view'; import RewardsPage from './view';
const select = state => ({ const select = state => ({
@ -23,6 +25,7 @@ const select = state => ({
const perform = dispatch => ({ const perform = dispatch => ({
fetchRewards: () => dispatch(doRewardList()), fetchRewards: () => dispatch(doRewardList()),
notify: data => dispatch(doToast(data)), notify: data => dispatch(doToast(data)),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_REWARDS))
}); });
export default connect(select, perform)(RewardsPage); export default connect(select, perform)(RewardsPage);

View file

@ -25,9 +25,11 @@ class RewardsPage extends React.PureComponent {
}; };
componentDidMount() { componentDidMount() {
this.props.fetchRewards(); const { fetchRewards, pushDrawerStack, navigation, user } = this.props;
pushDrawerStack();
fetchRewards();
const { user } = this.props;
this.setState({ this.setState({
isEmailVerified: (user && user.primary_email && user.has_verified_email), isEmailVerified: (user && user.primary_email && user.has_verified_email),
isIdentityVerified: (user && user.is_identity_verified), isIdentityVerified: (user && user.is_identity_verified),

View file

@ -1,16 +1,22 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { SETTINGS } from 'lbry-redux'; import { SETTINGS } from 'lbry-redux';
import { doSetClientSetting } from '../../redux/actions/settings'; import { doPushDrawerStack, doPopDrawerStack } from 'redux/actions/drawer';
import { makeSelectClientSetting } from '../../redux/selectors/settings'; import { doSetClientSetting } from 'redux/actions/settings';
import { selectDrawerStack } from 'redux/selectors/drawer';
import { makeSelectClientSetting } from 'redux/selectors/settings';
import Constants from 'constants';
import SettingsPage from './view'; import SettingsPage from './view';
const select = state => ({ const select = state => ({
backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state), backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state),
drawerStack: selectDrawerStack(state),
keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state), keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state),
showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state), showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SETTINGS)),
popDrawerStack: () => dispatch(doPopDrawerStack()),
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
}); });

View file

@ -1,19 +1,26 @@
import React from 'react'; import React from 'react';
import { SETTINGS } from 'lbry-redux'; import { SETTINGS } from 'lbry-redux';
import { Text, View, ScrollView, Switch, NativeModules } from 'react-native'; import { Text, View, ScrollView, Switch, NativeModules } from 'react-native';
import PageHeader from '../../component/pageHeader'; import { navigateBack } from 'utils/helper';
import settingsStyle from '../../styles/settings'; import PageHeader from 'component/pageHeader';
import settingsStyle from 'styles/settings';
class SettingsPage extends React.PureComponent { class SettingsPage extends React.PureComponent {
static navigationOptions = { static navigationOptions = {
title: 'Settings' title: 'Settings'
} }
componentDidMount() {
this.props.pushDrawerStack();
}
render() { render() {
const { const {
backgroundPlayEnabled, backgroundPlayEnabled,
drawerStack,
keepDaemonRunning, keepDaemonRunning,
navigation, navigation,
popDrawerStack,
showNsfw, showNsfw,
setClientSetting setClientSetting
} = this.props; } = this.props;
@ -24,7 +31,7 @@ class SettingsPage extends React.PureComponent {
return ( return (
<View> <View>
<PageHeader title={"Settings"} <PageHeader title={"Settings"}
onBackPressed={() => navigation.goBack(navigation.state.key)} /> onBackPressed={() => navigateBack(navigation, drawerStack, popDrawerStack)} />
<ScrollView style={settingsStyle.scrollContainer}> <ScrollView style={settingsStyle.scrollContainer}>
<View style={settingsStyle.row}> <View style={settingsStyle.row}>
<View style={settingsStyle.switchText}> <View style={settingsStyle.switchText}>

View file

@ -14,6 +14,8 @@ import {
selectFirstRunCompleted, selectFirstRunCompleted,
selectShowSuggestedSubs selectShowSuggestedSubs
} from 'lbryinc'; } from 'lbryinc';
import { doPushDrawerStack } from 'redux/actions/drawer';
import Constants from 'constants';
import SubscriptionsPage from './view'; import SubscriptionsPage from './view';
const select = state => ({ const select = state => ({
@ -28,13 +30,13 @@ const select = state => ({
showSuggestedSubs: selectShowSuggestedSubs(state), showSuggestedSubs: selectShowSuggestedSubs(state),
}); });
export default connect( const perform = dispatch => ({
select,
{
doFetchMySubscriptions, doFetchMySubscriptions,
doSetViewMode, doSetViewMode,
doFetchRecommendedSubscriptions, doFetchRecommendedSubscriptions,
doCompleteFirstRun, doCompleteFirstRun,
doShowSuggestedSubs, doShowSuggestedSubs,
} pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SUBSCRIPTIONS))
)(SubscriptionsPage); });
export default connect(select, perform)(SubscriptionsPage);

View file

@ -23,8 +23,10 @@ class SubscriptionsPage extends React.PureComponent {
componentDidMount() { componentDidMount() {
const { const {
doFetchMySubscriptions, doFetchMySubscriptions,
doFetchRecommendedSubscriptions doFetchRecommendedSubscriptions,
pushDrawerStack,
} = this.props; } = this.props;
pushDrawerStack();
doFetchMySubscriptions(); doFetchMySubscriptions();
//doFetchRecommendedSubscriptions(); //doFetchRecommendedSubscriptions();
} }

View file

@ -1,5 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doFetchTrendingUris, selectTrendingUris, selectFetchingTrendingUris } from 'lbry-redux'; import { doFetchTrendingUris, selectTrendingUris, selectFetchingTrendingUris } from 'lbry-redux';
import { doPushDrawerStack } from 'redux/actions/drawer';
import Constants from 'constants';
import TrendingPage from './view'; import TrendingPage from './view';
const select = state => ({ const select = state => ({
@ -9,6 +11,7 @@ const select = state => ({
const perform = dispatch => ({ const perform = dispatch => ({
fetchTrendingUris: () => dispatch(doFetchTrendingUris()), fetchTrendingUris: () => dispatch(doFetchTrendingUris()),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_TRENDING))
}); });
export default connect(select, perform)(TrendingPage); export default connect(select, perform)(TrendingPage);

View file

@ -18,7 +18,9 @@ import UriBar from '../../component/uriBar';
class TrendingPage extends React.PureComponent { class TrendingPage extends React.PureComponent {
componentDidMount() { componentDidMount() {
this.props.fetchTrendingUris(); const { fetchTrendingUris, pushDrawerStack } = this.props;
pushDrawerStack();
fetchTrendingUris();
} }
render() { render() {

View file

@ -1,7 +1,8 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doSetClientSetting } from '../../redux/actions/settings'; import { doSetClientSetting } from 'redux/actions/settings';
import { makeSelectClientSetting } from '../../redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import Constants from '../../constants'; import { doPushDrawerStack } from 'redux/actions/drawer';
import Constants from 'constants';
import WalletPage from './view'; import WalletPage from './view';
const select = state => ({ const select = state => ({
@ -10,6 +11,7 @@ const select = state => ({
const perform = dispatch => ({ const perform = dispatch => ({
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_WALLET))
}); });
export default connect(select, perform)(WalletPage); export default connect(select, perform)(WalletPage);

View file

@ -10,6 +10,10 @@ import Constants from 'constants';
import walletStyle from 'styles/wallet'; import walletStyle from 'styles/wallet';
class WalletPage extends React.PureComponent { class WalletPage extends React.PureComponent {
componentDidMount() {
this.props.pushDrawerStack();
}
render() { render() {
const { understandsRisks, setClientSetting } = this.props; const { understandsRisks, setClientSetting } = this.props;

View file

@ -0,0 +1,10 @@
import Constants from 'constants';
export const doPushDrawerStack = (routeName) => (dispatch) => dispatch({
type: Constants.ACTION_PUSH_DRAWER_STACK,
data: routeName
});
export const doPopDrawerStack = () => (dispatch) => dispatch({
type: Constants.ACTION_POP_DRAWER_STACK
});

View file

@ -0,0 +1,36 @@
import Constants from 'constants';
const reducers = {};
const defaultState = {
stack: [ Constants.DRAWER_ROUTE_DISCOVER ] // Discover is always the first drawer route
};
reducers[Constants.ACTION_PUSH_DRAWER_STACK] = (state, action) => {
const routeName = action.data;
const newStack = state.stack.slice();
if (routeName !== newStack[newStack.length -1]) {
newStack.push(routeName);
}
return {
...state,
stack: newStack
};
};
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
const newStack = (state.stack.length === 1) ? state.stack.slice() : state.stack.slice(0, state.stack.length - 1);
return {
...state,
stack: newStack
}
};
export default function reducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

View file

@ -0,0 +1,13 @@
import { createSelector } from 'reselect';
export const selectState = state => state.drawer || {};
export const selectDrawerStack = createSelector(selectState, (state) => state.stack);
export const selectLastDrawerRoute = createSelector(selectState, (state) => {
if (state.stack.length) {
return state.stack[state.stack.length - 1];
}
return null;
});

View file

@ -1,6 +1,7 @@
import { NavigationActions, StackActions } from 'react-navigation'; import { NavigationActions, StackActions } from 'react-navigation';
import { buildURI } from 'lbry-redux'; import { buildURI } from 'lbry-redux';
import Constants from '../constants'; import { DrawerRoutes } from 'constants';
import Constants from 'constants';
function getRouteForSpecialUri(uri) { function getRouteForSpecialUri(uri) {
let targetRoute; let targetRoute;
@ -85,6 +86,41 @@ export function navigateToUri(navigation, uri, additionalParams) {
navigation.navigate({ routeName: 'File', key: uri, params }); navigation.navigate({ routeName: 'File', key: uri, params });
} }
export function navigateBack(navigation, drawerStack, popDrawerStack) {
const shouldPopStack = DrawerRoutes.indexOf(navigation.state.routeName) > -1;
if (shouldPopStack) {
navigation.goBack();
if (popDrawerStack) {
popDrawerStack();
}
navigation.navigate({ routeName: drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0] });
return;
}
navigation.goBack(navigation.state.key);
}
export function dispatchNavigateBack(dispatch, nav, drawerStack, popDrawerStack) {
const drawerRouteIndex = nav.routes[0].index;
const shouldPopStack = (
(drawerRouteIndex > 0 && drawerRouteIndex !== 5) || // not the discover nor wallet stack
(drawerRouteIndex === 5 && nav.routes[0].routes[drawerRouteIndex].index === 0) // wallet stack, and tx history page not active
);
if (shouldPopStack) {
dispatch(NavigationActions.back());
if (popDrawerStack) {
dispatch(popDrawerStack());
}
const navigateAction = NavigationActions.navigate({ routeName: drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0] });
dispatch(navigateAction);
return;
}
dispatch(NavigationActions.back());
}
export function uriFromFileInfo(fileInfo) { export function uriFromFileInfo(fileInfo) {
const { name: claimName, claim_name: claimNameDownloaded, claim_id: claimId } = fileInfo; const { name: claimName, claim_name: claimNameDownloaded, claim_id: claimId } = fileInfo;
const uriParams = {}; const uriParams = {};

View file

@ -796,7 +796,7 @@ class ToolchainCL(object):
error("Unknown build mode {} for apk()".format( error("Unknown build mode {} for apk()".format(
args.build_mode)) args.build_mode))
exit(1) exit(1)
output = shprint(gradlew, gradle_task, _tail=20, output = shprint(gradlew, "--console=plain", gradle_task, _tail=20,
_critical=True, _env=env) _critical=True, _env=env)
# gradle output apks somewhere else # gradle output apks somewhere else