Add streamer dashboard stats; fix TTS overlap race properly
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 30s
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 30s
Dashboard now shows unique visitors (via sender link), total messages, and unique senders per streamer, tracked via new viewer_visits/messages tables. The previous overlay TTS-overlap fix had a race: audio not having arrived yet was treated the same as "no audio at all", letting the queue advance before slow-to-synthesize audio (e.g. a long question) ever started playing. Now "not arrived yet" is explicitly distinct from "finished playing", with a grace-period fallback for genuine TTS failures. Also drop the hardcoded AI name from ai-prompt.txt since it's now injected dynamically from the streamer's configured ai_name.
This commit is contained in:
parent
ec6d8c4cfe
commit
b669c2d0b7
5 changed files with 114 additions and 9 deletions
14
server.js
14
server.js
|
|
@ -17,6 +17,9 @@ const {
|
|||
setViewerName,
|
||||
updateDisplayDuration,
|
||||
updateAiName,
|
||||
recordVisit,
|
||||
recordMessage,
|
||||
getStreamerStats,
|
||||
} = require('./db');
|
||||
const { censorText } = require('./profanity');
|
||||
|
||||
|
|
@ -127,6 +130,7 @@ app.get('/api/dashboard', requireAuth, (req, res) => {
|
|||
ttsVoice: streamer.tts_voice,
|
||||
displayDurationSeconds: streamer.display_duration_seconds,
|
||||
aiName: streamer.ai_name,
|
||||
stats: getStreamerStats(streamer.id),
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -265,6 +269,14 @@ io.on('connection', (socket) => {
|
|||
} else {
|
||||
socket.join(`streamer-${streamer.id}`);
|
||||
}
|
||||
} else if (role === 'sender' && connectedUser) {
|
||||
// Only reached on the reconnect that happens right after login (see
|
||||
// socket.disconnect()/connect() in send.js) — the initial anonymous
|
||||
// connection has no session.user yet, so no visit is recorded for it.
|
||||
const streamer = findStreamerBySenderToken(token);
|
||||
if (streamer) {
|
||||
recordVisit(streamer.id, connectedUser.id);
|
||||
}
|
||||
}
|
||||
|
||||
socket.on('disconnect', (reason) => {
|
||||
|
|
@ -294,6 +306,8 @@ io.on('connection', (socket) => {
|
|||
return;
|
||||
}
|
||||
|
||||
recordMessage(streamer.id, user.id);
|
||||
|
||||
const rawMessage = text.trim().slice(0, 500);
|
||||
const message = censorText(rawMessage, '...');
|
||||
const speechMessage = censorText(rawMessage, 'бип');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue