Commit 53ceb647 authored by timel's avatar timel

feat: add valtio store and some basic codes

parent ac911303
......@@ -36,6 +36,7 @@
"react-scripts": "^2.1.3",
"socket.io-client": "^4.6.1",
"sql.js": "^1.8.0",
"valtio": "^1.10.4",
"vite-plugin-svgr": "^2.4.0",
"web-vitals": "^2.1.4",
"ygopro-deck-encode": "^1.0.3"
......@@ -19793,6 +19794,11 @@
"node": ">= 0.10"
}
},
"node_modules/proxy-compare": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.5.0.tgz",
"integrity": "sha512-f1us0OsVAJ3tdIMXGQx2lmseYS4YXe4W+sKF5g5ww/jV+5ogMadPt+sIZ+88Ga9kvMJsrRNWzCrKPpr6pMWYbA=="
},
"node_modules/prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
......@@ -26640,6 +26646,26 @@
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/valtio": {
"version": "1.10.4",
"resolved": "https://registry.npmjs.org/valtio/-/valtio-1.10.4.tgz",
"integrity": "sha512-gqGWh0DjtDMAy8Jaui8ufFoxlQB1k1NiA/QHrpKoTUk9EeY331WKeYhvtGn1u703RcefrDCez7PT+qeCu9lWEw==",
"dependencies": {
"proxy-compare": "2.5.0",
"use-sync-external-store": "1.2.0"
},
"engines": {
"node": ">=12.20.0"
},
"peerDependencies": {
"react": ">=16.8"
},
"peerDependenciesMeta": {
"react": {
"optional": true
}
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
......@@ -43821,6 +43847,11 @@
"ipaddr.js": "1.9.1"
}
},
"proxy-compare": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.5.0.tgz",
"integrity": "sha512-f1us0OsVAJ3tdIMXGQx2lmseYS4YXe4W+sKF5g5ww/jV+5ogMadPt+sIZ+88Ga9kvMJsrRNWzCrKPpr6pMWYbA=="
},
"prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
......@@ -49103,6 +49134,15 @@
"spdx-expression-parse": "^3.0.0"
}
},
"valtio": {
"version": "1.10.4",
"resolved": "https://registry.npmjs.org/valtio/-/valtio-1.10.4.tgz",
"integrity": "sha512-gqGWh0DjtDMAy8Jaui8ufFoxlQB1k1NiA/QHrpKoTUk9EeY331WKeYhvtGn1u703RcefrDCez7PT+qeCu9lWEw==",
"requires": {
"proxy-compare": "2.5.0",
"use-sync-external-store": "1.2.0"
}
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
......@@ -26,6 +26,8 @@ import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom";
import { ValtioProvider } from "@/stores";
import { store } from "./store";
import Neos from "./ui/Neos";
......@@ -36,12 +38,14 @@ root.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<ConfigProvider
theme={{ algorithm: theme.darkAlgorithm }}
locale={zhCN}
>
<Neos />
</ConfigProvider>
<ValtioProvider>
<ConfigProvider
theme={{ algorithm: theme.darkAlgorithm }}
locale={zhCN}
>
<Neos />
</ConfigProvider>
</ValtioProvider>
</Provider>
</BrowserRouter>
</React.StrictMode>
......
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { selectHandAble } from "@/reducers/moraSlice";
import { store } from "@/store";
import { moraStore } from "@/stores";
export default function handleSelectHand(_: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
dispatch(selectHandAble());
moraStore.selectHandAble = true;
}
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { postChat } from "@/reducers/chatSlice";
import { store } from "@/store";
import { chatStore } from "@/stores";
export default function handleChat(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
const chat = pb.stoc_chat;
dispatch(postChat(chat.msg));
chatStore.message = chat.msg;
}
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { player0Enter, player1Enter } from "@/reducers/playerSlice";
import { store } from "@/store";
import { playerStore } from "@/stores";
export default function handleHsPlayerEnter(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
......@@ -12,5 +13,6 @@ export default function handleHsPlayerEnter(pb: ygopro.YgoStocMsg) {
console.log("Currently only supported 2v2 mode.");
} else {
pos == 0 ? dispatch(player0Enter(name)) : dispatch(player1Enter(name));
playerStore[pos == 0 ? "player0" : "player1"].name = name;
}
}
import { proxy } from "valtio";
export interface ChatState {
message: string;
}
export const chatStore = proxy<ChatState>({
message: "",
});
export * from "./chatStore";
export * from "./joinStore";
export * from "./moraStore";
export * from "./playerStore";
import { createContext, type ReactNode, useRef } from "react";
import { proxy } from "valtio";
import { devtools } from "valtio/utils";
import { chatStore } from "./chatStore";
import { joinStore } from "./joinStore";
import { moraStore } from "./moraStore";
import { playerStore } from "./playerStore";
export const valtioStore = proxy({
playerStore,
chatStore,
joinStore,
moraStore,
});
devtools(valtioStore, { name: "valtio store", enabled: true });
/**
* 在组件之中使用valtio store
*/
export const ValtioContext = createContext<typeof valtioStore>({} as any);
/**
* 包裹根节点,使得所有子组件都可以使用valtio store
*/
export const ValtioProvider: React.FC<{ children: ReactNode }> = ({
children,
}) => {
const state = useRef(valtioStore).current;
return (
<ValtioContext.Provider value={state}>{children}</ValtioContext.Provider>
);
};
import { proxy } from "valtio";
export interface JoinState {
value: boolean;
}
export const joinStore = proxy<JoinState>({
value: false,
});
import { proxy } from "valtio";
export interface MoraState {
duelStart: boolean;
selectHandAble: boolean;
selectTpAble: boolean;
}
export const moraStore = proxy<MoraState>({
duelStart: false,
selectHandAble: false,
selectTpAble: false,
});
import { proxy } from "valtio";
export interface Player {
name?: string;
state?: string;
isHost?: boolean;
deckInfo?: deckInfo;
}
export interface deckInfo {
mainCnt: number;
extraCnt: number;
sideCnt: number;
}
export interface PlayerState {
player0: Player;
player1: Player;
observerCount: number;
isHost: boolean;
}
export const playerStore = proxy<PlayerState>({
player0: {},
player1: {},
observerCount: 0,
isHost: false,
});
import Icon, { StarOutlined } from "@ant-design/icons";
import { Button, Card, Col, Modal, Row } from "antd";
import { ReactComponent as BattleSvg } from "neos-assets/battle-axe.svg";
import { ReactComponent as DefenceSvg } from "neos-assets/checked-shield.svg";
import React from "react";
import { sendSelectIdleCmdResponse } from "@/api/ocgcore/ocgHelper";
......@@ -18,8 +20,6 @@ import {
} from "@/reducers/duel/modal/mod";
import { store } from "@/store";
import { ReactComponent as BattleSvg } from "neos-assets/battle-axe.svg";
import { ReactComponent as DefenceSvg } from "neos-assets/checked-shield.svg";
import {
Attribute2StringCodeMap,
extraCardTypes,
......
import Icon from "@ant-design/icons";
import { Button, Modal, Space } from "antd";
import { ReactComponent as BattleSvg } from "neos-assets/crossed-swords.svg";
import { ReactComponent as EpSvg } from "neos-assets/power-button.svg";
import { ReactComponent as Main2Svg } from "neos-assets/sword-in-stone.svg";
import { ReactComponent as SurrenderSvg } from "neos-assets/truce.svg";
import React, { useState } from "react";
import {
......@@ -22,11 +26,6 @@ import {
} from "@/reducers/duel/phaseSlice";
import { store } from "@/store";
import { ReactComponent as BattleSvg } from "neos-assets/crossed-swords.svg";
import { ReactComponent as EpSvg } from "neos-assets/power-button.svg";
import { ReactComponent as Main2Svg } from "neos-assets/sword-in-stone.svg";
import { ReactComponent as SurrenderSvg } from "neos-assets/truce.svg";
const IconSize = "150%";
const SpaceSize = 16;
......
import Icon, { StarOutlined } from "@ant-design/icons";
import { Button, Card, Col, Modal, Row } from "antd";
import { ReactComponent as BattleSvg } from "neos-assets/battle-axe.svg";
import { ReactComponent as DefenceSvg } from "neos-assets/checked-shield.svg";
import React from "react";
import { sendSelectIdleCmdResponse } from "@/api/ocgcore/ocgHelper";
......@@ -18,8 +20,6 @@ import {
} from "@/reducers/duel/modal/mod";
import { store } from "@/store";
import { ReactComponent as BattleSvg } from "neos-assets/battle-axe.svg";
import { ReactComponent as DefenceSvg } from "neos-assets/checked-shield.svg";
import {
Attribute2StringCodeMap,
extraCardTypes,
......
import Icon from "@ant-design/icons";
import { Button, Modal, Space } from "antd";
import { ReactComponent as BattleSvg } from "neos-assets/crossed-swords.svg";
import { ReactComponent as EpSvg } from "neos-assets/power-button.svg";
import { ReactComponent as Main2Svg } from "neos-assets/sword-in-stone.svg";
import { ReactComponent as SurrenderSvg } from "neos-assets/truce.svg";
import React, { useState } from "react";
import {
......@@ -22,11 +26,6 @@ import {
} from "@/reducers/duel/phaseSlice";
import { store } from "@/store";
import { ReactComponent as BattleSvg } from "neos-assets/crossed-swords.svg";
import { ReactComponent as EpSvg } from "neos-assets/power-button.svg";
import { ReactComponent as Main2Svg } from "neos-assets/sword-in-stone.svg";
import { ReactComponent as SurrenderSvg } from "neos-assets/truce.svg";
const IconSize = "150%";
const SpaceSize = 16;
......
......@@ -4,7 +4,7 @@ import {
TableOutlined,
} from "@ant-design/icons";
import { Button, Modal } from "antd";
import React, { useEffect } from "react";
import React, { useContext, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { sendHandResult, sendTpResult } from "@/api/ocgcore/ocgHelper";
......@@ -18,6 +18,7 @@ import {
unSelectTpAble,
} from "@/reducers/moraSlice";
import { store } from "@/store";
import { ValtioContext } from "@/stores";
const {
automation: { isAiMode, isAiFirst },
......@@ -25,6 +26,8 @@ const {
} = useConfig();
const Mora = () => {
const stateMora = useContext(ValtioContext).moraStore;
const dispatch = store.dispatch;
const selectHandAble = useAppSelector(selectHandSelectAble);
const selectTpAble = useAppSelector(selectTpSelectAble);
......@@ -39,10 +42,12 @@ const Mora = () => {
const handleSelectMora = (selected: string) => {
sendHandResult(selected);
dispatch(unSelectHandAble());
stateMora.selectHandAble = false;
};
const handleSelectTp = (isFirst: boolean) => {
sendTpResult(isFirst);
dispatch(unSelectTpAble());
stateMora.selectTpAble = false;
};
useEffect(() => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment