Add js appearance form (not complete c.f. nojs)
このコミットが含まれているのは:
コミット
4cde4ea07a
|
@ -9,3 +9,7 @@ The canonical location of this repo is https://git.076.ne.jp/ninya9k/anonstream.
|
||||||
These mirrors also exist:
|
These mirrors also exist:
|
||||||
* https://gitlab.com/ninya9k/anonstream
|
* https://gitlab.com/ninya9k/anonstream
|
||||||
* https://github.com/ninya9k/anonstream
|
* https://github.com/ninya9k/anonstream
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* [/anonstream/static/settings.svg](https://git.076.ne.jp/ninya9k/anonstream/src/branch/master/anonstream/static/settings.svg): [setting](https://thenounproject.com/icon/setting-685325/) by [ulimicon](https://thenounproject.com/unlimicon/) is licensed under [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/).
|
||||||
|
|
|
@ -141,7 +141,7 @@ async def nojs_submit_appearance(user):
|
||||||
|
|
||||||
# Collect form data
|
# Collect form data
|
||||||
name = form.get('name', '').strip()
|
name = form.get('name', '').strip()
|
||||||
if len(name) == 0 or name == get_default_name(user):
|
if len(name) == 0:
|
||||||
name = None
|
name = None
|
||||||
|
|
||||||
color = form.get('color', '')
|
color = form.get('color', '')
|
||||||
|
|
|
@ -28,11 +28,15 @@ const jsmarkup_chat_form = `\
|
||||||
<textarea id="chat-form_js__comment" name="comment" maxlength="512" required placeholder="Send a message..." rows="1" autofocus></textarea>
|
<textarea id="chat-form_js__comment" name="comment" maxlength="512" required placeholder="Send a message..." rows="1" autofocus></textarea>
|
||||||
<div id="chat-live">
|
<div id="chat-live">
|
||||||
<span id="chat-live__ball"></span>
|
<span id="chat-live__ball"></span>
|
||||||
<span id="chat-live__status"><span>Not connected<span data-verbose='true'> to chat</span></span></span>
|
<span id="chat-live__status">
|
||||||
|
<span data-verbose="true">Not connected to chat</span>
|
||||||
|
<span data-verbose="false">×</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input id="chat-form_js__captcha-digest" type="hidden" name="captcha-digest" disabled>
|
<input id="chat-form_js__captcha-digest" type="hidden" name="captcha-digest" disabled>
|
||||||
<input id="chat-form_js__captcha-image" type="image" width="72" height="30">
|
<input id="chat-form_js__captcha-image" type="image" width="72" height="30">
|
||||||
<input id="chat-form_js__captcha-answer" name="captcha-answer" placeholder="Captcha" disabled>
|
<input id="chat-form_js__captcha-answer" name="captcha-answer" placeholder="Captcha" disabled>
|
||||||
|
<input id="chat-form_js__settings" type="image" src="/static/settings.svg" width="28" height="28" alt="Settings">
|
||||||
<input id="chat-form_js__submit" type="submit" value="Chat" accesskey="p" disabled>
|
<input id="chat-form_js__submit" type="submit" value="Chat" accesskey="p" disabled>
|
||||||
<article id="chat-form_js__notice">
|
<article id="chat-form_js__notice">
|
||||||
<button id="chat-form_js__notice__button" type="button">
|
<button id="chat-form_js__notice__button" type="button">
|
||||||
|
@ -40,6 +44,17 @@ const jsmarkup_chat_form = `\
|
||||||
<small>Click to dismiss</small>
|
<small>Click to dismiss</small>
|
||||||
</button>
|
</button>
|
||||||
</article>
|
</article>
|
||||||
|
</form>
|
||||||
|
<form id="appearance-form_js" data-hidden="">
|
||||||
|
<span id="appearance-form_js__label-name">Name:</span>
|
||||||
|
<input id="appearance-form_js__name" name="name" maxlength="24">
|
||||||
|
<input id="appearance-form_js__color" type="color" name="color">
|
||||||
|
<span id="appearance-form_js__label-tripcode">Tripcode:</span>
|
||||||
|
<input id="appearance-form_js__password" type="password" name="password" placeholder="(tripcode password)" maxlength="1024">
|
||||||
|
<div id="appearance-form_js__row">
|
||||||
|
<article id="appearance-form_js__row__result"></article>
|
||||||
|
<input id="appearance-form_js__row__submit" type="submit" value="Update">
|
||||||
|
</div>
|
||||||
</form>`;
|
</form>`;
|
||||||
|
|
||||||
const insert_jsmarkup = () => {jsmarkup_info_float_viewership
|
const insert_jsmarkup = () => {jsmarkup_info_float_viewership
|
||||||
|
@ -115,6 +130,30 @@ const show_notice = (text) => {
|
||||||
chat_form.dataset.notice = "";
|
chat_form.dataset.notice = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* override chat form settings input */
|
||||||
|
const chat_appearance_form = document.getElementById("appearance-form_js");
|
||||||
|
const chat_appearance_form_result = document.getElementById("appearance-form_js__row__result");
|
||||||
|
const chat_form_settings = document.getElementById("chat-form_js__settings");
|
||||||
|
chat_form_settings.addEventListener("click", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (chat_appearance_form.dataset.hidden === undefined) {
|
||||||
|
chat_appearance_form.dataset.hidden = "";
|
||||||
|
chat_form_settings.style.backgroundColor = "";
|
||||||
|
chat_appearance_form_result.innerText = "";
|
||||||
|
if (!chat_appearance_form_submit.disabled) {
|
||||||
|
chat_appearance_form.reset();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chat_appearance_form.removeAttribute("data-hidden");
|
||||||
|
chat_form_settings.style.backgroundColor = "#4f4f53";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* appearance form */
|
||||||
|
const chat_appearance_form_name = document.getElementById("appearance-form_js__name");
|
||||||
|
const chat_appearance_form_color = document.getElementById("appearance-form_js__color");
|
||||||
|
const chat_appearance_form_password = document.getElementById("appearance-form_js__password");
|
||||||
|
|
||||||
/* create websocket */
|
/* create websocket */
|
||||||
const info_title = document.getElementById("info_js__title");
|
const info_title = document.getElementById("info_js__title");
|
||||||
const info_viewership = document.getElementById("info_js__float__viewership");
|
const info_viewership = document.getElementById("info_js__float__viewership");
|
||||||
|
@ -523,6 +562,7 @@ const on_websocket_message = (event) => {
|
||||||
case "error":
|
case "error":
|
||||||
console.log("ws error", receipt);
|
console.log("ws error", receipt);
|
||||||
chat_form_submit.disabled = false;
|
chat_form_submit.disabled = false;
|
||||||
|
chat_appearance_form_submit.disabled = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "init":
|
case "init":
|
||||||
|
@ -576,6 +616,14 @@ const on_websocket_message = (event) => {
|
||||||
update_user_tripcodes();
|
update_user_tripcodes();
|
||||||
update_users_list()
|
update_users_list()
|
||||||
|
|
||||||
|
// appearance form default values
|
||||||
|
const user = users[TOKEN_HASH];
|
||||||
|
if (user.name !== null) {
|
||||||
|
chat_appearance_form_name.setAttribute("value", user.name);
|
||||||
|
}
|
||||||
|
chat_appearance_form_name.setAttribute("placeholder", default_name[user.broadcaster]);
|
||||||
|
chat_appearance_form_color.setAttribute("value", user.color);
|
||||||
|
|
||||||
// insert new messages
|
// insert new messages
|
||||||
const last = chat_messages.children.length == 0 ? null : chat_messages.children[chat_messages.children.length - 1];
|
const last = chat_messages.children.length == 0 ? null : chat_messages.children[chat_messages.children.length - 1];
|
||||||
const last_seq = last === null ? null : parseInt(last.dataset.seq);
|
const last_seq = last === null ? null : parseInt(last.dataset.seq);
|
||||||
|
@ -666,6 +714,41 @@ const on_websocket_message = (event) => {
|
||||||
receipt.digest === null ? disable_captcha() : enable_captcha(receipt.digest);
|
receipt.digest === null ? disable_captcha() : enable_captcha(receipt.digest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "appearance":
|
||||||
|
console.log("ws appearance", receipt);
|
||||||
|
|
||||||
|
if (receipt.errors === undefined) {
|
||||||
|
if (receipt.name !== null) {
|
||||||
|
chat_appearance_form_name.setAttribute("value", receipt.name);
|
||||||
|
}
|
||||||
|
chat_appearance_form_color.setAttribute("value", receipt.color);
|
||||||
|
chat_appearance_form_result.innerHTML = receipt.result;
|
||||||
|
} else {
|
||||||
|
const ul = document.createElement("ul");
|
||||||
|
for (const error of receipt.errors) {
|
||||||
|
const li = document.createElement("li");
|
||||||
|
li.innerText = error[0];
|
||||||
|
for (const tuple of error.slice(1)) {
|
||||||
|
const mark = document.createElement("mark");
|
||||||
|
mark.innerText = tuple[0];
|
||||||
|
li.insertAdjacentText("beforeend", " ");
|
||||||
|
li.insertAdjacentElement("beforeend", mark);
|
||||||
|
li.insertAdjacentText("beforeend", tuple[1]);
|
||||||
|
}
|
||||||
|
ul.insertAdjacentElement("beforeend", li);
|
||||||
|
}
|
||||||
|
const result = document.createElement("div");
|
||||||
|
result.innerText = "Errors:";
|
||||||
|
result.insertAdjacentElement("beforeend", ul);
|
||||||
|
chat_appearance_form_result.innerHTML = result.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
chat_appearance_form_submit.disabled = false;
|
||||||
|
chat_appearance_form.removeAttribute("data-hidden");
|
||||||
|
chat_form_settings.style.backgroundColor = "#4f4f53";
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log("incomprehensible websocket message", receipt);
|
console.log("incomprehensible websocket message", receipt);
|
||||||
}
|
}
|
||||||
|
@ -680,13 +763,13 @@ const connect_websocket = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chat_live_ball.style.borderColor = "gold";
|
chat_live_ball.style.borderColor = "gold";
|
||||||
chat_live_status.innerHTML = "<span data-verbose='false'>Waiting...</span> <span data-verbose='true'>Connecting to chat...</span>";
|
chat_live_status.innerHTML = "<span data-verbose='true'>Connecting to chat...</span><span data-verbose='false'>···</span>";
|
||||||
ws = new WebSocket(`ws://${document.domain}:${location.port}/live?token=${encodeURIComponent(TOKEN)}`);
|
ws = new WebSocket(`ws://${document.domain}:${location.port}/live?token=${encodeURIComponent(TOKEN)}`);
|
||||||
ws.addEventListener("open", (event) => {
|
ws.addEventListener("open", (event) => {
|
||||||
console.log("websocket open", event);
|
console.log("websocket open", event);
|
||||||
chat_form_submit.disabled = false;
|
chat_form_submit.disabled = false;
|
||||||
chat_live_ball.style.borderColor = "green";
|
chat_live_ball.style.borderColor = "green";
|
||||||
chat_live_status.innerHTML = "<span>Connected<span data-verbose='true'> to chat</span></span>";
|
chat_live_status.innerHTML = "<span><span data-verbose='true'>Connected to chat</span><span data-verbose='false'>✓</span></span>";
|
||||||
// When the server is offline, a newly opened websocket can take a second
|
// When the server is offline, a newly opened websocket can take a second
|
||||||
// to close. This timeout tries to ensure the backoff doesn't instantly
|
// to close. This timeout tries to ensure the backoff doesn't instantly
|
||||||
// (erroneously) reset to 2 seconds in that case.
|
// (erroneously) reset to 2 seconds in that case.
|
||||||
|
@ -702,7 +785,7 @@ const connect_websocket = () => {
|
||||||
console.log("websocket close", event);
|
console.log("websocket close", event);
|
||||||
chat_form_submit.disabled = true;
|
chat_form_submit.disabled = true;
|
||||||
chat_live_ball.style.borderColor = "maroon";
|
chat_live_ball.style.borderColor = "maroon";
|
||||||
chat_live_status.innerHTML = "<span data-verbose='false'>Failed to connect</span> <span data-verbose='true'>Disconnected from chat</span>";
|
chat_live_status.innerHTML = "<span data-verbose='true'>Disconnected from chat</span><span data-verbose='false'>×</span>";
|
||||||
if (!ws.successor) {
|
if (!ws.successor) {
|
||||||
ws.successor = true;
|
ws.successor = true;
|
||||||
setTimeout(connect_websocket, websocket_backoff);
|
setTimeout(connect_websocket, websocket_backoff);
|
||||||
|
@ -745,6 +828,18 @@ chat_form.addEventListener("submit", (event) => {
|
||||||
ws.send(JSON.stringify(payload));
|
ws.send(JSON.stringify(payload));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* override js-only appearance form */
|
||||||
|
const chat_appearance_form_submit = document.getElementById("appearance-form_js__row__submit");
|
||||||
|
chat_appearance_form.addEventListener("submit", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const form = Object.fromEntries(new FormData(chat_appearance_form));
|
||||||
|
const payload = {type: "appearance", form: form};
|
||||||
|
chat_appearance_form_submit.disabled = true;
|
||||||
|
chat_appearance_form_password.value = "";
|
||||||
|
chat_appearance_form_result.innerText = "";
|
||||||
|
ws.send(JSON.stringify(payload));
|
||||||
|
});
|
||||||
|
|
||||||
/* when chat is being resized, peg its bottom in place (instead of its top) */
|
/* when chat is being resized, peg its bottom in place (instead of its top) */
|
||||||
const track_scroll = (element) => {
|
const track_scroll = (element) => {
|
||||||
chat_messages.dataset.scrollTop = chat_messages.scrollTop;
|
chat_messages.dataset.scrollTop = chat_messages.scrollTop;
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="243.55pt" height="243.55pt" version="1.1" viewBox="0 0 243.55 243.55" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m104.65 0-8.2461 29.598c-7.6914 2.1172-14.992 5.2305-21.777 9.0898l-27.062-15.012-23.891 23.891 15.012 27.062c-3.8594 6.7852-6.9727 14.086-9.0898 21.777l-29.598 8.2461v34.25l29.598 8.2461c2.1172 7.6914 5.2305 14.992 9.0898 21.777l-15.012 27.062 23.891 23.891 27.062-15.012c6.7852 3.8594 14.086 6.9727 21.777 9.0898l8.2461 29.598h34.25l8.2461-29.598c7.6914-2.1172 14.992-5.2305 21.777-9.0898l27.062 15.012 23.891-23.891-15.012-27.062c3.8594-6.7812 6.9727-14.086 9.0898-21.777l29.598-8.2461v-34.25l-29.598-8.2461c-2.1172-7.6914-5.2305-14.992-9.0898-21.777l15.012-27.062-23.891-23.891-27.062 15.012c-6.7852-3.8594-14.086-6.9727-21.777-9.0898l-8.2461-29.598zm17.125 74.418c26.156 0 47.359 21.203 47.359 47.359s-21.203 47.359-47.359 47.359-47.359-21.203-47.359-47.359 21.203-47.359 47.359-47.359z" fill="#bbbbbf"/>
|
||||||
|
</svg>
|
変更後 幅: | 高さ: | サイズ: 984 B |
|
@ -258,19 +258,19 @@ noscript {
|
||||||
#chat-users_nojs {
|
#chat-users_nojs {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
#chat__form {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
#chat-form_js {
|
#chat-form_js {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr min-content min-content 5rem;
|
grid-template-columns: 1fr min-content min-content min-content 5rem;
|
||||||
grid-template-rows: auto var(--button-height);
|
grid-template-rows: auto var(--button-height);
|
||||||
grid-gap: 0.375rem;
|
grid-gap: 0.375rem;
|
||||||
padding: 0 0.5rem 0.5rem 0.5rem;
|
padding: 0 0.5rem 0.5rem 0.5rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
#chat-form_js__submit {
|
|
||||||
grid-column: 2 / span 1;
|
|
||||||
}
|
|
||||||
#chat-form_js__comment {
|
#chat-form_js__comment {
|
||||||
grid-column: 1 / span 4;
|
grid-column: 1 / span 5;
|
||||||
background-color: #434347;
|
background-color: #434347;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
|
@ -299,9 +299,20 @@ noscript {
|
||||||
#chat-form_js__captcha-answer {
|
#chat-form_js__captcha-answer {
|
||||||
width: 8ch;
|
width: 8ch;
|
||||||
}
|
}
|
||||||
#chat-form_js__submit {
|
#chat-form_js__settings {
|
||||||
|
align-self: center;
|
||||||
|
padding: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: var(--text-color);
|
||||||
grid-column: 4;
|
grid-column: 4;
|
||||||
}
|
}
|
||||||
|
#chat-form_js__settings:hover {
|
||||||
|
background-color: #434347;
|
||||||
|
}
|
||||||
|
#chat-form_js__submit {
|
||||||
|
grid-column: 5;
|
||||||
|
}
|
||||||
#chat-form_js:not([data-captcha]) > #chat-form_js__captcha-image,
|
#chat-form_js:not([data-captcha]) > #chat-form_js__captcha-image,
|
||||||
#chat-form_js:not([data-captcha]) > #chat-form_js__captcha-answer {
|
#chat-form_js:not([data-captcha]) > #chat-form_js__captcha-answer {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -312,9 +323,10 @@ noscript {
|
||||||
#chat-form_js__notice {
|
#chat-form_js__notice {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(#2323277f 25%, #232327);
|
background: linear-gradient(#23232700, #2323277f 8%, #232327);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
#chat-form_js__notice__button {
|
#chat-form_js__notice__button {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -336,6 +348,51 @@ noscript {
|
||||||
#chat-form_nojs {
|
#chat-form_nojs {
|
||||||
height: 13ch;
|
height: 13ch;
|
||||||
}
|
}
|
||||||
|
#appearance-form_js {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 3rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin: 0 1rem;
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #343437df;
|
||||||
|
border: 2px outset #434347;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content 1fr min-content;
|
||||||
|
grid-template-rows: 1fr 1fr auto;
|
||||||
|
grid-gap: 0.375rem;
|
||||||
|
}
|
||||||
|
#appearance-form_js[data-hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#appearance-form_js__label-name,
|
||||||
|
#appearance-form_js__label-tripcode {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
#appearance-form_js__name,
|
||||||
|
#appearance-form_js__password {
|
||||||
|
min-width: 12ch;
|
||||||
|
}
|
||||||
|
#appearance-form_js__row {
|
||||||
|
grid-column: 1 / span 3;
|
||||||
|
grid-row: 3;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 4rem;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
#appearance-form_js__row__result {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 11pt;
|
||||||
|
}
|
||||||
|
#appearance-form_js__row__result > ul {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1.125rem;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
#appearance-form_js__row__submit {
|
||||||
|
min-height: 1.75rem;
|
||||||
|
}
|
||||||
#chat-live {
|
#chat-live {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 9pt;
|
font-size: 9pt;
|
||||||
|
|
|
@ -4,7 +4,7 @@ from math import inf
|
||||||
from quart import current_app
|
from quart import current_app
|
||||||
|
|
||||||
from anonstream.wrappers import try_except_log, with_timestamp
|
from anonstream.wrappers import try_except_log, with_timestamp
|
||||||
from anonstream.helpers.user import get_presence, Presence
|
from anonstream.helpers.user import get_default_name, get_presence, Presence
|
||||||
from anonstream.helpers.captcha import check_captcha_digest, Answer
|
from anonstream.helpers.captcha import check_captcha_digest, Answer
|
||||||
from anonstream.helpers.tripcode import generate_tripcode
|
from anonstream.helpers.tripcode import generate_tripcode
|
||||||
from anonstream.utils.colour import color_to_colour, get_contrast, NotAColor
|
from anonstream.utils.colour import color_to_colour, get_contrast, NotAColor
|
||||||
|
@ -69,6 +69,8 @@ def try_change_appearance(user, name, color, password, want_tripcode):
|
||||||
|
|
||||||
def change_name(user, name, dry_run=False):
|
def change_name(user, name, dry_run=False):
|
||||||
if dry_run:
|
if dry_run:
|
||||||
|
if name == get_default_name(user):
|
||||||
|
name = None
|
||||||
if name is not None:
|
if name is not None:
|
||||||
if len(name) == 0:
|
if len(name) == 0:
|
||||||
raise BadAppearance('Name was empty')
|
raise BadAppearance('Name was empty')
|
||||||
|
@ -91,7 +93,7 @@ def change_color(user, color, dry_run=False):
|
||||||
if contrast < min_contrast:
|
if contrast < min_contrast:
|
||||||
raise BadAppearance(
|
raise BadAppearance(
|
||||||
'Colour had insufficient contrast:',
|
'Colour had insufficient contrast:',
|
||||||
(f'{contrast:.2f}', f'/{min_contrast}'),
|
(f'{contrast:.2f}', f'/{min_contrast:.2f}'),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
user['color'] = color
|
user['color'] = color
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
WS = Enum('WS', names=('MESSAGE, CAPTCHA, APPEARANCE'))
|
||||||
|
|
||||||
class Malformed(Exception):
|
class Malformed(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -19,13 +23,27 @@ def parse_websocket_data(receipt):
|
||||||
comment = get(str, form, 'comment')
|
comment = get(str, form, 'comment')
|
||||||
digest = get(str, form, 'captcha-digest', '')
|
digest = get(str, form, 'captcha-digest', '')
|
||||||
answer = get(str, form, 'captcha-answer', '')
|
answer = get(str, form, 'captcha-answer', '')
|
||||||
return nonce, comment, digest, answer
|
return WS.MESSAGE, (nonce, comment, digest, answer)
|
||||||
|
|
||||||
case 'appearance':
|
case 'appearance':
|
||||||
raise NotImplemented
|
form = get(dict, receipt, 'form')
|
||||||
|
name = get(str, form, 'name').strip()
|
||||||
|
if len(name) == 0:
|
||||||
|
name = None
|
||||||
|
color = get(str, form, 'color')
|
||||||
|
password = get(str, form, 'password')
|
||||||
|
#match get(str | None, form, 'want-tripcode'):
|
||||||
|
# case '0':
|
||||||
|
# want_tripcode = False
|
||||||
|
# case '1':
|
||||||
|
# want_tripcode = True
|
||||||
|
# case _:
|
||||||
|
# want_tripcode = None
|
||||||
|
want_tripcode = bool(password)
|
||||||
|
return WS.APPEARANCE, (name, color, password, want_tripcode)
|
||||||
|
|
||||||
case 'captcha':
|
case 'captcha':
|
||||||
return None
|
return WS.CAPTCHA, ()
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
raise Malformed('malformed type')
|
raise Malformed('malformed type')
|
||||||
|
|
|
@ -6,9 +6,9 @@ from quart import current_app, websocket
|
||||||
from anonstream.stream import get_stream_title, get_stream_uptime_and_viewership
|
from anonstream.stream import get_stream_title, get_stream_uptime_and_viewership
|
||||||
from anonstream.captcha import get_random_captcha_digest_for
|
from anonstream.captcha import get_random_captcha_digest_for
|
||||||
from anonstream.chat import get_all_messages_for_websocket, add_chat_message, Rejected
|
from anonstream.chat import get_all_messages_for_websocket, add_chat_message, Rejected
|
||||||
from anonstream.user import get_all_users_for_websocket, see, verify, deverify, BadCaptcha
|
from anonstream.user import get_all_users_for_websocket, see, verify, deverify, BadCaptcha, try_change_appearance
|
||||||
from anonstream.utils.chat import generate_nonce
|
from anonstream.utils.chat import generate_nonce
|
||||||
from anonstream.utils.websocket import parse_websocket_data, Malformed
|
from anonstream.utils.websocket import parse_websocket_data, Malformed, WS
|
||||||
|
|
||||||
CONFIG = current_app.config
|
CONFIG = current_app.config
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ async def websocket_inbound(queue, user):
|
||||||
finally:
|
finally:
|
||||||
see(user)
|
see(user)
|
||||||
try:
|
try:
|
||||||
parsed = parse_websocket_data(receipt)
|
receipt_type, parsed = parse_websocket_data(receipt)
|
||||||
except Malformed as e:
|
except Malformed as e:
|
||||||
error , *_ = e.args
|
error , *_ = e.args
|
||||||
payload = {
|
payload = {
|
||||||
|
@ -49,12 +49,14 @@ async def websocket_inbound(queue, user):
|
||||||
'because': error,
|
'because': error,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
match parsed:
|
match receipt_type:
|
||||||
case [nonce, comment, digest, answer]:
|
case WS.MESSAGE:
|
||||||
payload = handle_inbound_message(user, *parsed)
|
handle = handle_inbound_message
|
||||||
|
case WS.APPEARANCE:
|
||||||
case None:
|
handle = handle_inbound_appearance
|
||||||
payload = handle_inbound_captcha(user)
|
case WS.CAPTCHA:
|
||||||
|
handle = handle_inbound_captcha
|
||||||
|
payload = handle(user, *parsed)
|
||||||
|
|
||||||
queue.put_nowait(payload)
|
queue.put_nowait(payload)
|
||||||
|
|
||||||
|
@ -64,6 +66,22 @@ def handle_inbound_captcha(user):
|
||||||
'digest': get_random_captcha_digest_for(user),
|
'digest': get_random_captcha_digest_for(user),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def handle_inbound_appearance(user, name, color, password, want_tripcode):
|
||||||
|
errors = try_change_appearance(user, name, color, password, want_tripcode)
|
||||||
|
if errors:
|
||||||
|
return {
|
||||||
|
'type': 'appearance',
|
||||||
|
'errors': [error.args for error in errors],
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
'type': 'appearance',
|
||||||
|
'result': 'Changed appearance',
|
||||||
|
'name': user['name'],
|
||||||
|
'color': user['color'],
|
||||||
|
#'tripcode': user['tripcode'],
|
||||||
|
}
|
||||||
|
|
||||||
def handle_inbound_message(user, nonce, comment, digest, answer):
|
def handle_inbound_message(user, nonce, comment, digest, answer):
|
||||||
try:
|
try:
|
||||||
verification_happened = verify(user, digest, answer)
|
verification_happened = verify(user, digest, answer)
|
||||||
|
|
読み込み中…
新しいイシューから参照