1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00
joplin/ReactNativeClient/lib/components/screens/search.js
Laurent Cozic 1dc4516efc Revert "Mobile: Refactored and made dialog boxes more reliable"
This reverts commit f432734338.

This new package has its own glitches and doesn't look good
when button labels are too large. So reverting to the less
glitchy package.
2020-06-13 16:20:59 +01:00

213 lines
5.4 KiB
JavaScript

const React = require('react');
const { StyleSheet, View, TextInput, FlatList, TouchableHighlight } = require('react-native');
const { connect } = require('react-redux');
const { ScreenHeader } = require('lib/components/screen-header.js');
const Icon = require('react-native-vector-icons/Ionicons').default;
const { _ } = require('lib/locale.js');
const Note = require('lib/models/Note.js');
const { NoteItem } = require('lib/components/note-item.js');
const { BaseScreenComponent } = require('lib/components/base-screen.js');
const { themeStyle } = require('lib/components/global-style.js');
const SearchEngineUtils = require('lib/services/SearchEngineUtils');
const DialogBox = require('react-native-dialogbox').default;
Icon.loadFont();
class SearchScreenComponent extends BaseScreenComponent {
static navigationOptions() {
return { header: null };
}
constructor() {
super();
this.state = {
query: '',
notes: [],
};
this.isMounted_ = false;
this.styles_ = {};
}
styles() {
const theme = themeStyle(this.props.theme);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
this.styles_ = {};
const styles = {
body: {
flex: 1,
},
searchContainer: {
flexDirection: 'row',
alignItems: 'center',
borderWidth: 1,
borderColor: theme.dividerColor,
},
};
styles.searchTextInput = Object.assign({}, theme.lineInput);
styles.searchTextInput.paddingLeft = theme.marginLeft;
styles.searchTextInput.flex = 1;
styles.searchTextInput.backgroundColor = theme.backgroundColor;
styles.searchTextInput.color = theme.color;
styles.clearIcon = Object.assign({}, theme.icon);
styles.clearIcon.color = theme.colorFaded;
styles.clearIcon.paddingRight = theme.marginRight;
styles.clearIcon.backgroundColor = theme.backgroundColor;
this.styles_[this.props.theme] = StyleSheet.create(styles);
return this.styles_[this.props.theme];
}
componentDidMount() {
this.setState({ query: this.props.query });
this.refreshSearch(this.props.query);
this.isMounted_ = true;
}
componentWillUnmount() {
this.isMounted_ = false;
}
// UNSAFE_componentWillReceiveProps(newProps) {
// console.info('UNSAFE_componentWillReceiveProps', newProps);
// let newState = {};
// if ('query' in newProps && !this.state.query) newState.query = newProps.query;
// if (Object.getOwnPropertyNames(newState).length) {
// this.setState(newState);
// this.refreshSearch(newState.query);
// }
// }
searchTextInput_submit() {
const query = this.state.query.trim();
if (!query) return;
this.props.dispatch({
type: 'SEARCH_QUERY',
query: query,
});
this.setState({ query: query });
this.refreshSearch(query);
}
clearButton_press() {
this.props.dispatch({
type: 'SEARCH_QUERY',
query: '',
});
this.setState({ query: '' });
this.refreshSearch('');
}
async refreshSearch(query = null) {
if (!this.props.visible) return;
query = query === null ? this.state.query.trim : query.trim();
let notes = [];
if (query) {
if (this.props.settings['db.ftsEnabled']) {
notes = await SearchEngineUtils.notesForQuery(query);
} else {
const p = query.split(' ');
const temp = [];
for (let i = 0; i < p.length; i++) {
const t = p[i].trim();
if (!t) continue;
temp.push(t);
}
notes = await Note.previews(null, {
anywherePattern: `*${temp.join('*')}*`,
});
}
}
if (!this.isMounted_) return;
this.setState({ notes: notes });
}
searchTextInput_changeText(text) {
this.setState({ query: text });
}
render() {
if (!this.isMounted_) return null;
const theme = themeStyle(this.props.theme);
const rootStyle = {
flex: 1,
backgroundColor: theme.backgroundColor,
};
if (!this.props.visible) {
rootStyle.flex = 0.001; // This is a bit of a hack but it seems to work fine - it makes the component invisible but without unmounting it
}
const thisComponent = this;
return (
<View style={rootStyle}>
<ScreenHeader
title={_('Search')}
parentComponent={thisComponent}
folderPickerOptions={{
enabled: this.props.noteSelectionEnabled,
mustSelect: true,
}}
showSideMenuButton={false}
showSearchButton={false}
/>
<View style={this.styles().body}>
<View style={this.styles().searchContainer}>
<TextInput
style={this.styles().searchTextInput}
autoFocus={this.props.visible}
underlineColorAndroid="#ffffff00"
onSubmitEditing={() => {
this.searchTextInput_submit();
}}
onChangeText={text => this.searchTextInput_changeText(text)}
value={this.state.query}
selectionColor={theme.textSelectionColor}
keyboardAppearance={theme.keyboardAppearance}
/>
<TouchableHighlight onPress={() => this.clearButton_press()}>
<Icon name="md-close-circle" style={this.styles().clearIcon} />
</TouchableHighlight>
</View>
<FlatList data={this.state.notes} keyExtractor={(item) => item.id} renderItem={event => <NoteItem note={event.item} />} />
</View>
<DialogBox
ref={dialogbox => {
this.dialogbox = dialogbox;
}}
/>
</View>
);
}
}
const SearchScreen = connect(state => {
return {
query: state.searchQuery,
theme: state.settings.theme,
settings: state.settings,
noteSelectionEnabled: state.noteSelectionEnabled,
};
})(SearchScreenComponent);
module.exports = { SearchScreen };