Skip to content

Commit bc23c31

Browse files
committed
Implement ADHD Controller and enhance ADHD layout components
- Introduced ADHDController component to manage ADHD-related functionalities. - Updated routing to replace ADHDPage with ADHDController for improved structure. - Enhanced ADHDLayout styles with new animations and layout adjustments for better user experience. - Refactored Notifications component for cleaner code and improved readability. - Adjusted Catisa component styles for better visibility and user interaction.
1 parent e513a36 commit bc23c31

File tree

13 files changed

+289
-70
lines changed

13 files changed

+289
-70
lines changed

api/swagger_hubs.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,24 @@
571571
"responses": { }
572572
}
573573
},
574+
"/hubs/telegramus/Adhd": {
575+
"post": {
576+
"tags": [
577+
"TelegramusHub"
578+
],
579+
"parameters": [
580+
{
581+
"name": "seconds",
582+
"in": "query",
583+
"schema": {
584+
"type": "integer",
585+
"format": "int32"
586+
}
587+
}
588+
],
589+
"responses": { }
590+
}
591+
},
574592
"/hubs/telegramus/Alert": {
575593
"post": {
576594
"tags": [

src/Site/Pages/Layout/Header/Header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const Header: React.FC = () => {
7171
{ label: "Random Mem", path: "/randommem" },
7272
{ label: "Экранные частицы", path: "/confetti" },
7373
{ label: "AFK Screen", path: "/afkscreen" },
74-
{ label: "ADHD News", path: "/adhd" },
74+
{ label: "ADHD Controller", path: "/adhd" },
7575
],
7676
},
7777
{
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { useEffect, useReducer, useRef, useState } from "react";
2+
3+
import { TelegramusHubSignalRContext as SignalRContext } from "@/shared/api/signalr-clients/TelegramusHub/SignalRHubWrapper";
4+
import Announce from "@/shared/Utils/Announce/Announce";
5+
6+
import styles from "./ADHDLayout.module.scss";
7+
import { ADHDPage } from "./ADHDPage";
8+
9+
interface ADHDState {
10+
isVisible: boolean;
11+
duration: number;
12+
remainingTime: number;
13+
}
14+
15+
type ADHDAction =
16+
| { type: "SHOW"; payload: { duration: number } }
17+
| { type: "HIDE" }
18+
| { type: "TICK" }
19+
| { type: "EXTEND"; payload: { duration: number } };
20+
21+
const adhdReducer = (state: ADHDState, action: ADHDAction): ADHDState => {
22+
switch (action.type) {
23+
case "SHOW":
24+
return {
25+
isVisible: true,
26+
duration: action.payload.duration,
27+
remainingTime: action.payload.duration,
28+
};
29+
case "HIDE":
30+
return {
31+
...state,
32+
isVisible: false,
33+
remainingTime: 0,
34+
};
35+
case "TICK":
36+
if (state.remainingTime <= 1) {
37+
return {
38+
...state,
39+
isVisible: false,
40+
remainingTime: 0,
41+
};
42+
}
43+
return {
44+
...state,
45+
remainingTime: state.remainingTime - 1,
46+
};
47+
case "EXTEND":
48+
return {
49+
...state,
50+
duration: state.duration + action.payload.duration,
51+
remainingTime: state.remainingTime + action.payload.duration,
52+
};
53+
default:
54+
return state;
55+
}
56+
};
57+
58+
const initialState: ADHDState = {
59+
isVisible: false,
60+
duration: 0,
61+
remainingTime: 0,
62+
};
63+
64+
export function ADHDController() {
65+
const [announced, setAnnounced] = useState<boolean>(false);
66+
const [state, dispatch] = useReducer(adhdReducer, initialState);
67+
const intervalRef = useRef<NodeJS.Timeout | null>(null);
68+
69+
// Функция форматирования времени в формат MM:SS
70+
const formatTime = (seconds: number): string => {
71+
const minutes = Math.floor(seconds / 60);
72+
const remainingSeconds = seconds % 60;
73+
return `${minutes.toString().padStart(2, "0")}:${remainingSeconds.toString().padStart(2, "0")}`;
74+
};
75+
76+
const handleMessage = (duration: number) => {
77+
if (state.isVisible) {
78+
// Если уже показывается, продлеваем время
79+
dispatch({ type: "EXTEND", payload: { duration } });
80+
} else {
81+
// Если не показывается, начинаем показ
82+
dispatch({ type: "SHOW", payload: { duration } });
83+
}
84+
};
85+
86+
// Подписка на SignalR события
87+
SignalRContext.useSignalREffect("adhd", handleMessage, [
88+
handleMessage,
89+
state.isVisible,
90+
]);
91+
92+
useEffect(() => {
93+
if (state.isVisible && state.remainingTime > 0) {
94+
intervalRef.current = setInterval(() => {
95+
dispatch({ type: "TICK" });
96+
}, 1000);
97+
} else {
98+
if (intervalRef.current) {
99+
clearInterval(intervalRef.current);
100+
intervalRef.current = null;
101+
}
102+
}
103+
104+
return () => {
105+
if (intervalRef.current) {
106+
clearInterval(intervalRef.current);
107+
intervalRef.current = null;
108+
}
109+
};
110+
}, [state.isVisible, state.remainingTime]);
111+
112+
return (
113+
<>
114+
{!announced && (
115+
<Announce title={"ADHD"} callback={() => setAnnounced(true)} />
116+
)}
117+
{state.isVisible && (
118+
<div className={styles.adhdControllerContainer}>
119+
<ADHDPage />
120+
<div className={styles.timerOverlay}>
121+
<div className={styles.timerContent}>
122+
<span className={styles.timerValue}>
123+
{formatTime(state.remainingTime)}
124+
</span>
125+
</div>
126+
</div>
127+
</div>
128+
)}
129+
</>
130+
);
131+
}

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

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,85 @@
9090
cursor: pointer;
9191
border: 2px solid white;
9292
}
93+
}
94+
95+
.adhdControllerContainer {
96+
width: 100vw;
97+
height: 100vh;
98+
background: transparent;
99+
position: fixed;
100+
top: 0;
101+
left: 0;
102+
z-index: 1000;
103+
pointer-events: none;
104+
overflow: hidden;
105+
--default-font: "InterTight";
106+
--mono-font: "InterTight";
107+
font-feature-settings: "tnum";
108+
font-variant-numeric: tabular-nums;
109+
110+
// Анимация появления сверху вниз
111+
animation: slideDown 5s ease-out forwards;
112+
113+
// Стили для ADHDPage внутри контроллера
114+
:global(.adhdLayoutContainer) {
115+
animation: slideDown 5s ease-out forwards;
116+
}
117+
}
118+
119+
@keyframes slideDown {
120+
0% {
121+
transform: translateY(-100%);
122+
opacity: 0;
123+
}
124+
125+
100% {
126+
transform: translateY(0);
127+
opacity: 1;
128+
}
129+
}
130+
131+
.timerOverlay {
132+
position: absolute;
133+
bottom: 36vh;
134+
right: 6vw;
135+
display: flex;
136+
align-items: center;
137+
justify-content: center;
138+
pointer-events: none;
139+
z-index: 1002;
140+
}
141+
142+
.timerContent {
143+
display: flex;
144+
flex-direction: column;
145+
align-items: center;
146+
gap: 10px;
147+
}
148+
149+
.timerValue {
150+
color: #ff0000;
151+
font-size: 96px;
152+
font-weight: 700;
153+
font-family: var(--mono-font);
154+
text-shadow:
155+
2px 2px 4px rgba(0, 0, 0, 0.8),
156+
-2px -2px 4px rgba(0, 0, 0, 0.8),
157+
2px -2px 4px rgba(0, 0, 0, 0.8),
158+
-2px 2px 4px rgba(0, 0, 0, 0.8),
159+
0 0 8px rgba(255, 0, 0, 0.6),
160+
0 0 16px rgba(255, 0, 0, 0.4),
161+
0 0 24px rgba(255, 0, 0, 0.3),
162+
0 0 32px rgba(255, 0, 0, 0.2);
163+
animation: timerPulse 2s ease-in-out infinite alternate;
164+
}
165+
166+
@keyframes timerPulse {
167+
0% {
168+
transform: scale(1);
169+
}
170+
171+
100% {
172+
transform: scale(1.4);
173+
}
93174
}

src/components/OBS_Components/ADHDLayout/ADHDPage.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
import { useState } from "react";
2-
3-
import Announce from "@/shared/Utils/Announce/Announce";
4-
51
import { BreakingNews } from "./components/BreakingNews";
62
import { Catisa } from "./components/Catisa";
73
import { DVDLogos } from "./components/DVDLogos";
@@ -16,14 +12,8 @@ import { StreamerVideo } from "./components/StreamerVideo";
1612
import { Surfer } from "./components/Surfer";
1713

1814
export function ADHDPage() {
19-
const [announced, setAnnounced] = useState<boolean>(false);
20-
document.title = "ADHD Layout";
21-
2215
return (
2316
<>
24-
{!announced && (
25-
<Announce callback={() => setAnnounced(true)} title={"ADHD Layout"} />
26-
)}
2717
<DVDLogos />
2818
<BreakingNews />
2919
<StreamerVideo />

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
width: 100%;
1313
height: 100%;
1414
object-fit: cover;
15-
opacity: 0.2;
15+
opacity: 0.5;
1616
}
Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,55 @@
1-
import React from 'react';
2-
import styles from './Notifications.module.scss';
1+
import styles from "./Notifications.module.scss";
32

4-
export const Notifications: React.FC = () => {
5-
return (
6-
<div className={styles.notifications}>
7-
<div className={styles.notificationsContainer}>
8-
<div className={`${styles.notification} ${styles.notificationFirst}`}>
9-
<div className={styles.notificationIconWrapper}>
10-
<img
11-
src="/src/components/OBS_Components/ADHDLayout/content/email.webp"
12-
className={styles.notificationIcon}
13-
alt="Email notification"
14-
/>
15-
</div>
16-
<div className={styles.notificationInfo}>
17-
<div className={styles.notificationFrom}>Cloud</div>
18-
<div className={styles.notificationText}>
19-
Your storage is 100% full
20-
</div>
21-
</div>
3+
export const Notifications: React.FC = () => (
4+
<div className={styles.notifications}>
5+
<div className={styles.notificationsContainer}>
6+
<div className={`${styles.notification} ${styles.notificationFirst}`}>
7+
<div className={styles.notificationIconWrapper}>
8+
<img
9+
src="/src/components/OBS_Components/ADHDLayout/content/email.webp"
10+
className={styles.notificationIcon}
11+
alt="Email notification"
12+
/>
2213
</div>
23-
24-
<div className={`${styles.notification} ${styles.notificationSecond}`}>
25-
<div className={styles.notificationIconWrapper}>
26-
<img
27-
src="/src/components/OBS_Components/ADHDLayout/content/email.webp"
28-
className={styles.notificationIcon}
29-
alt="Email notification"
30-
/>
31-
</div>
32-
<div className={styles.notificationInfo}>
33-
<div className={styles.notificationFrom}>Cloud</div>
34-
<div className={styles.notificationText}>
35-
Your storage is 100% full
36-
</div>
14+
<div className={styles.notificationInfo}>
15+
<div className={styles.notificationFrom}>Cloud</div>
16+
<div className={styles.notificationText}>
17+
Your storage is 100% full
3718
</div>
3819
</div>
39-
40-
<div className={`${styles.notification} ${styles.notificationThird}`}>
41-
<div className={styles.notificationIconWrapper}>
42-
<img
43-
src="/src/components/OBS_Components/ADHDLayout/content/email.webp"
44-
className={styles.notificationIcon}
45-
alt="Email notification"
46-
/>
20+
</div>
21+
22+
<div className={`${styles.notification} ${styles.notificationSecond}`}>
23+
<div className={styles.notificationIconWrapper}>
24+
<img
25+
src="/src/components/OBS_Components/ADHDLayout/content/email.webp"
26+
className={styles.notificationIcon}
27+
alt="Email notification"
28+
/>
29+
</div>
30+
<div className={styles.notificationInfo}>
31+
<div className={styles.notificationFrom}>Cloud</div>
32+
<div className={styles.notificationText}>
33+
Your storage is 100% full
4734
</div>
48-
<div className={styles.notificationInfo}>
49-
<div className={styles.notificationFrom}>Cloud</div>
50-
<div className={styles.notificationText}>
51-
Your storage is 100% full
52-
</div>
35+
</div>
36+
</div>
37+
38+
<div className={`${styles.notification} ${styles.notificationThird}`}>
39+
<div className={styles.notificationIconWrapper}>
40+
<img
41+
src="/src/components/OBS_Components/ADHDLayout/content/email.webp"
42+
className={styles.notificationIcon}
43+
alt="Email notification"
44+
/>
45+
</div>
46+
<div className={styles.notificationInfo}>
47+
<div className={styles.notificationFrom}>Cloud</div>
48+
<div className={styles.notificationText}>
49+
Your storage is 100% full
5350
</div>
5451
</div>
5552
</div>
5653
</div>
57-
);
58-
};
54+
</div>
55+
);
3.02 MB
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { ADHDPage } from "./ADHDPage";
2+
export { ADHDController } from "./ADHDController";
23
export { BreakingNews } from "./components/BreakingNews";
34
export { Quiz } from "./components/Quiz";

0 commit comments

Comments
 (0)