mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Mobile: Add support for realtime search
This commit is contained in:
parent
a189b2eff0
commit
767213cdc1
@ -1005,6 +1005,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
|
||||
packages/app-mobile/components/screens/encryption-config.d.ts
|
||||
packages/app-mobile/components/screens/encryption-config.js
|
||||
packages/app-mobile/components/screens/encryption-config.js.map
|
||||
packages/app-mobile/components/screens/search.d.ts
|
||||
packages/app-mobile/components/screens/search.js
|
||||
packages/app-mobile/components/screens/search.js.map
|
||||
packages/app-mobile/components/side-menu-content.d.ts
|
||||
packages/app-mobile/components/side-menu-content.js
|
||||
packages/app-mobile/components/side-menu-content.js.map
|
||||
@ -1878,6 +1881,9 @@ packages/lib/services/searchengine/filterParser.js.map
|
||||
packages/lib/services/searchengine/filterParser.test.d.ts
|
||||
packages/lib/services/searchengine/filterParser.test.js
|
||||
packages/lib/services/searchengine/filterParser.test.js.map
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.d.ts
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js.map
|
||||
packages/lib/services/searchengine/queryBuilder.d.ts
|
||||
packages/lib/services/searchengine/queryBuilder.js
|
||||
packages/lib/services/searchengine/queryBuilder.js.map
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -993,6 +993,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
|
||||
packages/app-mobile/components/screens/encryption-config.d.ts
|
||||
packages/app-mobile/components/screens/encryption-config.js
|
||||
packages/app-mobile/components/screens/encryption-config.js.map
|
||||
packages/app-mobile/components/screens/search.d.ts
|
||||
packages/app-mobile/components/screens/search.js
|
||||
packages/app-mobile/components/screens/search.js.map
|
||||
packages/app-mobile/components/side-menu-content.d.ts
|
||||
packages/app-mobile/components/side-menu-content.js
|
||||
packages/app-mobile/components/side-menu-content.js.map
|
||||
@ -1866,6 +1869,9 @@ packages/lib/services/searchengine/filterParser.js.map
|
||||
packages/lib/services/searchengine/filterParser.test.d.ts
|
||||
packages/lib/services/searchengine/filterParser.test.js
|
||||
packages/lib/services/searchengine/filterParser.test.js.map
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.d.ts
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js.map
|
||||
packages/lib/services/searchengine/queryBuilder.d.ts
|
||||
packages/lib/services/searchengine/queryBuilder.js
|
||||
packages/lib/services/searchengine/queryBuilder.js.map
|
||||
|
@ -8,6 +8,7 @@ const { connect } = require('react-redux');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
|
||||
import gotoAnythingStyleQuery from '@joplin/lib/services/searchengine/gotoAnythingStyleQuery';
|
||||
import BaseModel from '@joplin/lib/BaseModel';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
@ -242,19 +243,6 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
makeSearchQuery(query: string) {
|
||||
const output = [];
|
||||
const splitted = query.split(' ');
|
||||
|
||||
for (let i = 0; i < splitted.length; i++) {
|
||||
const s = splitted[i].trim();
|
||||
if (!s) continue;
|
||||
output.push(`${s}*`);
|
||||
}
|
||||
|
||||
return output.join(' ');
|
||||
}
|
||||
|
||||
async keywords(searchQuery: string) {
|
||||
const parsedQuery = await SearchEngine.instance().parseQuery(searchQuery);
|
||||
return SearchEngine.instance().allParsedQueryTerms(parsedQuery);
|
||||
@ -321,7 +309,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
}
|
||||
} else { // Note TITLE or BODY
|
||||
listType = BaseModel.TYPE_NOTE;
|
||||
searchQuery = this.makeSearchQuery(this.state.query);
|
||||
searchQuery = gotoAnythingStyleQuery(this.state.query);
|
||||
results = await SearchEngine.instance().search(searchQuery);
|
||||
|
||||
resultsInBody = !!results.find((row: any) => row.fields.includes('body'));
|
||||
|
@ -1,7 +1,7 @@
|
||||
const React = require('react');
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { PureComponent, Component } from 'react';
|
||||
import { PureComponent } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, Image, ScrollView, Dimensions, ViewStyle } from 'react-native';
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const { BackButtonService } = require('../services/back-button.js');
|
||||
@ -46,7 +46,7 @@ type DispatchCommandType=(event: { type: string })=> void;
|
||||
interface ScreenHeaderProps {
|
||||
selectedNoteIds: string[];
|
||||
noteSelectionEnabled: boolean;
|
||||
parentComponent: Component;
|
||||
parentComponent: any;
|
||||
showUndoButton: boolean;
|
||||
undoButtonDisabled?: boolean;
|
||||
showRedoButton: boolean;
|
||||
@ -55,8 +55,8 @@ interface ScreenHeaderProps {
|
||||
folders: FolderEntity[];
|
||||
folderPickerOptions?: {
|
||||
enabled: boolean;
|
||||
selectedFolderId: string;
|
||||
onValueChange: OnValueChangedListener;
|
||||
selectedFolderId?: string;
|
||||
onValueChange?: OnValueChangedListener;
|
||||
mustSelect?: boolean;
|
||||
};
|
||||
|
||||
|
@ -1,23 +1,31 @@
|
||||
const React = require('react');
|
||||
|
||||
const { StyleSheet, View, TextInput, FlatList, TouchableHighlight } = require('react-native');
|
||||
import { StyleSheet, View, TextInput, FlatList, TouchableHighlight } from 'react-native';
|
||||
const { connect } = require('react-redux');
|
||||
const { ScreenHeader } = require('../ScreenHeader');
|
||||
import ScreenHeader from '../ScreenHeader';
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import gotoAnythingStyleQuery from '@joplin/lib/services/searchengine/gotoAnythingStyleQuery';
|
||||
const { NoteItem } = require('../note-item.js');
|
||||
const { BaseScreenComponent } = require('../base-screen.js');
|
||||
const { themeStyle } = require('../global-style.js');
|
||||
const DialogBox = require('react-native-dialogbox').default;
|
||||
const SearchEngineUtils = require('@joplin/lib/services/searchengine/SearchEngineUtils').default;
|
||||
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine').default;
|
||||
import SearchEngineUtils from '@joplin/lib/services/searchengine/SearchEngineUtils';
|
||||
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
|
||||
import { AppState } from '../../utils/types';
|
||||
|
||||
Icon.loadFont();
|
||||
|
||||
class SearchScreenComponent extends BaseScreenComponent {
|
||||
|
||||
private state: any = null;
|
||||
private isMounted_ = false;
|
||||
private styles_: any = {};
|
||||
private scheduleSearchTimer_: any = null;
|
||||
|
||||
static navigationOptions() {
|
||||
return { header: null };
|
||||
return { header: null } as any;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@ -26,8 +34,6 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
query: '',
|
||||
notes: [],
|
||||
};
|
||||
this.isMounted_ = false;
|
||||
this.styles_ = {};
|
||||
}
|
||||
|
||||
styles() {
|
||||
@ -36,7 +42,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
|
||||
this.styles_ = {};
|
||||
|
||||
const styles = {
|
||||
const styles: any = {
|
||||
body: {
|
||||
flex: 1,
|
||||
},
|
||||
@ -65,7 +71,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ query: this.props.query });
|
||||
this.refreshSearch(this.props.query);
|
||||
void this.refreshSearch(this.props.query);
|
||||
this.isMounted_ = true;
|
||||
}
|
||||
|
||||
@ -73,19 +79,6 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
this.isMounted_ = false;
|
||||
}
|
||||
|
||||
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',
|
||||
@ -93,13 +86,13 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
|
||||
this.setState({ query: '' });
|
||||
this.refreshSearch('');
|
||||
void this.refreshSearch('');
|
||||
}
|
||||
|
||||
async refreshSearch(query = null) {
|
||||
async refreshSearch(query: string = null) {
|
||||
if (!this.props.visible) return;
|
||||
|
||||
query = query === null ? this.state.query.trim : query.trim();
|
||||
query = gotoAnythingStyleQuery(query);
|
||||
|
||||
let notes = [];
|
||||
|
||||
@ -134,8 +127,24 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
this.setState({ notes: notes });
|
||||
}
|
||||
|
||||
searchTextInput_changeText(text) {
|
||||
scheduleSearch() {
|
||||
if (this.scheduleSearchTimer_) clearTimeout(this.scheduleSearchTimer_);
|
||||
|
||||
this.scheduleSearchTimer_ = setTimeout(() => {
|
||||
this.scheduleSearchTimer_ = null;
|
||||
void this.refreshSearch(this.state.query);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
searchTextInput_changeText(text: string) {
|
||||
this.setState({ query: text });
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'SEARCH_QUERY',
|
||||
query: text,
|
||||
});
|
||||
|
||||
this.scheduleSearch();
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -172,9 +181,6 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
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}
|
||||
@ -188,7 +194,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
<FlatList data={this.state.notes} keyExtractor={(item) => item.id} renderItem={event => <NoteItem note={event.item} />} />
|
||||
</View>
|
||||
<DialogBox
|
||||
ref={dialogbox => {
|
||||
ref={(dialogbox: any) => {
|
||||
this.dialogbox = dialogbox;
|
||||
}}
|
||||
/>
|
||||
@ -197,7 +203,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
}
|
||||
|
||||
const SearchScreen = connect(state => {
|
||||
const SearchScreen = connect((state: AppState) => {
|
||||
return {
|
||||
query: state.searchQuery,
|
||||
themeId: state.settings.theme,
|
@ -3,7 +3,7 @@ import Note from '../../models/Note';
|
||||
import Setting from '../../models/Setting';
|
||||
|
||||
export default class SearchEngineUtils {
|
||||
static async notesForQuery(query: string, applyUserSettings: boolean, options: any = null, searchEngine: SearchEngine = null) {
|
||||
public static async notesForQuery(query: string, applyUserSettings: boolean, options: any = null, searchEngine: SearchEngine = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
if (!searchEngine) {
|
||||
|
14
packages/lib/services/searchengine/gotoAnythingStyleQuery.ts
Normal file
14
packages/lib/services/searchengine/gotoAnythingStyleQuery.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export default (query: string) => {
|
||||
if (!query) return '';
|
||||
|
||||
const output = [];
|
||||
const splitted = query.split(' ');
|
||||
|
||||
for (let i = 0; i < splitted.length; i++) {
|
||||
const s = splitted[i].trim();
|
||||
if (!s) continue;
|
||||
output.push(`${s}*`);
|
||||
}
|
||||
|
||||
return output.join(' ');
|
||||
};
|
Loading…
Reference in New Issue
Block a user