phanpy/src/pages/bookmarks.jsx

143 lines
3.9 KiB
React
Raw Normal View History

import { useEffect, useRef, useState } from 'preact/hooks';
2023-01-22 08:39:04 +00:00
import Icon from '../components/icon';
import Link from '../components/link';
2023-01-22 08:40:10 +00:00
import Loader from '../components/loader';
import Status from '../components/status';
import useTitle from '../utils/useTitle';
const LIMIT = 40;
function Bookmarks() {
useTitle('Bookmarks');
const [bookmarks, setBookmarks] = useState([]);
const [uiState, setUIState] = useState('default');
const [showMore, setShowMore] = useState(false);
2023-01-21 12:21:16 +00:00
const bookmarksIterator = useRef();
async function fetchBookmarks(firstLoad) {
2023-01-21 12:21:16 +00:00
if (firstLoad || !bookmarksIterator.current) {
bookmarksIterator.current = masto.v1.bookmarks.list({ limit: LIMIT });
}
const allBookmarks = await bookmarksIterator.current.next();
2023-01-21 12:21:16 +00:00
const bookmarksValue = allBookmarks.value;
if (bookmarksValue?.length) {
if (firstLoad) {
setBookmarks(bookmarksValue);
} else {
setBookmarks([...bookmarks, ...bookmarksValue]);
}
}
return allBookmarks;
}
const loadBookmarks = (firstLoad) => {
setUIState('loading');
(async () => {
try {
const { done } = await fetchBookmarks(firstLoad);
setShowMore(!done);
setUIState('default');
} catch (e) {
console.error(e);
setUIState('error');
}
})();
};
useEffect(() => {
loadBookmarks(true);
}, []);
const scrollableRef = useRef(null);
return (
<div
id="bookmarks-page"
class="deck-container"
ref={scrollableRef}
tabIndex="-1"
>
<div class="timeline-deck deck">
<header
onClick={(e) => {
if (e.target === e.currentTarget) {
scrollableRef.current?.scrollTo({
top: 0,
behavior: 'smooth',
});
}
}}
2023-01-21 12:21:16 +00:00
onDblClick={(e) => {
loadBookmarks(true);
}}
>
<div class="header-side">
<Link to="/" class="button plain">
<Icon icon="home" size="l" />
</Link>
</div>
<h1>Bookmarks</h1>
2023-01-21 12:21:16 +00:00
<div class="header-side">
<Loader hidden={uiState !== 'loading'} />
</div>
</header>
{!!bookmarks.length ? (
<>
<ul class="timeline">
{bookmarks.map((status) => (
<li key={`bookmark-${status.id}`}>
<Link class="status-link" to={`/s/${status.id}`}>
<Status status={status} />
</Link>
</li>
))}
</ul>
{showMore && (
<button
type="button"
class="plain block"
disabled={uiState === 'loading'}
onClick={() => loadBookmarks()}
style={{ marginBlockEnd: '6em' }}
>
{uiState === 'loading' ? <Loader /> : <>Show more&hellip;</>}
</button>
)}
</>
) : (
uiState !== 'loading' && (
<p class="ui-state">No bookmarks yet. Go bookmark something!</p>
)
)}
{uiState === 'loading' ? (
2023-01-21 12:21:16 +00:00
<ul class="timeline">
{Array.from({ length: 5 }).map((_, i) => (
<li key={i}>
<Status skeleton />
</li>
))}
</ul>
) : uiState === 'error' ? (
<p class="ui-state">
Unable to load bookmarks.
<br />
<br />
<button
class="button plain"
onClick={() => loadBookmarks(!bookmarks.length)}
>
Try again
</button>
</p>
) : (
bookmarks.length &&
!showMore && <p class="ui-state insignificant">The end.</p>
)}
</div>
</div>
);
}
export default Bookmarks;