Skip to content

Commit 59db8d6

Browse files
authored
fix: get available dates (#11954)
1 parent 2316525 commit 59db8d6

File tree

11 files changed

+106
-88
lines changed

11 files changed

+106
-88
lines changed

packages/plugins/Calendar/src/SiteAdaptor/CalendarContent.tsx

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { Trans } from '@lingui/macro'
22
import { EMPTY_LIST } from '@masknet/shared-base'
33
import { MaskTabList, makeStyles, useTabs } from '@masknet/theme'
4+
import { EventProvider } from '@masknet/web3-providers/types'
45
import { TabContext, TabPanel } from '@mui/lab'
56
import { Tab } from '@mui/material'
6-
import { uniq } from 'lodash-es'
7-
import { useMemo, useState, type HTMLProps } from 'react'
8-
import { useNewsList } from '../hooks/useEventList.js'
9-
import { useLumaEvents } from '../hooks/useLumaEvents.js'
7+
import { useState, type HTMLProps } from 'react'
8+
import { useAvailableDates } from '../hooks/useAvailableDates.js'
109
import { DatePickerTab } from './components/DatePickerTab.js'
1110
import { EventList } from './components/EventList.js'
1211
import { Footer } from './components/Footer.js'
@@ -52,16 +51,11 @@ export function CalendarContent(props: Props) {
5251
const [pickerDate, setPickerDate] = useState(date)
5352
const [open, setOpen] = useState(false)
5453

55-
const [allowedDates, setAllowedDates] = useState<string[]>(EMPTY_LIST)
56-
57-
const { data: newsList = EMPTY_LIST } = useNewsList(pickerDate, currentTab === tabs.news)
58-
const { data: eventList = EMPTY_LIST } = useLumaEvents(pickerDate, currentTab === tabs.events)
59-
60-
const allAllowedDates = useMemo(() => {
61-
const list = currentTab === tabs.news ? newsList : eventList
62-
const dates = list.map((x) => new Date(x.event_date).toLocaleDateString())
63-
return uniq([...dates, ...allowedDates])
64-
}, [allowedDates, newsList, eventList, currentTab])
54+
const isNews = currentTab === tabs.news
55+
const { data: allowedDates = EMPTY_LIST } = useAvailableDates(
56+
isNews ? EventProvider.CoinCarp : EventProvider.Luma,
57+
pickerDate,
58+
)
6559

6660
return (
6761
<div {...props} className={cx(classes.calendar, props.className)}>
@@ -77,14 +71,14 @@ export function CalendarContent(props: Props) {
7771
onToggle={setOpen}
7872
date={date}
7973
onChange={setDate}
80-
allowedDates={allAllowedDates}
74+
allowedDates={allowedDates}
8175
onMonthChange={setPickerDate}
8276
/>
8377
<TabPanel value={tabs.news} className={classes.tabPanel}>
84-
<NewsList date={date} onDatesUpdate={setAllowedDates} />
78+
<NewsList date={date} />
8579
</TabPanel>
8680
<TabPanel value={tabs.events} className={classes.tabPanel}>
87-
<EventList date={date} onDatesUpdate={setAllowedDates} />
81+
<EventList date={date} />
8882
</TabPanel>
8983
<Footer tab={currentTab} />
9084
</TabContext>

packages/plugins/Calendar/src/SiteAdaptor/components/DatePicker.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { Icons } from '@masknet/icons'
22
import { makeStyles } from '@masknet/theme'
33
import { IconButton, Typography } from '@mui/material'
44
import { Box } from '@mui/system'
5-
import { addMonths, endOfMonth, format, isAfter, startOfMonth } from 'date-fns'
5+
import { addMonths, endOfMonth, format, startOfMonth } from 'date-fns'
66
import { range } from 'lodash-es'
7-
import { useMemo, useState } from 'react'
7+
import { useState } from 'react'
88

99
const useStyles = makeStyles()((theme) => {
1010
const isDark = theme.palette.mode === 'dark'
@@ -144,7 +144,7 @@ export function DatePicker({ date, onChange, open, onToggle, allowedDates, onMon
144144
dayOfMonth - daysInMonth,
145145
)
146146
}
147-
const localeDateString = currentDatePointer.toLocaleDateString()
147+
const localeDateString = format(currentDatePointer, 'MM/dd/yyyy')
148148

149149
return (
150150
<td key={dayIndex}>

packages/plugins/Calendar/src/SiteAdaptor/components/DatePickerTab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Icons } from '@masknet/icons'
22
import { makeStyles } from '@masknet/theme'
33
import { ClickAwayListener, IconButton, Typography } from '@mui/material'
4-
import { eachDayOfInterval, endOfWeek, startOfWeek } from 'date-fns'
4+
import { eachDayOfInterval, endOfWeek, format, startOfWeek } from 'date-fns'
55
import { useMemo } from 'react'
66
import { DatePicker, type DatePickerProps } from './DatePicker.js'
77

@@ -52,7 +52,7 @@ export function DatePickerTab(props: DatePickerTabProps) {
5252
return (
5353
<div className={classes.container}>
5454
{days.map((v) => {
55-
const localeDateString = v.toLocaleDateString()
55+
const localeDateString = format(v, 'MM/dd/yyyy')
5656
return (
5757
<div
5858
className={`${classes.date} ${date.getDate() === v.getDate() ? classes.isActive : ''} ${

packages/plugins/Calendar/src/SiteAdaptor/components/EventList.tsx

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import { EMPTY_LIST } from '@masknet/shared-base'
55
import { LoadingBase, makeStyles } from '@masknet/theme'
66
import { Link, Typography } from '@mui/material'
77
import { format } from 'date-fns'
8-
import { uniq } from 'lodash-es'
9-
import { useEffect, useMemo } from 'react'
108
import { useLumaEvents } from '../../hooks/useLumaEvents.js'
119
import { ImageLoader } from './ImageLoader.js'
1210

@@ -93,24 +91,13 @@ const useStyles = makeStyles()((theme) => ({
9391

9492
interface EventListProps {
9593
date: Date
96-
onDatesUpdate(/** locale date string list */ dates: string[]): void
9794
}
9895

99-
export function EventList({ date, onDatesUpdate }: EventListProps) {
96+
export function EventList({ date }: EventListProps) {
10097
const { classes, cx } = useStyles()
101-
const { isLoading, isFetching, data, error, hasNextPage, fetchNextPage } = useLumaEvents(date)
98+
const { isPending, isFetching, data = EMPTY_LIST, error, hasNextPage, fetchNextPage } = useLumaEvents(date)
10299

103-
const comingEvents = useMemo(() => {
104-
if (!data) return EMPTY_LIST
105-
return data.filter((x) => new Date(x.event_date) >= date)
106-
}, [data, date])
107-
108-
useEffect(() => {
109-
if (!data) return onDatesUpdate(EMPTY_LIST)
110-
onDatesUpdate(uniq(data.map((x) => new Date(x.event_date).toLocaleDateString())))
111-
}, [onDatesUpdate, data])
112-
113-
if (isLoading) {
100+
if (isPending && !data.length) {
114101
return (
115102
<div className={classes.container}>
116103
<div className={classes.paddingWrap}>
@@ -133,7 +120,7 @@ export function EventList({ date, onDatesUpdate }: EventListProps) {
133120
</div>
134121
)
135122
}
136-
if (!comingEvents.length) {
123+
if (!data.length) {
137124
return (
138125
<div className={classes.container}>
139126
<div className={classes.paddingWrap}>
@@ -150,7 +137,7 @@ export function EventList({ date, onDatesUpdate }: EventListProps) {
150137
return (
151138
<div className={classes.container}>
152139
<div className={classes.paddingWrap}>
153-
{comingEvents.map((event) => {
140+
{data.map((event) => {
154141
return (
155142
<Link
156143
key={event.event_id}

packages/plugins/Calendar/src/SiteAdaptor/components/NewsList.tsx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import { LoadingBase, makeStyles } from '@masknet/theme'
55
import type { ParsedEvent } from '@masknet/web3-providers/types'
66
import { Link, Typography } from '@mui/material'
77
import { format } from 'date-fns'
8-
import { uniq } from 'lodash-es'
9-
import { useEffect, useMemo } from 'react'
8+
import { useMemo } from 'react'
109
import { useNewsList } from '../../hooks/useEventList.js'
1110

1211
const useStyles = makeStyles()((theme) => ({
@@ -111,7 +110,6 @@ const useStyles = makeStyles()((theme) => ({
111110

112111
interface NewsListProps {
113112
date: Date
114-
onDatesUpdate(/** locale date string list */ dates: string[]): void
115113
}
116114

117115
interface Group {
@@ -120,17 +118,16 @@ interface Group {
120118
label: string
121119
events: ParsedEvent[]
122120
}
123-
export function NewsList({ date, onDatesUpdate }: NewsListProps) {
121+
export function NewsList({ date }: NewsListProps) {
124122
const { classes, cx } = useStyles()
125-
const { isLoading, isFetching, data: newsList, error, hasNextPage, fetchNextPage } = useNewsList(date)
123+
const { isPending, isFetching, data: newsList, error, hasNextPage, fetchNextPage } = useNewsList(date)
126124

127125
const groups = useMemo(() => {
128126
if (!newsList?.length) return EMPTY_LIST
129127
const groups: Group[] = []
130128
newsList.forEach((event) => {
131129
const eventDate = new Date(event.event_date)
132-
if (eventDate < date) return
133-
const label = eventDate.toLocaleDateString()
130+
const label = format(eventDate, 'MM/dd/yyyy')
134131
const group: Group = groups.find((g) => g.label === label) || {
135132
date: event.event_date,
136133
label,
@@ -142,12 +139,7 @@ export function NewsList({ date, onDatesUpdate }: NewsListProps) {
142139
return groups
143140
}, [newsList, date])
144141

145-
useEffect(() => {
146-
if (!newsList) return onDatesUpdate(EMPTY_LIST)
147-
onDatesUpdate(uniq(newsList.map((x) => new Date(x.event_date).toLocaleDateString())))
148-
}, [onDatesUpdate, newsList])
149-
150-
if (isLoading) {
142+
if (isPending && !groups.length) {
151143
return (
152144
<div className={classes.container}>
153145
<div className={classes.paddingWrap}>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Calendar } from '@masknet/web3-providers'
2+
import { type EventProvider } from '@masknet/web3-providers/types'
3+
import { useQuery } from '@tanstack/react-query'
4+
import { startOfMonth, addDays, format } from 'date-fns'
5+
6+
export function useAvailableDates(type: EventProvider, date: Date, enabled = true) {
7+
const startTime = startOfMonth(date).getTime()
8+
const endTime = addDays(startTime, 45).getTime()
9+
return useQuery({
10+
enabled,
11+
queryKey: ['available-dates', type, startTime, endTime],
12+
queryFn: () => Calendar.getAvailableDates(type, startTime, endTime),
13+
select(dates) {
14+
return dates.map((date) => format(date, 'MM/dd/yyyy'))
15+
},
16+
})
17+
}
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import { Calendar } from '@masknet/web3-providers'
22
import { useInfiniteQuery } from '@tanstack/react-query'
3-
import { addDays, startOfMonth } from 'date-fns'
3+
import { addDays, startOfDay } from 'date-fns'
4+
import { uniqBy } from 'lodash-es'
45

5-
export function useNewsList(date: Date, enabled = true) {
6-
const startTime = startOfMonth(date).getTime()
7-
const endTime = addDays(startTime, 45).getTime()
6+
export function useNewsList(date: Date) {
7+
const startTime = startOfDay(date).getTime()
8+
const endTime = addDays(startTime, 14).getTime()
89

910
return useInfiniteQuery({
10-
enabled,
1111
queryKey: ['newsList', startTime, endTime],
1212
queryFn: async ({ pageParam }) => Calendar.getNewsList(startTime, endTime, pageParam),
1313
initialPageParam: undefined as any,
1414
getNextPageParam: (page) => page.nextIndicator,
1515
select(data) {
16-
return data.pages.flatMap((x) => x.data)
16+
return uniqBy(
17+
data.pages.flatMap((x) => x.data),
18+
(x) => x.event_id,
19+
)
1720
},
1821
})
1922
}

packages/plugins/Calendar/src/hooks/useLumaEvents.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import { Calendar } from '@masknet/web3-providers'
22
import { useInfiniteQuery } from '@tanstack/react-query'
3-
import { addDays, startOfMonth } from 'date-fns'
3+
import { addDays, startOfDay } from 'date-fns'
4+
5+
export function useLumaEvents(date: Date) {
6+
const startTime = startOfDay(date).getTime()
7+
const endTime = addDays(startTime, 14).getTime()
48

5-
export function useLumaEvents(date: Date, enabled = true) {
6-
const startTime = startOfMonth(date).getTime()
7-
const endTime = addDays(startOfMonth(date), 45).getTime()
89
return useInfiniteQuery({
9-
enabled,
1010
queryKey: ['lumaEvents', startTime, endTime],
1111
initialPageParam: undefined as any,
12-
queryFn: async ({ pageParam }) => {
13-
return Calendar.getEventList(startTime, endTime, pageParam)
14-
},
12+
queryFn: async ({ pageParam }) => Calendar.getEventList(startTime, endTime, pageParam),
1513
getNextPageParam(page) {
1614
return page.nextIndicator
1715
},

packages/web3-providers/src/Calendar/index.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { createNextIndicator, createPageable, type PageIndicator } from '@masknet/shared-base'
1+
import { createIndicator, createNextIndicator, createPageable, type PageIndicator } from '@masknet/shared-base'
22
import { compact } from 'lodash-es'
33
import urlcat from 'urlcat'
44
import { fetchCachedJSON } from '../entry-helpers.js'
5-
import type { Event, EventResponse, ParsedEvent } from './types.js'
5+
import type { Event, EventDatesResponse, EventProvider, EventResponse, ParsedEvent } from './types.js'
66

7-
const BASE_URL = 'https://mask-network-dev.firefly.land/v1/calendar/crypto_event_list'
7+
const BASE_URL = 'https://mask-network-dev.firefly.land/v1/calendar/'
88

99
function fixEventDate(event: Event): ParsedEvent {
1010
return {
@@ -59,35 +59,55 @@ function fixEvent(event: Event): ParsedEvent {
5959
}
6060
}
6161

62+
const SIZE = 50
6263
export class Calendar {
6364
static async getNewsList(startDate: number, endDate?: number, indicator?: PageIndicator) {
6465
const res = await fetchCachedJSON<EventResponse>(
65-
urlcat(BASE_URL, {
66+
urlcat(BASE_URL, 'crypto_event_list', {
6667
provider_type: 'coincarp',
68+
size: SIZE,
6769
start_date: Math.floor(startDate / 1000),
6870
end_date: endDate ? Math.floor(endDate / 1000) : 0,
6971
cursor: indicator?.id,
7072
}),
7173
)
72-
if (!res.data) return createPageable([], indicator, createNextIndicator(indicator))
74+
if (!res.data?.events.length) return createPageable([], createIndicator(indicator))
7375
const events = res.data.events.map(fixEventDate)
74-
return createPageable(events, indicator, createNextIndicator(indicator, res.data.page.next))
76+
const next = events.length < SIZE ? undefined : res.data.page.next
77+
return createPageable(
78+
events,
79+
indicator,
80+
createNextIndicator(indicator, next && next !== '0' ? next : undefined),
81+
)
7582
}
7683
static async getEventList(start_date: number, end_date: number, indicator?: PageIndicator) {
7784
const res = await fetchCachedJSON<EventResponse>(
78-
urlcat(BASE_URL, {
85+
urlcat(BASE_URL, 'crypto_event_list', {
7986
provider_type: 'luma',
80-
size: 20,
87+
size: SIZE,
8188
cursor: indicator?.id,
8289
start_date: start_date / 1000,
8390
end_date: end_date / 1000,
8491
}),
8592
)
86-
if (!res?.data?.events.length) {
87-
return createPageable([], indicator, createNextIndicator(indicator))
88-
}
93+
if (!res.data?.events.length) return createPageable([], createIndicator(indicator))
8994

9095
const events = res.data.events.map(fixEvent)
91-
return createPageable(events, indicator, createNextIndicator(indicator, res.data.page.next))
96+
const next = events.length < SIZE ? undefined : res.data.page.next
97+
return createPageable(
98+
events,
99+
indicator,
100+
createNextIndicator(indicator, next && next !== '0' ? next : undefined),
101+
)
102+
}
103+
static async getAvailableDates(type: EventProvider, start_date: number, end_date: number) {
104+
const res = await fetchCachedJSON<EventDatesResponse>(
105+
urlcat(BASE_URL, 'crypto_event_date_list', {
106+
provider_type: type,
107+
start_date: start_date / 1000,
108+
end_date: end_date / 1000,
109+
}),
110+
)
111+
return (res.data || []).map((x) => x * 1000)
92112
}
93113
}

packages/web3-providers/src/Calendar/types.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,24 @@ export type ParsedEvent = Omit<Event, 'event_date'> & {
4343
host_avatar?: string
4444
}
4545

46+
export enum EventProvider {
47+
CoinCarp = 'coincarp',
48+
Luma = 'luma',
49+
}
50+
4651
interface Response<T> {
4752
code: number
48-
data?: {
49-
events: T[]
50-
page: {
51-
cursor: string
52-
next: string
53-
}
54-
}
53+
data: T
5554
message: string
5655
reason?: string
5756
}
5857

59-
export type EventResponse = Response<Event>
58+
export type EventResponse = Response<{
59+
events: Event[]
60+
page: {
61+
cursor: string
62+
next: string
63+
}
64+
}>
65+
66+
export type EventDatesResponse = Response<number[]>

0 commit comments

Comments
 (0)