mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
add missing loading states
This commit is contained in:
@@ -5,6 +5,12 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.checkingSubscriptions {
|
||||
font-size: var(--topbar-font-size);
|
||||
color: var(--topbar-desktop-link-text-color);
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
.boardNavDesktop a, .navTopRight span {
|
||||
color: var(--topbar-desktop-link-text-color);
|
||||
text-decoration: var(--topbar-desktop-link-text-decoration);
|
||||
|
||||
@@ -8,6 +8,7 @@ import styles from './topbar.module.css';
|
||||
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
||||
import _, { debounce } from 'lodash';
|
||||
import { TimeFilter } from '../board-buttons';
|
||||
import { useAutoSubscribe } from '../../hooks/use-auto-subscribe';
|
||||
|
||||
const SearchBar = ({ setShowSearchBar }: { setShowSearchBar: (show: boolean) => void }) => {
|
||||
const navigate = useNavigate();
|
||||
@@ -197,12 +198,15 @@ const TopBarMobile = ({ subplebbitAddress }: { subplebbitAddress: string }) => {
|
||||
};
|
||||
|
||||
const TopBar = () => {
|
||||
const { t } = useTranslation();
|
||||
const params = useParams();
|
||||
const { isCheckingSubscriptions } = useAutoSubscribe();
|
||||
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
||||
|
||||
return (
|
||||
<>
|
||||
{isCheckingSubscriptions && <div className={styles.checkingSubscriptions}>{t('loading_subscriptions')}</div>}
|
||||
<TopBarDesktop />
|
||||
<TopBarMobile subplebbitAddress={subplebbitAddress} />
|
||||
</>
|
||||
|
||||
@@ -15,23 +15,42 @@ export interface MultisubSubplebbit {
|
||||
plebchanAutoSubscribe?: boolean;
|
||||
}
|
||||
|
||||
export interface DefaultSubplebbitsState {
|
||||
subplebbits: MultisubSubplebbit[];
|
||||
loading: boolean;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
let cacheSubplebbits: MultisubSubplebbit[] | null = null;
|
||||
let cacheMetadata: MultisubMetadata | null = null;
|
||||
let cacheAutoSubscribeAddresses: string[] | null = null;
|
||||
|
||||
export const useDefaultSubplebbits = () => {
|
||||
const [subplebbits, setSubplebbits] = useState<MultisubSubplebbit[]>([]);
|
||||
const [state, setState] = useState<DefaultSubplebbitsState>({
|
||||
subplebbits: [],
|
||||
loading: true,
|
||||
error: null,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (cacheSubplebbits) {
|
||||
setState({
|
||||
subplebbits: cacheSubplebbits,
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const multisub = await fetch(
|
||||
'https://raw.githubusercontent.com/plebbit/temporary-default-subplebbits/master/multisub.json',
|
||||
// { cache: 'no-cache' }
|
||||
).then((res) => res.json());
|
||||
const multisub = await fetch('https://raw.githubusercontent.com/plebbit/temporary-default-subplebbits/master/multisub.json').then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
});
|
||||
|
||||
cacheSubplebbits = multisub.subplebbits;
|
||||
|
||||
// Cache auto-subscribe addresses when we fetch subplebbits
|
||||
@@ -39,14 +58,69 @@ export const useDefaultSubplebbits = () => {
|
||||
.filter((sub: MultisubSubplebbit) => sub.plebchanAutoSubscribe && sub.address)
|
||||
.map((sub: MultisubSubplebbit) => sub.address);
|
||||
|
||||
setSubplebbits(multisub.subplebbits);
|
||||
setState({
|
||||
subplebbits: multisub.subplebbits,
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
error: e instanceof Error ? e : new Error('Failed to fetch subplebbits'),
|
||||
}));
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
return cacheSubplebbits || subplebbits;
|
||||
// To maintain backward compatibility, return the subplebbits array directly
|
||||
return cacheSubplebbits || state.subplebbits;
|
||||
};
|
||||
|
||||
export const useDefaultSubplebbitsState = () => {
|
||||
const [state, setState] = useState<DefaultSubplebbitsState>({
|
||||
subplebbits: cacheSubplebbits || [],
|
||||
loading: !cacheSubplebbits,
|
||||
error: null,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (cacheSubplebbits) {
|
||||
setState({
|
||||
subplebbits: cacheSubplebbits,
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const multisub = await fetch('https://raw.githubusercontent.com/plebbit/temporary-default-subplebbits/master/multisub.json').then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
});
|
||||
|
||||
setState({
|
||||
subplebbits: multisub.subplebbits,
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
error: e instanceof Error ? e : new Error('Failed to fetch subplebbits'),
|
||||
}));
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
export const useDefaultSubplebbitAddresses = () => {
|
||||
|
||||
+12
-22
@@ -7,7 +7,6 @@ import styles from './board.module.css';
|
||||
import { shouldShowSnow } from '../../lib/snow';
|
||||
import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
|
||||
import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||
import { useAutoSubscribe } from '../../hooks/use-auto-subscribe';
|
||||
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
||||
import useFeedStateString from '../../hooks/use-feed-state-string';
|
||||
import useReplyModal from '../../hooks/use-reply-modal';
|
||||
@@ -32,7 +31,6 @@ const threadsWithoutImagesFilter = (comment: Comment) => {
|
||||
};
|
||||
|
||||
const Board = () => {
|
||||
const { isCheckingSubscriptions } = useAutoSubscribe();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
||||
@@ -298,26 +296,18 @@ const Board = () => {
|
||||
/>
|
||||
)}
|
||||
{rules && !description && rules.length > 0 && <SubplebbitRules subplebbitAddress={subplebbitAddress} createdAt={createdAt} rules={rules} />}
|
||||
{isCheckingSubscriptions ? (
|
||||
<div className={styles.feed}>
|
||||
<div className={styles.footer}>
|
||||
<LoadingEllipsis string={t('loading_feed')} />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Virtuoso
|
||||
increaseViewportBy={{ bottom: 1200, top: 1200 }}
|
||||
totalCount={combinedFeed.length}
|
||||
data={combinedFeed}
|
||||
itemContent={(index, post) => <Post index={index} post={post} openReplyModal={openReplyModal} />}
|
||||
useWindowScroll={true}
|
||||
components={{ Footer }}
|
||||
endReached={loadMore}
|
||||
ref={virtuosoRef}
|
||||
restoreStateFrom={lastVirtuosoState}
|
||||
initialScrollTop={lastVirtuosoState?.scrollTop}
|
||||
/>
|
||||
)}
|
||||
<Virtuoso
|
||||
increaseViewportBy={{ bottom: 1200, top: 1200 }}
|
||||
totalCount={combinedFeed.length}
|
||||
data={combinedFeed}
|
||||
itemContent={(index, post) => <Post index={index} post={post} openReplyModal={openReplyModal} />}
|
||||
useWindowScroll={true}
|
||||
components={{ Footer }}
|
||||
endReached={loadMore}
|
||||
ref={virtuosoRef}
|
||||
restoreStateFrom={lastVirtuosoState}
|
||||
initialScrollTop={lastVirtuosoState?.scrollTop}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,10 +4,12 @@ import { useTranslation } from 'react-i18next';
|
||||
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
||||
import { Subplebbit, useSubplebbit, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
|
||||
import { useDefaultSubplebbitTags } from '../../../hooks/use-default-subplebbits-tags';
|
||||
import { useDefaultSubplebbitsState } from '../../../hooks/use-default-subplebbits';
|
||||
import useIsMobile from '../../../hooks/use-is-mobile';
|
||||
import useIsSubplebbitOffline from '../../../hooks/use-is-subplebbit-offline';
|
||||
import styles from '../home.module.css';
|
||||
import { nsfwTags } from '../home';
|
||||
import LoadingEllipsis from '../../../components/loading-ellipsis';
|
||||
|
||||
const Board = ({ subplebbit, isMobile }: { subplebbit: Subplebbit; isMobile: boolean }) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -60,6 +62,7 @@ const BoardsList = ({ multisub }: { multisub: Subplebbit[] }) => {
|
||||
const location = useLocation();
|
||||
const [displayCount, setDisplayCount] = useState(15);
|
||||
const isMobile = useIsMobile();
|
||||
const { loading, error } = useDefaultSubplebbitsState();
|
||||
|
||||
const currentTag = location.pathname.split('/').filter(Boolean)[0];
|
||||
const tags = useDefaultSubplebbitTags(multisub);
|
||||
@@ -68,6 +71,24 @@ const BoardsList = ({ multisub }: { multisub: Subplebbit[] }) => {
|
||||
setDisplayCount(15);
|
||||
}, [currentTag]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className={styles.boardsBox}>
|
||||
<span className={styles.loading}>
|
||||
<LoadingEllipsis string={t('loading_default_boards')} />
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className={styles.boardsBox}>
|
||||
<div className='red'>{error.message}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const filteredBoards = (currentTag && tags.includes(currentTag) ? multisub.filter((sub) => sub?.tags?.includes(currentTag)) : multisub).slice(0, displayCount);
|
||||
|
||||
const totalBoardCount = currentTag && tags.includes(currentTag) ? multisub.filter((sub) => sub?.tags?.includes(currentTag)).length : multisub.length;
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.offlineIcon {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
|
||||
Reference in New Issue
Block a user