feat(home): implement last visit time filter, automatically selected

This commit is contained in:
plebeius.eth
2024-01-21 11:53:22 +01:00
parent df82682f6c
commit 5f651fcffb
4 changed files with 38 additions and 14 deletions

View File

@@ -5,7 +5,7 @@ import { useAccount } from '@plebbit/plebbit-react-hooks';
import { getShortAddress } from '@plebbit/plebbit-js';
import styles from './topbar.module.css';
import { useDefaultSubplebbitAddresses } from '../../lib/utils/addresses-utils';
import useTimeFilter from '../../hooks/use-time-filter';
import useTimeFilter, { TimeFilterKey } from '../../hooks/use-time-filter';
import { isAllView, isHomeView, isSubplebbitView } from '../../lib/utils/view-utils';
const sortTypes = ['hot', 'new', 'active', 'controversialAll', 'topAll'];
@@ -16,14 +16,17 @@ const TopBar = () => {
const { t } = useTranslation();
const location = useLocation();
const params = useParams();
const { timeFilterNames } = useTimeFilter();
const subscriptions = account?.subscriptions;
const isinAllView = isAllView(location.pathname);
const isInHomeView = isHomeView(location.pathname, params);
const isInSubplebbitView = isSubplebbitView(location.pathname, params);
const homeButtonClass = isInHomeView ? styles.selected : styles.choice;
const selectedTimeFilterName = params.timeFilterName || (isInHomeView ? timeFilterNames[2] : timeFilterNames[5]);
const sortType = params?.sortType || 'hot';
const { timeFilterNames } = useTimeFilter();
const timeFilterName = params.timeFilterName as TimeFilterKey;
const { currentFilterName } = useTimeFilter(sortType, timeFilterName);
const selectedTimeFilter = isInSubplebbitView ? params.timeFilterName || 'all' : currentFilterName;
const [isSubsDropdownOpen, setIsSubsDropdownOpen] = useState(false);
const toggleSubsDropdown = () => setIsSubsDropdownOpen(!isSubsDropdownOpen);
@@ -133,7 +136,7 @@ const TopBar = () => {
</div>
</div>
<div className={styles.dropdown} ref={filterDropdownRef} onClick={toggleFilterDropdown}>
<span className={styles.selectedTitle}>{selectedTimeFilterName}</span>
<span className={styles.selectedTitle}>{selectedTimeFilter}</span>
<div className={`${styles.dropChoices} ${styles.filterDropChoices} ${filterDropdownClass}`} ref={filterDropdownChoicesRef}>
{timeFilterNames.map((choice, index) => (
<Link to={getTimeFilterLink(choice)} key={index} className={styles.dropdownChoice}>

View File

@@ -1,10 +1,16 @@
import assert from 'assert';
import { Comment } from '@plebbit/plebbit-react-hooks';
// Type Definitions
type TimeFilter = (comment: Comment) => boolean;
export type TimeFilterKey = '1h' | '24h' | '1w' | '1m' | '1y' | 'all';
type TimeFilters = { [key in TimeFilterKey]: TimeFilter | undefined };
export const timeFilterNames: TimeFilterKey[] = ['1h', '24h', '1w', '1m', '1y', 'all'];
interface TimeFilters {
[key: string]: TimeFilter | undefined;
}
// Time Filters
const timeFilters: TimeFilters = {
'1h': (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60,
'24h': (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24,
@@ -14,7 +20,16 @@ const timeFilters: TimeFilters = {
all: undefined,
};
const lastVisitTimestamp = Number(localStorage.getItem('seeditLastVisitTimestamp')) || Date.now();
// Last Visit Timestamp
const lastVisitTimestampString = localStorage.getItem('plebonesLastVisitTimestamp');
const lastVisitTimestamp = lastVisitTimestampString ? Number(lastVisitTimestampString) : Date.now();
// Update the last visited timestamp every n seconds
setInterval(() => {
localStorage.setItem('plebonesLastVisitTimestamp', Date.now().toString());
}, 60 * 1000);
// Calculate the Last Visit Filter
const secondsSinceLastVisit = (Date.now() - lastVisitTimestamp) / 1000;
const day = 24 * 60 * 60;
let lastVisitTimeFilterName: TimeFilterKey = '24h';
@@ -26,19 +41,25 @@ if (secondsSinceLastVisit > 30 * day) {
} else if (secondsSinceLastVisit > day) {
lastVisitTimeFilterName = '24h';
} else {
lastVisitTimeFilterName = '1h';
lastVisitTimeFilterName = '24h';
}
export const timeFilterNames: TimeFilterKey[] = ['1h', '24h', '1w', '1m', '1y', 'all'];
// useTimeFilter Function
const useTimeFilter = (
sortType?: string,
timeFilterName: TimeFilterKey = lastVisitTimeFilterName,
): { timeFilter: TimeFilter | undefined; timeFilterNames: TimeFilterKey[]; currentFilterName: TimeFilterKey } => {
// Default to the last visit time filter if no time filter name is provided
if (!timeFilterName) {
timeFilterName = lastVisitTimeFilterName;
}
const useTimeFilter = (sortType: string = 'hot', timeFilterName: TimeFilterKey = lastVisitTimeFilterName) => {
assert(typeof sortType === 'string', `useTimeFilter sortType argument '${sortType}' not a string`);
assert(!sortType || typeof sortType === 'string', `useTimeFilter sortType argument '${sortType}' not a string`);
assert(typeof timeFilterName === 'string', `useTimeFilter timeFilterName argument '${timeFilterName}' not a string`);
const timeFilter = timeFilters[timeFilterName];
assert(timeFilterName === 'all' || timeFilter !== undefined, `useTimeFilter no filter for timeFilterName '${timeFilterName}'`);
return { timeFilter, timeFilterNames };
return { timeFilter, timeFilterNames, currentFilterName: timeFilterName };
};
export default useTimeFilter;

View File

@@ -17,7 +17,7 @@ const All = () => {
const subplebbitAddresses = useDefaultSubplebbitAddresses();
const params = useParams<{ sortType?: string; timeFilterName?: string }>();
const sortType = params?.sortType || 'hot';
const timeFilterName = (params.timeFilterName as TimeFilterKey) || 'all';
const timeFilterName = params.timeFilterName as TimeFilterKey;
const { timeFilter } = useTimeFilter(sortType, timeFilterName);
const { feed, hasMore, loadMore } = useFeed({ subplebbitAddresses, sortType, filter: timeFilter });
const { t } = useTranslation();

View File

@@ -27,7 +27,7 @@ const Home = () => {
const params = useParams<{ sortType?: string; timeFilterName?: string }>();
const sortType = params?.sortType || 'hot';
const timeFilterName = (params.timeFilterName as TimeFilterKey) || '1w';
const timeFilterName = params.timeFilterName as TimeFilterKey;
const { timeFilter } = useTimeFilter(sortType, timeFilterName);
const { feed, hasMore, loadMore } = useFeed({