Let viewers set a per-streamer display name
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 29s

Viewers can type a custom name shown to the streamer instead of
their Google account name. It's saved per (streamer, viewer) pair
in SQLite and pre-filled on future visits to the same send link.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
vrubelroman 2026-07-01 16:49:51 +00:00
parent ed2b051c91
commit fab55cde1d
4 changed files with 76 additions and 5 deletions

View file

@ -38,6 +38,19 @@
color: #888;
font-size: 14px;
}
label {
display: block;
font-size: 13px;
color: #666;
margin-bottom: 4px;
}
#display-name {
width: 100%;
font-size: 16px;
padding: 8px 10px;
box-sizing: border-box;
margin-bottom: 16px;
}
textarea {
width: 100%;
height: 100px;
@ -77,6 +90,9 @@
<span id="logout">выйти</span>
</div>
<label for="display-name">Ваше имя (покажется стримеру вместо имени из Google)</label>
<input id="display-name" type="text" maxlength="60" placeholder="Имя..." />
<textarea id="message" placeholder="Текст для стрима..." maxlength="500"></textarea>
<br />
<button id="send">Отправить</button>

View file

@ -3,6 +3,7 @@ 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 displayNameInput = document.getElementById('display-name');
const messageInput = document.getElementById('message');
const sendBtn = document.getElementById('send');
const statusEl = document.getElementById('status');
@ -22,6 +23,13 @@ function showLoggedOut() {
mainSection.style.display = 'none';
}
async function loadDisplayName() {
const res = await fetch(`/api/viewer-name?token=${encodeURIComponent(token)}`);
if (!res.ok) return;
const { name } = await res.json();
displayNameInput.value = name || '';
}
async function handleCredentialResponse(response) {
const res = await fetch('/auth/google', {
method: 'POST',
@ -32,6 +40,7 @@ async function handleCredentialResponse(response) {
if (res.ok) {
const { user } = await res.json();
showLoggedIn(user);
loadDisplayName();
// The socket connected before login with no session cookie; reconnect so
// its handshake picks up the freshly-issued, now-authenticated cookie.
socket.disconnect();
@ -55,6 +64,7 @@ async function init() {
const { user } = await meRes.json();
if (user) {
showLoggedIn(user);
loadDisplayName();
} else {
showLoggedOut();
}
@ -63,7 +73,8 @@ async function init() {
sendBtn.addEventListener('click', () => {
const text = messageInput.value.trim();
if (!text) return;
socket.emit('send_message', { token, text });
const name = displayNameInput.value.trim();
socket.emit('send_message', { token, text, name });
messageInput.value = '';
statusEl.textContent = 'Отправлено';
setTimeout(() => { statusEl.textContent = ''; }, 1500);