Commit 55a8cd22 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/migrate/redux' into 'main'

Feat/migrate/redux

See merge request mycard/Neos!3
parents bfe59ab4 d94cd647
Pipeline #17237 passed with stage
in 1 minute and 26 seconds
This diff is collapsed.
import React from "react";
import JoinRoom from "./JoinRoom";
import WaitRoom from "./WaitRoom";
import JoinRoom from "./ui/JoinRoom";
import WaitRoom from "./ui//WaitRoom";
import ThreeJs from "./ThreeJs";
import { Routes, Route } from "react-router-dom";
......
This source diff could not be displayed because it is too large. You can view the blob instead.
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./store";
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { store } from "./store";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
......@@ -10,12 +11,9 @@ const root = ReactDOM.createRoot(
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "../store";
export interface chatState {
message: string;
}
const initialState: chatState = {
message: "",
};
const chatSlice = createSlice({
name: "chat",
initialState,
reducers: {
postChat: (state, action: PayloadAction<string>) => {
state.message = action.payload;
},
},
});
export const { postChat } = chatSlice.actions;
export const selectChat = (state: RootState) => state.chat.message;
export default chatSlice.reducer;
import { createSlice } from "@reduxjs/toolkit";
import { RootState } from "../store";
export interface JoinState {
value: boolean;
}
const initialState: JoinState = {
value: false,
};
const joinedSlice = createSlice({
name: "join",
initialState,
reducers: {
setJoined: (state) => {
state.value = true;
},
setUnJoined: (state) => {
state.value = false;
},
},
});
export const { setJoined, setUnJoined } = joinedSlice.actions;
export const selectJoined = (state: RootState) => state.join.value;
export default joinedSlice.reducer;
import { ReportHandler } from "web-vitals";
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;
import { configureStore } from "@reduxjs/toolkit";
import joinedReducer from "./reducers/joinSlice";
import chatReducer from "./reducers/chatSlice";
export const store = configureStore({
reducer: {
join: joinedReducer,
chat: chatReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
import React, { useState, ChangeEvent } from "react";
import { Link } from "react-router-dom";
import "./css/JoinRoom.css";
import "../css/JoinRoom.css";
export default function JoinRoom() {
const [player, setPlayer] = useState("");
......
import React, { useRef, useEffect, useState, useReducer } from "react";
import { useParams } from "react-router-dom";
import { ygopro } from "./api/idl/ocgcore";
import { fetchDeck, IDeck } from "./Card";
import "./css/WaitRoom.css";
import { ygopro } from "../api/idl/ocgcore";
import { fetchDeck, IDeck } from "../api/Card";
import "../css/WaitRoom.css";
import { useAppDispatch, useAppSelector } from "../hook";
import { setJoined, selectJoined } from "../reducers/joinSlice";
import { postChat, selectChat } from "../reducers/chatSlice";
type Player = {
name?: string;
......@@ -20,17 +23,17 @@ export default function WaitRoom() {
ip?: string;
}>();
const [joined, setJoined] = useState<boolean>(false);
const [chat, setChat] = useState<string>("");
const [choseDeck, setChoseDeck] = useState<boolean>(false);
const [observerCount, setObserverCount] = useState<number>(0);
const [player0, setPlayer0] = useState<Player>({});
const [player1, setPlayer1] = useState<Player>({});
const [isHost, setIsHost] = useState<boolean>(false);
const [_, forceUpdate] = useReducer(x => x + 1, 0); // todo: use correct update design
const [_, forceUpdate] = useReducer((x) => x + 1, 0); // todo: use correct update design
const ws = useRef<WebSocket | null>(null);
const dispatch = useAppDispatch();
const { player, passWd, ip } = params;
useEffect(() => {
......@@ -61,20 +64,21 @@ export default function WaitRoom() {
console.log("Websocket closed");
};
ws.current.onmessage = e => {
ws.current.onmessage = (e) => {
const pb = ygopro.YgoStocMsg.deserializeBinary(e.data);
switch (pb.msg) {
case "stoc_join_game": {
const msg = pb.stoc_join_game;
// todo
setJoined(true);
dispatch(setJoined());
break;
}
case "stoc_chat": {
const chat = pb.stoc_chat;
setChat(chat.msg);
dispatch(postChat(chat.msg));
break;
}
case "stoc_hs_player_change": {
......@@ -225,6 +229,9 @@ export default function WaitRoom() {
};
}, [ws]);
const joined = useAppSelector(selectJoined);
const chat = useAppSelector(selectChat);
const handleChoseDeck = async () => {
if (ws.current) {
const deck = await fetchDeck("hero.ydk");
......@@ -298,8 +305,8 @@ export default function WaitRoom() {
function sendPlayerInfo(ws: WebSocket, player: string) {
const playerInfo = new ygopro.YgoCtosMsg({
ctos_player_info: new ygopro.CtosPlayerInfo({
name: player
})
name: player,
}),
});
ws.send(playerInfo.serialize());
......@@ -310,8 +317,8 @@ function sendJoinGame(ws: WebSocket, version: number, passWd: string) {
ctos_join_game: new ygopro.CtosJoinGame({
version, // todo: use config
gameid: 0,
passwd: passWd
})
passwd: passWd,
}),
});
ws.send(joinGame.serialize());
......@@ -322,8 +329,8 @@ function sendUpdateDeck(ws: WebSocket, deck: IDeck) {
ctos_update_deck: new ygopro.CtosUpdateDeck({
main: deck.main,
extra: deck.extra,
side: deck.side
})
side: deck.side,
}),
});
ws.send(updateDeck.serialize());
......@@ -331,7 +338,7 @@ function sendUpdateDeck(ws: WebSocket, deck: IDeck) {
function sendHsReady(ws: WebSocket) {
const hasReady = new ygopro.YgoCtosMsg({
ctos_hs_ready: new ygopro.CtosHsReady({})
ctos_hs_ready: new ygopro.CtosHsReady({}),
});
ws.send(hasReady.serialize());
......@@ -339,7 +346,7 @@ function sendHsReady(ws: WebSocket) {
function sendHsStart(ws: WebSocket) {
const hasStart = new ygopro.YgoCtosMsg({
ctos_hs_start: new ygopro.CtosHsStart({})
ctos_hs_start: new ygopro.CtosHsStart({}),
});
ws.send(hasStart.serialize());
......
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