From 6a60ce07e96dd47aadb136a24e516097c8396568 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Sat, 26 May 2018 00:20:44 +0100 Subject: [PATCH] Improvements to the UriBar implementation and some navigation tweaks. --- app/src/component/AppNavigator.js | 7 +- app/src/component/fileItem/view.js | 2 +- .../internal/transaction-list-item.js | 6 +- app/src/component/uriBar/index.js | 11 +- .../component/uriBar/internal/uri-bar-item.js | 38 +++++++ app/src/component/uriBar/view.js | 99 ++++++++++++++---- app/src/page/file/view.js | 4 +- app/src/page/search/view.js | 28 ++++- app/src/page/splash/view.js | 2 +- app/src/styles/channelPage.js | 3 +- app/src/styles/discover.js | 3 +- app/src/styles/filePage.js | 6 +- app/src/styles/search.js | 3 +- app/src/styles/uriBar.js | 27 +++++ .../baseline_search_black_24.png | Bin 0 -> 386 bytes .../baseline_search_black_24.png | Bin 0 -> 236 bytes .../baseline_search_black_24.png | Bin 0 -> 420 bytes .../baseline_search_black_24.png | Bin 0 -> 636 bytes .../baseline_search_black_24.png | Bin 0 -> 827 bytes .../main/res/drawable/baseline_search_24.xml | 10 ++ 20 files changed, 206 insertions(+), 43 deletions(-) create mode 100644 app/src/component/uriBar/internal/uri-bar-item.js create mode 100755 p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-hdpi/baseline_search_black_24.png create mode 100755 p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-mdpi/baseline_search_black_24.png create mode 100755 p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-xhdpi/baseline_search_black_24.png create mode 100755 p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-xxhdpi/baseline_search_black_24.png create mode 100755 p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-xxxhdpi/baseline_search_black_24.png create mode 100755 p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable/baseline_search_24.xml diff --git a/app/src/component/AppNavigator.js b/app/src/component/AppNavigator.js index ae672103..925b9175 100644 --- a/app/src/component/AppNavigator.js +++ b/app/src/component/AppNavigator.js @@ -38,7 +38,6 @@ const discoverStack = StackNavigator({ navigationOptions: ({ navigation }) => ({ title: 'Discover', headerLeft: navigation.navigate('DrawerOpen')} />, - headerRight: navigation.navigate('Search')} /> }) }, File: { @@ -51,9 +50,7 @@ const discoverStack = StackNavigator({ Search: { screen: SearchPage, navigationOptions: ({ navigation }) => ({ - drawerLockMode: 'locked-closed', - headerTitle: , - headerRight: + drawerLockMode: 'locked-closed' }) } }, { @@ -66,7 +63,6 @@ const walletStack = StackNavigator({ navigationOptions: ({ navigation }) => ({ title: 'Wallet', headerLeft: navigation.navigate('DrawerOpen')} />, - headerRight: navigation.navigate('Search')} /> }) }, TransactionHistory: { @@ -185,6 +181,7 @@ class AppWithNavigationState extends React.Component { if (evt.url) { const navigateAction = NavigationActions.navigate({ routeName: 'File', + key: 'filePage', params: { uri: evt.url } }); dispatch(navigateAction); diff --git a/app/src/component/fileItem/view.js b/app/src/component/fileItem/view.js index 8a7bedff..378b2dc3 100644 --- a/app/src/component/fileItem/view.js +++ b/app/src/component/fileItem/view.js @@ -61,7 +61,7 @@ class FileItem extends React.PureComponent { if (NativeModules.Mixpanel) { NativeModules.Mixpanel.track('Discover Tap', { Uri: uri }); } - navigation.navigate('File', { uri: uri }); + navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri } }); } }> diff --git a/app/src/component/transactionList/internal/transaction-list-item.js b/app/src/component/transactionList/internal/transaction-list-item.js index cb4d416f..0dd3b18c 100644 --- a/app/src/component/transactionList/internal/transaction-list-item.js +++ b/app/src/component/transactionList/internal/transaction-list-item.js @@ -23,7 +23,11 @@ class TransactionListItem extends React.PureComponent { {name && claimId && ( navigation && navigation.navigate('File', { uri: buildURI({ claimName: name, claimId }) })} + onPress={() => navigation && navigation.navigate({ + routeName: 'File', + key: 'filePage', + params: { uri: buildURI({ claimName: name, claimId }) }}) + } text={name} /> )} diff --git a/app/src/component/uriBar/index.js b/app/src/component/uriBar/index.js index 703caa0d..343ffb39 100644 --- a/app/src/component/uriBar/index.js +++ b/app/src/component/uriBar/index.js @@ -1,12 +1,17 @@ import { connect } from 'react-redux'; +import { doUpdateSearchQuery, selectSearchState as selectSearch } from 'lbry-redux'; import UriBar from './view'; -const select = state => ({ +const select = state => { + const { ...searchState } = selectSearch(state); -}); + return { + ...searchState + }; +}; const perform = dispatch => ({ - + updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)), }); export default connect(select, perform)(UriBar); diff --git a/app/src/component/uriBar/internal/uri-bar-item.js b/app/src/component/uriBar/internal/uri-bar-item.js new file mode 100644 index 00000000..71126bf9 --- /dev/null +++ b/app/src/component/uriBar/internal/uri-bar-item.js @@ -0,0 +1,38 @@ +// @flow +import React from 'react'; +import { SEARCH_TYPES, normalizeURI } from 'lbry-redux'; +import { Text, TouchableOpacity, View } from 'react-native'; +import Feather from 'react-native-vector-icons/Feather'; +import uriBarStyle from '../../../styles/uriBar'; + +class UriBarItem extends React.PureComponent { + render() { + const { item, onPress } = this.props; + const { type, value } = item; + + let icon; + switch (type) { + case SEARCH_TYPES.CHANNEL: + icon = + break; + + case SEARCH_TYPES.SEARCH: + icon = + break; + + case SEARCH_TYPES.FILE: + default: + icon = + break; + } + + return ( + + {icon} + {value} + + ) + } +} + +export default UriBarItem; diff --git a/app/src/component/uriBar/view.js b/app/src/component/uriBar/view.js index a66a24ba..ace50902 100644 --- a/app/src/component/uriBar/view.js +++ b/app/src/component/uriBar/view.js @@ -1,41 +1,96 @@ // @flow import React from 'react'; -import { normalizeURI } from 'lbry-redux'; -import { TextInput, View } from 'react-native'; +import { SEARCH_TYPES, isNameValid, normalizeURI } from 'lbry-redux'; +import { FlatList, Keyboard, TextInput, View } from 'react-native'; +import UriBarItem from './internal/uri-bar-item'; import uriBarStyle from '../../styles/uriBar'; class UriBar extends React.PureComponent { + static INPUT_TIMEOUT = 500; + constructor(props) { super(props); this.state = { - uri: null, - currentValue: null + changeTextTimeout: null, + currentValue: null, + inputText: null, + focused: false }; } + + handleChangeText = text => { + const newValue = text ? text : ''; + clearTimeout(this.state.changeTextTimeout); + const { updateSearchQuery } = this.props; + + let timeout = setTimeout(() => { + updateSearchQuery(text); + }, UriBar.INPUT_TIMEOUT); + this.setState({ inputText: newValue, currentValue: newValue, changeTextTimeout: timeout }); + } + + handleItemPress = (item) => { + const { navigation, updateSearchQuery } = this.props; + const { type, value } = item; + + Keyboard.dismiss(); + + if (SEARCH_TYPES.SEARCH === type) { + navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: value }}); + } else { + navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri: normalizeURI(value) }}); + } + } render() { - const { value, navigation } = this.props; - if (!this.state.currentValue) { + const { navigation, suggestions, updateSearchQuery, value } = this.props; + if (this.state.currentValue === null) { this.setState({ currentValue: value }); } - // TODO: Search and URI suggestions overlay + let style = [uriBarStyle.overlay]; + if (this.state.focused) { + style.push(uriBarStyle.inFocus); + } + return ( - - this.setState({uri: text, currentValue: text})} - onSubmitEditing={() => { - if (this.state.uri) { - let uri = this.state.uri; - uri = uri.replace(/ /g, '-'); - navigation.navigate('File', { uri: normalizeURI(uri) }); - } - }}/> + + {this.state.focused && ( + + item.value} + renderItem={({item}) => this.handleItemPress(item)} />} /> + )} + + this.setState({ focused: true })} + onBlur={() => this.setState({ focused: false })} + onChangeText={this.handleChangeText} + onSubmitEditing={() => { + if (this.state.inputText) { + let inputText = this.state.inputText; + if (isNameValid(inputText)) { + navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri: normalizeURI(inputText) }}); + } else { + // Open the search page with the query populated + navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: inputText }}); + } + } + }}/> + ); } diff --git a/app/src/page/file/view.js b/app/src/page/file/view.js index fd887e02..746987e5 100644 --- a/app/src/page/file/view.js +++ b/app/src/page/file/view.js @@ -156,7 +156,7 @@ class FilePage extends React.PureComponent { Loading decentralized data... } - { claim === null && !isResolvingUri && + {claim === null && !isResolvingUri && There's nothing at this location. @@ -220,7 +220,7 @@ class FilePage extends React.PureComponent { renderIndicator={() => null} />} {!this.state.showWebView && ( - + {(canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) && } diff --git a/app/src/page/search/view.js b/app/src/page/search/view.js index 3cdb8ab0..5caa14c7 100644 --- a/app/src/page/search/view.js +++ b/app/src/page/search/view.js @@ -8,14 +8,29 @@ import { View, ScrollView } from 'react-native'; -import SearchResultItem from '../../component/searchResultItem'; import Colors from '../../styles/colors'; +import PageHeader from '../../component/pageHeader'; +import SearchResultItem from '../../component/searchResultItem'; +import UriBar from '../../component/uriBar'; import searchStyle from '../../styles/search'; class SearchPage extends React.PureComponent { + static navigationOptions = { + title: 'Search Results' + }; + + componentDidMount() { + const { navigation, search } = this.props; + const { searchQuery } = navigation.state.params; + if (searchQuery && searchQuery.trim().length > 0) { + search(searchQuery); + } + } + render() { - const { isSearching, navigation, uris } = this.props; - + const { isSearching, navigation, uris, query } = this.props; + const { searchQuery } = navigation.state.params; + return ( {!isSearching && (!uris || uris.length === 0) && @@ -26,10 +41,15 @@ class SearchPage extends React.PureComponent { uri={uri} style={searchStyle.resultItem} navigation={navigation} - onPress={() => {navigation.navigate('File', { uri: uri }); }}/>) + onPress={() => navigation.navigate({ + routeName: 'File', + key: 'filePage', + params: { uri }}) + }/>) ) : null } {isSearching && } + ); } diff --git a/app/src/page/splash/view.js b/app/src/page/splash/view.js index 0ff86583..99d91a92 100644 --- a/app/src/page/splash/view.js +++ b/app/src/page/splash/view.js @@ -54,7 +54,7 @@ class SplashScreen extends React.PureComponent { navigation.dispatch(resetAction); if (this.state.launchUrl) { - navigation.navigate('File', { uri: this.state.launchUrl }); + navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri: this.state.launchUrl } }); } }); return; diff --git a/app/src/styles/channelPage.js b/app/src/styles/channelPage.js index 8f9e465a..5f2cfef7 100644 --- a/app/src/styles/channelPage.js +++ b/app/src/styles/channelPage.js @@ -11,7 +11,8 @@ const channelPageStyle = StyleSheet.create({ }, fileList: { paddingTop: 30, - flex: 1 + flex: 1, + marginBottom: 60 }, title: { color: Colors.LbryGreen, diff --git a/app/src/styles/discover.js b/app/src/styles/discover.js index d6897d2d..0b9a1f46 100644 --- a/app/src/styles/discover.js +++ b/app/src/styles/discover.js @@ -5,7 +5,8 @@ const discoverStyle = StyleSheet.create({ flex: 1 }, scrollContainer: { - flex: 1 + flex: 1, + marginBottom: 60 }, busyContainer: { flex: 1, diff --git a/app/src/styles/filePage.js b/app/src/styles/filePage.js index 65b74841..ca145c46 100644 --- a/app/src/styles/filePage.js +++ b/app/src/styles/filePage.js @@ -12,6 +12,10 @@ const filePageStyle = StyleSheet.create({ pageContainer: { flex: 1 }, + innerPageContainer: { + flex: 1, + marginBottom: 60 + }, mediaContainer: { alignItems: 'center', width: screenWidth, @@ -150,7 +154,7 @@ const filePageStyle = StyleSheet.create({ left: 0, right: 0, top: 0, - bottom: 0, + bottom: 60, zIndex: 100 } }); diff --git a/app/src/styles/search.js b/app/src/styles/search.js index 4ad23e73..8ace8954 100644 --- a/app/src/styles/search.js +++ b/app/src/styles/search.js @@ -10,7 +10,8 @@ const searchStyle = StyleSheet.create({ flex: 1, width: '100%', height: '100%', - padding: 16 + padding: 16, + marginBottom: 60 }, scrollPadding: { paddingBottom: 16 diff --git a/app/src/styles/uriBar.js b/app/src/styles/uriBar.js index 9f9ab752..4061072f 100644 --- a/app/src/styles/uriBar.js +++ b/app/src/styles/uriBar.js @@ -6,6 +6,7 @@ const uriBarStyle = StyleSheet.create({ backgroundColor: Colors.White, padding: 8, alignSelf: 'flex-end', + height: 60, width: '100%', shadowColor: Colors.Black, shadowOpacity: 0.1, @@ -24,6 +25,32 @@ const uriBarStyle = StyleSheet.create({ fontFamily: 'Metropolis-Regular', fontSize: 16, width: '100%' + }, + overlay: { + position: 'absolute', + backgroundColor: 'transparent', + bottom: 0, + width: '100%', + zIndex: 200, + elevation: 16 + }, + inFocus: { + height: '100%' + }, + suggestions: { + backgroundColor: 'white', + flex: 1 + }, + item: { + flexDirection: 'row', + justifyContent: 'flex-start', + padding: 12 + }, + itemText: { + fontFamily: 'Metropolis-Regular', + fontSize: 16, + marginLeft: 12, + marginRight: 12 } }); diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-hdpi/baseline_search_black_24.png b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-hdpi/baseline_search_black_24.png new file mode 100755 index 0000000000000000000000000000000000000000..c1066f3da8c3ef190fe4925d25f07be900ef679f GIT binary patch literal 386 zcmV-|0e$|7P)8`ZQHi(cFI=Uwzj(6Yui|=V2Q0MQ;a3HZGO**bDxVjzq8%%J?}M^b?T1| z=eW*37GT*z+^C|qX{B?Io|x2=$5d0>Zbh*I6M7M(HdYbBFCODTcGHo)81_?b@?ktE zT{usX94%o!hAdY#kLW^cGf0$)D~32p*ny5LRgZr;x`s%!k}-7bwG=%^*G>rrqQyq$ zq3F6I!MA7`Df4V}-IU-%wDggA1-ed3@DEyM%RCWXtJLqH<-E-8(MO6z_tTMXgv#^? z`nWC89H!9T3-zdbp^yHgNj!~BZ65Pm_03IJfS0MVC2^}S^xk507*qoM6N<$g1pDB-T(jq literal 0 HcmV?d00001 diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-mdpi/baseline_search_black_24.png b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable-mdpi/baseline_search_black_24.png new file mode 100755 index 0000000000000000000000000000000000000000..87e74ffbf9f97879b5aa6122fa14ddde56ffb66c GIT binary patch literal 236 zcmVh%+a+GO9(f7Nf2Nv!arMj4p4wWCTeOYl4)IQi3%RCxUJtbqh{JWCWEyst{yF z97iggidg+-hAF|8h(19^r#GE4g5KZmF!_9kNmqjP|6Dq6S8$+)xM4H)+`6@>9S4z+ msCp-b8*-@HKQyRTxb6VVc~sxTM4g5J0000;$stM*R0?>{ZH_N^ zn|B*NS_y~nMJl4UbC=EBr5#aI@j(otHgL+}12!OPES|~G)IrYS#5o2vDg%#PN7N_m z#4|*_fhS&TS~e!KH1f5-50rq31b-i?Mbn}&5v7qWcw$o1j$z`MMo!>~aZNjdi6a_0 zi6`1LEeaEn8rf_6Cl}#~SFVd`wnqNL6E|E|v?qxA&`wh^q)|0^CLU26IqT5aH6rQ@ ze2`*jt~(GlZMQm{Tb$$sw|P%7g32_PY<8I=y8dOO(-;180Z~8WlX!<=OFhp4kl?p~ zXmsGkI4z{}i>E034t@(0iF@@H;VoX5WLqg_9GXMYuIaIR*xsq7` O0000CYeR-<&cn!?0Y z1x_QU&QO84smD#^+)e5c7j=1vi1wHz^rjJ&$WJ92(vL+vK}35%eY`8djU<0&5cxpewqQ<(S2>VpTfkhKyR}I5B4D|0e1<=+J^^skkt%#&5(5$58fiHD(n$F9M^<6n6++gxto8^!!h^fW zYL2_+$hv?B2awf2#&_9HJeZBF^|)J)tm$~rFQ!lGBD_adS3D@eXJie<%}`{0p%7lI zMb=x&l73})hpg>*(*D1H4{bwObitd0$o-|sbcDrGJZg&~O(1RKP^6A{wKB=6qX;Q0 zlH}AeBO}gb15-Gc4NP*RyhK5~tIvaEPp*9WNimHQ;WcZ{FdL=y}*<37n|wPeKKTiEYB=L*MJ zKu?MiRg1fhll;qulftAhDNG8JDrbR7S?MvdNm*r%P0A{BY?95%B5MCE8w-LU2z~%Z Wwf?8PY)cOS0000I7{pALv6G9u;}w_L!7^qth(biU8jRx@l0-)tM@^zqJO_~!c93|YN=a5D zscbdHhzjW##|I>g-Z74JL|6g#A|BdH0U{`dM~KHB5krJ@_l_ z&P+C*$sI_kp2pK}3Xas}i{TWABQ+8Xr{EXr;y@bCAX?8TLu!@b8KQNDG+5Wt@Xs|R z98C>JvL)7SL$rnyuHlH*RxB%vXdS_e!-!USteS{u#o$F8qBRk#?jTBQ@M;aBbQ_Dx zAzF>_sgbNZR=Por@tjz@^cp7R+|8iGTG*o}DTI%R2% zL~?|5jOAUJ`@{3d4S+;;1SrO8B$chFG`~sYM}T;aA}MSSUHF$o#|Ti9@f<^v=p@4_ zg>Fn_N6-~w5HnfIPA>8aL3qP1CeogQ=-iKB&DZwlmzMzb{FWBpn{XP*1HG?B@Ug002ovPDHLk FV1lmOX3GEo literal 0 HcmV?d00001 diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable/baseline_search_24.xml b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable/baseline_search_24.xml new file mode 100755 index 00000000..083d6364 --- /dev/null +++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/res/drawable/baseline_search_24.xml @@ -0,0 +1,10 @@ + + +