From e782cc0dde5470e2ce6df972177ac55444bae64c Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Sat, 13 Apr 2024 00:06:34 +0800 Subject: [PATCH] Refactor set/get current account ID And add fallback for standalone mode where session storage is not enough --- src/app.jsx | 4 ++-- src/components/account-info.jsx | 9 +++----- src/components/media-post.jsx | 3 ++- src/components/nav-menu.jsx | 6 +++--- src/components/notification.jsx | 3 ++- src/components/shortcuts-settings.jsx | 5 +++-- src/components/status.jsx | 3 ++- src/pages/accounts.jsx | 5 +++-- src/pages/catchup.jsx | 4 ++-- src/utils/api.js | 3 ++- src/utils/filters.jsx | 4 ++-- src/utils/relationships.js | 4 ++-- src/utils/store-utils.js | 31 +++++++++++++++++++++++++-- 13 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/app.jsx b/src/app.jsx index 1b18093f..e74246b4 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -53,7 +53,7 @@ import { getAccessToken } from './utils/auth'; import focusDeck from './utils/focus-deck'; import states, { initStates, statusKey } from './utils/states'; import store from './utils/store'; -import { getCurrentAccount } from './utils/store-utils'; +import { getCurrentAccount, setCurrentAccountID } from './utils/store-utils'; import './utils/toast-alert'; window.__STATES__ = states; @@ -338,7 +338,7 @@ function App() { window.__IGNORE_GET_ACCOUNT_ERROR__ = true; const account = getCurrentAccount(); if (account) { - store.session.set('currentAccount', account.info.id); + setCurrentAccountID(account.info.id); const { client } = api({ account }); const { instance } = client; // console.log('masto', masto); diff --git a/src/components/account-info.jsx b/src/components/account-info.jsx index f93fccab..35ea89ea 100644 --- a/src/components/account-info.jsx +++ b/src/components/account-info.jsx @@ -22,7 +22,7 @@ import shortenNumber from '../utils/shorten-number'; import showToast from '../utils/show-toast'; import states, { hideAllModals } from '../utils/states'; import store from '../utils/store'; -import { updateAccount } from '../utils/store-utils'; +import { getCurrentAccountID, updateAccount } from '../utils/store-utils'; import AccountBlock from './account-block'; import Avatar from './avatar'; @@ -198,10 +198,7 @@ function AccountInfo({ } } - const isSelf = useMemo( - () => id === store.session.get('currentAccount'), - [id], - ); + const isSelf = useMemo(() => id === getCurrentAccountID(), [id]); useEffect(() => { const infoHasEssentials = !!( @@ -920,7 +917,7 @@ function RelatedActions({ useEffect(() => { if (info) { - const currentAccount = store.session.get('currentAccount'); + const currentAccount = getCurrentAccountID(); let currentID; (async () => { if (sameInstance && authenticated) { diff --git a/src/components/media-post.jsx b/src/components/media-post.jsx index d5d09f5f..91ed67d7 100644 --- a/src/components/media-post.jsx +++ b/src/components/media-post.jsx @@ -8,6 +8,7 @@ import FilterContext from '../utils/filter-context'; import { isFiltered } from '../utils/filters'; import states, { statusKey } from '../utils/states'; import store from '../utils/store'; +import { getCurrentAccountID } from '../utils/store-utils'; import Media from './media'; @@ -88,7 +89,7 @@ function MediaPost({ }; const currentAccount = useMemo(() => { - return store.session.get('currentAccount'); + return getCurrentAccountID(); }, []); const isSelf = useMemo(() => { return currentAccount && currentAccount === accountId; diff --git a/src/components/nav-menu.jsx b/src/components/nav-menu.jsx index 2b622feb..769fb84f 100644 --- a/src/components/nav-menu.jsx +++ b/src/components/nav-menu.jsx @@ -11,6 +11,7 @@ import { getLists } from '../utils/lists'; import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding'; import states from '../utils/states'; import store from '../utils/store'; +import { getCurrentAccountID } from '../utils/store-utils'; import Avatar from './avatar'; import Icon from './icon'; @@ -24,9 +25,8 @@ function NavMenu(props) { const [currentAccount, moreThanOneAccount] = useMemo(() => { const accounts = store.local.getJSON('accounts') || []; const acc = - accounts.find( - (account) => account.info.id === store.session.get('currentAccount'), - ) || accounts[0]; + accounts.find((account) => account.info.id === getCurrentAccountID()) || + accounts[0]; return [acc, accounts.length > 1]; }, []); diff --git a/src/components/notification.jsx b/src/components/notification.jsx index f892fe81..beb2a202 100644 --- a/src/components/notification.jsx +++ b/src/components/notification.jsx @@ -4,6 +4,7 @@ import { memo } from 'preact/compat'; import shortenNumber from '../utils/shorten-number'; import states, { statusKey } from '../utils/states'; import store from '../utils/store'; +import { getCurrentAccountID } from '../utils/store-utils'; import useTruncated from '../utils/useTruncated'; import Avatar from './avatar'; @@ -132,7 +133,7 @@ function Notification({ const actualStatus = status?.reblog || status; const actualStatusID = actualStatus?.id; - const currentAccount = store.session.get('currentAccount'); + const currentAccount = getCurrentAccountID(); const isSelf = currentAccount === account?.id; const isVoted = status?.poll?.voted; const isReplyToOthers = diff --git a/src/components/shortcuts-settings.jsx b/src/components/shortcuts-settings.jsx index 5ccfdb4c..ad8aca57 100644 --- a/src/components/shortcuts-settings.jsx +++ b/src/components/shortcuts-settings.jsx @@ -19,6 +19,7 @@ import pmem from '../utils/pmem'; import showToast from '../utils/show-toast'; import states from '../utils/states'; import store from '../utils/store'; +import { getCurrentAccountID } from '../utils/store-utils'; import AsyncText from './AsyncText'; import Icon from './icon'; @@ -787,7 +788,7 @@ function ImportExport({ shortcuts, onClose }) { disabled={importUIState === 'cloud-downloading'} onClick={async () => { setImportUIState('cloud-downloading'); - const currentAccount = store.session.get('currentAccount'); + const currentAccount = getCurrentAccountID(); showToast( 'Downloading saved shortcuts from instance server…', ); @@ -1043,7 +1044,7 @@ function ImportExport({ shortcuts, onClose }) { disabled={importUIState === 'cloud-uploading'} onClick={async () => { setImportUIState('cloud-uploading'); - const currentAccount = store.session.get('currentAccount'); + const currentAccount = getCurrentAccountID(); try { const relationships = await masto.v1.accounts.relationships.fetch({ diff --git a/src/components/status.jsx b/src/components/status.jsx index a3f8fadb..41aace86 100644 --- a/src/components/status.jsx +++ b/src/components/status.jsx @@ -54,6 +54,7 @@ import { speak, supportsTTS } from '../utils/speech'; import states, { getStatus, saveStatus, statusKey } from '../utils/states'; import statusPeek from '../utils/status-peek'; import store from '../utils/store'; +import { getCurrentAccountID } from '../utils/store-utils'; import unfurlMastodonLink from '../utils/unfurl-link'; import useHotkeys from '../utils/useHotkeys'; import useTruncated from '../utils/useTruncated'; @@ -256,7 +257,7 @@ function Status({ if (mediaFirst && hasMediaAttachments) size = 's'; const currentAccount = useMemo(() => { - return store.session.get('currentAccount'); + return getCurrentAccountID(); }, []); const isSelf = useMemo(() => { return currentAccount && currentAccount === accountId; diff --git a/src/pages/accounts.jsx b/src/pages/accounts.jsx index 5d57ba21..efa38a19 100644 --- a/src/pages/accounts.jsx +++ b/src/pages/accounts.jsx @@ -13,12 +13,13 @@ import NameText from '../components/name-text'; import { api } from '../utils/api'; import states from '../utils/states'; import store from '../utils/store'; +import { getCurrentAccountID, setCurrentAccountID } from '../utils/store-utils'; function Accounts({ onClose }) { const { masto } = api(); // Accounts const accounts = store.local.getJSON('accounts'); - const currentAccount = store.session.get('currentAccount'); + const currentAccount = getCurrentAccountID(); const moreThanOneAccount = accounts.length > 1; const [_, reload] = useReducer((x) => x + 1, 0); @@ -81,7 +82,7 @@ function Accounts({ onClose }) { if (isCurrent) { states.showAccount = `${account.info.username}@${account.instanceURL}`; } else { - store.session.set('currentAccount', account.info.id); + setCurrentAccountID(account.info.id); location.reload(); } }} diff --git a/src/pages/catchup.jsx b/src/pages/catchup.jsx index 6801681c..e416d2e5 100644 --- a/src/pages/catchup.jsx +++ b/src/pages/catchup.jsx @@ -39,7 +39,7 @@ import showToast from '../utils/show-toast'; import states, { statusKey } from '../utils/states'; import statusPeek from '../utils/status-peek'; import store from '../utils/store'; -import { getCurrentAccountNS } from '../utils/store-utils'; +import { getCurrentAccountID, getCurrentAccountNS } from '../utils/store-utils'; import { assignFollowedTags } from '../utils/timeline-utils'; import useHotkeys from '../utils/useHotkeys'; import useTitle from '../utils/useTitle'; @@ -112,7 +112,7 @@ function Catchup() { const [showTopLinks, setShowTopLinks] = useState(false); const currentAccount = useMemo(() => { - return store.session.get('currentAccount'); + return getCurrentAccountID(); }, []); const isSelf = (accountID) => accountID === currentAccount; diff --git a/src/utils/api.js b/src/utils/api.js index d1c9981a..78674a26 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -7,6 +7,7 @@ import { getAccountByInstance, getCurrentAccount, saveAccount, + setCurrentAccountID, } from './store-utils'; // Default *fallback* instance @@ -118,7 +119,7 @@ export async function initAccount(client, instance, accessToken, vapidKey) { const mastoAccount = await masto.v1.accounts.verifyCredentials(); console.log('CURRENTACCOUNT SET', mastoAccount.id); - store.session.set('currentAccount', mastoAccount.id); + setCurrentAccountID(mastoAccount.id); saveAccount({ info: mastoAccount, diff --git a/src/utils/filters.jsx b/src/utils/filters.jsx index 5d51bc0b..794d6179 100644 --- a/src/utils/filters.jsx +++ b/src/utils/filters.jsx @@ -1,5 +1,5 @@ import mem from './mem'; -import store from './store'; +import { getCurrentAccountID } from './store-utils'; function _isFiltered(filtered, filterContext) { if (!filtered?.length) return false; @@ -43,7 +43,7 @@ export function filteredItem(item, filterContext, currentAccountID) { export function filteredItems(items, filterContext) { if (!items?.length) return []; if (!filterContext) return items; - const currentAccountID = store.session.get('currentAccount'); + const currentAccountID = getCurrentAccountID(); return items.filter((item) => filteredItem(item, filterContext, currentAccountID), ); diff --git a/src/utils/relationships.js b/src/utils/relationships.js index eb80da5f..868a8b97 100644 --- a/src/utils/relationships.js +++ b/src/utils/relationships.js @@ -1,11 +1,11 @@ import { api } from './api'; -import store from './store'; +import { getCurrentAccountID } from './store-utils'; export async function fetchRelationships(accounts, relationshipsMap = {}) { if (!accounts?.length) return; const { masto } = api(); - const currentAccount = store.session.get('currentAccount'); + const currentAccount = getCurrentAccountID(); const uniqueAccountIds = accounts.reduce((acc, a) => { // 1. Ignore duplicate accounts // 2. Ignore accounts that are already inside relationshipsMap diff --git a/src/utils/store-utils.js b/src/utils/store-utils.js index aff33e4a..46054eda 100644 --- a/src/utils/store-utils.js +++ b/src/utils/store-utils.js @@ -16,13 +16,40 @@ export function getAccountByInstance(instance) { return accounts.find((a) => a.instanceURL === instance); } +const standaloneMQ = window.matchMedia('(display-mode: standalone)'); + +export function getCurrentAccountID() { + try { + const id = store.session.get('currentAccount'); + if (id) return id; + } catch (e) {} + if (standaloneMQ.matches) { + try { + const id = store.local.get('currentAccount'); + if (id) return id; + } catch (e) {} + } + return null; +} + +export function setCurrentAccountID(id) { + try { + store.session.set('currentAccount', id); + } catch (e) {} + if (standaloneMQ.matches) { + try { + store.local.set('currentAccount', id); + } catch (e) {} + } +} + export function getCurrentAccount() { if (!window.__IGNORE_GET_ACCOUNT_ERROR__) { // Track down getCurrentAccount() calls before account-based states are initialized console.error('getCurrentAccount() called before states are initialized'); if (import.meta.env.DEV) console.trace(); } - const currentAccount = store.session.get('currentAccount'); + const currentAccount = getCurrentAccountID(); const account = getAccount(currentAccount); return account; } @@ -48,7 +75,7 @@ export function saveAccount(account) { accounts.push(account); } store.local.setJSON('accounts', accounts); - store.session.set('currentAccount', account.info.id); + setCurrentAccountID(account.info.id); } export function updateAccount(accountInfo) {