From b1df96689fd4243cdc28caa4ebc623266a5f5aaa Mon Sep 17 00:00:00 2001
From: Lim Chee Aun <cheeaun@gmail.com>
Date: Thu, 23 Feb 2023 21:42:38 +0800
Subject: [PATCH] Prevent keep calling Lists :id API for the title

Memoize all the things!!1!
---
 src/components/shortcuts-settings.jsx | 27 ++++++++++-----
 src/components/shortcuts.jsx          | 48 +++++++++++++++------------
 2 files changed, 45 insertions(+), 30 deletions(-)

diff --git a/src/components/shortcuts-settings.jsx b/src/components/shortcuts-settings.jsx
index da4af345..d933ce27 100644
--- a/src/components/shortcuts-settings.jsx
+++ b/src/components/shortcuts-settings.jsx
@@ -1,5 +1,6 @@
 import './shortcuts-settings.css';
 
+import mem from 'mem';
 import { useEffect, useState } from 'preact/hooks';
 import { useSnapshot } from 'valtio';
 
@@ -90,10 +91,15 @@ export const SHORTCUTS_META = {
     icon: 'notification',
   },
   list: {
-    title: async ({ id }) => {
-      const list = await api().masto.v1.lists.fetch(id);
-      return list.title;
-    },
+    title: mem(
+      async ({ id }) => {
+        const list = await api().masto.v1.lists.fetch(id);
+        return list.title;
+      },
+      {
+        cacheKey: ([{ id }]) => id,
+      },
+    ),
     path: ({ id }) => `/l/${id}`,
     icon: 'list',
   },
@@ -109,10 +115,15 @@ export const SHORTCUTS_META = {
     icon: 'search',
   },
   'account-statuses': {
-    title: async ({ id }) => {
-      const account = await api().masto.v1.accounts.fetch(id);
-      return account.username || account.acct || account.displayName;
-    },
+    title: mem(
+      async ({ id }) => {
+        const account = await api().masto.v1.accounts.fetch(id);
+        return account.username || account.acct || account.displayName;
+      },
+      {
+        cacheKey: ([{ id }]) => id,
+      },
+    ),
     path: ({ id }) => `/a/${id}`,
     icon: 'user',
   },
diff --git a/src/components/shortcuts.jsx b/src/components/shortcuts.jsx
index 280f75cc..19c8d338 100644
--- a/src/components/shortcuts.jsx
+++ b/src/components/shortcuts.jsx
@@ -1,7 +1,7 @@
 import './shortcuts.css';
 
 import { Menu, MenuItem } from '@szhsin/react-menu';
-import { useRef } from 'preact/hooks';
+import { useMemo, useRef } from 'preact/hooks';
 import { useHotkeys } from 'react-hotkeys-hook';
 import { useNavigate } from 'react-router-dom';
 import { useSnapshot } from 'valtio';
@@ -23,29 +23,33 @@ function Shortcuts() {
 
   const menuRef = useRef();
 
-  const formattedShortcuts = shortcuts
-    .map((pin, i) => {
-      const { type, ...data } = pin;
-      if (!SHORTCUTS_META[type]) return null;
-      let { path, title, icon } = SHORTCUTS_META[type];
+  const formattedShortcuts = useMemo(
+    () =>
+      shortcuts
+        .map((pin, i) => {
+          const { type, ...data } = pin;
+          if (!SHORTCUTS_META[type]) return null;
+          let { path, title, icon } = SHORTCUTS_META[type];
 
-      if (typeof path === 'function') {
-        path = path(data, i);
-      }
-      if (typeof title === 'function') {
-        title = title(data);
-      }
-      if (typeof icon === 'function') {
-        icon = icon(data);
-      }
+          if (typeof path === 'function') {
+            path = path(data, i);
+          }
+          if (typeof title === 'function') {
+            title = title(data);
+          }
+          if (typeof icon === 'function') {
+            icon = icon(data);
+          }
 
-      return {
-        path,
-        title,
-        icon,
-      };
-    })
-    .filter(Boolean);
+          return {
+            path,
+            title,
+            icon,
+          };
+        })
+        .filter(Boolean),
+    [shortcuts],
+  );
 
   const navigate = useNavigate();
   useHotkeys(['1', '2', '3', '4', '5', '6', '7', '8', '9'], (e, handler) => {