Offline screen
このコミットが含まれているのは:
コミット
a7bfab4f26
|
@ -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.captcha import get_random_captcha_digest_for
|
||||||
from anonstream.chat import add_chat_message, Rejected
|
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.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.routes.wrappers import with_user_from, render_template_with_etag
|
||||||
from anonstream.helpers.chat import get_scrollback
|
from anonstream.helpers.chat import get_scrollback
|
||||||
|
@ -24,6 +24,7 @@ async def nojs_stream(user):
|
||||||
'nojs_stream.html',
|
'nojs_stream.html',
|
||||||
csp=generate_csp(),
|
csp=generate_csp(),
|
||||||
user=user,
|
user=user,
|
||||||
|
online=is_online(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@current_app.route('/info.html')
|
@current_app.route('/info.html')
|
||||||
|
|
|
@ -11,7 +11,8 @@ const TOKEN_HASH = document.body.dataset.tokenHash;
|
||||||
const CSP = document.body.dataset.csp;
|
const CSP = document.body.dataset.csp;
|
||||||
|
|
||||||
/* insert js-only markup */
|
/* 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 = '<div id="info_js" data-js="true"></div>';
|
||||||
const jsmarkup_info_float = '<aside id="info_js__float"></aside>';
|
const jsmarkup_info_float = '<aside id="info_js__float"></aside>';
|
||||||
const jsmarkup_info_float_button = '<button id="info_js__float__button">Reload stream</button>';
|
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;
|
style_tripcode_colors.nonce = CSP;
|
||||||
document.head.insertAdjacentElement("beforeend", style_tripcode_colors);
|
document.head.insertAdjacentElement("beforeend", style_tripcode_colors);
|
||||||
}
|
}
|
||||||
if (document.getElementById("stream_js") === null) {
|
if (document.getElementById("stream__video") === null) {
|
||||||
const parent = document.getElementById("stream");
|
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) {
|
if (document.getElementById("info_js") === null) {
|
||||||
const parent = document.getElementById("info");
|
const parent = document.getElementById("info");
|
||||||
|
@ -568,6 +573,12 @@ const update_users_list = () => {
|
||||||
chat_users_notwatching_header.innerText = `Not watching (${notwatching})`;
|
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) => {
|
const on_websocket_message = (event) => {
|
||||||
//console.log("websocket message", event);
|
//console.log("websocket message", event);
|
||||||
const receipt = JSON.parse(event.data);
|
const receipt = JSON.parse(event.data);
|
||||||
|
@ -664,7 +675,7 @@ const on_websocket_message = (event) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// stream reload button
|
// stream reload button
|
||||||
if (stats === null || stream.networkState === stream.NETWORK_LOADING) {
|
if (stats === null || video.networkState === video.NETWORK_LOADING) {
|
||||||
info_button.removeAttribute("data-visible");
|
info_button.removeAttribute("data-visible");
|
||||||
} else {
|
} else {
|
||||||
info_button.dataset.visible = "";
|
info_button.dataset.visible = "";
|
||||||
|
@ -819,18 +830,26 @@ const connect_websocket = () => {
|
||||||
connect_websocket();
|
connect_websocket();
|
||||||
|
|
||||||
/* stream reload button */
|
/* stream reload button */
|
||||||
const stream = document.getElementById("stream_js");
|
const video = document.getElementById("stream__video");
|
||||||
const info_button = document.getElementById("info_js__float__button");
|
const info_button = document.getElementById("info_js__float__button");
|
||||||
info_button.addEventListener("click", (event) => {
|
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");
|
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) {
|
if (stats !== null) {
|
||||||
info_button.dataset.visible = "";
|
info_button.dataset.visible = "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* load stream */
|
||||||
|
video.src = `/stream.mp4?token=${encodeURIComponent(TOKEN)}`;
|
||||||
|
|
||||||
/* override js-only chat form */
|
/* override js-only chat form */
|
||||||
const chat_form_nonce = document.getElementById("chat-form_js__nonce");
|
const chat_form_nonce = document.getElementById("chat-form_js__nonce");
|
||||||
const chat_form_comment = document.getElementById("chat-form_js__comment");
|
const chat_form_comment = document.getElementById("chat-form_js__comment");
|
||||||
|
|
|
@ -56,11 +56,30 @@ noscript {
|
||||||
#stream {
|
#stream {
|
||||||
background: black;
|
background: black;
|
||||||
grid-area: stream;
|
grid-area: stream;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
#stream_js {
|
#stream__video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 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 {
|
#stream_nojs {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,35 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
color: #ddd;
|
||||||
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
#stream {
|
{% if online %}
|
||||||
width: 100%;
|
#video {
|
||||||
height: 100%;
|
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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
読み込み中…
新しいイシューから参照