Some checks failed
CI/CD Pipeline / build-and-deploy (push) Failing after 2s
Streamers log in with Google on a new landing page and get a dashboard with two auto-generated, permanent links: one for their OBS/StreamLabs Browser Source, one to share with viewers. Messages are now scoped to the right streamer via Socket.IO rooms instead of broadcasting globally. Streamer records and tokens are persisted in SQLite (node:sqlite) so links survive restarts/redeploys. Also adds a Forgejo Actions pipeline mirroring t2sTelegramBot's: build, smoke-test, push to the local registry, then deploy to the prod host over SSH. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
115 lines
2.7 KiB
HTML
115 lines
2.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>Ваши ссылки — Send2Streamer</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<style>
|
|
body {
|
|
font-family: system-ui, sans-serif;
|
|
max-width: 640px;
|
|
margin: 60px auto;
|
|
padding: 0 20px;
|
|
line-height: 1.5;
|
|
}
|
|
h1 { font-size: 28px; }
|
|
.card {
|
|
background: #f6f6f6;
|
|
border-radius: 12px;
|
|
padding: 20px 24px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.card h2 {
|
|
font-size: 16px;
|
|
margin: 0 0 4px;
|
|
}
|
|
.card p {
|
|
color: #666;
|
|
font-size: 14px;
|
|
margin: 0 0 12px;
|
|
}
|
|
.url-row {
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
.url-row input {
|
|
flex: 1;
|
|
padding: 8px 10px;
|
|
font-size: 14px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 6px;
|
|
background: #fff;
|
|
}
|
|
.url-row button {
|
|
padding: 8px 16px;
|
|
cursor: pointer;
|
|
}
|
|
#logout {
|
|
color: #888;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h1>Ваши ссылки</h1>
|
|
|
|
<div class="card">
|
|
<h2>Ссылка для OBS / StreamLabs</h2>
|
|
<p>Вставьте в свойства Browser Source (URL).</p>
|
|
<div class="url-row">
|
|
<input id="overlay-url" readonly />
|
|
<button data-copy="overlay-url">Копировать</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Ссылка для зрителей</h2>
|
|
<p>Опубликуйте её — зрители авторизуются через Google и смогут слать вам сообщения на стрим.</p>
|
|
<div class="url-row">
|
|
<input id="sender-url" readonly />
|
|
<button data-copy="sender-url">Копировать</button>
|
|
</div>
|
|
</div>
|
|
|
|
<p id="logout">выйти</p>
|
|
|
|
<script>
|
|
async function init() {
|
|
const meRes = await fetch('/me');
|
|
const { user } = await meRes.json();
|
|
if (!user) {
|
|
window.location.href = '/';
|
|
return;
|
|
}
|
|
|
|
const res = await fetch('/api/dashboard');
|
|
if (!res.ok) {
|
|
window.location.href = '/';
|
|
return;
|
|
}
|
|
const data = await res.json();
|
|
document.getElementById('overlay-url').value = data.overlayUrl;
|
|
document.getElementById('sender-url').value = data.senderUrl;
|
|
}
|
|
|
|
document.querySelectorAll('[data-copy]').forEach((btn) => {
|
|
btn.addEventListener('click', () => {
|
|
const input = document.getElementById(btn.dataset.copy);
|
|
input.select();
|
|
navigator.clipboard.writeText(input.value);
|
|
btn.textContent = 'Скопировано';
|
|
setTimeout(() => { btn.textContent = 'Копировать'; }, 1500);
|
|
});
|
|
});
|
|
|
|
document.getElementById('logout').addEventListener('click', async () => {
|
|
await fetch('/auth/logout', { method: 'POST' });
|
|
window.location.href = '/';
|
|
});
|
|
|
|
init();
|
|
</script>
|
|
</body>
|
|
</html>
|