Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions packages/common/src/hooks/purchaseContent/constants.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,5 +4,3 @@ export const AMOUNT_PRESET = 'amountPreset'
// Pay between $1 and $100 extra
export const minimumPayExtraAmountCents = 100
export const maximumPayExtraAmountCents = 10000

export const COOLDOWN_DAYS = 7
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,9 +5,9 @@ import {
UndisbursedUserChallenge,
audioRewardsPageSelectors
} from 'store/pages'
import { isCooldownChallengeClaimable } from 'utils/challenges'
import dayjs, { Dayjs } from 'utils/dayjs'

import { COOLDOWN_DAYS } from './constants'
import { utcToLocalTime } from 'utils/timeUtil'

const { getUndisbursedUserChallenges } = audioRewardsPageSelectors

Expand All@@ -27,40 +27,45 @@ export const useChallengeCooldownSchedule = (
const challenges = useSelector(getUndisbursedUserChallenges)
.filter((c) => c.challenge_id === challengeId)
.map((c) => ({ ...c, createdAtDate: dayjs.utc(c.created_at) }))
const now = dayjs.utc()
// Only challenges past the cooldown period are claimable
const claimableAmount = challenges
.filter((c) => now.diff(c.createdAtDate, 'day') >= COOLDOWN_DAYS)
.reduce((acc, curr) => acc + curr.amount, 0)
// Challenges are already ordered by completed_blocknumber ascending.
const cooldownChallenges = challenges.filter(
(c) => now.diff(c.createdAtDate, 'day') < COOLDOWN_DAYS
(c) => !isCooldownChallengeClaimable(c)
)
return { claimableAmount, cooldownChallenges }
const claimableAmount = challenges
.filter(isCooldownChallengeClaimable)
Comment thread
dharit-tan marked this conversation as resolved.
.reduce((acc, curr) => acc + curr.amount, 0)
return { cooldownChallenges, claimableAmount }
}

const getAudioMatchingCooldownLabel = (now: Dayjs, created_at: Dayjs) => {
const diff = now.diff(created_at, 'day')
if (diff === COOLDOWN_DAYS) {
const getAudioMatchingCooldownLabel = (
challenge: UndisbursedUserChallenge,
now: Dayjs
) => {
const createdAt = utcToLocalTime(challenge.created_at)
const cooldownDays = challenge.cooldown_days ?? 0
const diff = now.diff(createdAt, 'day')
if (diff === cooldownDays) {
return messages.laterToday
} else if (diff === COOLDOWN_DAYS - 1) {
} else if (diff === cooldownDays - 1) {
return messages.tomorrow
}
return created_at.local().add(COOLDOWN_DAYS, 'day').format('ddd (M/D)')
return createdAt.add(cooldownDays, 'day').format('ddd (M/D)')
}

const formatAudioMatchingChallengeCooldownSchedule = (
const formatAudioMatchingChallengesForCooldownSchedule = (
challenges: UndisbursedUserChallenge[]
) => {
const now = dayjs.utc().endOf('day')
const cooldownChallenges = new Array(7)
if (challenges.length === 0) return []
const now = dayjs().endOf('day')
const cooldownChallenges = new Array(challenges[0].cooldown_days)
challenges.forEach((c) => {
const createdAtUTC = dayjs.utc(c.created_at)
const diff = now.diff(createdAtUTC, 'day')
const createdAt = utcToLocalTime(c.created_at)
const diff = now.diff(createdAt, 'day')
cooldownChallenges[diff] = {
...cooldownChallenges[diff],
id: c.specifier,
label: getAudioMatchingCooldownLabel(now, createdAtUTC),
label: getAudioMatchingCooldownLabel(c, now),
value: (cooldownChallenges[diff]?.value ?? 0) + c.amount
}
})
Expand All@@ -84,7 +89,7 @@ export const useAudioMatchingChallengeCooldownSchedule = (
return {
claimableAmount,
cooldownChallenges:
formatAudioMatchingChallengeCooldownSchedule(cooldownChallenges),
formatAudioMatchingChallengesForCooldownSchedule(cooldownChallenges),
cooldownChallengesSummary:
claimableAmount > 0
? getAudioMatchingChallengeCooldownSummary(claimableAmount)
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/store/pages/audio-rewards/types.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,6 +29,7 @@ export type UndisbursedUserChallenge = Pick<
handle: string
wallet: string
created_at: string
cooldown_days?: number
}

export enum HCaptchaStatus {
Expand Down
19 changes: 12 additions & 7 deletions packages/common/src/utils/challenges.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -248,17 +248,20 @@ export const isAudioMatchingChallenge = (
)
}

// TODO: currently only $AUDIO matching challenges have cooldown
// so this works, but really we should check if `cooldown_period` exists on the
// challenge instead of using `!isAudioMatchingChallenge`. PAY-2030
/** Returns true if the challenge is not a cooldown challenge by checking
* whether it has `cooldown_days` defined and whether the challenge has been
* created for more than `cooldown_days` days.
*/
export const isCooldownChallengeClaimable = (
challenge: UndisbursedUserChallenge
) => {
return (
!isAudioMatchingChallenge(challenge.challenge_id) ||
dayjs.utc().diff(dayjs.utc(challenge.created_at), 'day') >= 7
challenge.cooldown_days === undefined ||
dayjs.utc().diff(dayjs.utc(challenge.created_at), 'day') >=
challenge.cooldown_days
)
}

/* Filter for only claimable challenges */
export const getClaimableChallengeSpecifiers = (
specifiers: SpecifierWithAmount[],
Expand All@@ -267,7 +270,9 @@ export const getClaimableChallengeSpecifiers = (
return specifiers.filter((s) => {
const challenge = undisbursedUserChallenges.filter(
(c) => c.specifier === s.specifier
)[0] // specifiers are unique
return isCooldownChallengeClaimable(challenge)
)
if (challenge.length === 0) return false
// specifiers are unique
return isCooldownChallengeClaimable(challenge[0])
})
}
6 changes: 6 additions & 0 deletions packages/common/src/utils/timeUtil.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
import type { MomentInput } from 'moment'
import moment from 'moment'

import dayjs from 'dayjs'

const SECONDS_PER_MINUTE = 60
const MINUTES_PER_HOUR = 60
const SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR
Expand DownExpand Up@@ -45,3 +47,7 @@ export const formatDate = (date: MomentInput, format?: string): string => {
export const formatDateWithTimezoneOffset = (date: MomentInput): string => {
return moment(date).add(moment().utcOffset(), 'm').format('MM/DD/YY')
}

export const utcToLocalTime = (date: string) => {
return dayjs.utc(date).local()
}