send2streamer/public/index.html

110 lines
3.4 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Send2Streamer — сообщения от зрителей прямо на стрим</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.googleGsiLoaded = new Promise((resolve) => { window.resolveGoogleGsiLoaded = resolve; });
</script>
<script src="https://accounts.google.com/gsi/client" async defer onload="resolveGoogleGsiLoaded()"></script>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 640px;
margin: 60px auto;
padding: 0 20px;
line-height: 1.5;
}
h1 {
font-size: 32px;
margin-bottom: 8px;
}
.subtitle {
color: #666;
font-size: 18px;
margin-bottom: 32px;
}
.steps {
background: #f6f6f6;
border-radius: 12px;
padding: 20px 24px;
margin-bottom: 32px;
}
.steps li {
margin-bottom: 8px;
}
#login-container {
margin-top: 8px;
}
#status {
margin-top: 12px;
color: #888;
font-size: 14px;
}
</style>
</head>
<body>
<h1>Send2Streamer</h1>
<p class="subtitle">Зрители пишут сообщения — они всплывают у вас на стриме голосом.</p>
<div class="steps">
<p><strong>Как это работает:</strong></p>
<ol>
<li>Вы входите через Google — сервис выдаёт вам две ссылки: для OBS/StreamLabs и для зрителей.</li>
<li>Первую вставляете в Browser Source в OBS/StreamLabs.</li>
<li>Вторую публикуете для зрителей (например, в описании канала или в чате).</li>
<li>Зритель авторизуется через Google по этой ссылке и пишет вам сообщение — оно появляется на стриме с текстом и озвучкой.</li>
</ol>
</div>
<p><strong>Войдите как стример, чтобы получить свои ссылки:</strong></p>
<div id="login-container"></div>
<div id="status"></div>
<script>
async function handleCredentialResponse(response) {
const statusEl = document.getElementById('status');
const res = await fetch('/auth/google', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ credential: response.credential }),
});
if (res.ok) {
window.location.href = '/dashboard.html';
} else {
statusEl.textContent = 'Не удалось войти, попробуйте ещё раз';
}
}
async function init() {
const meRes = await fetch('/me');
const { user } = await meRes.json();
if (user) {
window.location.href = '/dashboard.html';
return;
}
const configRes = await fetch('/config');
const { googleClientId } = await configRes.json();
// The GSI script tag is async/defer — without waiting for it to actually
// finish loading, this can run before `google` exists (a race that fails
// silently), which is why the button sometimes only appeared after a
// reload (once the script was already cached).
await window.googleGsiLoaded;
google.accounts.id.initialize({
client_id: googleClientId,
callback: handleCredentialResponse,
});
google.accounts.id.renderButton(document.getElementById('login-container'), { theme: 'outline', size: 'large' });
}
init();
</script>
</body>
</html>