From 672dd5ea4bddcc0743aa63eab39bd612bdbd390c Mon Sep 17 00:00:00 2001
From: Joel Jeremy Marquez <joeljeremy.marquez@gmail.com>
Date: Tue, 16 Apr 2024 13:06:26 -0700
Subject: [PATCH] [Mobile] Fix account notes not retrieving correctly in mobile
 (#2599)

* Fix account notes not retrieving correctly

* Release notes

* Update release notes

* Fix type errors
---
 .../desktop-client/src/components/NotesButton.tsx | 10 ++--------
 .../src/components/modals/AccountMenuModal.tsx    | 14 ++------------
 .../components/modals/CategoryGroupMenuModal.tsx  | 14 +++-----------
 .../src/components/modals/CategoryMenuModal.tsx   | 15 +++------------
 .../src/components/modals/Notes.tsx               | 11 ++---------
 packages/desktop-client/src/hooks/useNotes.ts     | 13 +++++++++++++
 upcoming-release-notes/2599.md                    |  6 ++++++
 7 files changed, 31 insertions(+), 52 deletions(-)
 create mode 100644 packages/desktop-client/src/hooks/useNotes.ts
 create mode 100644 upcoming-release-notes/2599.md

diff --git a/packages/desktop-client/src/components/NotesButton.tsx b/packages/desktop-client/src/components/NotesButton.tsx
index f39af2950..bbd42b33c 100644
--- a/packages/desktop-client/src/components/NotesButton.tsx
+++ b/packages/desktop-client/src/components/NotesButton.tsx
@@ -1,10 +1,8 @@
 import React, { useEffect, useRef, useState, type ComponentProps } from 'react';
 
-import { useLiveQuery } from 'loot-core/src/client/query-hooks';
 import { send } from 'loot-core/src/platform/client/fetch';
-import { q } from 'loot-core/src/shared/query';
-import { type NoteEntity } from 'loot-core/types/models';
 
+import { useNotes } from '../hooks/useNotes';
 import { SvgCustomNotesPaper } from '../icons/v2';
 import { type CSSProperties, theme } from '../style';
 
@@ -32,11 +30,7 @@ export function NotesButton({
 }: NotesButtonProps) {
   const triggerRef = useRef(null);
   const [isOpen, setIsOpen] = useState<boolean>(false);
-  const data = useLiveQuery<NoteEntity[]>(
-    () => q('notes').filter({ id }).select('*'),
-    [id],
-  );
-  const note = data && data.length > 0 ? data[0].note : '';
+  const note = useNotes(id) || '';
   const hasNotes = note && note !== '';
 
   const [tempNotes, setTempNotes] = useState<string>(note);
diff --git a/packages/desktop-client/src/components/modals/AccountMenuModal.tsx b/packages/desktop-client/src/components/modals/AccountMenuModal.tsx
index f798c5032..5e18914e4 100644
--- a/packages/desktop-client/src/components/modals/AccountMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/AccountMenuModal.tsx
@@ -1,10 +1,9 @@
 import React, { type ComponentProps, useState } from 'react';
 
-import { useLiveQuery } from 'loot-core/src/client/query-hooks';
-import { q } from 'loot-core/src/shared/query';
 import { type AccountEntity } from 'loot-core/types/models';
 
 import { useAccounts } from '../../hooks/useAccounts';
+import { useNotes } from '../../hooks/useNotes';
 import { SvgClose, SvgDotsHorizontalTriple, SvgLockOpen } from '../../icons/v1';
 import { SvgNotesPaper } from '../../icons/v2';
 import { type CSSProperties, styles, theme } from '../../style';
@@ -16,11 +15,6 @@ import { type CommonModalProps } from '../Modals';
 import { Notes } from '../Notes';
 import { Tooltip } from '../tooltips';
 
-type NoteEntity = {
-  id: string;
-  note: string;
-};
-
 type AccountMenuModalProps = {
   modalProps: CommonModalProps;
   accountId: string;
@@ -42,11 +36,7 @@ export function AccountMenuModal({
 }: AccountMenuModalProps) {
   const accounts = useAccounts();
   const account = accounts.find(c => c.id === accountId);
-  const data = useLiveQuery(
-    () => q('notes').filter({ id: account?.id }).select('*'),
-    [account?.id],
-  ) as NoteEntity[] | null;
-  const originalNotes = data && data.length > 0 ? data[0].note : null;
+  const originalNotes = useNotes(`account-${accountId}`);
 
   const _onClose = () => {
     modalProps?.onClose();
diff --git a/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx b/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx
index e9a2c1ffd..e9d9a7768 100644
--- a/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx
@@ -1,14 +1,10 @@
 // @ts-strict-ignore
 import React, { type ComponentProps, useState } from 'react';
 
-import { useLiveQuery } from 'loot-core/src/client/query-hooks';
-import { q } from 'loot-core/src/shared/query';
-import {
-  type CategoryGroupEntity,
-  type NoteEntity,
-} from 'loot-core/src/types/models';
+import { type CategoryGroupEntity } from 'loot-core/src/types/models';
 
 import { useCategories } from '../../hooks/useCategories';
+import { useNotes } from '../../hooks/useNotes';
 import { SvgDotsHorizontalTriple, SvgAdd, SvgTrash } from '../../icons/v1';
 import { SvgNotesPaper, SvgViewHide, SvgViewShow } from '../../icons/v2';
 import { type CSSProperties, styles, theme } from '../../style';
@@ -42,11 +38,7 @@ export function CategoryGroupMenuModal({
 }: CategoryGroupMenuModalProps) {
   const { grouped: categoryGroups } = useCategories();
   const group = categoryGroups.find(g => g.id === groupId);
-  const data = useLiveQuery<NoteEntity[]>(
-    () => q('notes').filter({ id: group.id }).select('*'),
-    [group.id],
-  );
-  const notes = data && data.length > 0 ? data[0].note : null;
+  const notes = useNotes(group.id);
 
   const _onClose = () => {
     modalProps?.onClose();
diff --git a/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx b/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx
index 686e99dd4..82c8bff78 100644
--- a/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx
@@ -1,15 +1,11 @@
 // @ts-strict-ignore
 import React, { useState } from 'react';
 
-import { useLiveQuery } from 'loot-core/src/client/query-hooks';
-import { q } from 'loot-core/src/shared/query';
-import {
-  type CategoryEntity,
-  type NoteEntity,
-} from 'loot-core/src/types/models';
+import { type CategoryEntity } from 'loot-core/src/types/models';
 
 import { useCategory } from '../../hooks/useCategory';
 import { useCategoryGroup } from '../../hooks/useCategoryGroup';
+import { useNotes } from '../../hooks/useNotes';
 import { SvgDotsHorizontalTriple, SvgTrash } from '../../icons/v1';
 import { SvgNotesPaper, SvgViewHide, SvgViewShow } from '../../icons/v2';
 import { type CSSProperties, styles, theme } from '../../style';
@@ -40,12 +36,7 @@ export function CategoryMenuModal({
 }: CategoryMenuModalProps) {
   const category = useCategory(categoryId);
   const categoryGroup = useCategoryGroup(category?.cat_group);
-  const data = useLiveQuery<NoteEntity[]>(
-    () => q('notes').filter({ id: category.id }).select('*'),
-    [category.id],
-  );
-  const originalNotes = data && data.length > 0 ? data[0].note : null;
-
+  const originalNotes = useNotes(category.id);
   const _onClose = () => {
     modalProps?.onClose();
     onClose?.();
diff --git a/packages/desktop-client/src/components/modals/Notes.tsx b/packages/desktop-client/src/components/modals/Notes.tsx
index 47815e4d0..239102721 100644
--- a/packages/desktop-client/src/components/modals/Notes.tsx
+++ b/packages/desktop-client/src/components/modals/Notes.tsx
@@ -1,10 +1,7 @@
 // @ts-strict-ignore
 import React, { useEffect, useState } from 'react';
 
-import { useLiveQuery } from 'loot-core/src/client/query-hooks';
-import { q } from 'loot-core/src/shared/query';
-import { type NoteEntity } from 'loot-core/types/models';
-
+import { useNotes } from '../../hooks/useNotes';
 import { SvgCheck } from '../../icons/v2';
 import { Button } from '../common/Button';
 import { Modal } from '../common/Modal';
@@ -20,11 +17,7 @@ type NotesProps = {
 };
 
 export function Notes({ modalProps, id, name, onSave }: NotesProps) {
-  const data = useLiveQuery<NoteEntity[]>(
-    () => q('notes').filter({ id }).select('*'),
-    [id],
-  );
-  const originalNotes = data && data.length > 0 ? data[0].note : null;
+  const originalNotes = useNotes(id);
 
   const [notes, setNotes] = useState(originalNotes);
   useEffect(() => setNotes(originalNotes), [originalNotes]);
diff --git a/packages/desktop-client/src/hooks/useNotes.ts b/packages/desktop-client/src/hooks/useNotes.ts
new file mode 100644
index 000000000..9819b1f65
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useNotes.ts
@@ -0,0 +1,13 @@
+import { useMemo } from 'react';
+
+import { useLiveQuery } from 'loot-core/client/query-hooks';
+import { q } from 'loot-core/shared/query';
+import { type NoteEntity } from 'loot-core/types/models';
+
+export function useNotes(id: string) {
+  const data = useLiveQuery<NoteEntity[]>(
+    () => q('notes').filter({ id }).select('*'),
+    [id],
+  );
+  return useMemo(() => (data && data.length > 0 ? data[0].note : null), [data]);
+}
diff --git a/upcoming-release-notes/2599.md b/upcoming-release-notes/2599.md
new file mode 100644
index 000000000..3e0e85dcf
--- /dev/null
+++ b/upcoming-release-notes/2599.md
@@ -0,0 +1,6 @@
+---
+category: Bugfix
+authors: [joel-jeremy]
+---
+
+Fix account notes not retrieving correctly in mobile.
-- 
GitLab