Add 3-hexdigit tags for default-name users

このコミットが含まれているのは:
n9k 2022-02-22 09:30:23 +00:00
コミット 672ef10159
6個のファイルの変更49行の追加19行の削除

ファイルの表示

@ -20,10 +20,14 @@ Presence = Enum(
)
)
def generate_token_hash(token):
def generate_token_hash_and_tag(token):
parts = CONFIG['SECRET_KEY'] + b'token-hash\0' + token.encode()
digest = hashlib.sha256(parts).digest()
return base64.b32encode(digest)[:26].lower().decode()
token_hash = base64.b32encode(digest)[:26].lower().decode()
tag = f'#{digest.hex()[:3]}'
return token_hash, tag
def generate_user(timestamp, token, broadcaster):
colour = generate_colour(
@ -31,9 +35,11 @@ def generate_user(timestamp, token, broadcaster):
bg=CONFIG['CHAT_BACKGROUND_COLOUR'],
contrast=4.53,
)
token_hash, tag = generate_token_hash_and_tag(token)
return {
'token': token,
'token_hash': generate_token_hash(token),
'token_hash': token_hash,
'tag': tag,
'broadcaster': broadcaster,
'verified': broadcaster,
'websockets': set(),

ファイルの表示

@ -111,12 +111,15 @@ async def nojs_submit_message(user):
@with_user_from(request)
async def nojs_submit_appearance(user):
form = await request.form
name = form.get('name', '') or None
name = form.get('name', '').strip()
color = form.get('color', '')
password = form.get('password', '')
want_delete_tripcode = form.get('clear-tripcode', type=bool)
want_change_tripcode = form.get('set-tripcode', type=bool)
if len(name) == 0 or name == get_default_name(user):
name = None
errors = try_change_appearance(
user,
name,

ファイルの表示

@ -76,10 +76,7 @@ const create_chat_message = (object) => {
chat_message_time.title = `${object.date} ${object.time_seconds}`;
chat_message_time.innerText = object.time_minutes;
const chat_message_name = document.createElement("span");
chat_message_name.classList.add("chat-message__name");
chat_message_name.innerText = get_user_name({user});
//chat_message_name.dataset.color = user.color; // not working in any browser
const chat_message_name = create_chat_message_name(user);
const chat_message_tripcode_nbsp = document.createElement("span");
chat_message_tripcode_nbsp.classList.add("for-tripcode");
@ -104,7 +101,20 @@ const create_chat_message = (object) => {
chat_message.insertAdjacentHTML("beforeend", ": ");
chat_message.insertAdjacentElement("beforeend", chat_message_markup);
return chat_message
return chat_message;
}
const create_chat_message_name = (user) => {
const chat_message_name = document.createElement("span");
chat_message_name.classList.add("chat-message__name");
chat_message_name.innerText = get_user_name({user});
//chat_message_name.dataset.color = user.color; // not working in any browser
if (!user.broadcaster && user.name === null) {
const chat_message_name_tag = document.createElement("sup");
chat_message_name_tag.classList.add("chat-message__name__tag");
chat_message_name_tag.innerText = user.tag;
chat_message_name.insertAdjacentElement("beforeend", chat_message_name_tag);
}
return chat_message_name;
}
const create_and_add_chat_message = (object) => {
const chat_message = create_chat_message(object);
@ -176,8 +186,9 @@ const update_user_names = (token_hash=null) => {
for (const chat_message of chat_messages.children) {
const this_token_hash = chat_message.dataset.tokenHash;
if (token_hashes.includes(this_token_hash)) {
const user = users[this_token_hash];
const chat_message_name = chat_message.querySelector(".chat-message__name");
chat_message_name.innerText = get_user_name({token_hash: this_token_hash});
chat_message_name.innerHTML = create_chat_message_name(user).innerHTML;
}
}
}
@ -315,13 +326,6 @@ const on_websocket_message = (event) => {
chat_form_nonce.value = receipt.nonce;
receipt.digest === null ? disable_captcha() : enable_captcha(receipt.digest);
default_name = receipt.default;
max_chat_scrollback = receipt.scrollback;
users = receipt.users;
update_user_names();
update_user_colors();
update_user_tripcodes();
const seqs = new Set(receipt.messages.map((message) => {return message.seq;}));
const to_delete = [];
for (const chat_message of chat_messages.children) {
@ -334,6 +338,13 @@ const on_websocket_message = (event) => {
chat_message.remove();
}
default_name = receipt.default;
max_chat_scrollback = receipt.scrollback;
users = receipt.users;
update_user_names();
update_user_colors();
update_user_tripcodes();
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);
for (const message of receipt.messages) {

ファイルの表示

@ -125,6 +125,11 @@ noscript {
/* color: attr("data-color"); */
cursor: default;
}
.chat-message__name__tag {
font-family: monospace;
font-size: 9pt;
vertical-align: top;
}
.chat-message__markup {
overflow-wrap: anywhere;
line-height: 1.3125;

ファイルの表示

@ -105,6 +105,11 @@
/* color: attr("data-color"); */
cursor: default;
}
.chat-message__name__tag {
font-family: monospace;
font-size: 9pt;
vertical-align: top;
}
.chat-message__markup {
overflow-wrap: anywhere;
line-height: 1.3125;
@ -131,7 +136,7 @@
{% for message in messages | reverse %}
<li class="chat-message" data-seq="{{ message.seq }}" data-token-hash="{{ user.token_hash }}">
{% with user = users_by_token[message.token] %}
<time class="chat-message__time" datetime="{{ message.date }}T{{ message.time_seconds }}Z" title="{{ message.date }} {{ message.time_seconds }}">{{ message.time_minutes }}</time>&nbsp;<span class="chat-message__name" style="color:{{ user.color }};">{{ user.name or get_default_name(user) }}</span>{% if user.tripcode %}<span class="for-tripcode">&nbsp;</span><span class="tripcode for-tripcode" style="background-color:{{ user.tripcode.background_color }};color:{{ user.tripcode.foreground_color }};">{{ user.tripcode.digest }}</span>{% endif %}:&nbsp;<span class="chat-message__markup">{{ message.markup }}</span>
<time class="chat-message__time" datetime="{{ message.date }}T{{ message.time_seconds }}Z" title="{{ message.date }} {{ message.time_seconds }}">{{ message.time_minutes }}</time>&nbsp;<span class="chat-message__name" style="color:{{ user.color }};">{{ user.name or get_default_name(user) }}{% if not user.broadcaster and user.name is none %}<sup class="chat-message__name__tag">{{ user.tag }}</sup>{% endif %}</span>{% if user.tripcode %}<span class="for-tripcode">&nbsp;</span><span class="tripcode for-tripcode" style="background-color:{{ user.tripcode.background_color }};color:{{ user.tripcode.foreground_color }};">{{ user.tripcode.digest }}</span>{% endif %}:&nbsp;<span class="chat-message__markup">{{ message.markup }}</span>
{% endwith %}
</li>
{% endfor %}

ファイルの表示

@ -10,7 +10,7 @@ def generate_token():
return secrets.token_hex(16)
def get_user_for_websocket(user):
keys = ['broadcaster', 'name', 'color', 'tripcode']
keys = ['broadcaster', 'name', 'color', 'tripcode', 'tag']
return {key: user[key] for key in keys}
def concatenate_for_notice(string, *tuples):