Skip to content

Commit

Permalink
Desktop: Fixes #10514: Fix focusing the note list doesn't work when t…
Browse files Browse the repository at this point in the history
…he selected note is off screen (#10515)
  • Loading branch information
personalizedrefrigerator authored May 30, 2024
1 parent 418a6e4 commit 55c222c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/app-desktop/gui/NoteList/NoteList2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const NoteList = (props: Props) => {
props.notes.length,
);

const focusNote = useFocusNote(itemRefs);
const focusNote = useFocusNote(itemRefs, props.notes, makeItemIndexVisible);

const moveNote = useMoveNote(
props.notesParentType,
Expand Down
20 changes: 16 additions & 4 deletions packages/app-desktop/gui/NoteList/utils/useFocusNote.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import shim from '@joplin/lib/shim';
import { useRef, useCallback, MutableRefObject } from 'react';
import { focus } from '@joplin/lib/utils/focusHandler';
import { NoteEntity } from '@joplin/lib/services/database/types';

export type FocusNote = (noteId: string)=> void;
type ItemRefs = MutableRefObject<Record<string, HTMLDivElement>>;
type OnMakeIndexVisible = (i: number)=> void;

const useFocusNote = (itemRefs: MutableRefObject<Record<string, HTMLDivElement>>) => {
const useFocusNote = (itemRefs: ItemRefs, notes: NoteEntity[], makeItemIndexVisible: OnMakeIndexVisible) => {
const focusItemIID = useRef(null);

const notesRef = useRef(notes);
notesRef.current = notes;

const focusNote: FocusNote = useCallback((noteId: string) => {
// - We need to focus the item manually otherwise focus might be lost when the
// list is scrolled and items within it are being rebuilt.
// - We need to use an interval because when leaving the arrow pressed, the rendering
// of items might lag behind and so the ref is not yet available at this point.
// - We need to use an interval because when leaving the arrow pressed or scrolling
// offscreen items into view, the rendering of items might lag behind and so the
// ref is not yet available at this point.

if (!itemRefs.current[noteId]) {
const targetIndex = notesRef.current.findIndex(note => note.id === noteId);
if (targetIndex > -1) {
makeItemIndexVisible(targetIndex);
}

if (focusItemIID.current) shim.clearInterval(focusItemIID.current);
focusItemIID.current = shim.setInterval(() => {
if (itemRefs.current[noteId]) {
Expand All @@ -26,7 +38,7 @@ const useFocusNote = (itemRefs: MutableRefObject<Record<string, HTMLDivElement>>
if (focusItemIID.current) shim.clearInterval(focusItemIID.current);
focus('useFocusNote2', itemRefs.current[noteId]);
}
}, [itemRefs]);
}, [itemRefs, makeItemIndexVisible]);

return focusNote;
};
Expand Down

0 comments on commit 55c222c

Please sign in to comment.