diff --git a/website/chat.py b/website/chat.py index 89d63e0..2d3e40e 100644 --- a/website/chat.py +++ b/website/chat.py @@ -12,7 +12,7 @@ from website.constants import BROADCASTER_TOKEN, MESSAGE_MAX_LENGTH, CHAT_MAX_ST from pprint import pprint -messages = deque() +messages = deque() # messages are stored from most recent on the left to least recent on the right captchas = {} viewers = viewership.viewers nonces = set() @@ -72,7 +72,8 @@ def comment(text, token, c_response, c_token, nonce): 'id': f'{token}-{secrets.token_hex(4)}', 'hidden': False, 'time': dt.strftime('%H:%M'), - 'date': dt.strftime('%F %T')}) + 'timestamp': dt.strftime('%F %T'), + 'date': dt.strftime('%F')}) viewers[token]['last_comment'] = now viewers[token]['recent_comments'].append(now) viewers[token]['verified'] = True @@ -138,3 +139,50 @@ def set_tripcode(password, token): def remove_tripcode(token): viewers[token]['tripcode'] = tripcode.default() return N_APPEAR_OK, True + +def decorate(messages): + ''' + add extra stuff to a list of messages, e.g. date, chat command responses + ''' + def _is_visible(message): + # uncomment the end part once the broadcaster can see hidden comments + return not message['hidden'] # or token == BROADCASTER_TOKEN + + first_visible_message = None + final_visible_message = None + for message in messages: + if _is_visible(message): + final_visible_message = message + break + messages.reverse() + for message in messages: + if _is_visible(message): + first_visible_message = message + break + + # if there are no messages, do nothing + if first_visible_message == None or final_visible_message == None: + return + + # TODO: chat commands e.g. !uptime; try to make it so responses always follow the message with the command, so not split over a date separator + + # add date at the top if necessary + if first_visible_message['date'] != final_visible_message['date']: + messages.insert(0, {'special': 'date', 'content': first_visible_message['date']}) + + # add dates between messages that cross over a day boundary + to_insert = [] + previous_message = None + for index, message in enumerate(messages): + if message.get('special'): + continue + if previous_message and message['date'] != previous_message['date']: + to_insert.append(index) + previous_message = message + + to_insert.reverse() + for index in to_insert: + messages.insert(index, {'special': 'date', 'content': messages[index]['date']}) + + # revert back to original ordering + messages.reverse() diff --git a/website/routes.py b/website/routes.py index b0d4a58..ad5d320 100644 --- a/website/routes.py +++ b/website/routes.py @@ -151,6 +151,8 @@ def chat_iframe(): messages = (message for message in chat.messages if not message['hidden']) messages = zip(messages, range(CHAT_SCROLLBACK)) # show at most CHAT_SCROLLBACK messages messages = [message for message, _ in messages] + + chat.decorate(messages) return render_template('chat-iframe.html', token=token, messages=messages, @@ -177,8 +179,9 @@ def heartbeat(): 'title': stream.get_title(), 'start_abs': start_abs if online else None, 'start_rel': start_rel if online else None} - if token in viewership.video_was_corrupted: - response['corrupted'] = True + # commented out because we should be able to tell if we're not receiving the stream already +# if token in viewership.video_was_corrupted: +# response['corrupted'] = True return response diff --git a/website/templates/chat-iframe.html b/website/templates/chat-iframe.html index 851879c..d056ba3 100644 --- a/website/templates/chat-iframe.html +++ b/website/templates/chat-iframe.html @@ -12,6 +12,7 @@ .reverse {direction: rtl;} .comment {color: white;padding:4px 0;margin-top:-4px;margin-bottom:calc(-4px + 0.375em);overflow:hidden;} + .date {color:gray;font-size:75%;text-align:center;border-bottom:1px solid #333;margin:0.5em 0 0.75em 0;} .name {font-weight: bold;unicode-bidi: isolate;} sup {margin: 0 -0.25em 0 0.125em;font-size: 90%;font-family:monospace;} @@ -91,22 +92,26 @@ {% for message in messages %} -