diff --git a/app/package-lock.json b/app/package-lock.json index aa9b0b4..8cfa17c 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -2440,6 +2440,15 @@ "object-assign": "^4.1.1" } }, + "create-react-context": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz", + "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==", + "requires": { + "fbjs": "^0.8.0", + "gud": "^1.0.0" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -3432,6 +3441,11 @@ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -3969,12 +3983,13 @@ "version": "github:lbryio/lbryinc#678c5098e2099dd1560b2fefa2795f38ca3ce07b", "from": "github:lbryio/lbryinc", "requires": { + "lbry-redux": "github:lbryio/lbry-redux#421321a78397251589e5a890f4caa95e79975e2b", "reselect": "^3.0.0" }, "dependencies": { "lbry-redux": { - "version": "github:lbryio/lbry-redux#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc", - "from": "github:lbryio/lbry-redux#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc", + "version": "github:lbryio/lbry-redux#421321a78397251589e5a890f4caa95e79975e2b", + "from": "github:lbryio/lbry-redux", "requires": { "proxy-polyfill": "0.1.6", "reselect": "^3.0.0" @@ -5020,6 +5035,15 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, + "query-string": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.1.0.tgz", + "integrity": "sha512-pNB/Gr8SA8ff8KpUFM36o/WFAlthgaThka5bV19AD9PNTH20Pwq5Zxodif2YyHwrctp6SkL4GqlOot0qR/wGaw==", + "requires": { + "decode-uri-component": "^0.2.0", + "strict-uri-encode": "^2.0.0" + } + }, "randomatic": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", @@ -5240,16 +5264,17 @@ } }, "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==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.9.0.tgz", + "integrity": "sha512-y792ScHMzvgwquxL869S9CER4dwiFu/TuCiXdy0xBtygmScMK4eWonnUT65LvOrsSSdr8o6XEK1mbI51h6ozvQ==", "requires": { "hoist-non-react-statics": "^2.3.1" } }, "react-native-tab-view": { - "version": "github:react-navigation/react-native-tab-view#36ebd834d78b841fc19778c966465d02fd1213bb", - "from": "react-native-tab-view@github:react-navigation/react-native-tab-view#36ebd834d78b841fc19778c966465d02fd1213bb", + "version": "0.0.77", + "resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-0.0.77.tgz", + "integrity": "sha512-9vjD4Ly1Zlum1Y4g23ODpi/F3gYIUIsKWrsZO/Oh5cuX1eiB1DRVn11nY1z+j/hsQfhfyW6nDlmySyDvYQvYCA==", "requires": { "prop-types": "^15.6.0" } @@ -5302,28 +5327,82 @@ } }, "react-navigation": { - "version": "1.5.12", - "resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-1.5.12.tgz", - "integrity": "sha512-+i0ymFHokQxjv0/0knBUtxC1zuyvLgbDVPFU7ScKxT25SGVh2exuRjYwXImF234/qtYMskfY7bfhEjGLcXPySQ==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-2.12.1.tgz", + "integrity": "sha512-C+do+STPvvd/5LbaDhrZyf1P8tCeffttdlHyIRe1NgGg8Nj93FZHWOThi2hnmEZ75kXsS/JGxox4DDPqYVAxeQ==", "requires": { "clamp": "^1.0.1", + "create-react-context": "^0.2.1", "hoist-non-react-statics": "^2.2.0", "path-to-regexp": "^1.7.0", - "prop-types": "^15.5.10", - "react-lifecycles-compat": "^3.0.2", - "react-native-drawer-layout-polyfill": "^1.3.2", - "react-native-safe-area-view": "^0.7.0", - "react-native-tab-view": "github:react-navigation/react-native-tab-view#36ebd834d78b841fc19778c966465d02fd1213bb" + "query-string": "^6.1.0", + "react-lifecycles-compat": "^3", + "react-native-safe-area-view": "^0.9.0", + "react-navigation-deprecated-tab-navigator": "1.3.0", + "react-navigation-drawer": "0.5.0", + "react-navigation-stack": "0.2.3", + "react-navigation-tabs": "0.6.0" + } + }, + "react-navigation-deprecated-tab-navigator": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-navigation-deprecated-tab-navigator/-/react-navigation-deprecated-tab-navigator-1.3.0.tgz", + "integrity": "sha512-Cm+qYOPFWbvvcuv0YYX0ioYwLGgw7XAqdhAfpo3sIr3trxRW8871ePmfFOPezjQtz4v6ItjZt6LPgtBAVZoroQ==", + "requires": { + "react-native-tab-view": "^0.0.77" + } + }, + "react-navigation-drawer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/react-navigation-drawer/-/react-navigation-drawer-0.5.0.tgz", + "integrity": "sha512-F1y593uC6pqBMGH+Omz75oNODEbxB/s0EGO8QtYwu1NmOOEUuuLA+c14zm+pgMsI4HlDabiHxPkWqsgGz25xVQ==", + "requires": { + "react-native-drawer-layout-polyfill": "^1.3.2" } }, "react-navigation-redux-helpers": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/react-navigation-redux-helpers/-/react-navigation-redux-helpers-1.0.7.tgz", - "integrity": "sha512-JUD3ycYS0EZLIzuaZVQ4/c3KMrEztPLqXzVV/qifeWQQLq01BmPnIuR7VWluSfZ98cgGlX9hY5r72wwgvvrfjw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/react-navigation-redux-helpers/-/react-navigation-redux-helpers-2.0.5.tgz", + "integrity": "sha512-oxDpPqmXdzUJJ32ef8NY6Cu9XDJNO4DU91p0+ZgleEfaZwec9t2ua6sKwQyOfdWQPDwbJAxiXfZIAe3ao5MG6Q==", "requires": { "invariant": "^2.2.2" } }, + "react-navigation-stack": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/react-navigation-stack/-/react-navigation-stack-0.2.3.tgz", + "integrity": "sha512-xjVqiI/ztcQt45jxQ3vfO8Lr+9bVq+0J/lRhMdZCvCDwiyOVuB64wx7qPNJW16pnBBLiI5h6H7uhWE3rAT0r/w==" + }, + "react-navigation-tabs": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/react-navigation-tabs/-/react-navigation-tabs-0.6.0.tgz", + "integrity": "sha512-Ax1rujJ51R1Jrz7b5bHUAIgsYC1VrFws+d3hxlPy5dXG84iJdV5dnDFRvdQMDDfDZc+NDx2a223lAYsc3p2+XA==", + "requires": { + "hoist-non-react-statics": "^2.5.0", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "react-native-safe-area-view": "^0.7.0", + "react-native-tab-view": "^1.0.0" + }, + "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": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-1.0.2.tgz", + "integrity": "sha512-x8I43V1X7/AyMnIwnqJGMU54LqQRlV6vJ9irbls9asA/axdHIdxagPIV6Jx1ttFe/bPKhFwXL+lRYdYxGyUlWg==", + "requires": { + "prop-types": "^15.6.1" + } + } + } + }, "react-proxy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-1.1.8.tgz", @@ -6339,6 +6418,11 @@ "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=" }, + "strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", diff --git a/app/package.json b/app/package.json index f70e51c..f890440 100644 --- a/app/package.json +++ b/app/package.json @@ -17,8 +17,8 @@ "react-native-image-zoom-viewer": "^2.2.5", "react-native-vector-icons": "^5.0.0", "react-native-video": "lbryio/react-native-video#exoplayer-lbry-android", - "react-navigation": "^1.5.12", - "react-navigation-redux-helpers": "^1.0.1", + "react-navigation": "^2.12.1", + "react-navigation-redux-helpers": "^2.0.5", "react-redux": "^5.0.3", "redux": "^3.6.0", "redux-logger": "3.0.6", diff --git a/app/src/component/AppNavigator.js b/app/src/component/AppNavigator.js index 68ee12f..fe7b1ca 100644 --- a/app/src/component/AppNavigator.js +++ b/app/src/component/AppNavigator.js @@ -13,13 +13,16 @@ import TransactionHistoryPage from '../page/transactionHistory'; import WalletPage from '../page/wallet'; import SearchInput from '../component/searchInput'; import { - addNavigationHelpers, - DrawerNavigator, - StackNavigator, + createDrawerNavigator, + createStackNavigator, NavigationActions } from 'react-navigation'; +import { + addListener, + reduxifyNavigator, + createReactNavigationReduxMiddleware, +} from 'react-navigation-redux-helpers'; import { connect } from 'react-redux'; -import { addListener } from '../utils/redux'; import { AppState, AsyncStorage, @@ -41,6 +44,7 @@ import { } from 'lbryinc'; import { makeSelectClientSetting } from '../redux/selectors/settings'; import { decode as atob } from 'base-64'; +import { dispatchNavigateToUri } from '../utils/helper'; import Colors from '../styles/colors'; import Constants from '../constants'; import Icon from 'react-native-vector-icons/FontAwesome5'; @@ -56,7 +60,7 @@ const menuNavigationButton = (navigation) => navigation.navigate('DrawerOpen')} /> -const discoverStack = StackNavigator({ +const discoverStack = createStackNavigator({ Discover: { screen: DiscoverPage, navigationOptions: ({ navigation }) => ({ @@ -78,10 +82,10 @@ const discoverStack = StackNavigator({ }) } }, { - headerMode: 'screen', + headerMode: 'screen' }); -const trendingStack = StackNavigator({ +const trendingStack = createStackNavigator({ Trending: { screen: TrendingPage, navigationOptions: ({ navigation }) => ({ @@ -91,7 +95,7 @@ const trendingStack = StackNavigator({ } }); -const myLbryStack = StackNavigator({ +const myLbryStack = createStackNavigator({ Downloads: { screen: DownloadsPage, navigationOptions: ({ navigation }) => ({ @@ -101,7 +105,7 @@ const myLbryStack = StackNavigator({ } }); -const rewardsStack = StackNavigator({ +const rewardsStack = createStackNavigator({ Rewards: { screen: RewardsPage, navigationOptions: ({ navigation }) => ({ @@ -111,7 +115,7 @@ const rewardsStack = StackNavigator({ } }); -const walletStack = StackNavigator({ +const walletStack = createStackNavigator({ Wallet: { screen: WalletPage, navigationOptions: ({ navigation }) => ({ @@ -130,21 +134,21 @@ const walletStack = StackNavigator({ headerMode: 'screen' }); -const drawer = DrawerNavigator({ +const drawer = createDrawerNavigator({ DiscoverStack: { screen: discoverStack, navigationOptions: { - drawerIcon: ({ tintColor }) => + title: 'Discover', drawerIcon: ({ tintColor }) => }}, TrendingStack: { screen: trendingStack, navigationOptions: { - drawerIcon: ({ tintColor }) => + title: 'Trending', drawerIcon: ({ tintColor }) => }}, MyLBRYStack: { screen: myLbryStack, navigationOptions: { - drawerIcon: ({ tintColor }) => + title: 'My LBRY', drawerIcon: ({ tintColor }) => }}, Rewards: { screen: rewardsStack, navigationOptions: { drawerIcon: ({ tintColor }) => }}, WalletStack: { screen: walletStack, navigationOptions: { - drawerIcon: ({ tintColor }) => + title: 'Wallet', drawerIcon: ({ tintColor }) => }}, Settings: { screen: SettingsPage, navigationOptions: { drawerLockMode: 'locked-closed', @@ -162,7 +166,7 @@ const drawer = DrawerNavigator({ } }); -export const AppNavigator = new StackNavigator({ +export const AppNavigator = new createStackNavigator({ FirstRun: { screen: FirstRunScreen, navigationOptions: { @@ -182,6 +186,16 @@ export const AppNavigator = new StackNavigator({ headerMode: 'none' }); +export const reactNavigationMiddleware = createReactNavigationReduxMiddleware( + "root", + state => state.nav, +); +const App = reduxifyNavigator(AppNavigator, "root"); +const appMapStateToProps = (state) => ({ + state: state.nav, +}); +const ReduxAppNavigator = connect(appMapStateToProps)(App); + class AppWithNavigationState extends React.Component { static supportedDisplayTypes = ['toast']; @@ -198,17 +212,11 @@ class AppWithNavigationState extends React.Component { const { dispatch, nav } = this.props; // There should be a better way to check this if (nav.routes.length > 0) { - if (nav.routes[0].routes && nav.routes[0].routes.length > 0) { - const subRoutes = nav.routes[0].routes[0].routes; - const lastRoute = subRoutes[subRoutes.length - 1]; - if (nav.routes[0].routes[0].index > 0 && - ['About', 'Settings'].indexOf(lastRoute.key) > -1) { - dispatch(NavigationActions.back()); - return true; - } - } if (nav.routes[0].routeName === 'Main') { - if (nav.routes[0].routes[0].routes[0].index > 0) { + const mainRoute = nav.routes[0]; + if (mainRoute.routes[0].index > 0 /* Discover stack index */ || + mainRoute.routes[4].index > 0 /* Wallet stack index */ || + mainRoute.index >= 5 /* Settings and About screens */) { dispatch(NavigationActions.back()); return true; } @@ -313,7 +321,7 @@ class AppWithNavigationState extends React.Component { } _handleUrl = (evt) => { - const { dispatch } = this.props; + const { dispatch, nav } = this.props; if (evt.url) { if (evt.url.startsWith('lbry://?verify=')) { this.setState({ emailVerifyDone: false }); @@ -340,27 +348,13 @@ class AppWithNavigationState extends React.Component { })); } } else { - const navigateAction = NavigationActions.navigate({ - routeName: 'File', - key: evt.url, - params: { uri: evt.url } - }); - dispatch(navigateAction); + dispatchNavigateToUri(dispatch, nav, evt.url); } } } render() { - const { dispatch, nav } = this.props; - return ( - - ); + return ; } } @@ -373,7 +367,7 @@ const mapStateToProps = state => ({ emailVerifyPending: selectEmailVerifyIsPending(state), emailVerifyErrorMessage: selectEmailVerifyErrorMessage(state), showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state), - user: selectUser(state), + user: selectUser(state) }); export default connect(mapStateToProps)(AppWithNavigationState); diff --git a/app/src/component/fileItem/view.js b/app/src/component/fileItem/view.js index cf63644..9539a25 100644 --- a/app/src/component/fileItem/view.js +++ b/app/src/component/fileItem/view.js @@ -2,6 +2,7 @@ import React from 'react'; import { normalizeURI } from 'lbry-redux'; import { NavigationActions } from 'react-navigation'; import { NativeModules, Text, View, TouchableOpacity } from 'react-native'; +import { navigateToUri } from '../../utils/helper'; import FileItemMedia from '../fileItemMedia'; import FilePrice from '../filePrice'; import Link from '../link'; @@ -54,7 +55,7 @@ class FileItem extends React.PureComponent { if (NativeModules.Mixpanel) { NativeModules.Mixpanel.track('Discover Tap', { Uri: uri }); } - navigation.navigate({ routeName: 'File', key: uri, params: { uri } }); + navigateToUri(navigation, uri); } }> { const channelUri = normalizeURI(channelName); - navigation.navigate({ routeName: 'File', key: channelUri, params: { uri: channelUri }}); + navigateToUri(navigation, channelUri); }} />} {obscureNsfw && navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />} diff --git a/app/src/component/fileItemMedia/view.js b/app/src/component/fileItemMedia/view.js index e4d792c..e403c30 100644 --- a/app/src/component/fileItemMedia/view.js +++ b/app/src/component/fileItemMedia/view.js @@ -37,7 +37,6 @@ class FileItemMedia extends React.PureComponent { case "contain": return FastImage.resizeMode.contain; case "stretch": - console.log('using stretch resize mode...'); return FastImage.resizeMode.stretch; case "center": return FastImage.resizeMode.center; diff --git a/app/src/component/fileListItem/view.js b/app/src/component/fileListItem/view.js index 8191652..aea9558 100644 --- a/app/src/component/fileListItem/view.js +++ b/app/src/component/fileListItem/view.js @@ -8,6 +8,7 @@ import { TouchableOpacity, View } from 'react-native'; +import { navigateToUri } from '../../utils/helper'; import Colors from '../../styles/colors'; import FileItemMedia from '../fileItemMedia'; import Link from '../../component/link'; @@ -52,6 +53,13 @@ class FileListItem extends React.PureComponent { return Math.ceil((fileInfo.written_bytes / fileInfo.total_bytes) * 100); } + componentDidMount() { + const { claim, resolveUri, uri } = this.props; + if (!claim) { + resolveUri(uri); + } + } + render() { const { claim, @@ -97,7 +105,7 @@ class FileListItem extends React.PureComponent { {!isResolving && channel && { const channelUri = normalizeURI(channel); - navigation.navigate({ routeName: 'File', key: channelUri, params: { uri: channelUri }}); + navigateToUri(navigation, channelUri); }} />} {fileInfo && diff --git a/app/src/component/floatingWalletBalance/view.js b/app/src/component/floatingWalletBalance/view.js index 42d4361..12f25fe 100644 --- a/app/src/component/floatingWalletBalance/view.js +++ b/app/src/component/floatingWalletBalance/view.js @@ -17,7 +17,7 @@ class FloatingWalletBalance extends React.PureComponent { return ( navigation && navigation.navigate({ routeName: 'Wallet' })}> + onPress={() => navigation && navigation.navigate({ routeName: 'WalletStack' })}> {isNaN(balance) && } {(balance || balance === 0) && (formatCredits(balance, 2) + ' LBC')} diff --git a/app/src/component/mediaPlayer/index.js b/app/src/component/mediaPlayer/index.js index e3715f5..54af075 100644 --- a/app/src/component/mediaPlayer/index.js +++ b/app/src/component/mediaPlayer/index.js @@ -6,6 +6,5 @@ import MediaPlayer from './view'; const select = state => ({ backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state), }); -const perform = dispatch => ({}); -export default connect(select, perform)(MediaPlayer); +export default connect(select, null)(MediaPlayer); diff --git a/app/src/component/mediaPlayer/view.js b/app/src/component/mediaPlayer/view.js index e1e51a9..38de91b 100644 --- a/app/src/component/mediaPlayer/view.js +++ b/app/src/component/mediaPlayer/view.js @@ -225,6 +225,11 @@ class MediaPlayer extends React.PureComponent { } componentDidMount() { + const { assignPlayer } = this.props; + if (assignPlayer) { + assignPlayer(this); + } + this.setSeekerPosition(this.calculateSeekerPosition()); DeviceEventEmitter.addListener('onBackgroundPlayPressed', this.play); DeviceEventEmitter.addListener('onBackgroundPausePressed', this.pause); diff --git a/app/src/component/transactionList/internal/transaction-list-item.js b/app/src/component/transactionList/internal/transaction-list-item.js index 711dbcb..7877808 100644 --- a/app/src/component/transactionList/internal/transaction-list-item.js +++ b/app/src/component/transactionList/internal/transaction-list-item.js @@ -2,6 +2,7 @@ import React from 'react'; import { Text, View, Linking } from 'react-native'; import { buildURI, formatCredits } from 'lbry-redux'; +import { navigateToUri } from '../../../utils/helper'; import Link from '../../link'; import moment from 'moment'; import transactionListStyle from '../../../styles/transactionList'; @@ -10,11 +11,11 @@ class TransactionListItem extends React.PureComponent { capitalize(string: string) { return string.charAt(0).toUpperCase() + string.slice(1); } - + render() { const { transaction, navigation } = this.props; const { amount, claim_id: claimId, claim_name: name, date, fee, txid, type } = transaction; - + return ( @@ -23,13 +24,9 @@ class TransactionListItem extends React.PureComponent { {name && claimId && ( navigation && navigation.navigate({ - routeName: 'File', - key: evt.Url, - params: { uri: buildURI({ claimName: name, claimId }) }}) - } + onPress={() => navigateToUri(navigation, buildURI({ claimName: name, claimId }))} text={name} /> - )} + )} {formatCredits(amount, 8)} @@ -47,7 +44,7 @@ class TransactionListItem extends React.PureComponent { {date ? ( {moment(date).format('MMM D')} ) : ( - Pending + Pending )} diff --git a/app/src/component/uriBar/view.js b/app/src/component/uriBar/view.js index d46b5e6..85cec42 100644 --- a/app/src/component/uriBar/view.js +++ b/app/src/component/uriBar/view.js @@ -2,6 +2,7 @@ import React from 'react'; import { SEARCH_TYPES, isNameValid, isURIValid, normalizeURI } from 'lbry-redux'; import { FlatList, Keyboard, TextInput, View } from 'react-native'; +import { navigateToUri } from '../../utils/helper'; import UriBarItem from './internal/uri-bar-item'; import uriBarStyle from '../../styles/uriBar'; @@ -62,7 +63,7 @@ class UriBar extends React.PureComponent { navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: value }}); } else { const uri = normalizeURI(value); - navigation.navigate({ routeName: 'File', key: uri, params: { uri }}); + navigateToUri(navigation, uri); } } @@ -127,7 +128,7 @@ class UriBar extends React.PureComponent { if (inputText.startsWith('lbry://') && isURIValid(inputText)) { // if it's a URI (lbry://...), open the file page const uri = normalizeURI(inputText); - navigation.navigate({ routeName: 'File', key: uri, params: { uri }}); + navigateToUri(navigation, uri); } else { // Not a URI, default to a search request if (onSearchSubmitted) { diff --git a/app/src/index.js b/app/src/index.js index f24da3e..15e7276 100644 --- a/app/src/index.js +++ b/app/src/index.js @@ -20,11 +20,9 @@ import { import { authReducer, rewardsReducer, userReducer } from 'lbryinc'; import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; import { createLogger } from 'redux-logger'; -import { StackNavigator, addNavigationHelpers } from 'react-navigation'; import { AppNavigator } from './component/AppNavigator'; import { persistStore, autoRehydrate } from 'redux-persist'; -import { reactNavigationMiddleware } from './utils/redux'; -import AppWithNavigationState from './component/AppNavigator'; +import AppWithNavigationState, { reactNavigationMiddleware } from './component/AppNavigator'; import FilesystemStorage from 'redux-persist-filesystem-storage'; import createCompressor from 'redux-persist-transform-compress'; import createFilter from 'redux-persist-transform-filter'; diff --git a/app/src/page/about/view.js b/app/src/page/about/view.js index 7766f2f..2f4c5a2 100644 --- a/app/src/page/about/view.js +++ b/app/src/page/about/view.js @@ -31,13 +31,14 @@ class AboutPage extends React.PureComponent { } render() { + const { navigation } = this.props; const loading = 'Loading...'; const ver = this.state.versionInfo ? this.state.versionInfo : null; return ( { this.props.navigation.goBack(); }} /> + onBackPressed={() => navigation.goBack(navigation.state.key)} /> Content Freedom diff --git a/app/src/page/channel/view.js b/app/src/page/channel/view.js index 0060c5c..2232071 100644 --- a/app/src/page/channel/view.js +++ b/app/src/page/channel/view.js @@ -47,12 +47,12 @@ class ChannelPage extends React.PureComponent { return ( - { this.props.navigation.goBack(); }} /> + navigation.goBack(navigation.state.key)} /> {contentList} ) - } + } } export default ChannelPage; diff --git a/app/src/page/downloads/view.js b/app/src/page/downloads/view.js index ae2e461..f8a924d 100644 --- a/app/src/page/downloads/view.js +++ b/app/src/page/downloads/view.js @@ -9,6 +9,7 @@ import { View, ScrollView } from 'react-native'; +import { navigateToUri } from '../../utils/helper'; import Colors from '../../styles/colors'; import PageHeader from '../../component/pageHeader'; import FileListItem from '../../component/fileListItem'; @@ -51,11 +52,7 @@ class DownloadsPage extends React.PureComponent { style={fileListStyle.item} uri={this.uriFromFileInfo(item)} navigation={navigation} - onPress={() => navigation.navigate({ - routeName: 'File', - key: 'filePage', - params: { uri: this.uriFromFileInfo(item), autoplay: true } - })} /> + onPress={() => navigateToUri(navigation, this.uriFromFileInfo(item), { autoplay: true })} /> ) } data={fileInfos.sort((a, b) => { diff --git a/app/src/page/file/view.js b/app/src/page/file/view.js index 475f5e2..8cd3ff7 100644 --- a/app/src/page/file/view.js +++ b/app/src/page/file/view.js @@ -37,25 +37,25 @@ class FilePage extends React.PureComponent { playerBackground = null; - player = null; - startTime = null; constructor(props) { super(props); this.state = { - fileViewLogged: false, - mediaLoaded: false, autoPlayMedia: false, downloadButtonShown: false, downloadPressed: false, + fileViewLogged: false, fullscreenMode: false, + imageUrls: null, + isLandscape: false, + mediaLoaded: false, + pageSuspended: false, showImageViewer: false, showWebView: false, - imageUrls: null, playerBgHeight: 0, playerHeight: 0, - isLandscape: false, + uri: null }; } @@ -64,6 +64,7 @@ class FilePage extends React.PureComponent { const { isResolvingUri, resolveUri, navigation } = this.props; const { uri } = navigation.state.params; + this.setState({ uri }); if (!isResolvingUri) resolveUri(uri); @@ -80,15 +81,23 @@ class FilePage extends React.PureComponent { componentDidUpdate(prevProps) { this.fetchFileInfo(this.props); - const { isResolvingUri, resolveUri, claim, navigation } = this.props; - const { uri } = navigation.state.params; - + const { claim, contentType, fileInfo, isResolvingUri, resolveUri, navigation } = this.props; + const { uri } = this.state; if (!isResolvingUri && claim === undefined && uri) { resolveUri(uri); } + // Returned to the page. If mediaLoaded, and currentMediaInfo is different, update + if (this.state.mediaLoaded && window.currentMediaInfo && window.currentMediaInfo.uri !== this.state.uri) { + const { metadata } = this.props; + window.currentMediaInfo = { + channel: claim ? claim.channel_name : null, + title: metadata ? metadata.title : claim.name, + uri: this.state.uri + }; + } + const prevFileInfo = prevProps.fileInfo; - const { fileInfo, contentType } = this.props; if (!prevFileInfo && fileInfo) { // started downloading const mediaType = Lbry.getMediaType(contentType); @@ -181,6 +190,7 @@ class FilePage extends React.PureComponent { if (window.currentMediaInfo) { window.currentMediaInfo = null; } + window.player = null; } localUriForFileInfo = (fileInfo) => { @@ -397,7 +407,7 @@ class FilePage extends React.PureComponent { }} />} {canLoadMedia && fileInfo && { this.player = ref; }} + assignPlayer={(ref) => { this.player = ref; }} uri={uri} style={playerStyle} autoPlay={autoplay || this.state.autoPlayMedia} @@ -432,7 +442,7 @@ class FilePage extends React.PureComponent { text={channelName} onPress={() => { const channelUri = normalizeURI(channelName); - navigation.navigate({ routeName: 'File', key: channelUri, params: { uri: channelUri }}); + navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri: channelUri }}); }} />} {description && description.length > 0 && } diff --git a/app/src/page/firstRun/view.js b/app/src/page/firstRun/view.js index c4329fb..36c6b4f 100644 --- a/app/src/page/firstRun/view.js +++ b/app/src/page/firstRun/view.js @@ -9,7 +9,7 @@ import { TouchableOpacity, View } from 'react-native'; -import { NavigationActions } from 'react-navigation'; +import { NavigationActions, StackActions } from 'react-navigation'; import Colors from '../../styles/colors'; import Constants from '../../constants'; import WelcomePage from './internal/welcome-page'; @@ -71,7 +71,7 @@ class FirstRunScreen extends React.PureComponent { launchSplashScreen() { const { navigation } = this.props; - const resetAction = NavigationActions.reset({ + const resetAction = StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Splash', params: { launchUri: this.state.launchUri } }) diff --git a/app/src/page/search/view.js b/app/src/page/search/view.js index 5a788cc..55fa19e 100644 --- a/app/src/page/search/view.js +++ b/app/src/page/search/view.js @@ -8,6 +8,7 @@ import { View, ScrollView } from 'react-native'; +import { navigateToUri } from '../../utils/helper'; import Colors from '../../styles/colors'; import PageHeader from '../../component/pageHeader'; import FileListItem from '../../component/fileListItem'; @@ -42,11 +43,7 @@ class SearchPage extends React.PureComponent { uri={uri} style={searchStyle.resultItem} navigation={navigation} - onPress={() => navigation.navigate({ - routeName: 'File', - key: 'filePage', - params: { uri }}) - }/>) + onPress={() => navigateToUri(navigation, uri)}/>) ) : null } {isSearching && } diff --git a/app/src/page/settings/view.js b/app/src/page/settings/view.js index 2870bb3..ac551b6 100644 --- a/app/src/page/settings/view.js +++ b/app/src/page/settings/view.js @@ -13,6 +13,7 @@ class SettingsPage extends React.PureComponent { const { backgroundPlayEnabled, keepDaemonRunning, + navigation, showNsfw, setClientSetting } = this.props; @@ -23,7 +24,7 @@ class SettingsPage extends React.PureComponent { return ( { this.props.navigation.goBack(); }} /> + onBackPressed={() => navigation.goBack(navigation.state.key)} /> diff --git a/app/src/page/splash/view.js b/app/src/page/splash/view.js index 633447c..0359edd 100644 --- a/app/src/page/splash/view.js +++ b/app/src/page/splash/view.js @@ -10,8 +10,9 @@ import { Text, View } from 'react-native'; -import { NavigationActions } from 'react-navigation'; +import { NavigationActions, StackActions } from 'react-navigation'; import { decode as atob } from 'base-64'; +import { navigateToUri } from '../../utils/helper'; import PropTypes from 'prop-types'; import Colors from '../../styles/colors'; import Constants from '../../constants'; @@ -75,7 +76,7 @@ class SplashScreen extends React.PureComponent { } // user is authenticated, navigate to the main view - const resetAction = NavigationActions.reset({ + const resetAction = StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Main'}) @@ -108,7 +109,7 @@ class SplashScreen extends React.PureComponent { }); } } else { - navigation.navigate({ routeName: 'File', key: launchUrl, params: { uri: launchUrl } }); + navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri: launchUrl } }); } } }); diff --git a/app/src/styles/discover.js b/app/src/styles/discover.js index 1b5a016..b73b1bc 100644 --- a/app/src/styles/discover.js +++ b/app/src/styles/discover.js @@ -6,7 +6,6 @@ const screenWidth = screenDimension.width; const screenHeight = screenDimension.height; const screenWidthPixels = PixelRatio.getPixelSizeForLayoutSize(screenWidth); const screenHeightPixels = PixelRatio.getPixelSizeForLayoutSize(screenHeight); -console.log('screenHeightPixels=' + screenHeightPixels); // calculate thumbnail width and height based on device's aspect ratio const horizontalMargin = 48; // left and right margins (24 + 24) const verticalMargin = (screenWidthPixels > 720 && screenHeightPixels > 1920) ? 0 : ((screenWidthPixels <= 720) ? 20 : 16); diff --git a/app/src/utils/helper.js b/app/src/utils/helper.js new file mode 100644 index 0000000..1a17789 --- /dev/null +++ b/app/src/utils/helper.js @@ -0,0 +1,40 @@ +import { NavigationActions, StackActions } from 'react-navigation'; + +export function navigateToUri(navigation, uri, additionalParams) { + if (!navigation) { + return; + } + + if (uri === navigation.state.key) { + return; + } + + const params = Object.assign({ uri }, additionalParams); + if ('File' === navigation.state.routeName) { + const stackAction = StackActions.replace({ routeName: 'File', newKey: uri, params }); + navigation.dispatch(stackAction); + return; + } + + navigation.navigate({ routeName: 'File', key: uri, params }); +} + +export function dispatchNavigateToUri(dispatch, nav, uri) { + const params = { uri }; + if (nav && nav.routes && nav.routes.length > 0 && 'Main' === nav.routes[0].routeName) { + const mainRoute = nav.routes[0]; + const discoverRoute = mainRoute.routes[0]; + if (discoverRoute.index > 0 && 'File' === discoverRoute.routes[discoverRoute.index].routeName) { + const fileRoute = discoverRoute.routes[discoverRoute.index]; + // Currently on a file page, so we can ignore (if the URI is the same) or replace (different URIs) + if (uri !== fileRoute.params.uri) { + const stackAction = StackActions.replace({ routeName: 'File', newKey: uri, params }); + dispatch(stackAction); + return; + } + } + } + + const navigateAction = NavigationActions.navigate({ routeName: 'File', key: uri, params }); + dispatch(navigateAction); +} \ No newline at end of file diff --git a/app/src/utils/redux.js b/app/src/utils/redux.js deleted file mode 100644 index 2dbdae5..0000000 --- a/app/src/utils/redux.js +++ /dev/null @@ -1,15 +0,0 @@ -import { - createReactNavigationReduxMiddleware, - createReduxBoundAddListener, -} from 'react-navigation-redux-helpers'; - -const reactNavigationMiddleware = createReactNavigationReduxMiddleware( - "root", - state => state.nav, -); -const addListener = createReduxBoundAddListener("root"); - -export { - reactNavigationMiddleware, - addListener, -}; diff --git a/src/main/res/drawable-hdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png b/src/main/res/drawable-hdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png new file mode 100644 index 0000000..ad03a63 Binary files /dev/null and b/src/main/res/drawable-hdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png differ diff --git a/src/main/res/drawable-mdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png b/src/main/res/drawable-mdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png new file mode 100644 index 0000000..083db29 Binary files /dev/null and b/src/main/res/drawable-mdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png differ diff --git a/src/main/res/drawable-mdpi/node_modules_reactnavigationstack_dist_views_assets_backiconmask.png b/src/main/res/drawable-mdpi/node_modules_reactnavigationstack_dist_views_assets_backiconmask.png new file mode 100644 index 0000000..5fa299b Binary files /dev/null and b/src/main/res/drawable-mdpi/node_modules_reactnavigationstack_dist_views_assets_backiconmask.png differ diff --git a/src/main/res/drawable-xhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png b/src/main/res/drawable-xhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png new file mode 100644 index 0000000..6de0a1c Binary files /dev/null and b/src/main/res/drawable-xhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png differ diff --git a/src/main/res/drawable-xxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png b/src/main/res/drawable-xxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png new file mode 100644 index 0000000..15a983a Binary files /dev/null and b/src/main/res/drawable-xxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png differ diff --git a/src/main/res/drawable-xxxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png b/src/main/res/drawable-xxxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png new file mode 100644 index 0000000..17e52e8 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png differ