Initial commit: overlay + sender pages for StreamLabs browser source
Express + Socket.IO backend with Google login on the sender page, a transparent overlay page for OBS/StreamLabs Browser Source, and TTS voice-over via the edge-tts Python CLI (same engine as t2sTelegramBot). Dockerized for deployment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
commit
7882db1f37
12 changed files with 1930 additions and 0 deletions
86
public/sender.js
Normal file
86
public/sender.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
const loginContainer = document.getElementById('login-container');
|
||||
const mainSection = document.getElementById('hidden-until-login');
|
||||
const userPic = document.getElementById('user-pic');
|
||||
const userName = document.getElementById('user-name');
|
||||
const logoutBtn = document.getElementById('logout');
|
||||
const messageInput = document.getElementById('message');
|
||||
const sendBtn = document.getElementById('send');
|
||||
const statusEl = document.getElementById('status');
|
||||
|
||||
const socket = io();
|
||||
|
||||
function showLoggedIn(user) {
|
||||
loginContainer.style.display = 'none';
|
||||
mainSection.style.display = 'block';
|
||||
userPic.src = user.picture || '';
|
||||
userName.textContent = user.name || user.email;
|
||||
}
|
||||
|
||||
function showLoggedOut() {
|
||||
loginContainer.style.display = 'block';
|
||||
mainSection.style.display = 'none';
|
||||
}
|
||||
|
||||
async function handleCredentialResponse(response) {
|
||||
const res = await fetch('/auth/google', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ credential: response.credential }),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const { user } = await res.json();
|
||||
showLoggedIn(user);
|
||||
// The socket connected before login with no session cookie; reconnect so
|
||||
// its handshake picks up the freshly-issued, now-authenticated cookie.
|
||||
socket.disconnect();
|
||||
socket.connect();
|
||||
} else {
|
||||
statusEl.textContent = 'Не удалось войти, попробуйте ещё раз';
|
||||
}
|
||||
}
|
||||
|
||||
async function init() {
|
||||
const configRes = await fetch('/config');
|
||||
const { googleClientId } = await configRes.json();
|
||||
|
||||
google.accounts.id.initialize({
|
||||
client_id: googleClientId,
|
||||
callback: handleCredentialResponse,
|
||||
});
|
||||
google.accounts.id.renderButton(loginContainer, { theme: 'outline', size: 'large' });
|
||||
|
||||
const meRes = await fetch('/me');
|
||||
const { user } = await meRes.json();
|
||||
if (user) {
|
||||
showLoggedIn(user);
|
||||
} else {
|
||||
showLoggedOut();
|
||||
}
|
||||
}
|
||||
|
||||
sendBtn.addEventListener('click', () => {
|
||||
const text = messageInput.value.trim();
|
||||
if (!text) return;
|
||||
socket.emit('send_message', text);
|
||||
messageInput.value = '';
|
||||
statusEl.textContent = 'Отправлено';
|
||||
setTimeout(() => { statusEl.textContent = ''; }, 1500);
|
||||
});
|
||||
|
||||
messageInput.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
|
||||
sendBtn.click();
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('send_error', (msg) => {
|
||||
statusEl.textContent = 'Ошибка: ' + msg;
|
||||
});
|
||||
|
||||
logoutBtn.addEventListener('click', async () => {
|
||||
await fetch('/auth/logout', { method: 'POST' });
|
||||
showLoggedOut();
|
||||
});
|
||||
|
||||
init();
|
||||
Loading…
Add table
Add a link
Reference in a new issue