Show and update stream uptime in js

このコミットが含まれているのは:
n9k 2022-02-22 10:36:59 +00:00
コミット 8d1f273a99
5個のファイルの変更57行の追加8行の削除

ファイルの表示

@ -2,7 +2,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
from anonstream.stream import get_stream_title, get_stream_uptime
from anonstream.user import add_state, pop_state, try_change_appearance, verify, deverify, BadCaptcha
from anonstream.routes.wrappers import with_user_from, render_template_with_etag
from anonstream.helpers.chat import get_scrollback
@ -20,6 +20,7 @@ async def nojs_info(user):
'nojs_info.html',
user=user,
title=get_stream_title(),
uptime=get_stream_uptime(),
)
@current_app.route('/chat/messages.html')

ファイルの表示

@ -5,8 +5,9 @@ const token = document.body.dataset.token;
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_info = '<div id="info_js"></div>';
const jsmarkup_info_title = '<header id="info_js__title" data-js="true"></header>';
const jsmarkup_info = '<div id="info_js" data-js="true"></div>';
const jsmarkup_info_uptime = '<aside id="info_js__uptime"></aside>';
const jsmarkup_info_title = '<header id="info_js__title"></header>';
const jsmarkup_chat_messages = '<ol id="chat-messages_js" data-js="true"></ol>';
const jsmarkup_chat_form = `\
<form id="chat-form_js" data-js="true" action="/chat" method="post">
@ -39,6 +40,10 @@ const insert_jsmarkup = () => {
const parent = document.getElementById("info");
parent.insertAdjacentHTML("beforeend", jsmarkup_info);
}
if (document.getElementById("info_js__uptime") === null) {
const parent = document.getElementById("info_js");
parent.insertAdjacentHTML("beforeend", jsmarkup_info_uptime);
}
if (document.getElementById("info_js__title") === null) {
const parent = document.getElementById("info_js");
parent.insertAdjacentHTML("beforeend", jsmarkup_info_title);
@ -60,6 +65,7 @@ const stylesheet_tripcode_colors = document.styleSheets[3];
/* create websocket */
const info_title = document.getElementById("info_js__title");
const info_uptime = document.getElementById("info_js__uptime");
const chat_messages = document.getElementById("chat-messages_js");
const create_chat_message = (object) => {
@ -310,6 +316,36 @@ const disable_captcha = () => {
chat_form_captcha_image.removeAttribute("src");
}
let frozen_uptime = null;
let frozen_uptime_received = null;
const set_frozen_uptime = (x) => {
frozen_uptime = x;
frozen_uptime_received = new Date();
}
const update_uptime = () => {
if (frozen_uptime_received === null) {
return;
} else if (frozen_uptime === null) {
info_uptime.innerText = "";
} else {
const frozen_uptime_received_ago = (new Date() - frozen_uptime_received) / 1000;
const uptime = Math.round(frozen_uptime + frozen_uptime_received_ago);
const s = Math.round(uptime % 60);
const m = Math.floor(uptime / 60) % 60
const h = Math.floor(uptime / 3600);
const ss = s.toString().padStart(2, "0");
if (uptime < 3600) {
info_uptime.innerText = `${m}:${ss}`;
} else {
const mm = m.toString().padStart(2, "0");
info_uptime.innerText = `${h}:${mm}:${ss}`;
}
}
}
setInterval(update_uptime, 1000); // always update uptime
const on_websocket_message = (event) => {
//console.log("websocket message", event);
const receipt = JSON.parse(event.data);
@ -322,6 +358,8 @@ const on_websocket_message = (event) => {
console.log("ws init", receipt);
info_title.innerText = receipt.title;
set_frozen_uptime(receipt.uptime);
update_uptime();
chat_form_nonce.value = receipt.nonce;
receipt.digest === null ? disable_captcha() : enable_captcha(receipt.digest);

ファイルの表示

@ -64,6 +64,10 @@ noscript {
padding: 1ch 1.5ch;
height: 100%;
}
#info_js__uptime {
float: right;
font-size: 11pt;
}
#info_js__title {
font-size: 18pt;
overflow-wrap: anywhere;

ファイルの表示

@ -56,12 +56,12 @@
box-sizing: border-box;
align-items: center;
}
#notice h1 {
#notice h2 {
margin: 0;
font-size: 18pt;
line-height: 1.25;
}
#notice.verbose h1 {
#notice.verbose h2 {
font-size: 14pt;
}
@ -202,7 +202,7 @@
<div id="appearance"></div>
{% if state.notice %}
<a id="notice" {% if state.verbose %}class="verbose" {% endif %}{% if prefer_chat_form %}href="#chat"{% else %}href="#appearance"{% endif %}>
<header><h1>{{ state.notice }}</h1></header>
<header><h2>{{ state.notice }}</h2></header>
<small>Click to dismiss</small>
</a>
{% endif %}

ファイルの表示

@ -9,13 +9,19 @@
font-family: sans-serif;
color: #ddd;
}
#title {
#uptime {
float: right;
font-size: 11pt;
}
#title > h1 {
margin: 0;
font-size: 18pt;
overflow-wrap: anywhere;
}
</style>
</head>
<body>
<header id="title">{{ title }}</header>
<aside id="uptime">{{ uptime }}</aside>
<header id="title"><h1>{{ title }}</h1></header>
</body>
</html>