Skip to content

Commit

Permalink
Chore: Mobile: Search screen: Use stronger types, try to prevent mult…
Browse files Browse the repository at this point in the history
…iple concurrent attempts to update the result list (#11075)
  • Loading branch information
personalizedrefrigerator committed Sep 21, 2024
1 parent 220f867 commit feb946a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 38 deletions.
4 changes: 2 additions & 2 deletions packages/app-mobile/components/app-nav.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { connect } from 'react-redux';
import NotesScreen from './screens/Notes';
const { SearchScreen } = require('./screens/search.js');
import SearchScreen from './screens/search';
import { Component } from 'react';
import { KeyboardAvoidingView, Keyboard, Platform, View, KeyboardEvent, Dimensions, EmitterSubscription } from 'react-native';
import { AppState } from '../utils/types';
Expand Down Expand Up @@ -116,7 +116,7 @@ class AppNavComponent extends Component<Props, State> {
style={style}
>
<NotesScreen visible={notesScreenVisible} />
{searchScreenLoaded && <SearchScreen visible={searchScreenVisible} navigation={{ state: route }} />}
{searchScreenLoaded && <SearchScreen visible={searchScreenVisible} />}
{!notesScreenVisible && !searchScreenVisible && <Screen navigation={{ state: route }} themeId={this.props.themeId} dispatch={this.props.dispatch} />}
<View style={{ height: this.state.autoCompletionBarExtraHeight }} />
</KeyboardAvoidingView>
Expand Down
86 changes: 51 additions & 35 deletions packages/app-mobile/components/screens/search.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,53 @@
const React = require('react');
import * as React from 'react';

import { StyleSheet, View, TextInput, FlatList, TouchableHighlight } from 'react-native';
const { connect } = require('react-redux');
import { connect } from 'react-redux';
import ScreenHeader from '../ScreenHeader';
const Icon = require('react-native-vector-icons/Ionicons').default;
import { _ } from '@joplin/lib/locale';
import Note from '@joplin/lib/models/Note';
import NoteItem from '../NoteItem';
const { BaseScreenComponent } = require('../base-screen');
import { BaseScreenComponent } from '../base-screen';
import { themeStyle } from '../global-style';
const DialogBox = require('react-native-dialogbox').default;
import SearchEngineUtils from '@joplin/lib/services/search/SearchEngineUtils';
import SearchEngine from '@joplin/lib/services/search/SearchEngine';
import { AppState } from '../../utils/types';
import { NoteEntity } from '@joplin/lib/services/database/types';
import AsyncActionQueue from '@joplin/lib/AsyncActionQueue';
import { Dispatch } from 'redux';

class SearchScreenComponent extends BaseScreenComponent {
interface Props {
themeId: number;
query: string;
visible: boolean;
dispatch: Dispatch;

noteSelectionEnabled: boolean;
ftsEnabled: number;
}

interface State {
query: string;
notes: NoteEntity[];
}

class SearchScreenComponent extends BaseScreenComponent<Props, State> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partial refactor of old code from before rule was applied.
public dialogbox: any;

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private state: any = null;
private isMounted_ = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private styles_: any = {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private scheduleSearchTimer_: any = null;
private styles_: Record<string, any> = {};
private searchActionQueue_ = new AsyncActionQueue(200);

public static navigationOptions() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
return { header: null } as any;
}

public constructor() {
super();
public constructor(props: Props) {
super(props);
this.state = {
query: '',
notes: [],
Expand All @@ -44,8 +60,7 @@ class SearchScreenComponent extends BaseScreenComponent {
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
this.styles_ = {};

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const styles: any = {
const styleSheet = StyleSheet.create({
body: {
flex: 1,
},
Expand All @@ -55,21 +70,22 @@ class SearchScreenComponent extends BaseScreenComponent {
borderWidth: 1,
borderColor: theme.dividerColor,
},
};

styles.searchTextInput = { ...theme.lineInput };
styles.searchTextInput.paddingLeft = theme.marginLeft;
styles.searchTextInput.flex = 1;
styles.searchTextInput.backgroundColor = theme.backgroundColor;
styles.searchTextInput.color = theme.color;

styles.clearIcon = { ...theme.icon };
styles.clearIcon.color = theme.colorFaded;
styles.clearIcon.paddingRight = theme.marginRight;
styles.clearIcon.backgroundColor = theme.backgroundColor;

this.styles_[this.props.themeId] = StyleSheet.create(styles);
return this.styles_[this.props.themeId];
searchTextInput: {
...theme.lineInput,
paddingLeft: theme.marginLeft,
flex: 1,
backgroundColor: theme.backgroundColor,
color: theme.color,
},
clearIcon: {
...theme.icon,
color: theme.colorFaded,
paddingRight: theme.marginRight,
backgroundColor: theme.backgroundColor,
},
});
this.styles_[this.props.themeId] = styleSheet;
return styleSheet;
}

public componentDidMount() {
Expand Down Expand Up @@ -98,7 +114,7 @@ class SearchScreenComponent extends BaseScreenComponent {
let notes: NoteEntity[] = [];

if (query) {
if (this.props.settings['db.ftsEnabled']) {
if (this.props.ftsEnabled) {
const r = await SearchEngineUtils.notesForQuery(query, true, { appendWildCards: true });
notes = r.notes;
} else {
Expand Down Expand Up @@ -130,12 +146,11 @@ class SearchScreenComponent extends BaseScreenComponent {
}

public scheduleSearch() {
if (this.scheduleSearchTimer_) clearTimeout(this.scheduleSearchTimer_);
this.searchActionQueue_.push(() => this.refreshSearch(this.state.query));
}

this.scheduleSearchTimer_ = setTimeout(() => {
this.scheduleSearchTimer_ = null;
void this.refreshSearch(this.state.query);
}, 200);
public onComponentWillUnmount() {
void this.searchActionQueue_.reset();
}

private searchTextInput_changeText(text: string) {
Expand Down Expand Up @@ -215,7 +230,8 @@ const SearchScreen = connect((state: AppState) => {
themeId: state.settings.theme,
settings: state.settings,
noteSelectionEnabled: state.noteSelectionEnabled,
ftsEnabled: state.settings['db.ftsEnabled'],
};
})(SearchScreenComponent);

module.exports = { SearchScreen };
export default SearchScreen;
2 changes: 1 addition & 1 deletion packages/app-mobile/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import ConfigScreen from './components/screens/ConfigScreen/ConfigScreen';
const { FolderScreen } = require('./components/screens/folder.js');
import LogScreen from './components/screens/LogScreen';
import StatusScreen from './components/screens/status';
const { SearchScreen } = require('./components/screens/search.js');
import SearchScreen from './components/screens/search';
const { OneDriveLoginScreen } = require('./components/screens/onedrive-login.js');
import EncryptionConfigScreen from './components/screens/encryption-config';
const { DropboxLoginScreen } = require('./components/screens/dropbox-login.js');
Expand Down

0 comments on commit feb946a

Please sign in to comment.