mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat: add time filter to p/all and p/subscriptions
This commit is contained in:
+8
-8
@@ -92,16 +92,16 @@ const App = () => {
|
|||||||
<Route path='/p/:subplebbitAddress/rules' element={<PostPage />} />
|
<Route path='/p/:subplebbitAddress/rules' element={<PostPage />} />
|
||||||
<Route path='/p/:subplebbitAddress/rules/settings' element={<PostPage />} />
|
<Route path='/p/:subplebbitAddress/rules/settings' element={<PostPage />} />
|
||||||
|
|
||||||
<Route path='/p/all' element={<Board />} />
|
<Route path='/p/all/:timeFilterName?' element={<Board />} />
|
||||||
|
<Route path='/p/all/:timeFilterName?/settings' element={<Board />} />
|
||||||
<Route path='/p/all/description' element={<PostPage />} />
|
<Route path='/p/all/description' element={<PostPage />} />
|
||||||
<Route path='/p/all/settings' element={<Board />} />
|
<Route path='/p/all/catalog/:timeFilterName?' element={<Catalog />} />
|
||||||
<Route path='/p/all/catalog' element={<Catalog />} />
|
<Route path='/p/all/catalog/:timeFilterName?/settings' element={<Catalog />} />
|
||||||
<Route path='/p/all/catalog/settings' element={<Catalog />} />
|
|
||||||
|
|
||||||
<Route path='/p/subscriptions' element={<Board />} />
|
<Route path='/p/subscriptions/:timeFilterName?' element={<Board />} />
|
||||||
<Route path='/p/subscriptions/settings' element={<Board />} />
|
<Route path='/p/subscriptions/:timeFilterName?/settings' element={<Board />} />
|
||||||
<Route path='/p/subscriptions/catalog' element={<Catalog />} />
|
<Route path='/p/subscriptions/catalog/:timeFilterName?' element={<Catalog />} />
|
||||||
<Route path='/p/subscriptions/catalog/settings' element={<Catalog />} />
|
<Route path='/p/subscriptions/catalog/:timeFilterName?/settings' element={<Catalog />} />
|
||||||
|
|
||||||
<Route path='/profile/:accountCommentIndex' element={<PendingPost />} />
|
<Route path='/profile/:accountCommentIndex' element={<PendingPost />} />
|
||||||
<Route path='/profile/:accountCommentIndex/settings' element={<PendingPost />} />
|
<Route path='/profile/:accountCommentIndex/settings' element={<PendingPost />} />
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link, useLocation, useParams } from 'react-router-dom';
|
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||||
import { useAccountComment, useSubscribe } from '@plebbit/plebbit-react-hooks';
|
import { useAccountComment, useSubscribe } from '@plebbit/plebbit-react-hooks';
|
||||||
import { isAllView, isCatalogView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
import { isAllView, isCatalogView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||||
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
||||||
import useSortingStore from '../../stores/use-sorting-store';
|
import useSortingStore from '../../stores/use-sorting-store';
|
||||||
|
import useTimeFilter from '../../hooks/use-time-filter';
|
||||||
import styles from './board-buttons.module.css';
|
import styles from './board-buttons.module.css';
|
||||||
|
|
||||||
interface BoardButtonsProps {
|
interface BoardButtonsProps {
|
||||||
@@ -55,6 +56,7 @@ const RefreshButton = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SortOptions = () => {
|
const SortOptions = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { sortType, setSortType } = useSortingStore();
|
const { sortType, setSortType } = useSortingStore();
|
||||||
|
|
||||||
const handleSortChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
const handleSortChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
@@ -63,21 +65,54 @@ const SortOptions = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
Sort by:
|
{t('sort_by')}:
|
||||||
<select value={sortType} onChange={handleSortChange}>
|
<select value={sortType} onChange={handleSortChange}>
|
||||||
<option value='active'>Bump order</option>
|
<option value='active'>{t('bump_order')}</option>
|
||||||
<option value='new'>Creation date</option>
|
<option value='new'>{t('creation_date')}</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TimeFilter = ({ isInCatalogView, isTopbar = false }: { isInCatalogView: boolean; isTopbar?: boolean }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const params = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { timeFilterNames } = useTimeFilter();
|
||||||
|
const selectedTimeFilterName = params.timeFilterName;
|
||||||
|
|
||||||
|
const changeTimeFilter = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
const timeFilterName = event.target.value;
|
||||||
|
const link = isInCatalogView ? `/p/all/catalog/${timeFilterName}` : `/p/all/${timeFilterName}`;
|
||||||
|
navigate(link);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{!isTopbar ? (
|
||||||
|
<>
|
||||||
|
<span className='capitalize'>{t('time_filter')}</span>:
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<> </>
|
||||||
|
)}
|
||||||
|
<select onChange={changeTimeFilter} className={[styles.feedName, styles.menuItem].join(' ')} value={selectedTimeFilterName}>
|
||||||
|
{timeFilterNames.map((timeFilterName, i) => (
|
||||||
|
<option key={timeFilterName + i} value={timeFilterName}>
|
||||||
|
{timeFilterName}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const MobileBoardButtons = () => {
|
export const MobileBoardButtons = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isInAllView = isAllView(location.pathname);
|
const isInAllView = isAllView(location.pathname);
|
||||||
const isInCatalogView = isCatalogView(location.pathname);
|
const isInCatalogView = isCatalogView(location.pathname, params);
|
||||||
const isInPendingPostPage = isPendingPostView(location.pathname, params);
|
const isInPendingPostPage = isPendingPostView(location.pathname, params);
|
||||||
const isInPostView = isPostPageView(location.pathname, params);
|
const isInPostView = isPostPageView(location.pathname, params);
|
||||||
const isInSubscriptionsView = isSubscriptionsView(location.pathname);
|
const isInSubscriptionsView = isSubscriptionsView(location.pathname);
|
||||||
@@ -106,10 +141,20 @@ export const MobileBoardButtons = () => {
|
|||||||
<>
|
<>
|
||||||
<hr />
|
<hr />
|
||||||
<div className={styles.options}>
|
<div className={styles.options}>
|
||||||
|
<TimeFilter isInCatalogView={true} />
|
||||||
|
|
||||||
<SortOptions />
|
<SortOptions />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{(isInAllView || isInSubscriptionsView) && !isInCatalogView && (
|
||||||
|
<>
|
||||||
|
<hr />
|
||||||
|
<div className={styles.options}>
|
||||||
|
<TimeFilter isInCatalogView={false} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -121,7 +166,7 @@ export const DesktopBoardButtons = () => {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||||
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
||||||
const isInCatalogView = isCatalogView(location.pathname);
|
const isInCatalogView = isCatalogView(location.pathname, params);
|
||||||
const isInAllView = isAllView(location.pathname);
|
const isInAllView = isAllView(location.pathname);
|
||||||
const isInPendingPostPage = isPendingPostView(location.pathname, params);
|
const isInPendingPostPage = isPendingPostView(location.pathname, params);
|
||||||
const isInPostView = isPostPageView(location.pathname, params);
|
const isInPostView = isPostPageView(location.pathname, params);
|
||||||
@@ -166,6 +211,11 @@ export const DesktopBoardButtons = () => {
|
|||||||
<SubscribeButton address={subplebbitAddress} />]
|
<SubscribeButton address={subplebbitAddress} />]
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{(isInAllView || isInSubscriptionsView) && (
|
||||||
|
<>
|
||||||
|
<TimeFilter isInCatalogView={isInCatalogView} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export { MobileBoardButtons, DesktopBoardButtons } from './board-buttons';
|
export { TimeFilter, MobileBoardButtons, DesktopBoardButtons } from './board-buttons';
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const BoardHeader = () => {
|
|||||||
|
|
||||||
const multisubMetadata = useMultisubMetadata();
|
const multisubMetadata = useMultisubMetadata();
|
||||||
|
|
||||||
const title = isInAllView ? multisubMetadata?.title : isInSubscriptionsView ? 'Subscriptions' : subplebbit?.title;
|
const title = isInAllView ? multisubMetadata?.title || 'all' : isInSubscriptionsView ? 'Subscriptions' : subplebbit?.title;
|
||||||
const subtitle = isInAllView ? 'p/all' : isInSubscriptionsView ? 'p/subscriptions' : `p/${address}`;
|
const subtitle = isInAllView ? 'p/all' : isInSubscriptionsView ? 'p/subscriptions' : `p/${address}`;
|
||||||
|
|
||||||
const isBoardOffline = subplebbit?.updatedAt && subplebbit.updatedAt < Date.now() / 1000 - 60 * 60;
|
const isBoardOffline = subplebbit?.updatedAt && subplebbit.updatedAt < Date.now() / 1000 - 60 * 60;
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ const PostMenuDesktop = ({ post }: { post: Comment }) => {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const isInAllView = isAllView(location.pathname);
|
const isInAllView = isAllView(location.pathname);
|
||||||
const isInCatalogView = isCatalogView(location.pathname);
|
const isInCatalogView = isCatalogView(location.pathname, params);
|
||||||
const isInPostPageView = isPostPageView(location.pathname, params);
|
const isInPostPageView = isPostPageView(location.pathname, params);
|
||||||
const isInSubscriptionsView = isSubscriptionsView(location.pathname);
|
const isInSubscriptionsView = isSubscriptionsView(location.pathname);
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { isAllView, isCatalogView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
import { isAllView, isCatalogView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||||
import styles from './topbar.module.css';
|
import styles from './topbar.module.css';
|
||||||
|
import useTimeFilter from '../../hooks/use-time-filter';
|
||||||
import useDefaultSubplebbits, { categorizeSubplebbits, useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
import useDefaultSubplebbits, { categorizeSubplebbits, useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
||||||
import _, { debounce } from 'lodash';
|
import _, { debounce } from 'lodash';
|
||||||
|
import { TimeFilter } from '../board-buttons';
|
||||||
|
|
||||||
const SearchBar = ({ setShowSearchBar }: { setShowSearchBar: (show: boolean) => void }) => {
|
const SearchBar = ({ setShowSearchBar }: { setShowSearchBar: (show: boolean) => void }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -55,7 +57,8 @@ const SearchBar = ({ setShowSearchBar }: { setShowSearchBar: (show: boolean) =>
|
|||||||
const TopBarDesktop = () => {
|
const TopBarDesktop = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isInCatalogView = isCatalogView(location.pathname);
|
const params = useParams();
|
||||||
|
const isInCatalogView = isCatalogView(location.pathname, params);
|
||||||
const subplebbits = useDefaultSubplebbits();
|
const subplebbits = useDefaultSubplebbits();
|
||||||
const [showSearchBar, setShowSearchBar] = useState(false);
|
const [showSearchBar, setShowSearchBar] = useState(false);
|
||||||
|
|
||||||
@@ -74,8 +77,13 @@ const TopBarDesktop = () => {
|
|||||||
return (
|
return (
|
||||||
<div className={styles.boardNavDesktop}>
|
<div className={styles.boardNavDesktop}>
|
||||||
<span className={styles.boardList}>
|
<span className={styles.boardList}>
|
||||||
[<Link to='/p/all'>all</Link> / <Link to='/p/subscriptions'>subscriptions</Link>] [{renderSubplebbits(plebbitSubs)}] [{renderSubplebbits(projectsSubs)}] [
|
[<Link to='/p/all'>all</Link> / <Link to='/p/subscriptions'>subscriptions</Link>]{' '}
|
||||||
{renderSubplebbits(interestsSubs)}] [{renderSubplebbits(randomSubs)}] [{renderSubplebbits(internationalSubs)}]
|
{subplebbits && (
|
||||||
|
<>
|
||||||
|
[{renderSubplebbits(plebbitSubs)}] [{renderSubplebbits(projectsSubs)}] [{renderSubplebbits(interestsSubs)}] [{renderSubplebbits(randomSubs)}] [
|
||||||
|
{renderSubplebbits(internationalSubs)}]
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className={styles.navTopRight}>
|
<span className={styles.navTopRight}>
|
||||||
[<Link to={!location.pathname.endsWith('settings') ? location.pathname.replace(/\/$/, '') + '/settings' : location.pathname}>{t('settings')}</Link>] [
|
[<Link to={!location.pathname.endsWith('settings') ? location.pathname.replace(/\/$/, '') + '/settings' : location.pathname}>{t('settings')}</Link>] [
|
||||||
@@ -96,8 +104,9 @@ const TopBarMobile = ({ subplebbitAddress }: { subplebbitAddress: string }) => {
|
|||||||
const currentSubplebbitIsInList = subplebbitAddresses.some((address: string) => address === subplebbitAddress);
|
const currentSubplebbitIsInList = subplebbitAddresses.some((address: string) => address === subplebbitAddress);
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const params = useParams();
|
||||||
const isInAllView = isAllView(location.pathname);
|
const isInAllView = isAllView(location.pathname);
|
||||||
const isInCatalogView = isCatalogView(location.pathname);
|
const isInCatalogView = isCatalogView(location.pathname, params);
|
||||||
const isInSubscriptionsView = isSubscriptionsView(location.pathname);
|
const isInSubscriptionsView = isSubscriptionsView(location.pathname);
|
||||||
const selectValue = isInAllView ? 'all' : isInSubscriptionsView ? 'subscriptions' : subplebbitAddress;
|
const selectValue = isInAllView ? 'all' : isInSubscriptionsView ? 'subscriptions' : subplebbitAddress;
|
||||||
|
|
||||||
@@ -140,6 +149,7 @@ const TopBarMobile = ({ subplebbitAddress }: { subplebbitAddress: string }) => {
|
|||||||
<div className={styles.boardSelect}>
|
<div className={styles.boardSelect}>
|
||||||
<strong>{t('board')}</strong>
|
<strong>{t('board')}</strong>
|
||||||
{boardSelect}
|
{boardSelect}
|
||||||
|
<TimeFilter isTopbar={true} isInCatalogView={isInCatalogView} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.pageJump}>
|
<div className={styles.pageJump}>
|
||||||
<Link to={useLocation().pathname.replace(/\/$/, '') + '/settings'}>{t('settings')}</Link>
|
<Link to={useLocation().pathname.replace(/\/$/, '') + '/settings'}>{t('settings')}</Link>
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import assert from 'assert';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
// the timestamp the last time the user visited
|
||||||
|
const lastVisitTimestamp = localStorage.getItem('plebchanLastVisitTimestamp');
|
||||||
|
|
||||||
|
// update the last visited timestamp every n seconds
|
||||||
|
setInterval(() => {
|
||||||
|
localStorage.setItem('plebchanLastVisitTimestamp', Date.now());
|
||||||
|
}, 60 * 1000);
|
||||||
|
|
||||||
|
const timeFilterNamesToSeconds = {
|
||||||
|
'1h': 60 * 60,
|
||||||
|
'12h': 60 * 60 * 12,
|
||||||
|
'24h': 60 * 60 * 24,
|
||||||
|
'48h': 60 * 60 * 24 * 2,
|
||||||
|
week: 60 * 60 * 24 * 7,
|
||||||
|
month: 60 * 60 * 24 * 30,
|
||||||
|
year: 60 * 60 * 24 * 365,
|
||||||
|
all: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
// calculate the last visit timeFilterNamesToSeconds
|
||||||
|
const secondsSinceLastVisit = lastVisitTimestamp ? (Date.now() - lastVisitTimestamp) / 1000 : Infinity;
|
||||||
|
const day = 24 * 60 * 60;
|
||||||
|
let lastVisitTimeFilterName;
|
||||||
|
if (secondsSinceLastVisit > 30 * day) {
|
||||||
|
lastVisitTimeFilterName = 'month';
|
||||||
|
timeFilterNamesToSeconds[lastVisitTimeFilterName] = timeFilterNamesToSeconds['month'];
|
||||||
|
} else if (secondsSinceLastVisit > 7 * day) {
|
||||||
|
const weeks = Math.ceil(secondsSinceLastVisit / day / 7);
|
||||||
|
lastVisitTimeFilterName = `${weeks}w`;
|
||||||
|
timeFilterNamesToSeconds[lastVisitTimeFilterName] = 60 * 60 * 24 * 7 * weeks;
|
||||||
|
} else if (secondsSinceLastVisit > day) {
|
||||||
|
const days = Math.ceil(secondsSinceLastVisit / day);
|
||||||
|
lastVisitTimeFilterName = `${days}d`;
|
||||||
|
timeFilterNamesToSeconds[lastVisitTimeFilterName] = 60 * 60 * 24 * days;
|
||||||
|
} else {
|
||||||
|
lastVisitTimeFilterName = '24h';
|
||||||
|
timeFilterNamesToSeconds[lastVisitTimeFilterName] = timeFilterNamesToSeconds['24h'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeFilterNames = [lastVisitTimeFilterName, '1h', '12h', '24h', '48h', 'week', 'month', 'year', 'all'];
|
||||||
|
|
||||||
|
const useTimeFilter = () => {
|
||||||
|
const params = useParams();
|
||||||
|
let timeFilterName = params.timeFilterName;
|
||||||
|
|
||||||
|
// the default time filter is the last visit time filter
|
||||||
|
if (!timeFilterName) {
|
||||||
|
timeFilterName = lastVisitTimeFilterName;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!timeFilterName || typeof timeFilterName === 'string', `useTimeFilter timeFilterName argument '${timeFilterName}' not a string`);
|
||||||
|
const timeFilterSeconds = timeFilterNamesToSeconds[timeFilterName];
|
||||||
|
assert(!timeFilterName || timeFilterName === 'all' || timeFilterSeconds !== undefined, `useTimeFilter no filter for timeFilterName '${timeFilterName}'`);
|
||||||
|
return { timeFilterSeconds, timeFilterNames };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useTimeFilter;
|
||||||
@@ -2,6 +2,7 @@ export type ParamsType = {
|
|||||||
accountCommentIndex?: string;
|
accountCommentIndex?: string;
|
||||||
commentCid?: string;
|
commentCid?: string;
|
||||||
subplebbitAddress?: string;
|
subplebbitAddress?: string;
|
||||||
|
timeFilterName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isAllView = (pathname: string): boolean => {
|
export const isAllView = (pathname: string): boolean => {
|
||||||
@@ -14,8 +15,17 @@ export const isBoardView = (pathname: string, params: ParamsType): boolean => {
|
|||||||
return params.subplebbitAddress ? decodedPathname.startsWith(`/p/${params.subplebbitAddress}`) : false;
|
return params.subplebbitAddress ? decodedPathname.startsWith(`/p/${params.subplebbitAddress}`) : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isCatalogView = (pathname: string): boolean => {
|
export const isCatalogView = (pathname: string, params: ParamsType): boolean => {
|
||||||
return pathname.endsWith('/catalog') || pathname.endsWith('/catalog/settings');
|
const { subplebbitAddress, timeFilterName } = params;
|
||||||
|
const decodedPathname = decodeURIComponent(pathname);
|
||||||
|
|
||||||
|
return (
|
||||||
|
decodedPathname === `/p/${subplebbitAddress}/catalog` ||
|
||||||
|
decodedPathname === `/p/all/catalog` ||
|
||||||
|
decodedPathname === `/p/all/catalog/${timeFilterName}` ||
|
||||||
|
decodedPathname === `/p/subscriptions/catalog` ||
|
||||||
|
decodedPathname === `/p/subscriptions/catalog/${timeFilterName}`
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isDescriptionView = (pathname: string, params: ParamsType): boolean => {
|
export const isDescriptionView = (pathname: string, params: ParamsType): boolean => {
|
||||||
@@ -63,7 +73,7 @@ export const isNotFoundView = (pathname: string, params: ParamsType): boolean =>
|
|||||||
return (
|
return (
|
||||||
!isAllView(pathname) &&
|
!isAllView(pathname) &&
|
||||||
!isBoardView(pathname, params) &&
|
!isBoardView(pathname, params) &&
|
||||||
!isCatalogView(pathname) &&
|
!isCatalogView(pathname, params) &&
|
||||||
!isDescriptionView(pathname, params) &&
|
!isDescriptionView(pathname, params) &&
|
||||||
!isHomeView(pathname) &&
|
!isHomeView(pathname) &&
|
||||||
!isPendingPostView(pathname, params) &&
|
!isPendingPostView(pathname, params) &&
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
|||||||
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
||||||
import useFeedStateString from '../../hooks/use-feed-state-string';
|
import useFeedStateString from '../../hooks/use-feed-state-string';
|
||||||
import useReplyModal from '../../hooks/use-reply-modal';
|
import useReplyModal from '../../hooks/use-reply-modal';
|
||||||
|
import useTimeFilter from '../../hooks/use-time-filter';
|
||||||
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
||||||
import useSortingStore from '../../stores/use-sorting-store';
|
import useSortingStore from '../../stores/use-sorting-store';
|
||||||
import LoadingEllipsis from '../../components/loading-ellipsis';
|
import LoadingEllipsis from '../../components/loading-ellipsis';
|
||||||
@@ -42,7 +43,8 @@ const Board = () => {
|
|||||||
}, [isInAllView, isInSubscriptionsView, subplebbitAddress, defaultSubplebbitAddresses, subscriptions]);
|
}, [isInAllView, isInSubscriptionsView, subplebbitAddress, defaultSubplebbitAddresses, subscriptions]);
|
||||||
|
|
||||||
const { sortType } = useSortingStore();
|
const { sortType } = useSortingStore();
|
||||||
const { feed, hasMore, loadMore, reset } = useFeed({ subplebbitAddresses, sortType });
|
const { timeFilterSeconds } = useTimeFilter();
|
||||||
|
const { feed, hasMore, loadMore, reset } = useFeed({ subplebbitAddresses, sortType, postsPerPage: 10, newerThan: timeFilterSeconds });
|
||||||
|
|
||||||
const setResetFunction = useFeedResetStore((state) => state.setResetFunction);
|
const setResetFunction = useFeedResetStore((state) => state.setResetFunction);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -91,15 +93,15 @@ const Board = () => {
|
|||||||
const setLastVirtuosoState = () => {
|
const setLastVirtuosoState = () => {
|
||||||
virtuosoRef.current?.getState((snapshot: StateSnapshot) => {
|
virtuosoRef.current?.getState((snapshot: StateSnapshot) => {
|
||||||
if (snapshot?.ranges?.length) {
|
if (snapshot?.ranges?.length) {
|
||||||
lastVirtuosoStates[location.pathname] = snapshot;
|
lastVirtuosoStates[sortType + timeFilterSeconds] = snapshot;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
window.addEventListener('scroll', setLastVirtuosoState);
|
window.addEventListener('scroll', setLastVirtuosoState);
|
||||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||||
}, [location.pathname]);
|
}, [sortType, timeFilterSeconds]);
|
||||||
|
|
||||||
const lastVirtuosoState = lastVirtuosoStates?.[location.pathname];
|
const lastVirtuosoState = lastVirtuosoStates?.[sortType + timeFilterSeconds];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = title ? title : shortAddress || subplebbitAddress;
|
document.title = title ? title : shortAddress || subplebbitAddress;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
|||||||
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
||||||
import useFeedStateString from '../../hooks/use-feed-state-string';
|
import useFeedStateString from '../../hooks/use-feed-state-string';
|
||||||
import { useMultisubMetadata } from '../../hooks/use-default-subplebbits';
|
import { useMultisubMetadata } from '../../hooks/use-default-subplebbits';
|
||||||
|
import useTimeFilter from '../../hooks/use-time-filter';
|
||||||
import useWindowWidth from '../../hooks/use-window-width';
|
import useWindowWidth from '../../hooks/use-window-width';
|
||||||
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
||||||
import useSortingStore from '../../stores/use-sorting-store';
|
import useSortingStore from '../../stores/use-sorting-store';
|
||||||
@@ -104,7 +105,8 @@ const Catalog = () => {
|
|||||||
const postsPerPage = useMemo(() => (columnCount <= 2 ? 10 : columnCount === 3 ? 15 : columnCount === 4 ? 20 : 25), []);
|
const postsPerPage = useMemo(() => (columnCount <= 2 ? 10 : columnCount === 3 ? 15 : columnCount === 4 ? 20 : 25), []);
|
||||||
|
|
||||||
const { sortType } = useSortingStore();
|
const { sortType } = useSortingStore();
|
||||||
const { feed, hasMore, loadMore, reset } = useFeed({ subplebbitAddresses, sortType, postsPerPage });
|
const { timeFilterSeconds } = useTimeFilter();
|
||||||
|
const { feed, hasMore, loadMore, reset } = useFeed({ subplebbitAddresses, sortType, postsPerPage, newerThan: timeFilterSeconds });
|
||||||
|
|
||||||
const setResetFunction = useFeedResetStore((state) => state.setResetFunction);
|
const setResetFunction = useFeedResetStore((state) => state.setResetFunction);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -147,14 +149,14 @@ const Catalog = () => {
|
|||||||
const setLastVirtuosoState = () =>
|
const setLastVirtuosoState = () =>
|
||||||
virtuosoRef.current?.getState((snapshot: StateSnapshot) => {
|
virtuosoRef.current?.getState((snapshot: StateSnapshot) => {
|
||||||
if (snapshot?.ranges?.length) {
|
if (snapshot?.ranges?.length) {
|
||||||
lastVirtuosoStates[location.pathname] = snapshot;
|
lastVirtuosoStates[sortType + timeFilterSeconds + 'catalog'] = snapshot;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
window.addEventListener('scroll', setLastVirtuosoState);
|
window.addEventListener('scroll', setLastVirtuosoState);
|
||||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||||
}, [location.pathname]);
|
}, [sortType, timeFilterSeconds]);
|
||||||
|
|
||||||
const lastVirtuosoState = lastVirtuosoStates?.[location.pathname];
|
const lastVirtuosoState = lastVirtuosoStates?.[sortType + timeFilterSeconds + 'catalog'];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let documentTitle = title ? title : shortAddress;
|
let documentTitle = title ? title : shortAddress;
|
||||||
|
|||||||
Reference in New Issue
Block a user