diff --git a/anonstream/routes/nojs.py b/anonstream/routes/nojs.py
index c1b7d59..967f894 100644
--- a/anonstream/routes/nojs.py
+++ b/anonstream/routes/nojs.py
@@ -5,7 +5,7 @@ from quart import current_app, request, render_template, redirect, url_for, esca
from anonstream.captcha import get_random_captcha_digest_for
from anonstream.chat import add_chat_message, Rejected
-from anonstream.stream import get_stream_title, get_stream_uptime_and_viewership
+from anonstream.stream import is_online, get_stream_title, get_stream_uptime_and_viewership
from anonstream.user import add_state, pop_state, try_change_appearance, update_presence, get_users_by_presence, Presence, verify, deverify, BadCaptcha
from anonstream.routes.wrappers import with_user_from, render_template_with_etag
from anonstream.helpers.chat import get_scrollback
@@ -24,6 +24,7 @@ async def nojs_stream(user):
'nojs_stream.html',
csp=generate_csp(),
user=user,
+ online=is_online(),
)
@current_app.route('/info.html')
diff --git a/anonstream/static/anonstream.js b/anonstream/static/anonstream.js
index f84f946..08eed06 100644
--- a/anonstream/static/anonstream.js
+++ b/anonstream/static/anonstream.js
@@ -11,7 +11,8 @@ const TOKEN_HASH = document.body.dataset.tokenHash;
const CSP = document.body.dataset.csp;
/* insert js-only markup */
-const jsmarkup_stream = ``
+const jsmarkup_stream_video = ''
+const jsmarkup_stream_offline = ''
const jsmarkup_info = '
';
const jsmarkup_info_float = '';
const jsmarkup_info_float_button = '';
@@ -83,9 +84,13 @@ const insert_jsmarkup = () => {
style_tripcode_colors.nonce = CSP;
document.head.insertAdjacentElement("beforeend", style_tripcode_colors);
}
- if (document.getElementById("stream_js") === null) {
+ if (document.getElementById("stream__video") === null) {
const parent = document.getElementById("stream");
- parent.insertAdjacentHTML("beforeend", jsmarkup_stream);
+ parent.insertAdjacentHTML("beforeend", jsmarkup_stream_video);
+ }
+ if (document.getElementById("stream__offline") === null) {
+ const parent = document.getElementById("stream");
+ parent.insertAdjacentHTML("beforeend", jsmarkup_stream_offline);
}
if (document.getElementById("info_js") === null) {
const parent = document.getElementById("info");
@@ -568,6 +573,12 @@ const update_users_list = () => {
chat_users_notwatching_header.innerText = `Not watching (${notwatching})`;
}
+const show_offline_screen = () => {
+ video.removeAttribute("src");
+ video.load();
+ stream.dataset.offline = "";
+}
+
const on_websocket_message = (event) => {
//console.log("websocket message", event);
const receipt = JSON.parse(event.data);
@@ -664,7 +675,7 @@ const on_websocket_message = (event) => {
}
// stream reload button
- if (stats === null || stream.networkState === stream.NETWORK_LOADING) {
+ if (stats === null || video.networkState === video.NETWORK_LOADING) {
info_button.removeAttribute("data-visible");
} else {
info_button.dataset.visible = "";
@@ -819,18 +830,26 @@ const connect_websocket = () => {
connect_websocket();
/* stream reload button */
-const stream = document.getElementById("stream_js");
+const video = document.getElementById("stream__video");
const info_button = document.getElementById("info_js__float__button");
info_button.addEventListener("click", (event) => {
- stream.load();
+ stream.removeAttribute("data-offline");
+ video.src = `/stream.mp4?token=${encodeURIComponent(TOKEN)}`;
+ video.load();
info_button.removeAttribute("data-visible");
});
-stream.addEventListener("error", (event) => {
+video.addEventListener("error", (event) => {
+ if (video.error !== null && video.error.message === "404: Not Found") {
+ show_offline_screen();
+ }
if (stats !== null) {
info_button.dataset.visible = "";
}
});
+/* load stream */
+video.src = `/stream.mp4?token=${encodeURIComponent(TOKEN)}`;
+
/* override js-only chat form */
const chat_form_nonce = document.getElementById("chat-form_js__nonce");
const chat_form_comment = document.getElementById("chat-form_js__comment");
diff --git a/anonstream/static/style.css b/anonstream/static/style.css
index 4420dcb..f0482dd 100644
--- a/anonstream/static/style.css
+++ b/anonstream/static/style.css
@@ -56,11 +56,30 @@ noscript {
#stream {
background: black;
grid-area: stream;
+ position: relative;
}
-#stream_js {
+#stream__video {
width: 100%;
height: 100%;
}
+#stream__offline {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ display: grid;
+ align-content: center;
+ font-size: 20pt;
+ background-color: black;
+ user-select: none;
+}
+#stream__offline > h1 {
+ margin: 0;
+}
+#stream:not([data-offline]) > #stream__offline {
+ display: none;
+}
#stream_nojs {
height: 100%;
}
diff --git a/anonstream/templates/nojs_stream.html b/anonstream/templates/nojs_stream.html
index 025e409..b657618 100644
--- a/anonstream/templates/nojs_stream.html
+++ b/anonstream/templates/nojs_stream.html
@@ -16,14 +16,35 @@
height: 100%;
margin: 0;
overflow: hidden;
+ color: #ddd;
+ font-family: sans-serif;
}
- #stream {
- width: 100%;
- height: 100%;
- }
+ {% if online %}
+ #video {
+ width: 100%;
+ height: 100%;
+ }
+ {% else %}
+ #offline {
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ display: grid;
+ align-content: center;
+ font-size: 20pt;
+ user-select: none;
+ }
+ #offline > h1 {
+ margin: 0;
+ }
+ {% endif %}
-
+ {% if online %}
+
+ {% else %}
+
+ {% endif %}