2018-03-11 16:32:13 +01:00
|
|
|
import React from 'react';
|
2018-05-03 20:58:31 +02:00
|
|
|
import AboutPage from '../page/about';
|
2018-03-11 16:32:13 +01:00
|
|
|
import DiscoverPage from '../page/discover';
|
2018-08-31 09:56:41 +02:00
|
|
|
import DownloadsPage from '../page/downloads';
|
2018-03-11 16:32:13 +01:00
|
|
|
import FilePage from '../page/file';
|
2018-06-08 10:13:45 +02:00
|
|
|
import FirstRunScreen from '../page/firstRun';
|
2018-08-28 12:59:14 +02:00
|
|
|
import RewardsPage from '../page/rewards';
|
2018-06-05 20:52:10 +02:00
|
|
|
import TrendingPage from '../page/trending';
|
2018-08-28 12:59:14 +02:00
|
|
|
import SearchPage from '../page/search';
|
2018-03-23 00:03:05 +01:00
|
|
|
import SettingsPage from '../page/settings';
|
2018-03-11 16:32:13 +01:00
|
|
|
import SplashScreen from '../page/splash';
|
2018-05-03 20:58:31 +02:00
|
|
|
import TransactionHistoryPage from '../page/transactionHistory';
|
|
|
|
import WalletPage from '../page/wallet';
|
2018-04-09 20:39:35 +02:00
|
|
|
import SearchInput from '../component/searchInput';
|
|
|
|
import {
|
2018-09-02 09:12:21 +02:00
|
|
|
createDrawerNavigator,
|
|
|
|
createStackNavigator,
|
2018-04-09 20:39:35 +02:00
|
|
|
NavigationActions
|
|
|
|
} from 'react-navigation';
|
2018-09-02 09:12:21 +02:00
|
|
|
import {
|
|
|
|
addListener,
|
|
|
|
reduxifyNavigator,
|
|
|
|
createReactNavigationReduxMiddleware,
|
|
|
|
} from 'react-navigation-redux-helpers';
|
2018-03-11 16:32:13 +01:00
|
|
|
import { connect } from 'react-redux';
|
2018-04-24 21:32:17 +02:00
|
|
|
import {
|
|
|
|
AppState,
|
|
|
|
AsyncStorage,
|
|
|
|
BackHandler,
|
2018-05-25 09:13:05 +02:00
|
|
|
Linking,
|
2018-04-24 21:32:17 +02:00
|
|
|
NativeModules,
|
2018-05-03 20:58:31 +02:00
|
|
|
TextInput,
|
|
|
|
ToastAndroid
|
2018-04-24 21:32:17 +02:00
|
|
|
} from 'react-native';
|
2018-08-17 20:11:15 +02:00
|
|
|
import { doDeleteCompleteBlobs } from '../redux/actions/file';
|
2018-11-20 18:07:12 +01:00
|
|
|
import { SETTINGS, doHideNotification, doToast, selectToast } from 'lbry-redux';
|
2018-08-16 11:48:34 +02:00
|
|
|
import {
|
|
|
|
doUserEmailVerify,
|
|
|
|
doUserEmailVerifyFailure,
|
|
|
|
selectEmailToVerify,
|
|
|
|
selectEmailVerifyIsPending,
|
|
|
|
selectEmailVerifyErrorMessage,
|
|
|
|
selectUser
|
|
|
|
} from 'lbryinc';
|
2018-04-09 20:39:35 +02:00
|
|
|
import { makeSelectClientSetting } from '../redux/selectors/settings';
|
2018-08-16 11:48:34 +02:00
|
|
|
import { decode as atob } from 'base-64';
|
2018-09-02 09:12:21 +02:00
|
|
|
import { dispatchNavigateToUri } from '../utils/helper';
|
2018-08-31 09:56:41 +02:00
|
|
|
import Colors from '../styles/colors';
|
2018-08-16 11:48:34 +02:00
|
|
|
import Constants from '../constants';
|
2018-08-31 09:56:41 +02:00
|
|
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
|
|
|
import NavigationButton from '../component/navigationButton';
|
2018-03-11 16:32:13 +01:00
|
|
|
import discoverStyle from '../styles/discover';
|
2018-04-09 20:39:35 +02:00
|
|
|
import searchStyle from '../styles/search';
|
2018-08-16 11:48:34 +02:00
|
|
|
import SearchRightHeaderIcon from '../component/searchRightHeaderIcon';
|
2018-03-11 16:32:13 +01:00
|
|
|
|
2018-08-29 22:19:49 +02:00
|
|
|
const menuNavigationButton = (navigation) => <NavigationButton
|
|
|
|
name="bars"
|
|
|
|
size={24}
|
|
|
|
style={discoverStyle.drawerMenuButton}
|
|
|
|
iconStyle={discoverStyle.drawerHamburger}
|
2018-09-02 09:32:09 +02:00
|
|
|
onPress={() => navigation.openDrawer() } />
|
2018-08-29 22:19:49 +02:00
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
const discoverStack = createStackNavigator({
|
2018-03-11 16:32:13 +01:00
|
|
|
Discover: {
|
|
|
|
screen: DiscoverPage,
|
|
|
|
navigationOptions: ({ navigation }) => ({
|
|
|
|
title: 'Discover',
|
2018-08-29 22:19:49 +02:00
|
|
|
headerLeft: menuNavigationButton(navigation),
|
2018-03-11 16:32:13 +01:00
|
|
|
})
|
|
|
|
},
|
|
|
|
File: {
|
|
|
|
screen: FilePage,
|
|
|
|
navigationOptions: {
|
2018-03-22 07:26:04 +01:00
|
|
|
header: null,
|
|
|
|
drawerLockMode: 'locked-closed'
|
2018-03-11 16:32:13 +01:00
|
|
|
}
|
2018-04-09 20:39:35 +02:00
|
|
|
},
|
|
|
|
Search: {
|
|
|
|
screen: SearchPage,
|
|
|
|
navigationOptions: ({ navigation }) => ({
|
2018-05-26 01:20:44 +02:00
|
|
|
drawerLockMode: 'locked-closed'
|
2018-04-09 20:39:35 +02:00
|
|
|
})
|
2018-03-11 16:32:13 +01:00
|
|
|
}
|
|
|
|
}, {
|
2018-09-02 09:12:21 +02:00
|
|
|
headerMode: 'screen'
|
2018-03-11 16:32:13 +01:00
|
|
|
});
|
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
const trendingStack = createStackNavigator({
|
2018-06-05 20:52:10 +02:00
|
|
|
Trending: {
|
|
|
|
screen: TrendingPage,
|
|
|
|
navigationOptions: ({ navigation }) => ({
|
|
|
|
title: 'Trending',
|
2018-08-29 22:19:49 +02:00
|
|
|
headerLeft: menuNavigationButton(navigation),
|
2018-06-05 20:52:10 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
const myLbryStack = createStackNavigator({
|
2018-08-31 09:56:41 +02:00
|
|
|
Downloads: {
|
|
|
|
screen: DownloadsPage,
|
|
|
|
navigationOptions: ({ navigation }) => ({
|
|
|
|
title: 'My LBRY',
|
|
|
|
headerLeft: menuNavigationButton(navigation),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
const rewardsStack = createStackNavigator({
|
2018-08-31 09:56:41 +02:00
|
|
|
Rewards: {
|
|
|
|
screen: RewardsPage,
|
|
|
|
navigationOptions: ({ navigation }) => ({
|
|
|
|
title: 'Rewards',
|
|
|
|
headerLeft: menuNavigationButton(navigation),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
const walletStack = createStackNavigator({
|
2018-05-03 20:58:31 +02:00
|
|
|
Wallet: {
|
|
|
|
screen: WalletPage,
|
|
|
|
navigationOptions: ({ navigation }) => ({
|
|
|
|
title: 'Wallet',
|
2018-08-29 22:19:49 +02:00
|
|
|
headerLeft: menuNavigationButton(navigation),
|
2018-05-03 20:58:31 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
TransactionHistory: {
|
|
|
|
screen: TransactionHistoryPage,
|
|
|
|
navigationOptions: {
|
|
|
|
title: 'Transaction History',
|
|
|
|
drawerLockMode: 'locked-closed'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
headerMode: 'screen'
|
|
|
|
});
|
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
const drawer = createDrawerNavigator({
|
2018-08-31 09:56:41 +02:00
|
|
|
DiscoverStack: { screen: discoverStack, navigationOptions: {
|
2018-09-02 09:12:21 +02:00
|
|
|
title: 'Discover', drawerIcon: ({ tintColor }) => <Icon name="compass" size={20} style={{ color: tintColor }} />
|
2018-08-31 09:56:41 +02:00
|
|
|
}},
|
|
|
|
TrendingStack: { screen: trendingStack, navigationOptions: {
|
2018-09-02 09:12:21 +02:00
|
|
|
title: 'Trending', drawerIcon: ({ tintColor }) => <Icon name="fire" size={20} style={{ color: tintColor }} />
|
2018-08-31 09:56:41 +02:00
|
|
|
}},
|
|
|
|
MyLBRYStack: { screen: myLbryStack, navigationOptions: {
|
2018-09-02 09:12:21 +02:00
|
|
|
title: 'My LBRY', drawerIcon: ({ tintColor }) => <Icon name="folder" size={20} style={{ color: tintColor }} />
|
2018-08-31 09:56:41 +02:00
|
|
|
}},
|
|
|
|
Rewards: { screen: rewardsStack, navigationOptions: {
|
|
|
|
drawerIcon: ({ tintColor }) => <Icon name="trophy" size={20} style={{ color: tintColor }} />
|
|
|
|
}},
|
|
|
|
WalletStack: { screen: walletStack, navigationOptions: {
|
2018-09-02 09:12:21 +02:00
|
|
|
title: 'Wallet', drawerIcon: ({ tintColor }) => <Icon name="wallet" size={20} style={{ color: tintColor }} />
|
2018-08-31 09:56:41 +02:00
|
|
|
}},
|
|
|
|
Settings: { screen: SettingsPage, navigationOptions: {
|
|
|
|
drawerLockMode: 'locked-closed',
|
|
|
|
drawerIcon: ({ tintColor }) => <Icon name="cog" size={20} style={{ color: tintColor }} />
|
|
|
|
}},
|
|
|
|
About: { screen: AboutPage, navigationOptions: {
|
|
|
|
drawerLockMode: 'locked-closed',
|
|
|
|
drawerIcon: ({ tintColor }) => <Icon name="info" size={20} style={{ color: tintColor }} />
|
|
|
|
}}
|
2018-03-11 16:32:13 +01:00
|
|
|
}, {
|
|
|
|
drawerWidth: 300,
|
2018-08-31 09:56:41 +02:00
|
|
|
headerMode: 'none',
|
|
|
|
contentOptions: {
|
|
|
|
activeTintColor: Colors.LbryGreen
|
|
|
|
}
|
2018-03-11 16:32:13 +01:00
|
|
|
});
|
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
export const AppNavigator = new createStackNavigator({
|
2018-06-08 10:13:45 +02:00
|
|
|
FirstRun: {
|
|
|
|
screen: FirstRunScreen,
|
|
|
|
navigationOptions: {
|
|
|
|
drawerLockMode: 'locked-closed'
|
|
|
|
}
|
|
|
|
},
|
2018-03-11 16:32:13 +01:00
|
|
|
Splash: {
|
2018-04-09 20:39:35 +02:00
|
|
|
screen: SplashScreen,
|
|
|
|
navigationOptions: {
|
|
|
|
drawerLockMode: 'locked-closed'
|
|
|
|
}
|
2018-03-11 16:32:13 +01:00
|
|
|
},
|
|
|
|
Main: {
|
|
|
|
screen: drawer
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
headerMode: 'none'
|
|
|
|
});
|
|
|
|
|
2018-09-02 09:12:21 +02:00
|
|
|
export const reactNavigationMiddleware = createReactNavigationReduxMiddleware(
|
|
|
|
"root",
|
|
|
|
state => state.nav,
|
|
|
|
);
|
|
|
|
const App = reduxifyNavigator(AppNavigator, "root");
|
|
|
|
const appMapStateToProps = (state) => ({
|
|
|
|
state: state.nav,
|
|
|
|
});
|
|
|
|
const ReduxAppNavigator = connect(appMapStateToProps)(App);
|
|
|
|
|
2018-03-11 16:32:13 +01:00
|
|
|
class AppWithNavigationState extends React.Component {
|
2018-05-03 20:58:31 +02:00
|
|
|
static supportedDisplayTypes = ['toast'];
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-08-16 11:48:34 +02:00
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
this.state = {
|
|
|
|
emailVerifyDone: false
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-03-11 16:32:13 +01:00
|
|
|
componentWillMount() {
|
2018-03-23 00:03:05 +01:00
|
|
|
AppState.addEventListener('change', this._handleAppStateChange);
|
2018-03-11 16:32:13 +01:00
|
|
|
BackHandler.addEventListener('hardwareBackPress', function() {
|
2018-05-25 09:13:05 +02:00
|
|
|
const { dispatch, nav } = this.props;
|
2018-04-23 06:01:33 +02:00
|
|
|
// There should be a better way to check this
|
2018-05-10 22:07:18 +02:00
|
|
|
if (nav.routes.length > 0) {
|
|
|
|
if (nav.routes[0].routeName === 'Main') {
|
2018-09-02 09:12:21 +02:00
|
|
|
const mainRoute = nav.routes[0];
|
2018-09-02 09:32:09 +02:00
|
|
|
if (mainRoute.index > 0 ||
|
|
|
|
mainRoute.routes[0].index > 0 /* Discover stack index */ ||
|
2018-09-02 09:12:21 +02:00
|
|
|
mainRoute.routes[4].index > 0 /* Wallet stack index */ ||
|
|
|
|
mainRoute.index >= 5 /* Settings and About screens */) {
|
2018-05-10 22:07:18 +02:00
|
|
|
dispatch(NavigationActions.back());
|
2018-04-23 06:01:33 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2018-03-11 16:32:13 +01:00
|
|
|
}
|
2018-08-16 11:48:34 +02:00
|
|
|
return false;
|
2018-03-11 16:32:13 +01:00
|
|
|
}.bind(this));
|
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-05-25 09:13:05 +02:00
|
|
|
componentDidMount() {
|
|
|
|
Linking.addEventListener('url', this._handleUrl);
|
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-03-11 16:32:13 +01:00
|
|
|
componentWillUnmount() {
|
2018-03-23 00:03:05 +01:00
|
|
|
AppState.removeEventListener('change', this._handleAppStateChange);
|
2018-03-11 16:32:13 +01:00
|
|
|
BackHandler.removeEventListener('hardwareBackPress');
|
2018-05-25 09:13:05 +02:00
|
|
|
Linking.removeEventListener('url', this._handleUrl);
|
2018-03-11 16:32:13 +01:00
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-05-03 20:58:31 +02:00
|
|
|
componentWillUpdate(nextProps) {
|
|
|
|
const { dispatch } = this.props;
|
2018-08-16 11:48:34 +02:00
|
|
|
const {
|
2018-11-20 18:07:12 +01:00
|
|
|
toast,
|
2018-08-16 11:48:34 +02:00
|
|
|
emailToVerify,
|
|
|
|
emailVerifyPending,
|
|
|
|
emailVerifyErrorMessage,
|
|
|
|
user
|
|
|
|
} = nextProps;
|
|
|
|
|
2018-11-20 18:07:12 +01:00
|
|
|
if (toast) {
|
|
|
|
const { message } = toast;
|
2018-05-03 20:58:31 +02:00
|
|
|
let currentDisplayType;
|
2018-08-28 12:59:14 +02:00
|
|
|
if (displayType && displayType.length) {
|
2018-05-03 20:58:31 +02:00
|
|
|
for (let i = 0; i < displayType.length; i++) {
|
|
|
|
const type = displayType[i];
|
|
|
|
if (AppWithNavigationState.supportedDisplayTypes.indexOf(type) > -1) {
|
|
|
|
currentDisplayType = type;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (AppWithNavigationState.supportedDisplayTypes.indexOf(displayType) > -1) {
|
|
|
|
currentDisplayType = displayType;
|
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-08-28 12:59:14 +02:00
|
|
|
if (!currentDisplayType && message) {
|
|
|
|
// default to toast if no display type set and there is a message specified
|
|
|
|
currentDisplayType = 'toast';
|
|
|
|
}
|
|
|
|
|
2018-05-03 20:58:31 +02:00
|
|
|
if ('toast' === currentDisplayType) {
|
2018-09-03 03:57:54 +02:00
|
|
|
ToastAndroid.show(message, ToastAndroid.LONG);
|
2018-05-03 20:58:31 +02:00
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-05-03 20:58:31 +02:00
|
|
|
dispatch(doHideNotification());
|
|
|
|
}
|
2018-08-16 11:48:34 +02:00
|
|
|
|
|
|
|
if (user &&
|
|
|
|
!emailVerifyPending &&
|
|
|
|
!this.state.emailVerifyDone &&
|
|
|
|
(emailToVerify || emailVerifyErrorMessage)) {
|
|
|
|
AsyncStorage.getItem(Constants.KEY_SHOULD_VERIFY_EMAIL).then(shouldVerify => {
|
|
|
|
if ('true' === shouldVerify) {
|
|
|
|
this.setState({ emailVerifyDone: true });
|
|
|
|
const message = emailVerifyErrorMessage ?
|
|
|
|
String(emailVerifyErrorMessage) : 'Your email address was successfully verified.';
|
2018-08-16 14:21:28 +02:00
|
|
|
if (!emailVerifyErrorMessage) {
|
|
|
|
AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL);
|
|
|
|
}
|
|
|
|
AsyncStorage.removeItem(Constants.KEY_SHOULD_VERIFY_EMAIL);
|
2018-11-20 18:07:12 +01:00
|
|
|
dispatch(doToast({ message }));
|
2018-08-16 11:48:34 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-05-03 20:58:31 +02:00
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-03-23 00:03:05 +01:00
|
|
|
_handleAppStateChange = (nextAppState) => {
|
2018-08-20 17:00:16 +02:00
|
|
|
const { backgroundPlayEnabled, dispatch } = this.props;
|
2018-04-24 21:32:17 +02:00
|
|
|
// Check if the app was suspended
|
|
|
|
if (AppState.currentState && AppState.currentState.match(/inactive|background/)) {
|
|
|
|
AsyncStorage.getItem('firstLaunchTime').then(start => {
|
|
|
|
if (start !== null && !isNaN(parseInt(start, 10))) {
|
|
|
|
// App suspended during first launch?
|
|
|
|
// If so, this needs to be included as a property when tracking
|
|
|
|
AsyncStorage.setItem('firstLaunchSuspended', 'true');
|
|
|
|
}
|
2018-08-20 17:00:16 +02:00
|
|
|
|
|
|
|
// Background media
|
|
|
|
if (backgroundPlayEnabled && NativeModules.BackgroundMedia && window.currentMediaInfo) {
|
2018-09-01 23:45:20 +02:00
|
|
|
const { title, channel, uri } = window.currentMediaInfo;
|
|
|
|
NativeModules.BackgroundMedia.showPlaybackNotification(title, channel, uri, false);
|
2018-08-20 17:00:16 +02:00
|
|
|
}
|
2018-04-24 21:32:17 +02:00
|
|
|
});
|
|
|
|
}
|
2018-08-17 20:11:15 +02:00
|
|
|
|
|
|
|
if (AppState.currentState && AppState.currentState.match(/active/)) {
|
|
|
|
// Cleanup blobs for completed files upon app resume to save space
|
|
|
|
dispatch(doDeleteCompleteBlobs());
|
2018-08-20 17:00:16 +02:00
|
|
|
if (backgroundPlayEnabled || NativeModules.BackgroundMedia) {
|
|
|
|
NativeModules.BackgroundMedia.hidePlaybackNotification();
|
|
|
|
}
|
2018-08-17 20:11:15 +02:00
|
|
|
}
|
2018-03-23 00:03:05 +01:00
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-05-25 09:13:05 +02:00
|
|
|
_handleUrl = (evt) => {
|
2018-09-02 09:12:21 +02:00
|
|
|
const { dispatch, nav } = this.props;
|
2018-05-25 09:13:05 +02:00
|
|
|
if (evt.url) {
|
2018-08-16 11:48:34 +02:00
|
|
|
if (evt.url.startsWith('lbry://?verify=')) {
|
|
|
|
this.setState({ emailVerifyDone: false });
|
|
|
|
let verification = {};
|
|
|
|
try {
|
|
|
|
verification = JSON.parse(atob(evt.url.substring(15)));
|
|
|
|
} catch (error) {
|
|
|
|
console.log(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (verification.token && verification.recaptcha) {
|
|
|
|
AsyncStorage.setItem(Constants.KEY_SHOULD_VERIFY_EMAIL, 'true');
|
|
|
|
try {
|
|
|
|
dispatch(doUserEmailVerify(verification.token, verification.recaptcha));
|
|
|
|
} catch (error) {
|
|
|
|
const message = 'Invalid Verification Token';
|
|
|
|
dispatch(doUserEmailVerifyFailure(message));
|
2018-11-20 18:07:12 +01:00
|
|
|
dispatch(doToast({ message }));
|
2018-08-16 11:48:34 +02:00
|
|
|
}
|
|
|
|
} else {
|
2018-11-20 18:07:12 +01:00
|
|
|
dispatch(doToast({
|
2018-08-16 11:48:34 +02:00
|
|
|
message: 'Invalid Verification URI',
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
} else {
|
2018-09-02 09:12:21 +02:00
|
|
|
dispatchNavigateToUri(dispatch, nav, evt.url);
|
2018-08-16 11:48:34 +02:00
|
|
|
}
|
2018-05-25 09:13:05 +02:00
|
|
|
}
|
|
|
|
}
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-03-11 16:32:13 +01:00
|
|
|
render() {
|
2018-09-02 09:12:21 +02:00
|
|
|
return <ReduxAppNavigator />;
|
2018-03-11 16:32:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const mapStateToProps = state => ({
|
2018-08-20 17:00:16 +02:00
|
|
|
backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state),
|
2018-08-16 11:48:34 +02:00
|
|
|
keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state),
|
2018-03-11 16:32:13 +01:00
|
|
|
nav: state.nav,
|
2018-11-20 18:07:12 +01:00
|
|
|
toast: selectToast(state),
|
2018-08-16 11:48:34 +02:00
|
|
|
emailToVerify: selectEmailToVerify(state),
|
|
|
|
emailVerifyPending: selectEmailVerifyIsPending(state),
|
|
|
|
emailVerifyErrorMessage: selectEmailVerifyErrorMessage(state),
|
|
|
|
showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state),
|
2018-09-02 09:12:21 +02:00
|
|
|
user: selectUser(state)
|
2018-03-11 16:32:13 +01:00
|
|
|
});
|
2018-06-08 10:13:45 +02:00
|
|
|
|
2018-05-03 20:58:31 +02:00
|
|
|
export default connect(mapStateToProps)(AppWithNavigationState);
|