Skip to content

Commit

Permalink
Mobile: Fixes #10237: Automatically set focus on title or body when c…
Browse files Browse the repository at this point in the history
…reating a new note
  • Loading branch information
laurent22 committed May 28, 2024
1 parent 70c5448 commit 2386f58
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
4 changes: 4 additions & 0 deletions packages/app-mobile/components/NoteEditor/NoteEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ const useEditorControl = (
return bodyControl.execCommand(command, ...args);
},

focus() {
void bodyControl.execCommand(EditorCommandType.Focus);
},

undo() {
bodyControl.undo();
},
Expand Down
1 change: 1 addition & 0 deletions packages/app-mobile/components/NoteEditor/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface EditorControl extends EditorBodyControl {
toggleUnorderedList(): void;
toggleTaskList(): void;
toggleHeaderLevel(level: number): void;
focus(): void;

scrollSelectionIntoView(): void;
showLinkDialog(): void;
Expand Down
47 changes: 29 additions & 18 deletions packages/app-mobile/components/screens/Note.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ class NoteScreenComponent extends BaseScreenComponent<Props, State> implements B
voiceTypingDialogShown: false,
};

this.titleTextFieldRef = React.createRef();

this.saveActionQueues_ = {};

// this.markdownEditorRef = React.createRef(); // For focusing the Markdown editor
Expand Down Expand Up @@ -538,7 +540,7 @@ class NoteScreenComponent extends BaseScreenComponent<Props, State> implements B
public componentDidUpdate(prevProps: any, prevState: any) {
if (this.doFocusUpdate_) {
this.doFocusUpdate_ = false;
this.focusUpdate();
this.scheduleFocusUpdate();
}

if (prevProps.showSideMenu !== this.props.showSideMenu && this.props.showSideMenu) {
Expand Down Expand Up @@ -1354,27 +1356,36 @@ class NoteScreenComponent extends BaseScreenComponent<Props, State> implements B
}

public scheduleFocusUpdate() {
if (this.focusUpdateIID_) shim.clearTimeout(this.focusUpdateIID_);
if (this.focusUpdateIID_) shim.clearInterval(this.focusUpdateIID_);

this.focusUpdateIID_ = shim.setTimeout(() => {
this.focusUpdateIID_ = null;
this.focusUpdate();
}, 100);
}
const startTime = Date.now();

public focusUpdate() {
if (this.focusUpdateIID_) shim.clearTimeout(this.focusUpdateIID_);
this.focusUpdateIID_ = null;
this.focusUpdateIID_ = shim.setInterval(() => {
if (!this.state.note) return;

if (!this.state.note) return;
let fieldToFocus = this.state.note.is_todo ? 'title' : 'body';
if (this.state.mode === 'view') fieldToFocus = '';
let fieldToFocus = this.state.note.is_todo ? 'title' : 'body';
if (this.state.mode === 'view') fieldToFocus = '';

// Avoid writing `this.titleTextFieldRef.current` -- titleTextFieldRef may
// be undefined.
if (fieldToFocus === 'title' && this.titleTextFieldRef?.current) {
focus('Note::focusUpdate', this.titleTextFieldRef.current);
}
let done = false;

if (fieldToFocus === 'title' && this.titleTextFieldRef?.current) {
done = true;
focus('Note::focusUpdate::title', this.titleTextFieldRef.current);
} else if (fieldToFocus === 'body' && this.editorRef?.current) {
done = true;
focus('Note::focusUpdate::body', this.editorRef.current);
}

if (Date.now() - startTime > 5000) {
logger.warn(`Timeout while trying to set focus on ${fieldToFocus}`);
done = true;
}

if (done) {
shim.clearInterval(this.focusUpdateIID_);
this.focusUpdateIID_ = null;
}
}, 50);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
Expand Down

0 comments on commit 2386f58

Please sign in to comment.