Skip to content

Commit b03ea97

Browse files
committed
current duel detection & reconnection on home page mount
1 parent b52b49d commit b03ea97

File tree

8 files changed

+53
-30
lines changed

8 files changed

+53
-30
lines changed

src/entities/duel/api/duelApi.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ export const duelApiSlice = apiSlice.injectEndpoints({
1818
]
1919
: [{ type: "Duel", id: "LIST" }],
2020
}),
21+
getCurrentDuel: builder.query<Duel, void>({
22+
query: () => `/duels/current`,
23+
providesTags: (result) => [{ type: "Duel", id: result?.id ?? "CURRENT" }],
24+
}),
2125
}),
2226
});
2327

24-
export const { useGetDuelQuery, useGetAllUserDuelsQuery } = duelApiSlice;
28+
export const { useGetDuelQuery, useGetAllUserDuelsQuery, useGetCurrentDuelQuery } = duelApiSlice;

src/entities/duel/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export { duelApiSlice } from "./api/duelApi";
22

3-
export { useGetDuelQuery, useGetAllUserDuelsQuery } from "./api/duelApi";
3+
export { useGetDuelQuery, useGetAllUserDuelsQuery, useGetCurrentDuelQuery } from "./api/duelApi";
44

55
export { DuelResult } from "./ui/DuelResult/DuelResult";
66
export { DuelHistory } from "./ui/DuelHistory/DuelHistory";

src/entities/duel/ui/DuelResult/DuelResult.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ export const DuelResult = ({ winnerId, meId, otherId }: Props) => {
2727

2828
return (
2929
<div className={styles.result}>
30-
<span className={classMap[other]}>{other}</span>
31-
<span>-</span>
3230
<span className={classMap[me]}>{me}</span>
31+
<span>-</span>
32+
<span className={classMap[other]}>{other}</span>
3333
</div>
3434
);
3535
};

src/features/duel-session/api/duelSessionApi.ts

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
resetDuelSession,
1111
} from "../model/duelSessionSlice";
1212
import { DuelMessage } from "../model/types";
13+
import { SSE_RETRY_TIMEOUT } from "../lib/const";
1314

1415
// TODO: надо порефакторить будет я уже путаюсь
1516
export const duelSessionApiSlice = apiSlice.injectEndpoints({
@@ -75,37 +76,40 @@ export const duelSessionApiSlice = apiSlice.injectEndpoints({
7576
};
7677

7778
const errorListener = async (event: MessageEvent) => {
78-
console.warn("SSE error:", event);
79-
console.log("Retrying SSE connection...");
79+
const sseReconnect = async () => {
80+
const state = getState() as RootState;
8081

81-
const newAccessToken = await refreshAuthToken(
82-
getState() as RootState,
83-
dispatch,
84-
);
82+
if (state.duelSession.phase === "idle") return;
8583

86-
if (newAccessToken) {
87-
eventSource.close();
84+
console.warn("SSE error:", event);
85+
console.log("Retrying SSE connection...");
8886

89-
const currentState = getState() as RootState;
90-
const lastEventId = currentState.duelSession.lastEventId;
91-
const reconnectHeaders: Record<string, string> = {
92-
Authorization: `Bearer ${newAccessToken}`,
93-
};
87+
const newAccessToken = await refreshAuthToken(state, dispatch);
9488

95-
if (lastEventId) {
96-
reconnectHeaders["Last-Event-ID"] = lastEventId;
97-
}
89+
if (newAccessToken) {
90+
eventSource.close();
9891

99-
eventSource = new SSE(
100-
`${import.meta.env.VITE_BASE_URL}/duels/connect`,
101-
{
102-
headers: reconnectHeaders,
103-
},
104-
);
105-
setupListeners();
92+
const currentState = getState() as RootState;
93+
const lastEventId = currentState.duelSession.lastEventId;
94+
const reconnectHeaders: Record<string, string> = {
95+
Authorization: `Bearer ${newAccessToken}`,
96+
};
10697

107-
console.log("SSE Connection re-established");
108-
}
98+
if (lastEventId) {
99+
reconnectHeaders["Last-Event-ID"] = lastEventId;
100+
}
101+
102+
eventSource = new SSE(
103+
`${import.meta.env.VITE_BASE_URL}/duels/connect`,
104+
{
105+
headers: reconnectHeaders,
106+
},
107+
);
108+
setupListeners();
109+
}
110+
};
111+
112+
setTimeout(sseReconnect, SSE_RETRY_TIMEOUT);
109113
};
110114

111115
const setupListeners = () => {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const SSE_RETRY_TIMEOUT = 3000;

src/features/duel-session/model/duelSessionSlice.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
22

3+
import { duelApiSlice } from "entities/duel";
34
import { DuelSessionState, DuelSessionPhase } from "./types";
5+
import { restoreDuelSession } from "./thunks";
46

57
const initialState: DuelSessionState = {
68
activeDuelId: null,
@@ -37,6 +39,15 @@ const duelSessionSlice = createSlice({
3739
state.lastEventId = null;
3840
},
3941
},
42+
extraReducers: (builder) => {
43+
builder.addMatcher(
44+
duelApiSlice.endpoints.getCurrentDuel.matchFulfilled,
45+
(state, { payload }) => {
46+
state.activeDuelId = payload.id;
47+
restoreDuelSession(state.activeDuelId);
48+
},
49+
);
50+
},
4051
});
4152

4253
export const { setPhase, setActiveDuelId, setLastEventId, resetDuelSession } =

src/features/duel-session/ui/DuelSessionButton/DuelSessionButton.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useGetCurrentDuelQuery } from "entities/duel";
12
import { setPhase } from "features/duel-session/model/duelSessionSlice";
23
import { selectDuelSession } from "features/duel-session/model/selectors";
34
import { DuelSessionPhase } from "features/duel-session/model/types";
@@ -11,6 +12,8 @@ export const DuelSessionButton = () => {
1112

1213
const dispatch = useAppDispatch();
1314

15+
useGetCurrentDuelQuery();
16+
1417
const { phase, activeDuelId } = useAppSelector(selectDuelSession);
1518
const prevPhaseRef = useRef<DuelSessionPhase>(phase);
1619

src/features/duel-session/ui/DuelSessionManager/DuelSessionManager.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const DuelSessionManager = () => {
1515
const subscriptionRef = useRef<{ unsubscribe: () => void } | null>(null);
1616

1717
useEffect(() => {
18-
// If user logged in and he has an active duel but phase is idle, try to restore session
18+
// If user logged in and he has an active duel but phase is idle, try to restore session
1919
if (user && activeDuelId && phase === "idle") {
2020
dispatch(restoreDuelSession(activeDuelId));
2121
}

0 commit comments

Comments
 (0)