Make fetches on-demand

Also, cache them
This commit is contained in:
Lim Chee Aun 2023-11-04 01:11:29 +08:00
parent f726f47fcb
commit e0cf2e22fd

View file

@ -118,6 +118,14 @@ const TYPE_PARAMS = {
}, },
], ],
}; };
const fetchListTitle = pmem(async ({ id }) => {
const list = await api().masto.v1.lists.$select(id).fetch();
return list.title;
});
const fetchAccountTitle = pmem(async ({ id }) => {
const account = await api().masto.v1.accounts.$select(id).fetch();
return account.username || account.acct || account.displayName;
});
export const SHORTCUTS_META = { export const SHORTCUTS_META = {
following: { following: {
id: 'home', id: 'home',
@ -139,10 +147,7 @@ export const SHORTCUTS_META = {
}, },
list: { list: {
id: 'list', id: 'list',
title: pmem(async ({ id }) => { title: fetchListTitle,
const list = await api().masto.v1.lists.$select(id).fetch();
return list.title;
}),
path: ({ id }) => `/l/${id}`, path: ({ id }) => `/l/${id}`,
icon: 'list', icon: 'list',
}, },
@ -168,10 +173,7 @@ export const SHORTCUTS_META = {
}, },
'account-statuses': { 'account-statuses': {
id: 'account-statuses', id: 'account-statuses',
title: pmem(async ({ id }) => { title: fetchAccountTitle,
const account = await api().masto.v1.accounts.$select(id).fetch();
return account.username || account.acct || account.displayName;
}),
path: ({ id }) => `/a/${id}`, path: ({ id }) => `/a/${id}`,
icon: 'user', icon: 'user',
}, },
@ -201,43 +203,12 @@ export const SHORTCUTS_META = {
function ShortcutsSettings({ onClose }) { function ShortcutsSettings({ onClose }) {
const snapStates = useSnapshot(states); const snapStates = useSnapshot(states);
const { masto } = api();
const { shortcuts } = snapStates; const { shortcuts } = snapStates;
const [lists, setLists] = useState([]);
const [followedHashtags, setFollowedHashtags] = useState([]);
const [showForm, setShowForm] = useState(false); const [showForm, setShowForm] = useState(false);
const [showImportExport, setShowImportExport] = useState(false); const [showImportExport, setShowImportExport] = useState(false);
const [shortcutsListParent] = useAutoAnimate(); const [shortcutsListParent] = useAutoAnimate();
useEffect(() => {
(async () => {
try {
const lists = await masto.v1.lists.list();
lists.sort((a, b) => a.title.localeCompare(b.title));
setLists(lists);
} catch (e) {
console.error(e);
}
})();
(async () => {
try {
const iterator = masto.v1.followedTags.list();
const tags = [];
do {
const { value, done } = await iterator.next();
if (done || value?.length === 0) break;
tags.push(...value);
} while (true);
setFollowedHashtags(tags);
} catch (e) {
console.error(e);
}
})();
}, []);
return ( return (
<div id="shortcuts-settings-container" class="sheet" tabindex="-1"> <div id="shortcuts-settings-container" class="sheet" tabindex="-1">
{!!onClose && ( {!!onClose && (
@ -454,8 +425,6 @@ function ShortcutsSettings({ onClose }) {
<ShortcutForm <ShortcutForm
shortcut={showForm.shortcut} shortcut={showForm.shortcut}
shortcutIndex={showForm.shortcutIndex} shortcutIndex={showForm.shortcutIndex}
lists={lists}
followedHashtags={followedHashtags}
onSubmit={({ result, mode }) => { onSubmit={({ result, mode }) => {
console.log('onSubmit', result); console.log('onSubmit', result);
if (mode === 'edit') { if (mode === 'edit') {
@ -487,9 +456,27 @@ function ShortcutsSettings({ onClose }) {
); );
} }
const FETCH_MAX_AGE = 1000 * 60; // 1 minute
const fetchLists = pmem(
() => {
const { masto } = api();
return masto.v1.lists.list();
},
{
maxAge: FETCH_MAX_AGE,
},
);
const fetchFollowedHashtags = pmem(
() => {
const { masto } = api();
return masto.v1.followedTags.list();
},
{
maxAge: FETCH_MAX_AGE,
},
);
function ShortcutForm({ function ShortcutForm({
lists,
followedHashtags,
onSubmit, onSubmit,
disabled, disabled,
shortcut, shortcut,
@ -500,6 +487,41 @@ function ShortcutForm({
const editMode = !!shortcut; const editMode = !!shortcut;
const [currentType, setCurrentType] = useState(shortcut?.type || null); const [currentType, setCurrentType] = useState(shortcut?.type || null);
const [uiState, setUIState] = useState('default');
const [lists, setLists] = useState([]);
const [followedHashtags, setFollowedHashtags] = useState([]);
useEffect(() => {
(async () => {
if (currentType !== 'list') return;
try {
setUIState('loading');
const lists = await fetchLists();
lists.sort((a, b) => a.title.localeCompare(b.title));
setLists(lists);
setUIState('default');
} catch (e) {
console.error(e);
setUIState('error');
}
})();
(async () => {
if (currentType !== 'hashtag') return;
try {
const iterator = fetchFollowedHashtags();
const tags = [];
do {
const { value, done } = await iterator.next();
if (done || value?.length === 0) break;
tags.push(...value);
} while (true);
setFollowedHashtags(tags);
} catch (e) {
console.error(e);
}
})();
}, [currentType]);
const formRef = useRef(); const formRef = useRef();
useEffect(() => { useEffect(() => {
if (editMode && currentType && TYPE_PARAMS[currentType]) { if (editMode && currentType && TYPE_PARAMS[currentType]) {
@ -588,7 +610,8 @@ function ShortcutForm({
<select <select
name="id" name="id"
required={!notRequired} required={!notRequired}
disabled={disabled} disabled={disabled || uiState === 'loading'}
defaultValue={editMode ? shortcut.id : undefined}
> >
{lists.map((list) => ( {lists.map((list) => (
<option value={list.id}>{list.title}</option> <option value={list.id}>{list.title}</option>
@ -633,7 +656,11 @@ function ShortcutForm({
}, },
)} )}
<footer> <footer>
<button type="submit" class="block" disabled={disabled}> <button
type="submit"
class="block"
disabled={disabled || uiState === 'loading'}
>
{editMode ? 'Save' : 'Add'} {editMode ? 'Save' : 'Add'}
</button> </button>
{editMode && ( {editMode && (