Commit 100e9f96 authored by timel's avatar timel

feat: valtio store logic

parent 4b3fa376
......@@ -26,7 +26,7 @@ import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom";
import { ValtioProvider } from "@/stores";
import { ValtioProvider } from "@/valtioStores";
import { store } from "./store";
import Neos from "./ui/Neos";
......
......@@ -2,6 +2,8 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { player0DeckInfo, player1DeckInfo } from "@/reducers/playerSlice";
import { store } from "@/store";
import { playerStore } from "@/valtioStores";
// FIXME: player0 不一定是当前玩家
export default function handleDeckCount(pb: ygopro.YgoStocMsg) {
const dispath = store.dispatch;
......@@ -15,6 +17,12 @@ export default function handleDeckCount(pb: ygopro.YgoStocMsg) {
})
);
playerStore.player0.deckInfo = {
mainCnt: deckCount.meMain,
extraCnt: deckCount.meExtra,
sideCnt: deckCount.meSide,
};
dispath(
player1DeckInfo({
mainCnt: deckCount.opMain,
......@@ -22,4 +30,10 @@ export default function handleDeckCount(pb: ygopro.YgoStocMsg) {
sideCnt: deckCount.opSide,
})
);
playerStore.player1.deckInfo = {
mainCnt: deckCount.opMain,
extraCnt: deckCount.opExtra,
sideCnt: deckCount.opSide,
};
}
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { selectHandAble } from "@/reducers/moraSlice";
import { store } from "@/store";
import { moraStore } from "@/stores";
import { moraStore } from "@/valtioStores";
export default function handleSelectHand(_: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
......
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { selectTpAble } from "@/reducers/moraSlice";
import { store } from "@/store";
import { moraStore } from "@/valtioStores";
export default function handleSelectTp(_: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
dispatch(selectTpAble());
moraStore.selectTpAble = true;
}
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { postChat } from "@/reducers/chatSlice";
import { store } from "@/store";
import { chatStore } from "@/stores";
import { chatStore } from "@/valtioStores";
export default function handleChat(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
......
......@@ -2,8 +2,11 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { duelStart } from "@/reducers/moraSlice";
import { store } from "@/store";
import { moraStore } from "@/valtioStores";
export default function handleDuelStart(_pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
dispatch(duelStart());
moraStore.duelStart = true;
}
......@@ -6,6 +6,7 @@ import {
player1Leave,
player1Update,
} from "@/reducers/playerSlice";
import { playerStore } from "@/valtioStores";
import { store } from "@/store";
const READY_STATE = "ready";
......@@ -48,25 +49,30 @@ export default function handleHsPlayerChange(pb: ygopro.YgoStocMsg) {
change.pos == 0
? dispatch(player0Update(READY_STATE))
: dispatch(player1Update(READY_STATE));
playerStore[change.pos == 0 ? "player0" : "player1"].state =
READY_STATE;
break;
}
case ygopro.StocHsPlayerChange.State.NO_READY: {
change.pos == 0
? dispatch(player0Update(NO_READY_STATE))
: dispatch(player1Update(NO_READY_STATE));
playerStore[change.pos == 0 ? "player0" : "player1"].state =
NO_READY_STATE;
break;
}
case ygopro.StocHsPlayerChange.State.LEAVE: {
change.pos == 0 ? dispatch(player0Leave) : dispatch(player1Leave);
playerStore[change.pos == 0 ? "player0" : "player1"] = {};
break;
}
case ygopro.StocHsPlayerChange.State.TO_OBSERVER: {
change.pos == 0 ? dispatch(player0Leave) : dispatch(player1Leave);
dispatch(observerIncrement());
playerStore[change.pos == 0 ? "player0" : "player1"] = {}; // todo: 有没有必要?
playerStore.observerCount += 1;
break;
}
default: {
......
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { player0Enter, player1Enter } from "@/reducers/playerSlice";
import { store } from "@/store";
import { playerStore } from "@/stores";
import { playerStore } from "@/valtioStores";
export default function handleHsPlayerEnter(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
......
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { observerChange } from "@/reducers/playerSlice";
import { store } from "@/store";
import { playerStore } from "@/valtioStores";
export default function handleHsWatchChange(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
const count = pb.stoc_hs_watch_change.count;
dispatch(observerChange(count));
playerStore.observerCount = count;
}
......@@ -2,10 +2,14 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { setJoined } from "@/reducers/joinSlice";
import { store } from "@/store";
import { joinStore } from "@/valtioStores";
export default function handleJoinGame(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
const msg = pb.stoc_join_game;
// todo
dispatch(setJoined());
joinStore.value = true;
}
......@@ -6,6 +6,7 @@ import {
updateIsHost,
} from "@/reducers/playerSlice";
import { store } from "@/store";
import { playerStore } from "@/valtioStores";
const NO_READY_STATE = "not ready";
......@@ -22,12 +23,20 @@ export default function handleTypeChange(pb: ygopro.YgoStocMsg) {
dispatch(hostChange(0));
dispatch(player0Update(NO_READY_STATE));
playerStore.player0.isHost = true;
playerStore.player1.isHost = false;
playerStore.player0.state = NO_READY_STATE;
break;
}
case ygopro.StocTypeChange.SelfType.PLAYER2: {
dispatch(hostChange(0));
dispatch(player1Update(NO_READY_STATE));
playerStore.player0.isHost = false;
playerStore.player1.isHost = true;
playerStore.player1.state = NO_READY_STATE;
break;
}
default: {
......
import { MessageOutlined } from "@ant-design/icons";
import { Timeline, TimelineItemProps } from "antd";
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useContext } from "react";
import { useAppSelector } from "@/hook";
import { selectChat } from "@/reducers/chatSlice";
import { valtioContext } from "@/valtioStores";
import { useSnapshot } from "valtio";
export const DuelTimeLine = () => {
const [items, setItems] = useState<TimelineItemProps[]>([]);
const chat = useAppSelector(selectChat);
const stateChat = useContext(valtioContext).chatStore;
const snapChat = useSnapshot(stateChat);
// const chat = snapChat.message;
useEffect(() => {
setItems((prev) =>
prev.concat([
......
import { MessageOutlined } from "@ant-design/icons";
import { Timeline, TimelineItemProps } from "antd";
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useContext } from "react";
import { useAppSelector } from "@/hook";
import { selectChat } from "@/reducers/chatSlice";
import { valtioContext } from "@/valtioStores";
import { useSnapshot } from "valtio";
export const DuelTimeLine = () => {
const [items, setItems] = useState<TimelineItemProps[]>([]);
const chat = useAppSelector(selectChat);
const stateChat = useContext(valtioContext).chatStore;
const snapChat = useSnapshot(stateChat);
// const chat = snapChat.message;
useEffect(() => {
setItems((prev) =>
prev.concat([
......
......@@ -18,7 +18,8 @@ import {
unSelectTpAble,
} from "@/reducers/moraSlice";
import { store } from "@/store";
import { ValtioContext } from "@/stores";
import { valtioContext } from "@/valtioStores";
import { useSnapshot } from "valtio";
const {
automation: { isAiMode, isAiFirst },
......@@ -26,12 +27,18 @@ const {
} = useConfig();
const Mora = () => {
const stateMora = useContext(ValtioContext).moraStore;
const stateMora = useContext(valtioContext).moraStore;
const snapMora = useSnapshot(stateMora);
const dispatch = store.dispatch;
const selectHandAble = useAppSelector(selectHandSelectAble);
const selectTpAble = useAppSelector(selectTpSelectAble);
const duelHsStart = useAppSelector(selectDuelHsStart);
// const selectHandAble = snapMora.selectHandAble;
// const selectTpAble = snapMora.selectTpAble;
// const duelHsStart = snapMora.duelStart;
const navigate = useNavigate();
const { player, passWd, ip } = useParams<{
player?: string;
......
......@@ -19,7 +19,7 @@ import {
Space,
Upload,
} from "antd";
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useContext } from "react";
import { useNavigate, useParams } from "react-router-dom";
import rustInit from "rust-src";
import YGOProDeck from "ygopro-deck-encode";
......@@ -45,6 +45,8 @@ import {
selectPlayer1,
} from "@/reducers/playerSlice";
import { store } from "@/store";
import { valtioContext } from "@/valtioStores";
import { useSnapshot } from "valtio";
const NeosConfig = useConfig();
......@@ -56,6 +58,8 @@ const {
} = useConfig();
const WaitRoom = () => {
const state = useContext(valtioContext);
const snap = useSnapshot(state);
const params = useParams<{
player?: string;
passWd?: string;
......@@ -108,6 +112,13 @@ const WaitRoom = () => {
const duelStart = useAppSelector(selectDuelStart);
const [api, contextHolder] = notification.useNotification();
// const joined = snap.joinStore.value;
// const chat = snap.chatStore.message;
// const isHost = snap.playerStore.isHost;
// const player0 = snap.playerStore.player0;
// const player1 = snap.playerStore.player1;
// const duelStart = snap.moraStore.duelStart;
// FIXME: 这些数据应该从`store`中获取
// TODO: 云卡组
const decks = [...DeckManager.keys()].map((deckName) => ({
......
......@@ -24,7 +24,7 @@ devtools(valtioStore, { name: "valtio store", enabled: true });
/**
* 在组件之中使用valtio store
*/
export const ValtioContext = createContext<typeof valtioStore>({} as any);
export const valtioContext = createContext<typeof valtioStore>({} as any);
/**
* 包裹根节点,使得所有子组件都可以使用valtio store
......@@ -34,6 +34,6 @@ export const ValtioProvider: React.FC<{ children: ReactNode }> = ({
}) => {
const state = useRef(valtioStore).current;
return (
<ValtioContext.Provider value={state}>{children}</ValtioContext.Provider>
<valtioContext.Provider value={state}>{children}</valtioContext.Provider>
);
};
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