Skip to content

Commit

Permalink
feat(hooks): implement time filter for all views
Browse files Browse the repository at this point in the history
  • Loading branch information
estebanabaroa committed Jan 27, 2024
1 parent 4cd0c5e commit 91ffb79
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 47 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@capacitor/app": "1.1.1",
"@floating-ui/react": "0.24.8",
"@plebbit/plebbit-logger": "https://github.com/plebbit/plebbit-logger.git",
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#8293c15b666b6b57128d750410f3f6060dfdc6d4",
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#6b614e0bf6c304de7b184564198a0ce7b98bca1d",
"electron-context-menu": "3.3.0",
"electron-is-dev": "2.0.0",
"ext-name": "5.0.0",
Expand Down
54 changes: 21 additions & 33 deletions src/hooks/use-time-filter.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,60 @@
import assert from 'assert'
import {useParams} from 'react-router-dom'

// the timestamp the last time the user visited
const lastVisitTimestamp = localStorage.getItem('plebonesLastVisitTimestamp')

// TODO: remove debug, test setting some older date in console
// localStorage.setItem('plebonesLastVisitTimestamp', Date.now() - 20 * 24 * 60 * 60 * 1000)
console.log('lastVisitTimestamp', lastVisitTimestamp, ((Date.now() - lastVisitTimestamp) / (60 * 60 * 1000)).toFixed(2) + ' hours ago')

// update the last visited timestamp every n seconds
setInterval(() => {
localStorage.setItem('plebonesLastVisitTimestamp', Date.now())
}, 60 * 1000)

const timeFilters = {
'1h': (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60,
'12h': (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 12,
'24h': (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24,
'48h': (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24 * 2,
week: (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24 * 7,
month: (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24 * 30,
year: (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24 * 365,
'1h-active': (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60,
'12h-active': (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 12,
'24h-active': (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 24,
'48h-active': (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 24 * 2,
'week-active': (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 24 * 7,
'month-active': (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 24 * 30,
'year-active': (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 24 * 365,
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 filter
// 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'
timeFilters[lastVisitTimeFilterName] = timeFilters['month']
timeFilters[`${lastVisitTimeFilterName}-active`] = timeFilters['month-active']
timeFilterNamesToSeconds[lastVisitTimeFilterName] = timeFilterNamesToSeconds['month']
} else if (secondsSinceLastVisit > 7 * day) {
const weeks = Math.ceil(secondsSinceLastVisit / day / 7)
lastVisitTimeFilterName = `${weeks}w`
timeFilters[lastVisitTimeFilterName] = (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24 * 7 * weeks
timeFilters[`${lastVisitTimeFilterName}-active`] = (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 24 * 7 * weeks
timeFilterNamesToSeconds[lastVisitTimeFilterName] = 60 * 60 * 24 * 7 * weeks
} else if (secondsSinceLastVisit > day) {
const days = Math.ceil(secondsSinceLastVisit / day)
lastVisitTimeFilterName = `${days}d`
timeFilters[lastVisitTimeFilterName] = (comment) => comment.timestamp > Date.now() / 1000 - 60 * 60 * 24 * days
timeFilters[`${lastVisitTimeFilterName}-active`] = (comment) => (comment.lastReplyTimestamp || comment.timestamp) > Date.now() / 1000 - 60 * 60 * 24 * days
timeFilterNamesToSeconds[lastVisitTimeFilterName] = 60 * 60 * 24 * days
} else {
lastVisitTimeFilterName = '24h'
timeFilters[lastVisitTimeFilterName] = timeFilters['24h']
timeFilters[`${lastVisitTimeFilterName}-active`] = timeFilters['24h-active']
timeFilterNamesToSeconds[lastVisitTimeFilterName] = timeFilterNamesToSeconds['24h']
}

const timeFilterNames = [lastVisitTimeFilterName, '1h', '12h', '24h', '48h', 'week', 'month', 'year', 'all']

const useTimeFilter = (sortType, timeFilterName) => {
const useTimeFilter = () => {
const params = useParams()
let timeFilterName = params.timeFilterName

// the default time filter is the last visit time filter
if (!timeFilterName) {
timeFilterName = lastVisitTimeFilterName
}

assert(!sortType || typeof sortType === 'string', `useTimeFilter sortType argument '${sortType}' not a string`)
assert(!timeFilterName || typeof timeFilterName === 'string', `useTimeFilter timeFilterName argument '${timeFilterName}' not a string`)
const timeFilter = sortType === 'active' ? timeFilters[timeFilterName + '-active'] : timeFilters[timeFilterName]
assert(!timeFilterName || timeFilterName === 'all' || timeFilter !== undefined, `useTimeFilter no filter for timeFilterName '${timeFilterName}'`)
return {timeFilter, timeFilterNames}
const timeFilterSeconds = timeFilterNamesToSeconds[timeFilterName]
assert(!timeFilterName || timeFilterName === 'all' || timeFilterSeconds !== undefined, `useTimeFilter no filter for timeFilterName '${timeFilterName}'`)
return {timeFilterSeconds, timeFilterNames}
}

export default useTimeFilter
4 changes: 3 additions & 1 deletion src/views/catalog/catalog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {useParams} from 'react-router-dom'
import utils from '../../lib/utils'
import CatalogRow from '../../components/catalog-row'
import useFeedStateString from '../../hooks/use-feed-state-string'
import useTimeFilter from '../../hooks/use-time-filter'

const useFeedRows = (feed, columnCount) => {
const rowsRef = useRef()
Expand Down Expand Up @@ -39,10 +40,11 @@ function Catalog() {
const params = useParams()
const subplebbitAddresses = useDefaultSubplebbitAddresses()
const sortType = params?.sortType || 'active'
const {timeFilterSeconds} = useTimeFilter()
// postPerPage based on columnCount for optimized feed, dont change value after first render
// eslint-disable-next-line
const postsPerPage = useMemo(() => (columnCount <= 2 ? 10 : columnCount === 3 ? 15 : columnCount === 4 ? 20 : 25), [])
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage, filter: utils.catalogFilter})
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage, filter: utils.catalogFilter, newerThan: timeFilterSeconds})
const loadingStateString = useFeedStateString(subplebbitAddresses) || 'loading...'

// split feed into rows
Expand Down
11 changes: 5 additions & 6 deletions src/views/home/home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ function Home() {
const params = useParams()
const subplebbitAddresses = useDefaultSubplebbitAddresses()
const sortType = params?.sortType || 'hot'
const timeFilterName = params.timeFilterName
const {timeFilter} = useTimeFilter(sortType, timeFilterName)
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage: 10, filter: timeFilter})
const {timeFilterSeconds} = useTimeFilter()
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage: 10, newerThan: timeFilterSeconds})
const loadingStateString = useFeedStateString(subplebbitAddresses) || 'loading...'

let Footer
Expand All @@ -35,14 +34,14 @@ function Home() {
virtuosoRef.current?.getState((snapshot) => {
// TODO: not sure if checking for empty snapshot.ranges works for all scenarios
if (snapshot?.ranges?.length) {
lastVirtuosoStates[sortType + timeFilterName] = snapshot
lastVirtuosoStates[sortType + timeFilterSeconds] = snapshot
}
})
window.addEventListener('scroll', setLastVirtuosoState)
// clean listener on unmount
return () => window.removeEventListener('scroll', setLastVirtuosoState)
}, [sortType, timeFilterName])
const lastVirtuosoState = lastVirtuosoStates?.[sortType + timeFilterName]
}, [sortType, timeFilterSeconds])
const lastVirtuosoState = lastVirtuosoStates?.[sortType + timeFilterSeconds]

return (
<div>
Expand Down
4 changes: 3 additions & 1 deletion src/views/subplebbit-catalog/subplebbit-catalog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {useParams} from 'react-router-dom'
import utils from '../../lib/utils'
import CatalogRow from '../../components/catalog-row'
import useFeedStateString from '../../hooks/use-feed-state-string'
import useTimeFilter from '../../hooks/use-time-filter'

const useFeedRows = (feed, columnCount) => {
const rowsRef = useRef()
Expand Down Expand Up @@ -40,10 +41,11 @@ function Catalog() {
const subplebbitAddress = params.subplebbitAddress
const subplebbitAddresses = useMemo(() => [subplebbitAddress], [subplebbitAddress])
const sortType = params?.sortType || 'active'
const {timeFilterSeconds} = useTimeFilter()
// postPerPage based on columnCount for optimized feed, dont change value after first render
// eslint-disable-next-line
const postsPerPage = useMemo(() => (columnCount <= 2 ? 10 : columnCount === 3 ? 15 : columnCount === 4 ? 20 : 25), [])
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage, filter: utils.catalogFilter})
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage, filter: utils.catalogFilter, newerThan: timeFilterSeconds})
const loadingStateString = useFeedStateString(subplebbitAddresses) || 'loading...'

// split feed into rows
Expand Down
4 changes: 3 additions & 1 deletion src/views/subplebbit/subplebbit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {useParams} from 'react-router-dom'
import styles from './subplebbit.module.css'
import {Link} from 'react-router-dom'
import useFeedStateString from '../../hooks/use-feed-state-string'
import useTimeFilter from '../../hooks/use-time-filter'

const SubplebbitInfo = ({subplebbitAddress}) => {
const subplebbit = useSubplebbit({subplebbitAddress})
Expand Down Expand Up @@ -60,7 +61,8 @@ function Subplebbit() {
const subplebbitAddress = params.subplebbitAddress
const subplebbitAddresses = useMemo(() => [subplebbitAddress], [subplebbitAddress])
const sortType = params?.sortType || 'hot'
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType})
const {timeFilterSeconds} = useTimeFilter()
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, newerThan: timeFilterSeconds})
const loadingStateString = useFeedStateString(subplebbitAddresses) || 'loading...'

let Footer
Expand Down
4 changes: 3 additions & 1 deletion src/views/subscriptions-catalog/subscriptions-catalog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {useParams} from 'react-router-dom'
import utils from '../../lib/utils'
import CatalogRow from '../../components/catalog-row'
import useFeedStateString from '../../hooks/use-feed-state-string'
import useTimeFilter from '../../hooks/use-time-filter'

const useFeedRows = (feed, columnCount) => {
const rowsRef = useRef()
Expand Down Expand Up @@ -40,10 +41,11 @@ function Catalog() {
const account = useAccount()
const subplebbitAddresses = account?.subscriptions
const sortType = params?.sortType || 'active'
const {timeFilterSeconds} = useTimeFilter()
// postPerPage based on columnCount for optimized feed, dont change value after first render
// eslint-disable-next-line
const postsPerPage = useMemo(() => (columnCount <= 2 ? 10 : columnCount === 3 ? 15 : columnCount === 4 ? 20 : 25), [])
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage, filter: utils.catalogFilter})
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage, filter: utils.catalogFilter, newerThan: timeFilterSeconds})
const loadingStateString = useFeedStateString(subplebbitAddresses) || 'loading...'

// split feed into rows
Expand Down
4 changes: 3 additions & 1 deletion src/views/subscriptions/subscriptions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Virtuoso} from 'react-virtuoso'
import FeedPost from '../../components/feed-post'
import {useParams} from 'react-router-dom'
import useFeedStateString from '../../hooks/use-feed-state-string'
import useTimeFilter from '../../hooks/use-time-filter'

const lastVirtuosoStates = {}

Expand All @@ -15,7 +16,8 @@ function Subscriptions() {
const account = useAccount()
const subplebbitAddresses = account?.subscriptions
const sortType = params?.sortType || 'hot'
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage: 10})
const {timeFilterSeconds} = useTimeFilter()
const {feed, hasMore, loadMore} = useFeed({subplebbitAddresses, sortType, postsPerPage: 10, newerThan: timeFilterSeconds})
const loadingStateString = useFeedStateString(subplebbitAddresses) || 'loading...'

let Footer
Expand Down
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2764,9 +2764,9 @@
dependencies:
debug "4.3.3"

"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#8293c15b666b6b57128d750410f3f6060dfdc6d4":
"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#6b614e0bf6c304de7b184564198a0ce7b98bca1d":
version "0.0.1"
resolved "https://github.com/plebbit/plebbit-react-hooks.git#8293c15b666b6b57128d750410f3f6060dfdc6d4"
resolved "https://github.com/plebbit/plebbit-react-hooks.git#6b614e0bf6c304de7b184564198a0ce7b98bca1d"
dependencies:
"@plebbit/plebbit-js" "https://github.com/plebbit/plebbit-js.git#4a7ced7497fcbf863e9457b7e83a7bb2889bd518"
"@plebbit/plebbit-logger" "https://github.com/plebbit/plebbit-logger.git"
Expand Down

0 comments on commit 91ffb79

Please sign in to comment.