Stop re-parsing dates in isStatusStillActive
This runs per post, per render while scrolling, and showed up in the scroll profile as parseISO plus two Date objects. Date.parse returns NaN for an unparseable value and NaN > n is false, which is the same "not active" answer the date-fns version gave. Moved to liveNow/utils.ts alongside the other pure helpers so it can be tested without pulling in the feature's React and query imports. index.tsx already re-exports utils, so every existing import site is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,6 @@ import {moderateStatus} from '@bsky/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
import {isAfter, parseISO} from 'date-fns'
|
||||
|
||||
import {uploadBlob} from '#/lib/api'
|
||||
import {imageToThumb} from '#/lib/api/resolve'
|
||||
@@ -23,7 +22,11 @@ import {useTickEveryMinute} from '#/state/shell'
|
||||
import {useDialogContext} from '#/components/Dialog'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {getLiveNowHost, getLiveServiceNames} from '#/features/liveNow/utils'
|
||||
import {
|
||||
getLiveNowHost,
|
||||
getLiveServiceNames,
|
||||
isStatusStillActive,
|
||||
} from '#/features/liveNow/utils'
|
||||
import {app, com} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
@@ -151,14 +154,6 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) {
|
||||
}, [shadowed, config, tick, moderation])
|
||||
}
|
||||
|
||||
export function isStatusStillActive(timeStr: string | undefined) {
|
||||
if (!timeStr) return false
|
||||
const now = new Date()
|
||||
const expiry = parseISO(timeStr)
|
||||
|
||||
return isAfter(expiry, now)
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates whether the live status is valid for display in the app. Does NOT
|
||||
* validate if the status is valid for the acting user e.g. as they go live.
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import {isStatusStillActive} from '#/features/liveNow/utils'
|
||||
|
||||
describe('isStatusStillActive', () => {
|
||||
const iso = (offsetMs: number) =>
|
||||
new Date(Date.now() + offsetMs).toISOString()
|
||||
|
||||
it('is active for a future expiry', () => {
|
||||
expect(isStatusStillActive(iso(60_000))).toBe(true)
|
||||
})
|
||||
|
||||
it('is not active for a past expiry', () => {
|
||||
expect(isStatusStillActive(iso(-60_000))).toBe(false)
|
||||
})
|
||||
|
||||
it('is not active without a value', () => {
|
||||
expect(isStatusStillActive(undefined)).toBe(false)
|
||||
expect(isStatusStillActive('')).toBe(false)
|
||||
})
|
||||
|
||||
/*
|
||||
* The predicate reads an atproto `datetime`, which always carries an offset.
|
||||
* An unparseable value yields NaN, and every NaN comparison is false, so a
|
||||
* bad timestamp reads as "not live" rather than throwing or showing a stale
|
||||
* live badge.
|
||||
*/
|
||||
it('is not active for an unparseable value', () => {
|
||||
expect(isStatusStillActive('not-a-date')).toBe(false)
|
||||
})
|
||||
|
||||
it('handles offsets and fractional seconds', () => {
|
||||
const future = new Date(Date.now() + 3_600_000)
|
||||
expect(isStatusStillActive(future.toISOString())).toBe(true)
|
||||
expect(isStatusStillActive('2000-01-01T00:00:00.123+00:00')).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -97,3 +97,16 @@ export function getLiveNowHost(url: string) {
|
||||
const {hostname} = new URL(url)
|
||||
return sanitizeLiveNowHost(hostname)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a live status has not yet expired.
|
||||
*
|
||||
* Called per post, per render while scrolling, so this stays on primitives -
|
||||
* `parseISO` plus two `Date` objects showed up in the scroll profile.
|
||||
* `Date.parse` returns `NaN` for an unparseable value and `NaN > n` is `false`,
|
||||
* which is the same "not active" answer the date-fns version gave.
|
||||
*/
|
||||
export function isStatusStillActive(timeStr: string | undefined) {
|
||||
if (!timeStr) return false
|
||||
return Date.parse(timeStr) > Date.now()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user