Skip to content

Commit

Permalink
[Issue-100] Update UI and logic for events screen
Browse files Browse the repository at this point in the history
  • Loading branch information
lw-cdm committed Oct 29, 2024
1 parent 3a33d6c commit 5c0749b
Show file tree
Hide file tree
Showing 12 changed files with 262 additions and 92 deletions.
159 changes: 128 additions & 31 deletions packages/extension-koni-ui/src/Popup/Home/Events/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// SPDX-License-Identifier: Apache-2.0

import { FilterTabItemType, FilterTabs } from '@subwallet/extension-koni-ui/components/FilterTabs';
import { EventDifficulty, EventItem, EventStatus, MainScreenHeader } from '@subwallet/extension-koni-ui/components/Mythical';
import { EventDifficulty, EventItem, EventItemType, EventState, MainScreenHeader } from '@subwallet/extension-koni-ui/components/Mythical';
import { BookaSdk } from '@subwallet/extension-koni-ui/connector/booka/sdk';
import { GameEvent } from '@subwallet/extension-koni-ui/connector/booka/types';
import { HomeContext } from '@subwallet/extension-koni-ui/contexts/screen/HomeContext';
import { useSetCurrentPage } from '@subwallet/extension-koni-ui/hooks';
import { ThemeProps } from '@subwallet/extension-koni-ui/types';
Expand All @@ -12,33 +14,87 @@ import styled from 'styled-components';

type Props = ThemeProps;

// note: this is for mocking, will remove on production
type EventItemType = {
id: string;
difficulty: EventDifficulty;
status: EventStatus;
};
const apiSDK = BookaSdk.instance;

function getEventDifficult (difficult: number): EventDifficulty {
if (difficult <= 10 && difficult >= 7) {
return EventDifficulty.HARD;
}

if (difficult <= 6 && difficult >= 4) {
return EventDifficulty.HARD;
}

return EventDifficulty.EASY;
}

function getEventState (gameEvent: GameEvent, dateNow: number): EventState {
const startTime = new Date(gameEvent.startTime).getTime();
const endTime = new Date(gameEvent.endTime).getTime();

if (dateNow < startTime) {
return EventState.COMING_SOON;
}

if (dateNow < endTime && dateNow >= startTime) {
return EventState.AVAILABLE;
}

return EventState.UNKNOWN;
}

function getTimeRemaining (dateNow: number, targetTime: string) {
const end = new Date(targetTime).getTime();
const diff = end - dateNow;

if (diff <= 0) {
return '---';
}

let days = Math.floor(diff / (1000 * 60 * 60 * 24));
let hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));

// Adjust hours to ensure it’s always less than 24
if (hours === 24) {
days += 1;
hours = 0;
}

const dayLabel = days === 1 ? 'day' : 'days';
const hourLabel = hours === 1 ? 'hr' : 'hrs';

if (days > 0) {
return `${days} ${dayLabel} ${hours} ${hourLabel}`;
} else {
return `${hours} ${hourLabel}`;
}
}

const Component = ({ className }: Props): React.ReactElement => {
useSetCurrentPage('/home/events');
const { setContainerClass } = useContext(HomeContext);
const [gameEvents, setGameEvents] = useState<GameEvent[]>(apiSDK.gameEventList);

console.log('gameEvents', gameEvents);

const [eventItems, setEventItems] = useState<EventItemType[]>([]);

const { t } = useTranslation();
const [selectedFilterTab, setSelectedFilterTab] = useState<string>(EventStatus.READY);
const [selectedFilterTab, setSelectedFilterTab] = useState<string>(EventState.AVAILABLE);

const filterTabItems = useMemo<FilterTabItemType[]>(() => {
return [
{
label: t('All events'),
value: EventStatus.READY
value: EventState.AVAILABLE
},
{
label: t('Upcoming'),
value: EventStatus.COMING_SOON
value: EventState.COMING_SOON
},
{
label: t('Completed'),
value: EventStatus.COMPLETED
value: EventState.COMPLETED
}
];
}, [t]);
Expand All @@ -47,25 +103,67 @@ const Component = ({ className }: Props): React.ReactElement => {
setSelectedFilterTab(value);
}, []);

const eventItems: EventItemType[] = useMemo(() => {
return [
{
id: '1',
difficulty: EventDifficulty.EASY,
status: selectedFilterTab
},
{
id: '2',
difficulty: EventDifficulty.MEDIUM,
status: selectedFilterTab
},
{
id: '3',
difficulty: EventDifficulty.HARD,
status: selectedFilterTab
const getEventItems = useCallback(() => {
const dateNow = Date.now();

const result: EventItemType[] = [];

gameEvents.forEach((eventInfo) => {
const eventState = getEventState(eventInfo, dateNow);

if (selectedFilterTab !== eventState) {
return;
}
] as EventItemType[];
}, [selectedFilterTab]);

const datetime = (() => {
if (eventState === EventState.COMING_SOON) {
return getTimeRemaining(dateNow, eventInfo.startTime);
}

if (eventState === EventState.AVAILABLE) {
return getTimeRemaining(dateNow, eventInfo.endTime);
}

return '---';
})();

result.push({
id: eventInfo.id,
difficulty: getEventDifficult(eventInfo.tossUpInfo.difficulty),
state: eventState,
stats: eventInfo.tossUpInfo.stats,
round: eventInfo.tossUpInfo.round,
logoSrc: eventInfo.icon,
datetime,
bonusText: eventInfo.description,
name: eventInfo.name
});
});

return result;
}, [gameEvents, selectedFilterTab]);

useEffect(() => {
setEventItems(getEventItems());

const timer = setInterval(() => {
setEventItems(getEventItems());
}, 1000);

return () => {
clearInterval(timer);
};
}, [getEventItems, setContainerClass]);

useEffect(() => {
const gameEventListSub = apiSDK.subscribeGameEventList().subscribe((data) => {
setGameEvents(data);
});

return () => {
gameEventListSub.unsubscribe();
};
}, []);

useEffect(() => {
setContainerClass('events-screen-wrapper');
Expand All @@ -92,10 +190,9 @@ const Component = ({ className }: Props): React.ReactElement => {
{
eventItems.map((item) => (
<EventItem
{...item}
className={'event-item'}
difficulty={item.difficulty}
key={item.id}
status={item.status}
/>
))
}
Expand Down
2 changes: 1 addition & 1 deletion packages/extension-koni-ui/src/Popup/Home/Games/gameSDK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { BookaSdk } from '@subwallet/extension-koni-ui/connector/booka/sdk';
import { Game } from '@subwallet/extension-koni-ui/connector/booka/types';
import { TelegramConnector } from '@subwallet/extension-koni-ui/connector/telegram';
import { camelCase } from 'lodash';
import z, { undefined } from 'zod';
import z from 'zod';

export interface GameAppOptions {
viewport: HTMLIFrameElement;
Expand Down
Loading

0 comments on commit 5c0749b

Please sign in to comment.