Skip to content

Commit

Permalink
fix: get available dates
Browse files Browse the repository at this point in the history
  • Loading branch information
swkatmask committed Nov 27, 2024
1 parent 2316525 commit 07a4648
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 80 deletions.
29 changes: 12 additions & 17 deletions packages/plugins/Calendar/src/SiteAdaptor/CalendarContent.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Trans } from '@lingui/macro'
import { EMPTY_LIST } from '@masknet/shared-base'
import { MaskTabList, makeStyles, useTabs } from '@masknet/theme'
import { EventProvider } from '@masknet/web3-providers/types'
import { TabContext, TabPanel } from '@mui/lab'
import { Tab } from '@mui/material'
import { uniq } from 'lodash-es'
import { useMemo, useState, type HTMLProps } from 'react'
import { useNewsList } from '../hooks/useEventList.js'
import { useLumaEvents } from '../hooks/useLumaEvents.js'
import { useState, type HTMLProps } from 'react'
import { useAvailableDates } from '../hooks/useAvailableDates.js'
import { DatePickerTab } from './components/DatePickerTab.js'
import { EventList } from './components/EventList.js'
import { Footer } from './components/Footer.js'
Expand Down Expand Up @@ -52,16 +51,12 @@ export function CalendarContent(props: Props) {
const [pickerDate, setPickerDate] = useState(date)
const [open, setOpen] = useState(false)

const [allowedDates, setAllowedDates] = useState<string[]>(EMPTY_LIST)

const { data: newsList = EMPTY_LIST } = useNewsList(pickerDate, currentTab === tabs.news)
const { data: eventList = EMPTY_LIST } = useLumaEvents(pickerDate, currentTab === tabs.events)

const allAllowedDates = useMemo(() => {
const list = currentTab === tabs.news ? newsList : eventList
const dates = list.map((x) => new Date(x.event_date).toLocaleDateString())
return uniq([...dates, ...allowedDates])
}, [allowedDates, newsList, eventList, currentTab])
const isNews = currentTab === tabs.news
const { data: allowedDates = EMPTY_LIST } = useAvailableDates(
isNews ? EventProvider.CoinCarp : EventProvider.Luma,
pickerDate,
open,
)

return (
<div {...props} className={cx(classes.calendar, props.className)}>
Expand All @@ -77,14 +72,14 @@ export function CalendarContent(props: Props) {
onToggle={setOpen}
date={date}
onChange={setDate}
allowedDates={allAllowedDates}
allowedDates={allowedDates}
onMonthChange={setPickerDate}
/>
<TabPanel value={tabs.news} className={classes.tabPanel}>
<NewsList date={date} onDatesUpdate={setAllowedDates} />
<NewsList date={date} />
</TabPanel>
<TabPanel value={tabs.events} className={classes.tabPanel}>
<EventList date={date} onDatesUpdate={setAllowedDates} />
<EventList date={date} />
</TabPanel>
<Footer tab={currentTab} />
</TabContext>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Icons } from '@masknet/icons'
import { makeStyles } from '@masknet/theme'
import { IconButton, Typography } from '@mui/material'
import { Box } from '@mui/system'
import { addMonths, endOfMonth, format, isAfter, startOfMonth } from 'date-fns'
import { addMonths, endOfMonth, format, startOfMonth } from 'date-fns'
import { range } from 'lodash-es'
import { useMemo, useState } from 'react'
import { useState } from 'react'

const useStyles = makeStyles()((theme) => {
const isDark = theme.palette.mode === 'dark'
Expand Down
23 changes: 5 additions & 18 deletions packages/plugins/Calendar/src/SiteAdaptor/components/EventList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { EMPTY_LIST } from '@masknet/shared-base'
import { LoadingBase, makeStyles } from '@masknet/theme'
import { Link, Typography } from '@mui/material'
import { format } from 'date-fns'
import { uniq } from 'lodash-es'
import { useEffect, useMemo } from 'react'
import { useLumaEvents } from '../../hooks/useLumaEvents.js'
import { ImageLoader } from './ImageLoader.js'

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

interface EventListProps {
date: Date
onDatesUpdate(/** locale date string list */ dates: string[]): void
}

export function EventList({ date, onDatesUpdate }: EventListProps) {
export function EventList({ date }: EventListProps) {
const { classes, cx } = useStyles()
const { isLoading, isFetching, data, error, hasNextPage, fetchNextPage } = useLumaEvents(date)
const { isPending, isFetching, data = EMPTY_LIST, error, hasNextPage, fetchNextPage } = useLumaEvents(date)

const comingEvents = useMemo(() => {
if (!data) return EMPTY_LIST
return data.filter((x) => new Date(x.event_date) >= date)
}, [data, date])

useEffect(() => {
if (!data) return onDatesUpdate(EMPTY_LIST)
onDatesUpdate(uniq(data.map((x) => new Date(x.event_date).toLocaleDateString())))
}, [onDatesUpdate, data])

if (isLoading) {
if (isPending && !data.length) {
return (
<div className={classes.container}>
<div className={classes.paddingWrap}>
Expand All @@ -133,7 +120,7 @@ export function EventList({ date, onDatesUpdate }: EventListProps) {
</div>
)
}
if (!comingEvents.length) {
if (!data.length) {
return (
<div className={classes.container}>
<div className={classes.paddingWrap}>
Expand All @@ -150,7 +137,7 @@ export function EventList({ date, onDatesUpdate }: EventListProps) {
return (
<div className={classes.container}>
<div className={classes.paddingWrap}>
{comingEvents.map((event) => {
{data.map((event) => {
return (
<Link
key={event.event_id}
Expand Down
16 changes: 4 additions & 12 deletions packages/plugins/Calendar/src/SiteAdaptor/components/NewsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { LoadingBase, makeStyles } from '@masknet/theme'
import type { ParsedEvent } from '@masknet/web3-providers/types'
import { Link, Typography } from '@mui/material'
import { format } from 'date-fns'
import { uniq } from 'lodash-es'
import { useEffect, useMemo } from 'react'
import { useMemo } from 'react'
import { useNewsList } from '../../hooks/useEventList.js'

const useStyles = makeStyles()((theme) => ({
Expand Down Expand Up @@ -111,7 +110,6 @@ const useStyles = makeStyles()((theme) => ({

interface NewsListProps {
date: Date
onDatesUpdate(/** locale date string list */ dates: string[]): void
}

interface Group {
Expand All @@ -120,16 +118,15 @@ interface Group {
label: string
events: ParsedEvent[]
}
export function NewsList({ date, onDatesUpdate }: NewsListProps) {
export function NewsList({ date }: NewsListProps) {
const { classes, cx } = useStyles()
const { isLoading, isFetching, data: newsList, error, hasNextPage, fetchNextPage } = useNewsList(date)
const { isPending, isFetching, data: newsList, error, hasNextPage, fetchNextPage } = useNewsList(date)

const groups = useMemo(() => {
if (!newsList?.length) return EMPTY_LIST
const groups: Group[] = []
newsList.forEach((event) => {
const eventDate = new Date(event.event_date)
if (eventDate < date) return
const label = eventDate.toLocaleDateString()
const group: Group = groups.find((g) => g.label === label) || {
date: event.event_date,
Expand All @@ -142,12 +139,7 @@ export function NewsList({ date, onDatesUpdate }: NewsListProps) {
return groups
}, [newsList, date])

useEffect(() => {
if (!newsList) return onDatesUpdate(EMPTY_LIST)
onDatesUpdate(uniq(newsList.map((x) => new Date(x.event_date).toLocaleDateString())))
}, [onDatesUpdate, newsList])

if (isLoading) {
if (isPending && !groups.length) {
return (
<div className={classes.container}>
<div className={classes.paddingWrap}>
Expand Down
17 changes: 17 additions & 0 deletions packages/plugins/Calendar/src/hooks/useAvailableDates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Calendar } from '@masknet/web3-providers'
import { type EventProvider } from '@masknet/web3-providers/types'
import { useQuery } from '@tanstack/react-query'
import { startOfMonth, addDays } from 'date-fns'

export function useAvailableDates(type: EventProvider, date: Date, enabled = true) {
const startTime = startOfMonth(date).getTime()
const endTime = addDays(startTime, 45).getTime()
return useQuery({
enabled,
queryKey: ['available-dates', type, startTime, endTime],
queryFn: () => Calendar.getAvailableDates(type, startTime, endTime),
select(dates) {
return dates.map((date) => new Date(date).toLocaleDateString())
},
})
}
12 changes: 8 additions & 4 deletions packages/plugins/Calendar/src/hooks/useEventList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Calendar } from '@masknet/web3-providers'
import { useInfiniteQuery } from '@tanstack/react-query'
import { addDays, startOfMonth } from 'date-fns'
import { addDays, startOfDay } from 'date-fns'
import { uniqBy } from 'lodash-es'

export function useNewsList(date: Date, enabled = true) {
const startTime = startOfMonth(date).getTime()
const endTime = addDays(startTime, 45).getTime()
const startTime = startOfDay(date).getTime()
const endTime = addDays(startTime, 14).getTime()

return useInfiniteQuery({
enabled,
Expand All @@ -13,7 +14,10 @@ export function useNewsList(date: Date, enabled = true) {
initialPageParam: undefined as any,
getNextPageParam: (page) => page.nextIndicator,
select(data) {
return data.pages.flatMap((x) => x.data)
return uniqBy(
data.pages.flatMap((x) => x.data),
(x) => x.event_id,
)
},
})
}
11 changes: 5 additions & 6 deletions packages/plugins/Calendar/src/hooks/useLumaEvents.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { Calendar } from '@masknet/web3-providers'
import { useInfiniteQuery } from '@tanstack/react-query'
import { addDays, startOfMonth } from 'date-fns'
import { addDays, startOfDay } from 'date-fns'

export function useLumaEvents(date: Date, enabled = true) {
const startTime = startOfMonth(date).getTime()
const endTime = addDays(startOfMonth(date), 45).getTime()
const startTime = startOfDay(date).getTime()
const endTime = addDays(startTime, 14).getTime()

return useInfiniteQuery({
enabled,
queryKey: ['lumaEvents', startTime, endTime],
initialPageParam: undefined as any,
queryFn: async ({ pageParam }) => {
return Calendar.getEventList(startTime, endTime, pageParam)
},
queryFn: async ({ pageParam }) => Calendar.getEventList(startTime, endTime, pageParam),
getNextPageParam(page) {
return page.nextIndicator
},
Expand Down
44 changes: 32 additions & 12 deletions packages/web3-providers/src/Calendar/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createNextIndicator, createPageable, type PageIndicator } from '@masknet/shared-base'
import { createIndicator, createNextIndicator, createPageable, type PageIndicator } from '@masknet/shared-base'
import { compact } from 'lodash-es'
import urlcat from 'urlcat'
import { fetchCachedJSON } from '../entry-helpers.js'
import type { Event, EventResponse, ParsedEvent } from './types.js'
import type { Event, EventDatesResponse, EventProvider, EventResponse, ParsedEvent } from './types.js'

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

function fixEventDate(event: Event): ParsedEvent {
return {
Expand Down Expand Up @@ -59,35 +59,55 @@ function fixEvent(event: Event): ParsedEvent {
}
}

const SIZE = 50
export class Calendar {
static async getNewsList(startDate: number, endDate?: number, indicator?: PageIndicator) {
const res = await fetchCachedJSON<EventResponse>(
urlcat(BASE_URL, {
urlcat(BASE_URL, 'crypto_event_list', {
provider_type: 'coincarp',
size: SIZE,
start_date: Math.floor(startDate / 1000),
end_date: endDate ? Math.floor(endDate / 1000) : 0,
cursor: indicator?.id,
}),
)
if (!res.data) return createPageable([], indicator, createNextIndicator(indicator))
if (!res.data?.events.length) return createPageable([], createIndicator(indicator))
const events = res.data.events.map(fixEventDate)
return createPageable(events, indicator, createNextIndicator(indicator, res.data.page.next))
const next = events.length < SIZE ? undefined : res.data.page.next
return createPageable(
events,
indicator,
createNextIndicator(indicator, next && next !== '0' ? next : undefined),
)
}
static async getEventList(start_date: number, end_date: number, indicator?: PageIndicator) {
const res = await fetchCachedJSON<EventResponse>(
urlcat(BASE_URL, {
urlcat(BASE_URL, 'crypto_event_list', {
provider_type: 'luma',
size: 20,
size: SIZE,
cursor: indicator?.id,
start_date: start_date / 1000,
end_date: end_date / 1000,
}),
)
if (!res?.data?.events.length) {
return createPageable([], indicator, createNextIndicator(indicator))
}
if (!res.data?.events.length) return createPageable([], createIndicator(indicator))

const events = res.data.events.map(fixEvent)
return createPageable(events, indicator, createNextIndicator(indicator, res.data.page.next))
const next = events.length < SIZE ? undefined : res.data.page.next
return createPageable(
events,
indicator,
createNextIndicator(indicator, next && next !== '0' ? next : undefined),
)
}
static async getAvailableDates(type: EventProvider, start_date: number, end_date: number) {
const res = await fetchCachedJSON<EventDatesResponse>(
urlcat(BASE_URL, 'crypto_event_date_list', {
provider_type: type,
start_date: start_date / 1000,
end_date: end_date / 1000,
}),
)
return (res.data || []).map((x) => x * 1000)
}
}
23 changes: 15 additions & 8 deletions packages/web3-providers/src/Calendar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,24 @@ export type ParsedEvent = Omit<Event, 'event_date'> & {
host_avatar?: string
}

export enum EventProvider {
CoinCarp = 'coincarp',
Luma = 'luma',
}

interface Response<T> {
code: number
data?: {
events: T[]
page: {
cursor: string
next: string
}
}
data: T
message: string
reason?: string
}

export type EventResponse = Response<Event>
export type EventResponse = Response<{
events: Event[]
page: {
cursor: string
next: string
}
}>

export type EventDatesResponse = Response<number[]>
2 changes: 1 addition & 1 deletion packages/web3-providers/src/entry-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export type * from './Web3/Router/types/index.js'
export * from './RedPacket/types.js'
export * from './AvatarStore/types.js'
export type * from './OKX/types.js'
export type * from './Calendar/types.js'
export * from './Calendar/types.js'

export type { BaseConnectionOptions } from './Web3/Base/apis/ConnectionOptions.js'
export type { BaseHubOptions } from './Web3/Base/apis/HubOptions.js'

0 comments on commit 07a4648

Please sign in to comment.