From e95954a7fd016e9f783580078e6fab2a039843fb Mon Sep 17 00:00:00 2001
From: Lim Chee Aun <cheeaun@gmail.com>
Date: Thu, 2 Feb 2023 17:29:57 +0800
Subject: [PATCH] Begin work on account-specific store

1. Move boostsCarousel setting to account-specific, sadly no migration from previous setting
2. Cache last notification to prevent keep getting unread notification badge
---
 src/app.jsx                 |  8 +++++---
 src/main.jsx                |  7 +++++--
 src/pages/notifications.jsx |  2 +-
 src/utils/states.js         | 23 ++++++++++++-----------
 src/utils/store.js          | 36 +++++++++++++++++++++++++++++++++++-
 5 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/src/app.jsx b/src/app.jsx
index f69c1964..92408411 100644
--- a/src/app.jsx
+++ b/src/app.jsx
@@ -214,7 +214,7 @@ function App() {
         {/* <Route path="/:anything" element={<NotFound />} /> */}
       </Routes>
       <Routes>
-        {isLoggedIn && <Route path="/s/:id" element={<Status />} />}
+        <Route path="/s/:id" element={<Status />} />
       </Routes>
       <nav id="tab-bar" hidden>
         <li>
@@ -409,6 +409,7 @@ async function startStream() {
 
   const handleNewStatus = debounce((status) => {
     console.log('UPDATE', status);
+    if (document.visibilityState === 'hidden') return;
 
     const inHomeNew = states.homeNew.find((s) => s.id === status.id);
     const inHome = status.id === states.homeLast?.id;
@@ -444,7 +445,7 @@ async function startStream() {
     const inNotificationsNew = states.notificationsNew.find(
       (n) => n.id === notification.id,
     );
-    const inNotifications = notification.id === states.notificationLast?.id;
+    const inNotifications = notification.id === states.notificationsLast?.id;
     if (!inNotificationsNew && !inNotifications) {
       states.notificationsNew.unshift(notification);
     }
@@ -483,6 +484,7 @@ function startVisibility() {
           try {
             const firstStatusID = states.homeLast?.id;
             const firstNotificationID = states.notificationsLast?.id;
+            console.log({ states, firstNotificationID, firstStatusID });
             const fetchHome = masto.v1.timelines.listHome({
               limit: 5,
               ...(firstStatusID && { sinceId: firstStatusID }),
@@ -518,7 +520,7 @@ function startVisibility() {
                 (n) => n.id === notification.id,
               );
               const inNotifications =
-                notification.id === states.notificationLast?.id;
+                notification.id === states.notificationsLast?.id;
               if (!inNotificationsNew && !inNotifications) {
                 states.notificationsNew.unshift(notification);
               }
diff --git a/src/main.jsx b/src/main.jsx
index bee7d956..e43407d5 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -18,10 +18,10 @@ render(
   document.getElementById('app'),
 );
 
-// Clean up iconify localStorage
-// TODO: Remove this after few weeks?
+// Storage cleanup
 setTimeout(() => {
   try {
+    // Clean up iconify localStorage
     Object.keys(localStorage).forEach((key) => {
       if (key.startsWith('iconify')) {
         localStorage.removeItem(key);
@@ -32,5 +32,8 @@ setTimeout(() => {
         sessionStorage.removeItem(key);
       }
     });
+
+    // Clean up old settings key
+    localStorage.removeItem('settings:boostsCarousel');
   } catch (e) {}
 }, 5000);
diff --git a/src/pages/notifications.jsx b/src/pages/notifications.jsx
index a7c58238..d5ec0f2f 100644
--- a/src/pages/notifications.jsx
+++ b/src/pages/notifications.jsx
@@ -81,7 +81,7 @@ function Notifications() {
       const groupedNotifications = groupNotifications(notificationsValues);
 
       if (firstLoad) {
-        states.notificationLast = notificationsValues[0];
+        states.notificationsLast = notificationsValues[0];
         states.notifications = groupedNotifications;
       } else {
         states.notifications.push(...groupedNotifications);
diff --git a/src/utils/states.js b/src/utils/states.js
index 3e1bc33b..9b8d1648 100644
--- a/src/utils/states.js
+++ b/src/utils/states.js
@@ -1,4 +1,5 @@
-import { proxy, subscribe } from 'valtio';
+import { proxy } from 'valtio';
+import { subscribeKey } from 'valtio/utils';
 
 import store from './store';
 
@@ -14,7 +15,7 @@ const states = proxy({
   homeLast: null, // Last item in 'home' list
   homeLastFetchTime: null,
   notifications: [],
-  notificationLast: null, // Last item in 'notifications' list
+  notificationsLast: store.account.get('notificationsLast') || null, // Last item in 'notifications' list
   notificationsNew: [],
   notificationsLastFetchTime: null,
   accounts: {},
@@ -27,20 +28,20 @@ const states = proxy({
   showAccount: false,
   showDrafts: false,
   showMediaModal: false,
-  composeCharacterCount: 0,
+  // Settings
   settings: {
-    boostsCarousel: store.local.get('settings:boostsCarousel')
-      ? store.local.get('settings:boostsCarousel') === '1'
-      : true,
+    boostsCarousel: store.account.get('settings-boostCarousel') ?? true,
   },
 });
+
 export default states;
 
-subscribe(states.settings, () => {
-  store.local.set(
-    'settings:boostsCarousel',
-    states.settings.boostsCarousel ? '1' : '0',
-  );
+subscribeKey(states, 'notificationsLast', (v) => {
+  console.log('CHANGE', v);
+  store.account.set('notificationsLast', states.notificationsLast);
+});
+subscribeKey(states, 'settings-boostCarousel', (v) => {
+  store.account.set('settings-boostCarousel', !!v);
 });
 
 export function hideAllModals() {
diff --git a/src/utils/store.js b/src/utils/store.js
index cf9a750e..fb587b11 100644
--- a/src/utils/store.js
+++ b/src/utils/store.js
@@ -1,3 +1,5 @@
+import { getCurrentAccountNS } from './store-utils';
+
 const local = {
   get: (key) => {
     try {
@@ -84,4 +86,36 @@ const session = {
   },
 };
 
-export default { local, session };
+// Store with account namespace (id@domain.tld) <- uses id, not username
+const account = {
+  get: (key) => {
+    try {
+      return local.getJSON(key)[getCurrentAccountNS()];
+    } catch (e) {
+      console.warn(e);
+      return null;
+    }
+  },
+  set: (key, value) => {
+    try {
+      const data = local.getJSON(key) || {};
+      data[getCurrentAccountNS()] = value;
+      return local.setJSON(key, data);
+    } catch (e) {
+      console.warn(e);
+      return null;
+    }
+  },
+  del: (key) => {
+    try {
+      const data = local.getJSON(key) || {};
+      delete data[getCurrentAccountNS()];
+      return local.setJSON(key, data);
+    } catch (e) {
+      console.warn(e);
+      return null;
+    }
+  },
+};
+
+export default { local, session, account };