Add nojs 'Reload stream' button
The nojs button appears when the stream is online and the user is not watching. The js button appears when the stream is online and the media element either (1) is not using the network or (2) fires an error event.
このコミットが含まれているのは:
コミット
46fce9c393
|
@ -3,7 +3,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.user import add_state, pop_state, try_change_appearance, 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.helpers.chat import get_scrollback
|
||||
from anonstream.helpers.user import get_default_name
|
||||
|
@ -13,9 +13,18 @@ from anonstream.utils.user import concatenate_for_notice
|
|||
CONFIG = current_app.config
|
||||
USERS_BY_TOKEN = current_app.users_by_token
|
||||
|
||||
@current_app.route('/stream.html')
|
||||
@with_user_from(request)
|
||||
async def nojs_stream(user):
|
||||
return await render_template(
|
||||
'nojs_stream.html',
|
||||
user=user,
|
||||
)
|
||||
|
||||
@current_app.route('/info.html')
|
||||
@with_user_from(request)
|
||||
async def nojs_info(user):
|
||||
update_presence(user)
|
||||
uptime, viewership = get_stream_uptime_and_viewership()
|
||||
return await render_template(
|
||||
'nojs_info.html',
|
||||
|
@ -23,6 +32,7 @@ async def nojs_info(user):
|
|||
viewership=viewership,
|
||||
uptime=uptime,
|
||||
title=await get_stream_title(),
|
||||
Presence=Presence,
|
||||
)
|
||||
|
||||
@current_app.route('/chat/messages.html')
|
||||
|
|
|
@ -6,6 +6,7 @@ const TOKEN_HASH = document.body.dataset.tokenHash;
|
|||
const jsmarkup_style_color = '<style id="style-color"></style>'
|
||||
const jsmarkup_style_tripcode_display = '<style id="style-tripcode-display"></style>'
|
||||
const jsmarkup_style_tripcode_colors = '<style id="style-tripcode-colors"></style>'
|
||||
const jsmarkup_stream = `<video id="stream_js" src="/stream.mp4?token=${encodeURIComponent(TOKEN)}" autoplay controls></video>`
|
||||
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>';
|
||||
|
@ -48,6 +49,10 @@ const insert_jsmarkup = () => {jsmarkup_info_float_viewership
|
|||
const parent = document.head;
|
||||
parent.insertAdjacentHTML("beforeend", jsmarkup_style_tripcode_colors);
|
||||
}
|
||||
if (document.getElementById("stream_js") === null) {
|
||||
const parent = document.getElementById("stream");
|
||||
parent.insertAdjacentHTML("beforeend", jsmarkup_stream);
|
||||
}
|
||||
if (document.getElementById("info_js") === null) {
|
||||
const parent = document.getElementById("info");
|
||||
parent.insertAdjacentHTML("beforeend", jsmarkup_info);
|
||||
|
@ -680,7 +685,7 @@ const connect_websocket = () => {
|
|||
connect_websocket();
|
||||
|
||||
/* stream reload button */
|
||||
const stream = document.getElementById("stream");
|
||||
const stream = document.getElementById("stream_js");
|
||||
const info_button = document.getElementById("info_js__float__button");
|
||||
info_button.addEventListener("click", (event) => {
|
||||
stream.load();
|
||||
|
|
|
@ -50,10 +50,15 @@ noscript {
|
|||
|
||||
#stream {
|
||||
background: black;
|
||||
width: 100%;
|
||||
height: var(--video-height);
|
||||
grid-area: stream;
|
||||
}
|
||||
#stream_js {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#stream_nojs {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#info {
|
||||
border-top: var(--main-border);
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css">
|
||||
</head>
|
||||
<body id="both" data-token="{{ user.token }}" data-token-hash="{{ user.token_hash }}">
|
||||
<video id="stream" src="{{ url_for('stream', token=user.token) }}" autoplay controls></video>
|
||||
<article id="stream">
|
||||
<noscript><iframe id="stream_nojs" name="stream_nojs" src="{{ url_for('nojs_stream', token=user.token) }}"></iframe></noscript>
|
||||
</article>
|
||||
<article id="info">
|
||||
<noscript><iframe id="info_nojs" src="{{ url_for('nojs_info', token=user.token) }}" data-js="false"></iframe></noscript>
|
||||
</article>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="12">
|
||||
<meta http-equiv="refresh" content="6">
|
||||
<style>
|
||||
body {
|
||||
overflow-y: auto;
|
||||
|
@ -17,6 +17,10 @@
|
|||
grid-auto-flow: column;
|
||||
grid-gap: 2.5ch;
|
||||
}
|
||||
#float__form {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
#float__uptime {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
@ -31,6 +35,12 @@
|
|||
<body>
|
||||
{% if uptime is not none %}
|
||||
<aside id="float">
|
||||
{% if user.presence != Presence.WATCHING %}
|
||||
<form id="float__form" action="{{ url_for('nojs_stream') }}" target="stream_nojs">
|
||||
<input type="hidden" name="token" value="{{ user.token }}">
|
||||
<input type="submit" value="Reload stream">
|
||||
</form>
|
||||
{% endif %}
|
||||
<div id="float__viewership">{{ viewership }} viewers</div>
|
||||
<div id="float__uptime">{{ uptime }}</div>
|
||||
</aside>
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#stream {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<video id="stream" src="{{ url_for('stream', token=user.token) }}" autoplay controls></video>
|
||||
</body>
|
||||
</html>
|
|
@ -155,11 +155,19 @@ def deverify(timestamp, user):
|
|||
if n_user_messages >= CONFIG['FLOOD_THRESHOLD']:
|
||||
user['verified'] = False
|
||||
|
||||
def _update_presence(timestamp, user):
|
||||
old, user['presence'] = user['presence'], get_presence(timestamp, user)
|
||||
if trilean(user['presence']) != trilean(old):
|
||||
USERS_UPDATE_BUFFER.add(user['token'])
|
||||
return user['presence']
|
||||
|
||||
@with_timestamp
|
||||
def update_presence(timestamp, user):
|
||||
return _update_presence(timestamp, user)
|
||||
|
||||
def get_users_and_update_presence(timestamp):
|
||||
for user in USERS:
|
||||
old, user['presence'] = user['presence'], get_presence(timestamp, user)
|
||||
if trilean(user['presence']) != trilean(old):
|
||||
USERS_UPDATE_BUFFER.add(user['token'])
|
||||
_update_presence(timestamp, user)
|
||||
yield user
|
||||
|
||||
def get_watching_users(timestamp):
|
||||
|
|
読み込み中…
新しいイシューから参照