diff --git a/packages/extension-koni-ui/src/Popup/Home/Mission/TaskItem.tsx b/packages/extension-koni-ui/src/Popup/Home/Mission/TaskItem.tsx
index e9e2432f30..cede784395 100644
--- a/packages/extension-koni-ui/src/Popup/Home/Mission/TaskItem.tsx
+++ b/packages/extension-koni-ui/src/Popup/Home/Mission/TaskItem.tsx
@@ -2,16 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
import { SWTransactionResponse } from '@subwallet/extension-base/services/transaction-service/types';
-import CountDown from '@subwallet/extension-koni-ui/components/Common/CountDown';
-import { GamePoint } from '@subwallet/extension-koni-ui/components/Games/Logo';
+import { GamePoint } from '@subwallet/extension-koni-ui/components';
import { BookaSdk } from '@subwallet/extension-koni-ui/connector/booka/sdk';
import { Task, TaskHistoryStatus } from '@subwallet/extension-koni-ui/connector/booka/types';
import { TelegramConnector } from '@subwallet/extension-koni-ui/connector/telegram';
import { useNotification, useSetCurrentPage, useTranslation } from '@subwallet/extension-koni-ui/hooks';
import { ThemeProps } from '@subwallet/extension-koni-ui/types';
-import { formatInteger } from '@subwallet/extension-koni-ui/utils';
+import { customFormatDate, formatInteger } from '@subwallet/extension-koni-ui/utils';
import { actionTaskOnChain } from '@subwallet/extension-koni-ui/utils/game/task';
-import { Button, Icon, Image, Typography } from '@subwallet/react-ui';
+import { Button, Icon, Image } from '@subwallet/react-ui';
import CN from 'classnames';
import { CheckCircle } from 'phosphor-react';
import React, { useCallback, useEffect, useState } from 'react';
@@ -24,7 +23,8 @@ type Props = {
const apiSDK = BookaSdk.instance;
const telegramConnector = TelegramConnector.instance;
-const _TaskItem = ({ className, task, actionReloadPoint }: Props): React.ReactElement => {
+
+const _TaskItem = ({ actionReloadPoint, className, task }: Props): React.ReactElement => {
useSetCurrentPage('/home/mission');
const notify = useNotification();
const [account, setAccount] = useState(apiSDK.account);
@@ -53,7 +53,7 @@ const _TaskItem = ({ className, task, actionReloadPoint }: Props): React.ReactEl
}
return () => clearInterval(taskItemUpdaterInterval);
- }, [checking]);
+ }, [actionReloadPoint, checking, task.taskHistoryId]);
useEffect(() => {
const accountSub = apiSDK.subscribeAccount().subscribe((data) => {
@@ -65,71 +65,75 @@ const _TaskItem = ({ className, task, actionReloadPoint }: Props): React.ReactEl
};
}, []);
- const finishTask = useCallback(async () => {
- const taskId = task.id;
- const onChainType = task.onChainType;
- const { address } = account?.info || {};
+ const finishTask = useCallback(() => {
+ (async () => {
+ const taskId = task.id;
+ const onChainType = task.onChainType;
+ const { address } = account?.info || {};
- if (!address) {
- return;
- }
+ if (!address) {
+ return;
+ }
- setTaskLoading(true);
- let res: SWTransactionResponse | null = null;
- const networkKey = 'alephTest';
+ setTaskLoading(true);
+ let res: SWTransactionResponse | null = null;
+ const networkKey = 'alephTest';
- if (onChainType) {
- const now = new Date();
- const date = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
- const data = JSON.stringify({ address, type: onChainType, date });
+ if (onChainType) {
+ const now = new Date();
+ const date = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
+ const data = JSON.stringify({ address, type: onChainType, date });
- res = await actionTaskOnChain(onChainType, 'alephTest', address, data);
+ res = await actionTaskOnChain(onChainType, 'alephTest', address, data);
- if ((res && res.errors.length > 0) || !res) {
- setTaskLoading(false);
- let message = t(`Network ${networkKey} not enable`);
- if (res && res.errors.length > 0) {
- const error = res?.errors[0] || {};
- // @ts-ignore
- message = error?.message || '';
- }
+ if ((res && res.errors.length > 0) || !res) {
+ setTaskLoading(false);
+ let message = t(`Network ${networkKey} not enable`);
- notify({
- message: message,
- type: 'error'
- });
+ if (res && res.errors.length > 0) {
+ const error = res?.errors[0] || {};
- return;
- }
- }
+ // @ts-ignore
+ message = error?.message || '';
+ }
- let extrinsicHash = '';
+ notify({
+ message: message,
+ type: 'error'
+ });
- if (res) {
- extrinsicHash = res.extrinsicHash || '';
- }
+ return;
+ }
+ }
- apiSDK.finishTask(taskId, extrinsicHash, networkKey)
- .finally(() => {
- setTaskLoading(false);
+ let extrinsicHash = '';
- if (onChainType) {
- setChecking(true);
- } else {
- setCompleted(true);
- actionReloadPoint();
- }
- })
- .catch(console.error);
+ if (res) {
+ extrinsicHash = res.extrinsicHash || '';
+ }
- setTimeout(() => {
- task.url && telegramConnector.openLink(task.url);
- }, 100);
- }, [task.id, task.url]);
+ apiSDK.finishTask(taskId, extrinsicHash, networkKey)
+ .finally(() => {
+ setTaskLoading(false);
+
+ if (onChainType) {
+ setChecking(true);
+ } else {
+ setCompleted(true);
+ actionReloadPoint();
+ }
+ })
+ .catch(console.error);
+
+ setTimeout(() => {
+ task.url && telegramConnector.openLink(task.url);
+ }, 100);
+ })().catch(console.error);
+ }, [account?.info, actionReloadPoint, notify, t, task.id, task.onChainType, task.url]);
const { endTime,
isDisabled,
- isEnd, isInTimeRange,
+ isInTimeRange,
isNotStarted,
startTime } = (() => {
const now = Date.now();
@@ -145,118 +149,143 @@ const _TaskItem = ({ className, task, actionReloadPoint }: Props): React.ReactEl
endTime,
isNotStarted,
isInTimeRange,
+ // @ts-ignore
isEnd,
isDisabled: isNotStarted || isEnd
};
})();
- return
-
-
-
{task.name}
-
-
+ const renderTaskDate = () => {
+ const now = Date.now();
+
+ let content: string | undefined;
+
+ if (isNotStarted && !!startTime && startTime < now) {
+ content = `${t('Begins at')} ${customFormatDate(startTime, '#hhhh#:#mm# - #DD#/#MM#/#YYYY#')}`;
+ } else if (isInTimeRange && !!endTime && endTime > now) {
+ content = `${t('Ends at')} ${customFormatDate(endTime, '#hhhh#:#mm# - #DD#/#MM#/#YYYY#')}`;
+ }
+
+ if (content) {
+ return (
+
+ content
+
+ );
+ }
+
+ return null;
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {renderTaskDate()}
+
+
+
+
+ {!completed && (
+
+ )}
{
- isNotStarted && !!startTime && (
-
- )
- }
- {
- isInTimeRange && !!endTime && (
-
)
}
- {
- isEnd && ({t('Ended')})
- }
-
+
- {!completed && !checking && }
- {completed && !checking && }
- size={'xs'}
- type={'ghost'}
- />}
- {checking && !completed && }
- size={'xs'}
- type={'ghost'}
- />}
- ;
+ );
};
const TaskItem = styled(_TaskItem)
(({ theme: { extendToken, token } }: ThemeProps) => {
- return { alignItems: 'center',
+ return {
+ alignItems: 'center',
display: 'flex',
- marginBottom: token.marginXS,
padding: token.paddingSM,
borderRadius: token.borderRadius,
- backgroundColor: token.colorBgSecondary,
'&.disabled': {
opacity: 0.6
},
- '.task-banner': {
- marginRight: token.marginSM
+ '.__mid-part': {
+ flex: 1
},
- '.task-title': {
- flex: 1,
+ '.__task-banner': {
+ marginRight: token.marginXS
+ },
- '.__title': {
- marginBottom: 0
- },
+ '.__min-part-line-1': {
- '.__sub-title': {
- color: token.colorTextDark4
- }
},
- '.play-button, .checked-button': {
- marginLeft: token.marginSM
+ '.__min-part-line-2': {
+ display: 'flex',
+ alignItems: 'center'
},
- '.checked-button': {
- color: token.colorSuccess
- } };
+ '.__task-name': {
+ color: token.colorTextDark2,
+ fontWeight: token.headingFontWeight,
+ fontSize: token.fontSize,
+ lineHeight: token.lineHeight
+ },
+
+ '.__task-date': {
+ display: 'flex',
+ fontSize: 10,
+ lineHeight: '16px',
+ fontWeight: token.headingFontWeight,
+ color: token.colorTextDark3,
+ paddingLeft: token.paddingXS,
+ alignItems: 'center',
+
+ '&:before': {
+ content: '""',
+ marginRight: token.marginXS,
+ backgroundColor: token.colorTextDark4,
+ height: 12,
+ width: 1
+ }
+ }
+ };
});
export default TaskItem;
diff --git a/packages/extension-koni-ui/src/Popup/Home/Mission/TaskList.tsx b/packages/extension-koni-ui/src/Popup/Home/Mission/TaskList.tsx
index cfeec490cb..b922c33838 100644
--- a/packages/extension-koni-ui/src/Popup/Home/Mission/TaskList.tsx
+++ b/packages/extension-koni-ui/src/Popup/Home/Mission/TaskList.tsx
@@ -5,107 +5,93 @@ import { TaskCategory, TaskCategoryInfo } from '@subwallet/extension-koni-ui/con
import { useTranslation } from '@subwallet/extension-koni-ui/hooks';
import TaskItem from '@subwallet/extension-koni-ui/Popup/Home/Mission/TaskItem';
import { ThemeProps } from '@subwallet/extension-koni-ui/types';
-import { Button, Icon, Typography } from '@subwallet/react-ui';
-import { CaretLeft } from 'phosphor-react';
-import React, { useMemo } from 'react';
+import React from 'react';
import styled from 'styled-components';
type Props = ThemeProps & {
- currentTaskCategory?: number;
+ taskCategoryMap: Record;
taskCategoryInfoMap: Record;
- onBackToCategoryList: VoidFunction;
actionReloadPoint: VoidFunction;
- taskCategory: TaskCategory | undefined;
};
-const Component = ({ actionReloadPoint, className, currentTaskCategory, onBackToCategoryList, taskCategory, taskCategoryInfoMap }: Props): React.ReactElement => {
+const Component = ({ actionReloadPoint, className, taskCategoryInfoMap, taskCategoryMap }: Props): React.ReactElement => {
const { t } = useTranslation();
- const sortedTaskList = useMemo(() => {
- const now = Date.now();
-
- const taskList = currentTaskCategory ? taskCategoryInfoMap[currentTaskCategory]?.tasks || [] : [];
-
- return taskList.filter((task) => {
- // Filter out the task that ended more than 1 day ago
- if (!task.completedAt && task.endTime && new Date(task.endTime).getTime() < now) {
- return false;
- } else {
- return true;
- }
- })
- .sort((a, b) => {
- const aDisabled = ((a.startTime && new Date(a.startTime).getTime() > now) || (a.endTime && new Date(a.endTime).getTime() < now));
- const bDisabled = ((b.startTime && new Date(b.startTime).getTime() > now) || (b.endTime && new Date(b.endTime).getTime() < now));
-
- if (aDisabled && !bDisabled) {
- return 1;
- }
-
- if (!aDisabled && bDisabled) {
- return -1;
- }
-
- if (a.status === 0 && b.status !== 0) {
- return -1;
- }
-
- if (a.status !== 0 && b.status === 0) {
- return 1;
- }
-
- return a.status - b.status;
- });
- }, [currentTaskCategory, taskCategoryInfoMap]);
-
return (
-
-
- )}
- onClick={onBackToCategoryList}
- size='xs'
- type='ghost'
- />
-
-
- {taskCategory ? taskCategory.name : t('Missions')}
-
-
-
- {sortedTaskList.map((task) => (
-
- ))}
+ {
+ Object.values(taskCategoryInfoMap).map((tci) => (
+
+
+
+ {taskCategoryMap[tci.id]?.name}
+
+
+
+ {`${tci.completeCount}/${tci.tasks.length}`} {t('mission')}
+
+
+
+ {
+ tci.tasks.map((t) => (
+
+ ))
+ }
+
+
+ ))
+ }
);
};
export const TaskList = styled(Component)(({ theme: { extendToken, token } }: ThemeProps) => {
return {
- '.__list-header': {
+ '.__task-category-item': {
+ marginBottom: token.marginXS
+ },
+
+ '.__tasks-container': {
+ backgroundColor: token.colorWhite,
+ borderRadius: 20,
+ paddingTop: token.paddingXXS,
+ paddingBottom: token.paddingXXS
+ },
+
+ '.__task-category-info': {
+ color: token.colorTextDark1,
display: 'flex',
- alignItems: 'center',
- marginBottom: token.marginXS,
+ gap: token.sizeXS,
+ overflow: 'hidden',
+ paddingLeft: token.paddingSM,
+ paddingRight: token.paddingSM,
+ marginBottom: token.marginXS
+ },
- '.ant-typography': {
- marginBottom: 0
- }
+ '.__task-category-name': {
+ fontSize: token.fontSizeLG,
+ flex: 1,
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ 'white-space': 'nowrap',
+ fontWeight: token.headingFontWeight
},
- '.task-list': {
- padding: token.padding,
+ '.__complete-missions': {
+ fontSize: token.fontSize,
+ lineHeight: token.lineHeight
+ },
- '.account-info': {
- marginBottom: token.marginSM
- }
+ '.__task-item + .__task-item': {
+ marginTop: token.marginXXS
}
};
});
diff --git a/packages/extension-koni-ui/src/Popup/Home/Mission/index.tsx b/packages/extension-koni-ui/src/Popup/Home/Mission/index.tsx
index c5b018fc90..9c8cd51f99 100644
--- a/packages/extension-koni-ui/src/Popup/Home/Mission/index.tsx
+++ b/packages/extension-koni-ui/src/Popup/Home/Mission/index.tsx
@@ -1,24 +1,28 @@
// Copyright 2019-2022 @subwallet/extension-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0
-import GameAccount from '@subwallet/extension-koni-ui/components/Games/GameAccount';
+import { GameAccountBlock } from '@subwallet/extension-koni-ui/components';
import { BookaSdk } from '@subwallet/extension-koni-ui/connector/booka/sdk';
-import { Task, TaskCategory, TaskCategoryInfo } from '@subwallet/extension-koni-ui/connector/booka/types';
+import { EnergyConfig, Task, TaskCategory, TaskCategoryInfo, TaskHistoryStatus } 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 { TaskList } from '@subwallet/extension-koni-ui/Popup/Home/Mission/TaskList';
import { ThemeProps } from '@subwallet/extension-koni-ui/types';
-import React, { useCallback, useEffect, useState } from 'react';
+import React, { useCallback, useContext, useEffect, useState } from 'react';
import styled from 'styled-components';
-import { TaskCategoryList } from './TaskCategoryList';
-
type Props = ThemeProps;
const apiSDK = BookaSdk.instance;
-enum ViewMode {
- CATEGORY_LIST = 'category_list',
- TASK_LIST = 'task_list',
+function getTaskCategoryMap (taskCategories: TaskCategory[]): Record {
+ const result: Record = {};
+
+ taskCategories.forEach((tc) => {
+ result[tc.id] = tc;
+ });
+
+ return result;
}
function getTaskCategoryInfoMap (tasks: Task[]): Record {
@@ -33,26 +37,45 @@ function getTaskCategoryInfoMap (tasks: Task[]): Record {
+ tci.tasks.sort((a, b) => {
+ const aDisabled = ((a.startTime && new Date(a.startTime).getTime() > now) || (a.endTime && new Date(a.endTime).getTime() < now));
+ const bDisabled = ((b.startTime && new Date(b.startTime).getTime() > now) || (b.endTime && new Date(b.endTime).getTime() < now));
- if (t.completedAt || t.status > 0) {
- return;
+ if (aDisabled && !bDisabled) {
+ return 1;
}
- if (t.startTime && (now < new Date(t.startTime).getTime())) {
- return;
+ if (!aDisabled && bDisabled) {
+ return -1;
}
- if (t.endTime && (now >= new Date(t.endTime).getTime())) {
- return;
+ if (a.status === TaskHistoryStatus.COMPLETED && b.status !== TaskHistoryStatus.COMPLETED) {
+ return 1;
}
- result[t.categoryId].minPoint += (t.pointReward || 0);
- }
+ if (a.status !== TaskHistoryStatus.COMPLETED && b.status === TaskHistoryStatus.COMPLETED) {
+ return -1;
+ }
+
+ return 0;
+ });
});
return result;
@@ -60,14 +83,12 @@ function getTaskCategoryInfoMap (tasks: Task[]): Record {
useSetCurrentPage('/home/mission');
- const [taskCategoryList, setTaskCategoryList] = useState(apiSDK.taskCategoryList);
- const [taskCategoryInfoMap, setTaskCategoryInfoMap] = useState>(getTaskCategoryInfoMap(apiSDK.taskList));
+ const [taskCategoryMap, setTaskCategoryMap] = useState>({});
+ const [taskCategoryInfoMap, setTaskCategoryInfoMap] = useState>({});
const [account, setAccount] = useState(apiSDK.account);
- const [currentViewMode, setCurrentViewMode] = useState(ViewMode.CATEGORY_LIST);
- const [currentTaskCategory, setCurrentTaskCategory] = useState();
- const [taskCategory, setTaskCategory] = useState();
+ const [energyConfig, setEnergyConfig] = useState(apiSDK.energyConfig);
const [reloadAccount, setReloadAccount] = useState(0);
- const [point, setPoint] = useState(account?.attributes.point || 0);
+ const { setContainerClass } = useContext(HomeContext);
const actionReloadPoint = useCallback(() => {
setReloadAccount(reloadAccount + 1);
@@ -76,17 +97,24 @@ const Component = ({ className }: Props): React.ReactElement => {
useEffect(() => {
const accountSub = apiSDK.subscribeAccount().subscribe((data) => {
setAccount(data);
- setPoint(data?.attributes.point || 0);
+ });
+
+ const energyConfigSub = apiSDK.subscribeEnergyConfig().subscribe((data) => {
+ setEnergyConfig(data);
});
return () => {
accountSub.unsubscribe();
+ energyConfigSub.unsubscribe();
};
}, [reloadAccount]);
useEffect(() => {
+ setTaskCategoryMap(getTaskCategoryMap(apiSDK.taskCategoryList));
+ setTaskCategoryInfoMap(getTaskCategoryInfoMap(apiSDK.taskList));
+
const taskCategoryListSub = apiSDK.subscribeTaskCategoryList().subscribe((data) => {
- setTaskCategoryList(data);
+ setTaskCategoryMap(getTaskCategoryMap(data));
});
let taskListUpdaterInterval: NodeJS.Timer;
@@ -108,61 +136,51 @@ const Component = ({ className }: Props): React.ReactElement => {
};
}, []);
- const onClickCategoryItem = useCallback((categoryId: number) => {
- setCurrentViewMode(ViewMode.TASK_LIST);
- setCurrentTaskCategory(categoryId);
- setTaskCategory(taskCategoryList.find((tc) => tc.id === categoryId));
- }, []);
-
- const onBackToCategoryList = useCallback(() => {
- setCurrentViewMode(ViewMode.CATEGORY_LIST);
- setCurrentTaskCategory(undefined);
- }, []);
+ useEffect(() => {
+ setContainerClass('mission-screen-wrapper');
- return
-
- {account && (
-
{
+ setContainerClass(undefined);
+ };
+ }, [setContainerClass]);
+
+ return (
+
+
+
- )}
-
- {
- currentViewMode === ViewMode.CATEGORY_LIST && (
-
- )
- }
+
- {
- currentViewMode === ViewMode.TASK_LIST && (
-
- )
- }
+
+
+
- ;
+ );
};
const Mission = styled(Component)
(({ theme: { extendToken, token } }: ThemeProps) => {
return {
- '.task-list': {
- padding: token.padding,
-
- '.account-info': {
- marginBottom: token.marginSM
- }
+ overflow: 'hidden',
+ display: 'flex',
+ flexDirection: 'column',
+
+ '.game-account-block-wrapper': {
+ paddingLeft: token.paddingXS,
+ paddingRight: token.paddingXS,
+ paddingBottom: token.paddingSM
+ },
+
+ '.task-list-container': {
+ paddingLeft: token.paddingXS,
+ paddingRight: token.paddingXS,
+ overflow: 'auto',
+ paddingBottom: 34
}
};
});
diff --git a/packages/extension-koni-ui/src/Popup/Home/index.tsx b/packages/extension-koni-ui/src/Popup/Home/index.tsx
index f2f8573563..4f1294d32d 100644
--- a/packages/extension-koni-ui/src/Popup/Home/index.tsx
+++ b/packages/extension-koni-ui/src/Popup/Home/index.tsx
@@ -108,7 +108,7 @@ const Home = styled(Component)(({ theme: { token } }: Props) => {
}
},
- '&.game-screen-wrapper, &.invitation-screen-wrapper': {
+ '&.game-screen-wrapper, &.invitation-screen-wrapper, &.mission-screen-wrapper': {
'.ant-sw-screen-layout-body': {
paddingBottom: 56,
diff --git a/packages/extension-koni-ui/src/components/Games/GamePoint.tsx b/packages/extension-koni-ui/src/components/Games/GamePoint.tsx
new file mode 100644
index 0000000000..2778b8b085
--- /dev/null
+++ b/packages/extension-koni-ui/src/components/Games/GamePoint.tsx
@@ -0,0 +1,41 @@
+// Copyright 2019-2022 @subwallet/extension-koni-ui authors & contributors
+// SPDX-License-Identifier: Apache-2.0
+
+import DefaultLogosMap from '@subwallet/extension-koni-ui/assets/logo';
+import { ThemeProps } from '@subwallet/extension-koni-ui/types';
+import React from 'react';
+import styled from 'styled-components';
+
+type GamePointProps = ThemeProps & {
+ point: string;
+ size?: number;
+};
+
+function Component ({ className, point, size = 16 }: GamePointProps) {
+ return (
+
+
{point}
+
+
+
+ );
+}
+
+const GamePoint = styled(Component)(({ theme: { token } }: GamePointProps) => {
+ return ({
+ display: 'flex',
+ gap: token.sizeXXS,
+ alignItems: 'center',
+ color: token.colorTextDark3,
+ fontSize: token.fontSize,
+ lineHeight: token.lineHeight
+ });
+});
+
+export default GamePoint;
diff --git a/packages/extension-koni-ui/src/components/Games/Logo.tsx b/packages/extension-koni-ui/src/components/Games/Logo.tsx
deleted file mode 100644
index 9099e919d4..0000000000
--- a/packages/extension-koni-ui/src/components/Games/Logo.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2019-2022 @subwallet/extension-koni-ui authors & contributors
-// SPDX-License-Identifier: Apache-2.0
-
-import { ThemeProps } from '@subwallet/extension-koni-ui/types';
-import { Image } from '@subwallet/react-ui';
-import React from 'react';
-import styled from 'styled-components';
-
-type GameLogoProps = {
- className?: string;
- size?: number;
-}
-
-type GamePointProps = ThemeProps & {
- className?: string;
- preText?: string;
- text: string;
- size?: number;
-};
-
-export function GameLogo ({ className, size = 24 }: GameLogoProps) {
- return ();
-}
-
-function _GamePoint ({ className, preText, size = 16, text }: GamePointProps) {
- return
- {preText && {preText}}
-
- {text}
-
;
-}
-
-export const GamePoint = styled(_GamePoint)(({ theme: { token } }: GamePointProps) => {
- return ({
- display: 'flex',
- alignItems: 'center',
- fontSize: '14px',
- color: token.colorTextDark4,
-
- '.pre-text': {
- marginRight: '3px'
- },
-
- '.game-point': {
- marginRight: '3px'
- }
- });
-});
diff --git a/packages/extension-koni-ui/src/components/Games/index.ts b/packages/extension-koni-ui/src/components/Games/index.ts
index c75decb26f..443196e68d 100644
--- a/packages/extension-koni-ui/src/components/Games/index.ts
+++ b/packages/extension-koni-ui/src/components/Games/index.ts
@@ -5,3 +5,4 @@ export { default as GameAccountAvatar } from './GameAccountAvatar';
export { default as GameAccountBlock } from './GameAccountBlock';
export { default as GameCardItem } from './GameCardItem';
export { default as GameEnergyBar } from './GameEnergyBar';
+export { default as GamePoint } from './GamePoint';
diff --git a/packages/extension-koni-ui/src/connector/booka/types.ts b/packages/extension-koni-ui/src/connector/booka/types.ts
index 26ee744028..1a349ecefe 100644
--- a/packages/extension-koni-ui/src/connector/booka/types.ts
+++ b/packages/extension-koni-ui/src/connector/booka/types.ts
@@ -101,12 +101,11 @@ export interface TaskCategory {
description?: string | null;
icon?: string | null;
active: boolean;
- minPoint?: number;
}
export type TaskCategoryInfo = {
id: number;
- minPoint: number;
+ completeCount: number;
tasks: Task[];
}
diff --git a/packages/extension-koni-ui/src/contexts/ThemeContext.tsx b/packages/extension-koni-ui/src/contexts/ThemeContext.tsx
index b8dc32c7c0..6ca6c6030f 100644
--- a/packages/extension-koni-ui/src/contexts/ThemeContext.tsx
+++ b/packages/extension-koni-ui/src/contexts/ThemeContext.tsx
@@ -419,6 +419,20 @@ const GlobalStyle = createGlobalStyle(({ theme }) => {
'.ant-progress.ant-progress .ant-progress-bg': {
backgroundColor: extendToken.colorBgSecondary2
+ },
+
+ // background icon
+
+ '.background-icon': {
+ '&.-primary-1': {
+ color: token.colorPrimary,
+ backgroundColor: extendToken.colorBgSecondary2
+ },
+
+ '&.-primary-2': {
+ color: token.colorTextDark1,
+ backgroundColor: token.colorPrimary
+ }
}
});
});
diff --git a/packages/webapp/public/assets/reset.css b/packages/webapp/public/assets/reset.css
index f7834f8750..6989d9b2b1 100644
--- a/packages/webapp/public/assets/reset.css
+++ b/packages/webapp/public/assets/reset.css
@@ -808,3 +808,41 @@ div.ant-notification-notice {
.ant-btn.ant-btn > span + .anticon {
margin-inline-start: 4px
}
+
+/* icon */
+.background-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 100%;
+}
+
+.background-icon.-size-1 {
+ font-size: 8px;
+ min-width: 12px;
+ height: 12px;
+}
+
+.background-icon.-size-2 {
+ font-size: 10px;
+ min-width: 16px;
+ height: 16px;
+}
+
+.background-icon.-size-3 {
+ font-size: 16px;
+ min-width: 24px;
+ height: 24px;
+}
+
+.background-icon.-size-4 {
+ font-size: 20px;
+ min-width: 32px;
+ height: 32px;
+}
+
+.background-icon.-size-5 {
+ font-size: 24px;
+ min-width: 40px;
+ height: 40px;
+}