diff --git a/src/app.tsx b/src/app.tsx
index 5d97983f..153e0782 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
-import { Outlet, Route, Routes, useParams } from 'react-router-dom';
+import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom';
import useTheme from './hooks/use-theme';
import useTimeFilter from './hooks/use-time-filter';
import styles from './app.module.css';
@@ -23,6 +23,7 @@ import ChallengeModal from './components/challenge-modal';
import Header from './components/header';
import StickyHeader from './components/sticky-header';
import TopBar from './components/topbar';
+import { isAboutView } from './lib/utils/view-utils';
export const sortTypes = ['hot', 'new', 'active', 'controversialAll', 'topAll'];
@@ -31,10 +32,16 @@ const CheckRouteParams = () => {
const { timeFilterNames, lastVisitTimeFilterName } = useTimeFilter();
const isValidAccountCommentIndex = !accountCommentIndex || (!isNaN(parseInt(accountCommentIndex)) && parseInt(accountCommentIndex) >= 0);
const isSortTypeValid = !sortType || sortTypes.includes(sortType);
- const isTimeFilterNameValid = !timeFilterName || timeFilterNames.includes(timeFilterName as any) || timeFilterName === lastVisitTimeFilterName;
- const isAccountCommentIndexValid = !accountCommentIndex || !isNaN(parseInt(accountCommentIndex));
- if (!isValidAccountCommentIndex || !isSortTypeValid || !isTimeFilterNameValid || !isAccountCommentIndexValid) {
+ const isDynamicTimeFilter = (filter: string) => /^\d+[dwmy]$/.test(filter);
+ const isTimeFilterNameValid =
+ !timeFilterName || timeFilterNames.includes(timeFilterName as any) || timeFilterName === lastVisitTimeFilterName || isDynamicTimeFilter(timeFilterName);
+
+ const isAccountCommentIndexValid = !accountCommentIndex || !isNaN(parseInt(accountCommentIndex));
+ const location = useLocation();
+ const isInAboutView = isAboutView(location.pathname);
+
+ if (!isValidAccountCommentIndex || (!isSortTypeValid && !isInAboutView) || !isTimeFilterNameValid || !isAccountCommentIndexValid) {
return ;
}
@@ -77,32 +84,9 @@ const App = () => {
-
- }>
- } />
-
- } />
-
- } />
-
- } />
-
- }>
- } />
- } />
- } />
- } />
- } />
- } />
-
-
- } />
- } />
- } />
-
-
} />
+ } />
} />
} />
@@ -141,6 +125,30 @@ const App = () => {
} />
+
+ }>
+ } />
+
+ } />
+
+ } />
+
+ } />
+
+ }>
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+ } />
+ } />
+ } />
+
+
diff --git a/src/components/header/header.tsx b/src/components/header/header.tsx
index e11b1261..4ef73612 100644
--- a/src/components/header/header.tsx
+++ b/src/components/header/header.tsx
@@ -254,7 +254,7 @@ const HeaderTabs = () => {
const isInAllView = isAllView(location.pathname);
const isInAuthorView = isAuthorView(location.pathname);
const isInHomeSidebarView = isHomeSidebarView(location.pathname);
- const isInHomeView = isHomeView(location.pathname, params);
+ const isInHomeView = isHomeView(location.pathname);
const isInInboxView = isInboxView(location.pathname);
const isInPendingView = isPendingView(location.pathname, params);
const isInPostView = isPostView(location.pathname, params);
@@ -359,7 +359,7 @@ const Header = () => {
const isInAllSidebarView = isAllSidebarView(location.pathname);
const isInAllView = isAllView(location.pathname);
const isInAuthorView = isAuthorView(location.pathname);
- const isInHomeView = isHomeView(location.pathname, params);
+ const isInHomeView = isHomeView(location.pathname);
const isInHomeSidebarView = isHomeSidebarView(location.pathname);
const isInInboxView = isInboxView(location.pathname);
const isInPostView = isPostView(location.pathname, params);
diff --git a/src/components/sidebar/sidebar.tsx b/src/components/sidebar/sidebar.tsx
index 8153d659..73d9dee1 100644
--- a/src/components/sidebar/sidebar.tsx
+++ b/src/components/sidebar/sidebar.tsx
@@ -159,7 +159,7 @@ const Sidebar = ({ comment, isSubCreatedButNotYetPublished, settings, subplebbit
const isInAllView = isAllView(location.pathname);
const isInHomeSidebarView = isHomeSidebarView(location.pathname);
const isInAboutView = isAboutView(location.pathname);
- const isInHomeView = isHomeView(location.pathname, params);
+ const isInHomeView = isHomeView(location.pathname);
const isInPendingView = isPendingView(location.pathname, params);
const isInPostView = isPostView(location.pathname, params);
const isInSubplebbitsView = isSubplebbitsView(location.pathname);
diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx
index e4cda04f..882a8743 100644
--- a/src/components/topbar/topbar.tsx
+++ b/src/components/topbar/topbar.tsx
@@ -19,7 +19,7 @@ const TopBar = () => {
const params = useParams();
const subscriptions = account?.subscriptions;
const isinAllView = isAllView(location.pathname);
- const isInHomeView = isHomeView(location.pathname, params);
+ const isInHomeView = isHomeView(location.pathname);
const isInSubplebbitView = isSubplebbitView(location.pathname, params);
const homeButtonClass = isInHomeView ? styles.selected : styles.choice;
@@ -93,14 +93,6 @@ const TopBar = () => {
};
}, [handleClickOutside]);
- let homeLink = '/';
- let allLink = '/p/all';
-
- if (timeFilterName && !isInSubplebbitView) {
- homeLink += `${selectedSortType}/${timeFilterName}`;
- allLink += `/${selectedSortType}/${timeFilterName}`;
- }
-
const isConnectedToRpc = !!account?.plebbitOptions.plebbitRpcClientsOptions;
const navigate = useNavigate();
const handleCreateCommunity = () => {
@@ -162,7 +154,7 @@ const TopBar = () => {
{selectedTimeFilter}
- {timeFilterNames.map((timeFilterName, index) => (
+ {timeFilterNames.slice(0, -1).map((timeFilterName, index) => (
{timeFilterNames[index]}
@@ -172,13 +164,13 @@ const TopBar = () => {
-
-
+
{t('home')}
-
-
-
+
{t('all')}
diff --git a/src/hooks/use-redirect-to-default-sort.ts b/src/hooks/use-redirect-to-default-sort.ts
new file mode 100644
index 00000000..c0acb70e
--- /dev/null
+++ b/src/hooks/use-redirect-to-default-sort.ts
@@ -0,0 +1,22 @@
+import { useEffect } from 'react';
+import { useLocation, useNavigate } from 'react-router-dom';
+
+const DEFAULT_SORT = 'hot';
+
+const useRedirectToDefaultSort = () => {
+ const location = useLocation();
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ const path = location.pathname;
+ const parts = path.split('/').filter(Boolean);
+
+ // If we're at the root or the path doesn't start with a sort type
+ if (path === '/' || (parts.length > 0 && !['hot', 'new', 'active', 'controversialAll', 'topAll'].includes(parts[0]))) {
+ const newPath = path === '/' ? `/${DEFAULT_SORT}` : `/${DEFAULT_SORT}${path}`;
+ navigate(newPath, { replace: true });
+ }
+ }, [location.pathname, navigate]);
+};
+
+export default useRedirectToDefaultSort;
diff --git a/src/hooks/use-time-filter.ts b/src/hooks/use-time-filter.ts
index d328c9e4..0fbe709a 100644
--- a/src/hooks/use-time-filter.ts
+++ b/src/hooks/use-time-filter.ts
@@ -49,16 +49,45 @@ const useTimeFilter = () => {
let timeFilterName = params.timeFilterName;
// the default time filter is the last visit time filter
if (!timeFilterName) {
- if (isInSubplebbitView) {
- timeFilterName = 'all';
- } else {
- timeFilterName = lastVisitTimeFilterName;
+ timeFilterName = isInSubplebbitView ? 'all' : lastVisitTimeFilterName;
+ }
+
+ let timeFilterSeconds: number | undefined;
+
+ if (timeFilterName === 'all') {
+ timeFilterSeconds = undefined;
+ } else if (timeFilterName && timeFilterName in timeFilterNamesToSeconds) {
+ timeFilterSeconds = timeFilterNamesToSeconds[timeFilterName as keyof typeof timeFilterNamesToSeconds];
+ } else if (timeFilterName) {
+ // Handle dynamic time filters (e.g., "3d", "2w")
+ const match = timeFilterName.match(/^(\d+)([dwmy])$/);
+ if (match) {
+ const [, value, unit] = match;
+ const numValue = parseInt(value, 10);
+ switch (unit) {
+ case 'd':
+ timeFilterSeconds = numValue * 24 * 60 * 60;
+ break;
+ case 'w':
+ timeFilterSeconds = numValue * 7 * 24 * 60 * 60;
+ break;
+ case 'm':
+ timeFilterSeconds = numValue * 30 * 24 * 60 * 60;
+ break;
+ case 'y':
+ timeFilterSeconds = numValue * 365 * 24 * 60 * 60;
+ break;
+ }
}
}
- assert(!timeFilterName || typeof timeFilterName === 'string', `useTimeFilter timeFilterName argument '${timeFilterName}' not a string`);
- const timeFilterSeconds = timeFilterNamesToSeconds[timeFilterName as keyof typeof timeFilterNamesToSeconds];
- assert(!timeFilterName || timeFilterName === 'all' || timeFilterSeconds !== undefined, `useTimeFilter no filter for timeFilterName '${timeFilterName}'`);
+ // If we still don't have a valid timeFilterSeconds, use the default (24h)
+ if (timeFilterSeconds === undefined && timeFilterName !== 'all') {
+ timeFilterSeconds = timeFilterNamesToSeconds['24h'];
+ }
+
+ assert(timeFilterName === 'all' || timeFilterSeconds !== undefined, `useTimeFilter no filter for timeFilterName '${timeFilterName}'`);
+
return { timeFilterSeconds, timeFilterNames, timeFilterName, lastVisitTimeFilterName };
};
diff --git a/src/lib/utils/view-utils.ts b/src/lib/utils/view-utils.ts
index 30595954..34d0e3ac 100644
--- a/src/lib/utils/view-utils.ts
+++ b/src/lib/utils/view-utils.ts
@@ -1,5 +1,3 @@
-import { timeFilterNames } from '../../hooks/use-time-filter';
-
export type ParamsType = {
accountCommentIndex?: string;
authorAddress?: string;
@@ -32,7 +30,7 @@ export const getSidebarLink = (pathname: string, params: ParamsType): string =>
};
export const isAboutView = (pathname: string): boolean => {
- return pathname === '/about';
+ return pathname.startsWith('/about');
};
export const isSidebarView = (pathname: string): boolean => {
@@ -63,8 +61,16 @@ export const isCreateSubplebbitView = (pathname: string): boolean => {
return pathname === '/communities/create';
};
-export const isHomeView = (pathname: string, params: ParamsType): boolean => {
- return pathname === '/' || sortTypes.includes(pathname) || (timeFilterNames.includes(params.timeFilterName || '') && !pathname.startsWith('/p/'));
+export const isHomeView = (pathname: string): boolean => {
+ if (pathname === '/') return true;
+
+ const pathParts = pathname.split('/');
+ if (pathParts.length >= 2) {
+ const potentialSortType = '/' + pathParts[1];
+ return sortTypes.includes(potentialSortType);
+ }
+
+ return false;
};
export const isHomeSidebarView = (pathname: string): boolean => {
diff --git a/src/views/home/home.tsx b/src/views/home/home.tsx
index c40df127..c04eac82 100644
--- a/src/views/home/home.tsx
+++ b/src/views/home/home.tsx
@@ -10,11 +10,13 @@ import Sidebar from '../../components/sidebar';
import { useDefaultAndSubscriptionsSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
import useFeedStateString from '../../hooks/use-feed-state-string';
import useTimeFilter from '../../hooks/use-time-filter';
+import useRedirectToDefaultSort from '../../hooks/use-redirect-to-default-sort';
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
const Home = () => {
const { t } = useTranslation();
+ useRedirectToDefaultSort();
const subplebbitAddresses = useDefaultAndSubscriptionsSubplebbitAddresses();
const params = useParams<{ sortType?: string; timeFilterName?: string }>();
const sortType = params?.sortType || 'hot';