diff --git a/package-lock.json b/package-lock.json index 0b63958..861c1fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5640,8 +5640,8 @@ } }, "lbry-redux": { - "version": "github:lbryio/lbry-redux#7ec72a737bcd336f000c5f5085891643110298c3", - "from": "github:lbryio/lbry-redux#7ec72a737bcd336f000c5f5085891643110298c3", + "version": "github:lbryio/lbry-redux#4c4f926ee2cd77d750df0a95fad669257aa31ae7", + "from": "github:lbryio/lbry-redux#4c4f926ee2cd77d750df0a95fad669257aa31ae7", "requires": { "proxy-polyfill": "0.1.6", "reselect": "^3.0.0", diff --git a/package.json b/package.json index 4e3f28b..b1bdd7c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "base-64": "^0.1.0", "@expo/vector-icons": "^8.1.0", "gfycat-style-urls": "^1.0.3", - "lbry-redux": "lbryio/lbry-redux#7ec72a737bcd336f000c5f5085891643110298c3", + "lbry-redux": "lbryio/lbry-redux#4c4f926ee2cd77d750df0a95fad669257aa31ae7", "lbryinc": "lbryio/lbryinc#c55a2c98ab92c72149c824ee5906aed4404fd89b", "lodash": ">=4.17.11", "merge": ">=1.2.1", diff --git a/src/component/uriBar/index.js b/src/component/uriBar/index.js index 1f01ae7..9320187 100644 --- a/src/component/uriBar/index.js +++ b/src/component/uriBar/index.js @@ -4,8 +4,10 @@ import { selectSearchState as selectSearch, selectSearchValue, selectSearchSuggestions, + SETTINGS, } from 'lbry-redux'; import { selectCurrentRoute } from 'redux/selectors/drawer'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import UriBar from './view'; const select = state => { @@ -16,6 +18,7 @@ const select = state => { query: selectSearchValue(state), currentRoute: selectCurrentRoute(state), suggestions: selectSearchSuggestions(state), + showUriBarSuggestions: makeSelectClientSetting(SETTINGS.SHOW_URI_BAR_SUGGESTIONS)(state), }; }; diff --git a/src/component/uriBar/internal/uri-bar-item.js b/src/component/uriBar/internal/uri-bar-item.js index ab42170..dd65b9f 100644 --- a/src/component/uriBar/internal/uri-bar-item.js +++ b/src/component/uriBar/internal/uri-bar-item.js @@ -20,6 +20,10 @@ class UriBarItem extends React.PureComponent { icon = ; break; + case SEARCH_TYPES.TAG: + icon = ; + break; + case SEARCH_TYPES.FILE: default: icon = ; @@ -37,6 +41,7 @@ class UriBarItem extends React.PureComponent { {type === SEARCH_TYPES.SEARCH && `Search for '${value}'`} {type === SEARCH_TYPES.CHANNEL && `View the @${shorthand} channel`} {type === SEARCH_TYPES.FILE && `View content at ${value}`} + {type === SEARCH_TYPES.TAG && `Explore the '${value}' tag`} diff --git a/src/component/uriBar/view.js b/src/component/uriBar/view.js index 8a2b605..de12496 100644 --- a/src/component/uriBar/view.js +++ b/src/component/uriBar/view.js @@ -1,7 +1,7 @@ // @flow import React from 'react'; import { SEARCH_TYPES, isNameValid, isURIValid, normalizeURI } from 'lbry-redux'; -import { FlatList, Keyboard, Text, TextInput, TouchableOpacity, View } from 'react-native'; +import { Dimensions, FlatList, Keyboard, Text, TextInput, TouchableOpacity, View } from 'react-native'; import { navigateToUri, transformUrl } from 'utils/helper'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import UriBarItem from './internal/uri-bar-item'; @@ -14,6 +14,8 @@ class UriBar extends React.PureComponent { textInput = null; + keyboardDidShowListener = null; + keyboardDidHideListener = null; state = { @@ -21,17 +23,19 @@ class UriBar extends React.PureComponent { currentValue: null, inputText: null, focused: false, - - // TODO: Add a setting to enable / disable direct search? - directSearch: true, + keyboardHeight: 0, }; componentDidMount() { + this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow); this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide); this.setSelection(); } componentWillUnmount() { + if (this.keyboardDidShowListener) { + this.keyboardDidShowListener.remove(); + } if (this.keyboardDidHideListener) { this.keyboardDidHideListener.remove(); } @@ -49,25 +53,28 @@ class UriBar extends React.PureComponent { handleChangeText = text => { const newValue = text || ''; clearTimeout(this.state.changeTextTimeout); - const { updateSearchQuery, onSearchSubmitted, navigation } = this.props; + const { updateSearchQuery, onSearchSubmitted, showUriBarSuggestions, navigation } = this.props; - let timeout = setTimeout(() => { - if (text.trim().length === 0) { - // don't do anything if the text is empty - return; - } + updateSearchQuery(text); - updateSearchQuery(text); - - if (!text.startsWith('lbry://')) { - // not a URI input, so this is a search, perform a direct search - if (onSearchSubmitted) { - onSearchSubmitted(text); - } else { - navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: text } }); + let timeout = -1; + if (!showUriBarSuggestions) { + timeout = setTimeout(() => { + if (text.trim().length === 0) { + // don't do anything if the text is empty + return; } - } - }, UriBar.INPUT_TIMEOUT); + + if (!text.startsWith('lbry://')) { + // not a URI input, so this is a search, perform a direct search + if (onSearchSubmitted) { + onSearchSubmitted(text); + } else { + navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: text } }); + } + } + }, UriBar.INPUT_TIMEOUT); + } this.setState({ inputText: newValue, currentValue: newValue, changeTextTimeout: timeout }); }; @@ -86,18 +93,34 @@ class UriBar extends React.PureComponent { return; } - navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: value } }); + navigation.navigate({ + routeName: Constants.DRAWER_ROUTE_SEARCH, + key: 'searchPage', + params: { searchQuery: value }, + }); + } else if (SEARCH_TYPES.TAG === type) { + navigation.navigate({ + routeName: Constants.DRAWER_ROUTE_TAG, + key: 'tagPage', + params: { + tag: value.toLowerCase(), + }, + }); } else { const uri = normalizeURI(value); navigateToUri(navigation, uri); } }; + _keyboardDidShow = evt => { + this.setState({ keyboardHeight: evt.endCoordinates.height }); + }; + _keyboardDidHide = () => { if (this.textInput) { this.textInput.blur(); } - this.setState({ focused: false }); + this.setState({ focused: false, keyboardHeight: 0 }); }; setSelection() { @@ -152,16 +175,18 @@ class UriBar extends React.PureComponent { selectedItemCount, selectionMode, suggestions, + showUriBarSuggestions, value, } = this.props; if (this.state.currentValue === null) { this.setState({ currentValue: value }); } - let style = [uriBarStyle.overlay, belowOverlay ? null : uriBarStyle.overlayElevated]; - - // TODO: Add optional setting to enable URI / search bar suggestions - /* if (this.state.focused) { style.push(uriBarStyle.inFocus); } */ + let style = [ + uriBarStyle.overlay, + belowOverlay ? null : uriBarStyle.overlayElevated, + this.state.focused && showUriBarSuggestions ? uriBarStyle.inFocus : null, + ]; // TODO: selectionModeActions should be dynamically created / specified return ( @@ -248,20 +273,21 @@ class UriBar extends React.PureComponent { onSubmitEditing={this.handleSubmitEditing} /> )} - {this.state.focused && !this.state.directSearch && ( - - item.value} - renderItem={({ item }) => ( - this.handleItemPress(item)} /> - )} - /> - - )} + {this.state.focused && showUriBarSuggestions && ( + `${item.value}-${item.type}`} + renderItem={({ item }) => ( + this.handleItemPress(item)} /> + )} + /> + )} ); } diff --git a/src/page/settings/index.js b/src/page/settings/index.js index e630143..c90d2d5 100644 --- a/src/page/settings/index.js +++ b/src/page/settings/index.js @@ -4,7 +4,7 @@ import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/a import { doSetClientSetting } from 'redux/actions/settings'; import { selectCurrentRoute, selectDrawerStack } from 'redux/selectors/drawer'; import { makeSelectClientSetting } from 'redux/selectors/settings'; -import Constants from 'constants'; +import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import SettingsPage from './view'; const select = state => ({ @@ -13,6 +13,7 @@ const select = state => ({ drawerStack: selectDrawerStack(state), keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state), showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state), + showUriBarSuggestions: makeSelectClientSetting(SETTINGS.SHOW_URI_BAR_SUGGESTIONS)(state), }); const perform = dispatch => ({ diff --git a/src/page/settings/view.js b/src/page/settings/view.js index ea2a3a2..659fe72 100644 --- a/src/page/settings/view.js +++ b/src/page/settings/view.js @@ -51,6 +51,7 @@ class SettingsPage extends React.PureComponent { navigation, popDrawerStack, showNsfw, + showUriBarSuggestions, setClientSetting, } = this.props; @@ -62,6 +63,7 @@ class SettingsPage extends React.PureComponent { navigateBack(navigation, drawerStack, popDrawerStack)} /> + Content Enable background media playback @@ -79,13 +81,29 @@ class SettingsPage extends React.PureComponent { - Show NSFW content + Show mature content setClientSetting(SETTINGS.SHOW_NSFW, value)} /> + + Search + + + Show URL suggestions + + + setClientSetting(SETTINGS.SHOW_URI_BAR_SUGGESTIONS, value)} + /> + + + + + Other Keep the daemon background service running after closing the app diff --git a/src/styles/settings.js b/src/styles/settings.js index f20f302..adcc434 100644 --- a/src/styles/settings.js +++ b/src/styles/settings.js @@ -39,6 +39,14 @@ const settingsStyle = StyleSheet.create({ fontFamily: 'Inter-UI-Regular', lineHeight: 18, }, + sectionTitle: { + fontFamily: 'Inter-UI-Regular', + fontSize: 20, + marginBottom: 4, + }, + sectionDivider: { + marginTop: 24, + }, }); export default settingsStyle; diff --git a/src/styles/uriBar.js b/src/styles/uriBar.js index c21618d..d44d955 100644 --- a/src/styles/uriBar.js +++ b/src/styles/uriBar.js @@ -36,7 +36,7 @@ const uriBarStyle = StyleSheet.create({ }, overlay: { position: 'absolute', - backgroundColor: 'transparent', + backgroundColor: 'red', top: 0, width: '100%', zIndex: 200, @@ -54,9 +54,10 @@ const uriBarStyle = StyleSheet.create({ item: { flexDirection: 'row', alignItems: 'center', - padding: 12, - paddingTop: 8, - paddingBottom: 8, + paddingLeft: 16, + paddingRight: 16, + paddingTop: 12, + paddingBottom: 12, }, itemContent: { marginLeft: 12,