1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-05-13 21:46:37 +02:00

194 lines
4.8 KiB
JavaScript
Raw Normal View History

2018-03-09 17:49:35 +00:00
const React = require("react");
const Component = React.Component;
const { ListView, 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 { dialogs } = require("lib/dialogs.js");
const DialogBox = require("react-native-dialogbox").default;
2017-07-22 23:52:24 +01:00
class SearchScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
return { header: null };
}
constructor() {
super();
this.state = {
2018-03-09 17:49:35 +00:00
query: "",
2017-07-22 23:52:24 +01:00
notes: [],
};
this.isMounted_ = false;
2017-08-01 17:59:01 +00:00
this.styles_ = {};
}
styles() {
const theme = themeStyle(this.props.theme);
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
this.styles_ = {};
let styles = {
body: {
flex: 1,
},
searchContainer: {
2018-03-09 17:49:35 +00:00
flexDirection: "row",
alignItems: "center",
2017-08-01 17:59:01 +00:00
borderWidth: 1,
borderColor: theme.dividerColor,
2018-03-09 17:49:35 +00:00
},
};
2017-08-01 17:59:01 +00:00
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];
2017-07-22 23:52:24 +01:00
}
componentDidMount() {
this.setState({ query: this.props.query });
this.refreshSearch(this.props.query);
this.isMounted_ = true;
}
componentWillUnmount() {
this.isMounted_ = false;
}
componentWillReceiveProps(newProps) {
let newState = {};
2018-03-09 17:49:35 +00:00
if ("query" in newProps) newState.query = newProps.query;
2017-07-22 23:52:24 +01:00
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({
2018-03-09 17:49:35 +00:00
type: "SEARCH_QUERY",
2017-07-22 23:52:24 +01:00
query: query,
});
}
clearButton_press() {
this.props.dispatch({
2018-03-09 17:49:35 +00:00
type: "SEARCH_QUERY",
query: "",
2017-07-22 23:52:24 +01:00
});
}
async refreshSearch(query = null) {
if (!this.props.visible) return;
2017-07-22 23:52:24 +01:00
query = query === null ? this.state.query.trim : query.trim();
2018-03-09 17:49:35 +00:00
let notes = [];
2017-07-22 23:52:24 +01:00
if (query) {
2018-03-09 17:49:35 +00:00
let p = query.split(" ");
2017-07-23 19:26:50 +01:00
let temp = [];
for (let i = 0; i < p.length; i++) {
let t = p[i].trim();
if (!t) continue;
temp.push(t);
}
2017-07-22 23:52:24 +01:00
notes = await Note.previews(null, {
2018-03-09 17:49:35 +00:00
anywherePattern: "*" + temp.join("*") + "*",
2017-07-22 23:52:24 +01:00
});
}
if (!this.isMounted_) return;
this.setState({ notes: notes });
}
searchTextInput_changeText(text) {
this.setState({ query: text });
}
render() {
2017-07-25 21:24:30 +01:00
if (!this.isMounted_) return null;
const theme = themeStyle(this.props.theme);
let rootStyle = {
flex: 1,
backgroundColor: theme.backgroundColor,
2018-03-09 17:49:35 +00:00
};
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;
2017-07-22 23:52:24 +01:00
return (
<View style={rootStyle}>
<ScreenHeader
2018-03-09 17:49:35 +00:00
title={_("Search")}
parentComponent={thisComponent}
folderPickerOptions={{
enabled: this.props.noteSelectionEnabled,
mustSelect: true,
}}
/>
2017-08-01 17:59:01 +00:00
<View style={this.styles().body}>
<View style={this.styles().searchContainer}>
2017-07-22 23:52:24 +01:00
<TextInput
2017-08-01 17:59:01 +00:00
style={this.styles().searchTextInput}
autoFocus={this.props.visible}
2018-03-09 17:49:35 +00:00
underlineColorAndroid="#ffffff00"
onSubmitEditing={() => {
this.searchTextInput_submit();
}}
onChangeText={text => this.searchTextInput_changeText(text)}
2017-07-22 23:52:24 +01:00
value={this.state.query}
/>
2018-03-09 17:49:35 +00:00
<TouchableHighlight onPress={() => this.clearButton_press()}>
<Icon name="md-close-circle" style={this.styles().clearIcon} />
2017-07-22 23:52:24 +01:00
</TouchableHighlight>
</View>
2018-03-09 17:49:35 +00:00
<FlatList data={this.state.notes} keyExtractor={(item, index) => item.id} renderItem={event => <NoteItem note={event.item} />} />
2017-07-22 23:52:24 +01:00
</View>
2018-03-09 17:49:35 +00:00
<DialogBox
ref={dialogbox => {
this.dialogbox = dialogbox;
}}
/>
2017-07-22 23:52:24 +01:00
</View>
);
}
}
2018-03-09 17:49:35 +00:00
const SearchScreen = connect(state => {
return {
query: state.searchQuery,
theme: state.settings.theme,
noteSelectionEnabled: state.noteSelectionEnabled,
};
})(SearchScreenComponent);
2017-07-22 23:52:24 +01:00
2018-03-09 17:49:35 +00:00
module.exports = { SearchScreen };