Offline screen

このコミットが含まれているのは:
n9k 2022-03-30 08:41:42 +00:00
コミット a7bfab4f26
4個のファイルの変更74行の追加14行の削除

ファイルの表示

@ -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')

ファイルの表示

@ -11,7 +11,8 @@ const TOKEN_HASH = document.body.dataset.tokenHash;
const CSP = document.body.dataset.csp;
/* insert js-only markup */
const jsmarkup_stream = `<video id="stream_js" src="/stream.mp4?token=${encodeURIComponent(TOKEN)}" autoplay controls></video>`
const jsmarkup_stream_video = '<video id="stream__video" autoplay controls></video>'
const jsmarkup_stream_offline = '<header id="stream__offline"><h1>[offline]</h1></header>'
const jsmarkup_info = '<div id="info_js" data-js="true"></div>';
const jsmarkup_info_float = '<aside id="info_js__float"></aside>';
const jsmarkup_info_float_button = '<button id="info_js__float__button">Reload stream</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");

ファイルの表示

@ -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%;
}

ファイルの表示

@ -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 %}
</style>
</head>
<body>
<video id="stream" src="{{ url_for('stream', token=user.token) }}" autoplay controls></video>
{% if online %}
<video id="video" src="{{ url_for('stream', token=user.token) }}" autoplay controls></video>
{% else %}
<header id="offline"><h1>[offline]</h1></header>
{% endif %}
</body>
</html>