Twitch stream event platform with OBS browser source overlay. Features: - Twitch OAuth login (streamer + mod access) - EventSub WebSocket for subs, gift subs, bits, channel points, follows, raids - Chat commands via tmi.js in the overlay - Gap audio — tone plays on new chat message after silence, volume/pitch scale with gap length - Self-hosted media library (upload sounds and videos) - Action configuration — map any event to sound, video, or alert - Per-action cooldowns, test button, enable/disable toggle - Multiple actions per event (all matching actions fire) - Activity log dashboard with EventSub connection status - Layout editor — iframe-based WYSIWYG with drag handles, live style preview - Custom CSS and custom JS injection into overlay - Custom DOM events (bashyoverlay:sub, bashyoverlay:raid, etc.) for custom JS hooks - deploy.sh — one-shot setup and launch script Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
2.3 KiB
HTML
54 lines
2.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<link rel="stylesheet" href="/static/overlay.css">
|
|
{% if custom_css %}<style>{{ custom_css | safe }}</style>{% endif %}
|
|
<style>
|
|
:root {
|
|
--chat-left: {{ layout.chat_left }}%;
|
|
--chat-top: {{ layout.chat_top }}%;
|
|
--chat-width: {{ layout.chat_width }}%;
|
|
--chat-height: {{ layout.chat_height }}%;
|
|
--chat-font-size: {{ layout.chat_font_size }}px;
|
|
--chat-bg-opacity: {{ layout.chat_bg_opacity }};
|
|
--chat-text-color: {{ layout.chat_text_color }};
|
|
--alert-left: {{ layout.alert_left }}%;
|
|
--alert-top: {{ layout.alert_top }}%;
|
|
--alert-font-size: {{ layout.alert_font_size }}px;
|
|
--alert-bg-opacity: {{ layout.alert_bg_opacity }};
|
|
--alert-text-color: {{ layout.alert_text_color }};
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="alert" style="display:none"></div>
|
|
<div id="alert-video-wrap" style="display:none"><video id="alert-video" playsinline></video></div>
|
|
<div id="chat">
|
|
<div class="chat-msg"><span class="uname" style="color:#9b59b6">StreamFriend</span>: Let's goooo! 🎉</div>
|
|
<div class="chat-msg"><span class="uname" style="color:#e74c3c">Viewer42</span>: PogChamp PogChamp</div>
|
|
<div class="chat-msg"><span class="uname" style="color:#2ecc71">ChatUser</span>: great stream today!</div>
|
|
<div class="chat-msg"><span class="uname" style="color:#f39c12">AnotherFan</span>: !airhorn</div>
|
|
<div class="chat-msg"><span class="uname" style="color:#3498db">NewViewer</span>: first time here!</div>
|
|
</div>
|
|
<script>
|
|
const ALERT_DURATION = {{ alert_duration_ms }};
|
|
let alertTimer = null;
|
|
|
|
function showMockAlert(text) {
|
|
const el = document.getElementById('alert');
|
|
el.style.display = 'none';
|
|
void el.offsetWidth;
|
|
el.textContent = text || 'StreamFan just subscribed! 🎉';
|
|
el.style.display = 'block';
|
|
if (alertTimer) clearTimeout(alertTimer);
|
|
alertTimer = setTimeout(() => { el.style.display = 'none'; }, ALERT_DURATION);
|
|
}
|
|
|
|
window.addEventListener('message', (e) => {
|
|
if (e.data?.type === 'preview-alert') showMockAlert(e.data.text);
|
|
});
|
|
</script>
|
|
{% if custom_js %}<script>{{ custom_js | safe }}</script>{% endif %}
|
|
</body>
|
|
</html>
|