diff --git a/web/plugins/com.msgbyte.genshin/manifest.json b/web/plugins/com.msgbyte.genshin/manifest.json new file mode 100644 index 00000000..d8be0f94 --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/manifest.json @@ -0,0 +1,9 @@ +{ + "label": "原神工具箱插件", + "name": "com.msgbyte.genshin", + "url": "/plugins/com.msgbyte.genshin/index.js", + "version": "0.0.0", + "author": "msgbyte", + "description": "为Tailchat增加原神相关的娱乐能力", + "requireRestart": true +} diff --git a/web/plugins/com.msgbyte.genshin/package.json b/web/plugins/com.msgbyte.genshin/package.json new file mode 100644 index 00000000..ef82b57e --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/package.json @@ -0,0 +1,9 @@ +{ + "name": "@plugins/com.msgbyte.genshin", + "main": "src/index.ts", + "version": "0.0.0", + "private": true, + "dependencies": { + "genshin-gacha-kit": "^1.1.0" + } +} diff --git a/web/plugins/com.msgbyte.genshin/src/GenshinPanel/GachaPool.tsx b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/GachaPool.tsx new file mode 100644 index 00000000..8a6de7ec --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/GachaPool.tsx @@ -0,0 +1,50 @@ +import { useAsync } from '@capital/common'; +import { Divider } from '@capital/component'; +import React from 'react'; +import { OfficialGachaPoolItem, util } from 'genshin-gacha-kit'; + +const GachaPoolItem: React.FC<{ + items: OfficialGachaPoolItem[]; +}> = React.memo((props) => { + return ( +
+ {props.items.map((i) => ( +
+ + +
{i.item_name}
+
+ ))} +
+ ); +}); +GachaPoolItem.displayName = 'GachaPoolItem'; + +export const GachaPool: React.FC<{ + gachaId: string; +}> = React.memo((props) => { + const { value: poolData } = useAsync(() => { + return util.getGachaData(props.gachaId); + }, [props.gachaId]); + + if (!poolData) { + return
Loading...
; + } + + return ( +
+
{poolData.banner}
+ +
{poolData.date_range}
+
+ + +
+ + + +
{poolData.content}
+
+ ); +}); +GachaPool.displayName = 'GachaPool'; diff --git a/web/plugins/com.msgbyte.genshin/src/GenshinPanel/index.less b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/index.less new file mode 100644 index 00000000..1bf6459a --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/index.less @@ -0,0 +1,23 @@ +.plugin-genshin-panel { + width: 100%; + padding: 10px; + display: flex; + flex-direction: column; + + .gacha-title { + font-weight: bold; + font-size: 22px; + margin-bottom: 10px; + } + + .gacha-pool { + display: flex; + flex-direction: column; + gap: 10px; + + > div { + display: flex; + gap: 10px; + } + } +} diff --git a/web/plugins/com.msgbyte.genshin/src/GenshinPanel/index.tsx b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/index.tsx new file mode 100644 index 00000000..97c7153c --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/index.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { Translate } from '../translate'; +import { util } from 'genshin-gacha-kit'; +import { useAsync } from '@capital/common'; +import { PillTabs, PillTabPane } from '@capital/component'; +import './index.less'; +import { GachaPool } from './GachaPool'; + +const GenshinPanel: React.FC = React.memo(() => { + const { value: gachaList } = useAsync(() => { + return util.getGachaIndex(); + }, []); + + return ( +
+
+ {Translate.genshin} - {Translate.gacha} +
+ + + {(gachaList ?? []).map((item) => ( + + + + ))} + +
+ ); +}); +GenshinPanel.displayName = 'GenshinPanel'; + +export default GenshinPanel; diff --git a/web/plugins/com.msgbyte.genshin/src/index.ts b/web/plugins/com.msgbyte.genshin/src/index.ts new file mode 100644 index 00000000..dc244f7e --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/index.ts @@ -0,0 +1,10 @@ +import { regCustomPanel, Loadable } from '@capital/common'; +import { Translate } from './translate'; + +regCustomPanel({ + position: 'personal', + icon: 'akar-icons:game-controller', + name: 'com.msgbyte.genshin/genshinPanel', + label: Translate.genshin, + render: Loadable(() => import('./GenshinPanel')), +}); diff --git a/web/plugins/com.msgbyte.genshin/src/translate.ts b/web/plugins/com.msgbyte.genshin/src/translate.ts new file mode 100644 index 00000000..4ac43768 --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/translate.ts @@ -0,0 +1,6 @@ +import { localTrans } from '@capital/common'; + +export const Translate = { + genshin: localTrans({ 'zh-CN': '原神', 'en-US': 'Genshin' }), + gacha: localTrans({ 'zh-CN': '抽卡', 'en-US': 'Gacha' }), +}; diff --git a/web/plugins/com.msgbyte.genshin/tsconfig.json b/web/plugins/com.msgbyte.genshin/tsconfig.json new file mode 100644 index 00000000..465a28b5 --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": "./src", + "esModuleInterop": true, + "jsx": "react", + "paths": { + "@capital/*": ["../../../src/plugin/*"], + } + } +} diff --git a/web/src/components/PillTabs.tsx b/web/src/components/PillTabs.tsx index fc8b8898..514edf8c 100644 --- a/web/src/components/PillTabs.tsx +++ b/web/src/components/PillTabs.tsx @@ -1,4 +1,4 @@ -import { Tabs } from 'antd'; +import { Tabs, TabsProps } from 'antd'; import React from 'react'; import './PillTabs.less'; @@ -11,7 +11,7 @@ import './PillTabs.less'; * * */ -export const PillTabs = React.memo((props) => { +export const PillTabs: React.FC = React.memo((props) => { return ( {props.children} diff --git a/web/src/plugin/component/index.tsx b/web/src/plugin/component/index.tsx index 9149b6b6..ae9d04b1 100644 --- a/web/src/plugin/component/index.tsx +++ b/web/src/plugin/component/index.tsx @@ -1,6 +1,6 @@ import { Input } from 'antd'; -export { Button, Checkbox, Input } from 'antd'; +export { Button, Checkbox, Input, Divider } from 'antd'; export const TextArea = Input.TextArea; export { Image } from '@/components/Image'; export { Icon } from '@iconify/react';