Skip to content

Commit 1448a5c

Browse files
committed
Дополнение: Добавлены компоненты макета Phonk и TikTok с медиафайлами
- Введены новые компоненты PhonkLayout и TikTokLayoutManager для улучшенной обработки медиафайлов. - Добавлены несколько синих изображений (blue1.png до blue95.png) и изображений Caveira (caveira1.png до caveira10.png) для визуальных ресурсов. - Реализованы аудиофайлы для TikTok с треками с 1 по 8. - Создан скрипт PowerShell для переименования файлов, начинающихся с "file_", в соответствии с синей системой именования. - Обновлен компонент BigTextBlockForAudio для приема строкового содержимого или MediaDto. - Улучшена конфигурация маршрутизации для включения новых компонентов для интеграции с OBS. - Добавлены шаблоны и версии оповещений для аудио оповещений TikTok.
1 parent d931d4d commit 1448a5c

File tree

129 files changed

+890
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+890
-6
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { useEffect, useReducer, useState } from "react";
2+
import { v4 as uuidv4 } from "uuid";
3+
4+
import { TelegramusHubSignalRContext } from "@/shared/api";
5+
import Announce from "@/shared/Utils/Announce/Announce";
6+
7+
import PhonkShitAlerts from "./PhonkShitAlerts";
8+
9+
type Action =
10+
| { type: "ENQUEUE"; payload: string }
11+
| { type: "DEQUEUE" }
12+
| { type: "START_PLAY" }
13+
| { type: "STOP_PLAY" };
14+
15+
interface State {
16+
queue: string[];
17+
playing: boolean;
18+
current: string | null;
19+
}
20+
21+
const initialState: State = {
22+
queue: [],
23+
playing: false,
24+
current: null,
25+
};
26+
27+
function reducer(state: State, action: Action): State {
28+
switch (action.type) {
29+
case "ENQUEUE": {
30+
return { ...state, queue: [...state.queue, action.payload] };
31+
}
32+
case "DEQUEUE": {
33+
const [, ...rest] = state.queue;
34+
return {
35+
...state,
36+
queue: rest,
37+
current: rest.length > 0 ? rest[0] : null,
38+
playing: rest.length > 0 ? true : false,
39+
};
40+
}
41+
case "START_PLAY": {
42+
if (state.playing) return state;
43+
const next = state.current ?? state.queue[0] ?? null;
44+
return {
45+
...state,
46+
playing: !!next,
47+
current: next,
48+
};
49+
}
50+
case "STOP_PLAY": {
51+
return { ...state, playing: false, current: null };
52+
}
53+
default:
54+
return state;
55+
}
56+
}
57+
58+
export default function PhonkLayoutManager() {
59+
const [state, dispatch] = useReducer(reducer, initialState);
60+
const [isAnnounced, setIsAnnounced] = useState(false);
61+
62+
TelegramusHubSignalRContext.useSignalREffect(
63+
"TiktokEdit",
64+
() => {
65+
dispatch({
66+
type: "ENQUEUE",
67+
payload: uuidv4(),
68+
});
69+
},
70+
[]
71+
);
72+
73+
useEffect(() => {
74+
if (!state.playing && state.queue.length > 0) {
75+
dispatch({ type: "START_PLAY" });
76+
}
77+
}, [state.queue, state.playing]);
78+
79+
return (
80+
<>
81+
{!isAnnounced && (
82+
<Announce
83+
title="TikTok Edit"
84+
callback={() => setIsAnnounced(true)}
85+
key={1}
86+
/>
87+
)}
88+
<div style={{ width: "100%", height: "100%" }}>
89+
{state.playing && state.current && (
90+
<PhonkShitAlerts
91+
key={state.current}
92+
callback={() => dispatch({ type: "DEQUEUE" })}
93+
/>
94+
)}
95+
</div>
96+
</>
97+
);
98+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
.container {
2+
position: fixed;
3+
inset: 0;
4+
pointer-events: none;
5+
// background-color: #000000;
6+
}
7+
8+
.sideBar {
9+
position: absolute;
10+
top: 0;
11+
bottom: 0;
12+
width: max(0px, calc((100vw - (100vh * 9 / 16)) / 2));
13+
background: #000;
14+
z-index: 9999;
15+
}
16+
17+
.leftBar {
18+
left: 0;
19+
}
20+
21+
.rightBar {
22+
right: 0;
23+
}
24+
25+
.image {
26+
position: absolute;
27+
left: 50%;
28+
transform: translateX(-50%);
29+
bottom: 22%;
30+
max-width: 200px;
31+
max-height: 200px;
32+
object-fit: contain;
33+
z-index: 10000;
34+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useRef, useState } from "react";
2+
3+
import { useInjectStyles } from "@/shared/hooks";
4+
5+
import { getRandomAudio, getRandomImage } from "./mediaAssets";
6+
import styles from "./PhonkShitAlerts.module.scss";
7+
8+
export default function PhonkShitAlerts({
9+
callback,
10+
}: {
11+
callback: () => void;
12+
}) {
13+
const [imageSrc] = useState<string>(getRandomImage());
14+
const [audioSrc] = useState<string>(getRandomAudio());
15+
const audioRef = useRef<HTMLAudioElement | null>(null);
16+
17+
useInjectStyles(`
18+
body {
19+
background-color: #00000052 !important;
20+
}
21+
22+
`);
23+
24+
return (
25+
<div className={styles.container}>
26+
{/* Left black bar */}
27+
<div className={`${styles.sideBar} ${styles.leftBar}`} />
28+
29+
{/* Right black bar */}
30+
<div className={`${styles.sideBar} ${styles.rightBar}`} />
31+
32+
{/* Невидимый audio элемент в дереве для управления через реф */}
33+
<audio
34+
ref={audioRef}
35+
autoPlay
36+
onPlay={event => {
37+
event.currentTarget.volume = 0.22;
38+
}}
39+
onEnded={callback}
40+
style={{ display: "none" }}
41+
src={audioSrc}
42+
/>
43+
44+
{/* Random image positioned 22% from bottom, centered horizontally */}
45+
{imageSrc && <img src={imageSrc} alt="" className={styles.image} />}
46+
</div>
47+
);
48+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)