Skip to content

Commit 8fb4bd5

Browse files
committed
Enhance ADHDController with explosion handling and update styles
- Added explosion state management to ADHDController, allowing for visual effects during specific actions. - Implemented new action types for explosion start, finish, and completion in the reducer. - Introduced a video element for explosion effects, enhancing user experience. - Updated ADHDLayout styles to accommodate the new explosion video. - Modified BreakingNews styles for improved readability with italic font style.
1 parent bc23c31 commit 8fb4bd5

File tree

4 files changed

+98
-5
lines changed

4 files changed

+98
-5
lines changed

src/components/OBS_Components/ADHDLayout/ADHDController.tsx

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ interface ADHDState {
1010
isVisible: boolean;
1111
duration: number;
1212
remainingTime: number;
13+
isExploding: boolean;
1314
}
1415

1516
type ADHDAction =
1617
| { type: "SHOW"; payload: { duration: number } }
1718
| { type: "HIDE" }
1819
| { type: "TICK" }
19-
| { type: "EXTEND"; payload: { duration: number } };
20+
| { type: "EXTEND"; payload: { duration: number } }
21+
| { type: "START_EXPLOSION" }
22+
| { type: "FINISH_EXPLOSION" }
23+
| { type: "COMPLETE_EXPLOSION" };
2024

2125
const adhdReducer = (state: ADHDState, action: ADHDAction): ADHDState => {
2226
switch (action.type) {
@@ -25,31 +29,55 @@ const adhdReducer = (state: ADHDState, action: ADHDAction): ADHDState => {
2529
isVisible: true,
2630
duration: action.payload.duration,
2731
remainingTime: action.payload.duration,
32+
isExploding: false,
2833
};
2934
case "HIDE":
3035
return {
3136
...state,
3237
isVisible: false,
3338
remainingTime: 0,
39+
isExploding: false,
3440
};
3541
case "TICK":
3642
if (state.remainingTime <= 1) {
3743
return {
3844
...state,
39-
isVisible: false,
40-
remainingTime: 0,
45+
isExploding: true,
4146
};
4247
}
4348
return {
4449
...state,
4550
remainingTime: state.remainingTime - 1,
4651
};
4752
case "EXTEND":
53+
if (state.isExploding) {
54+
// Если идет взрыв, добавляем в очередь
55+
return state;
56+
}
4857
return {
4958
...state,
5059
duration: state.duration + action.payload.duration,
5160
remainingTime: state.remainingTime + action.payload.duration,
5261
};
62+
case "START_EXPLOSION":
63+
return {
64+
...state,
65+
isExploding: true,
66+
};
67+
case "FINISH_EXPLOSION":
68+
return {
69+
...state,
70+
isVisible: false,
71+
remainingTime: 0,
72+
// isExploding остается true для продолжения воспроизведения видео
73+
};
74+
case "COMPLETE_EXPLOSION":
75+
return {
76+
...state,
77+
isVisible: false,
78+
remainingTime: 0,
79+
isExploding: false,
80+
};
5381
default:
5482
return state;
5583
}
@@ -59,12 +87,15 @@ const initialState: ADHDState = {
5987
isVisible: false,
6088
duration: 0,
6189
remainingTime: 0,
90+
isExploding: false,
6291
};
6392

6493
export function ADHDController() {
6594
const [announced, setAnnounced] = useState<boolean>(false);
6695
const [state, dispatch] = useReducer(adhdReducer, initialState);
96+
const [pendingExtensions, setPendingExtensions] = useState<number[]>([]);
6797
const intervalRef = useRef<NodeJS.Timeout | null>(null);
98+
const explosionRef = useRef<HTMLVideoElement | null>(null);
6899

69100
// Функция форматирования времени в формат MM:SS
70101
const formatTime = (seconds: number): string => {
@@ -74,6 +105,12 @@ export function ADHDController() {
74105
};
75106

76107
const handleMessage = (duration: number) => {
108+
if (state.isExploding) {
109+
// Если идет взрыв, добавляем в очередь продлений
110+
setPendingExtensions(prev => [...prev, duration]);
111+
return;
112+
}
113+
77114
if (state.isVisible) {
78115
// Если уже показывается, продлеваем время
79116
dispatch({ type: "EXTEND", payload: { duration } });
@@ -87,10 +124,11 @@ export function ADHDController() {
87124
SignalRContext.useSignalREffect("adhd", handleMessage, [
88125
handleMessage,
89126
state.isVisible,
127+
state.isExploding,
90128
]);
91129

92130
useEffect(() => {
93-
if (state.isVisible && state.remainingTime > 0) {
131+
if (state.isVisible && state.remainingTime > 0 && !state.isExploding) {
94132
intervalRef.current = setInterval(() => {
95133
dispatch({ type: "TICK" });
96134
}, 1000);
@@ -107,7 +145,41 @@ export function ADHDController() {
107145
intervalRef.current = null;
108146
}
109147
};
110-
}, [state.isVisible, state.remainingTime]);
148+
}, [state.isVisible, state.remainingTime, state.isExploding]);
149+
150+
useEffect(() => {
151+
if (state.isExploding && explosionRef.current) {
152+
const videoElement = explosionRef.current;
153+
videoElement.play();
154+
155+
// Скрываем ADHDPage через 2 секунды после начала взрыва
156+
const hideTimer = setTimeout(() => {
157+
dispatch({ type: "FINISH_EXPLOSION" });
158+
159+
// Проверяем очередь продлений
160+
if (pendingExtensions.length > 0) {
161+
const totalExtension = pendingExtensions.reduce(
162+
(sum, ext) => sum + ext,
163+
0
164+
);
165+
setPendingExtensions([]);
166+
dispatch({ type: "SHOW", payload: { duration: totalExtension } });
167+
}
168+
}, 2000);
169+
170+
// Ждем окончания видео для полного завершения состояния
171+
const handleVideoEnd = () => {
172+
dispatch({ type: "COMPLETE_EXPLOSION" });
173+
};
174+
175+
videoElement.addEventListener("ended", handleVideoEnd);
176+
177+
return () => {
178+
clearTimeout(hideTimer);
179+
videoElement.removeEventListener("ended", handleVideoEnd);
180+
};
181+
}
182+
}, [state.isExploding, pendingExtensions]);
111183

112184
return (
113185
<>
@@ -126,6 +198,15 @@ export function ADHDController() {
126198
</div>
127199
</div>
128200
)}
201+
{state.isExploding && (
202+
<video
203+
ref={explosionRef}
204+
className={styles.explosionVideo}
205+
src="/src/components/OBS_Components/ADHDLayout/content/explosion.webm"
206+
autoPlay
207+
muted
208+
/>
209+
)}
129210
</>
130211
);
131212
}

src/components/OBS_Components/ADHDLayout/ADHDLayout.module.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,15 @@
171171
100% {
172172
transform: scale(1.4);
173173
}
174+
}
175+
176+
.explosionVideo {
177+
position: absolute;
178+
top: 0;
179+
left: 0;
180+
width: 100%;
181+
height: 100%;
182+
object-fit: cover;
183+
z-index: 1003;
184+
pointer-events: none;
174185
}

src/components/OBS_Components/ADHDLayout/components/BreakingNews.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
align-items: center;
1111
border-top: 1px solid #000;
1212
border-bottom: 1px solid #000;
13+
font-style: italic;
1314
}
1415

1516
.breakingNewsContent {
-1.55 MB
Binary file not shown.

0 commit comments

Comments
 (0)