Modify Chat UI

This commit is contained in:
cuom1999 2023-08-29 18:36:01 -05:00
parent 9f0213865d
commit 00113848c8
10 changed files with 1663 additions and 1572 deletions

View file

@ -18,15 +18,22 @@ class Room(models.Model):
Profile, related_name="user_two", verbose_name="user 2", on_delete=CASCADE
)
@cache_wrapper(prefix="Rc")
def contain(self, profile):
return self.user_one == profile or self.user_two == profile
@cache_wrapper(prefix="Rou")
def other_user(self, profile):
return self.user_one if profile == self.user_two else self.user_two
@cache_wrapper(prefix="Rus")
def users(self):
return [self.user_one, self.user_two]
@cache_wrapper(prefix="Rlmb")
def last_message_body(self):
return self.message_set.first().body
class Message(models.Model):
author = models.ForeignKey(Profile, verbose_name=_("user"), on_delete=CASCADE)

View file

@ -22,6 +22,7 @@ from django.db.models import (
Count,
IntegerField,
F,
Max,
)
from django.db.models.functions import Coalesce
from django.utils import timezone
@ -206,6 +207,7 @@ def post_message(request):
},
)
else:
Room.last_message_body.dirty(room)
for user in room.users():
event.post(
encrypt_channel("chat_" + str(user.id)),
@ -342,15 +344,31 @@ def get_online_status(profile, other_profile_ids, rooms=None):
if rooms:
unread_count = get_unread_count(rooms, profile)
count = {}
last_msg = {}
room_of_user = {}
for i in unread_count:
count[i["other_user"]] = i["unread_count"]
room = Room.objects.get(id=i["room"])
other_profile = room.other_user(profile)
count[other_profile.id] = i["unread_count"]
for room in rooms:
room = Room.objects.get(id=room)
other_profile = room.other_user(profile)
last_msg[other_profile.id] = room.last_message_body()
room_of_user[other_profile.id] = room.id
for other_profile in other_profiles:
is_online = False
if other_profile.last_access >= last_5_minutes:
is_online = True
user_dict = {"user": other_profile, "is_online": is_online}
if rooms and other_profile.id in count:
user_dict["unread_count"] = count[other_profile.id]
if rooms:
user_dict.update(
{
"unread_count": count.get(other_profile.id),
"last_msg": last_msg.get(other_profile.id),
"room": room_of_user.get(other_profile.id),
}
)
user_dict["url"] = encrypt_url(profile.id, other_profile.id)
ret.append(user_dict)
return ret
@ -386,17 +404,9 @@ def get_status_context(profile, include_ignored=False):
recent_profile_ids = [str(i["other_user"]) for i in recent_profile]
recent_rooms = [int(i["id"]) for i in recent_profile]
friend_list = (
Friend.get_friend_profiles(profile)
.exclude(id__in=recent_profile_ids)
.exclude(id__in=ignored_users)
.order_by("-last_access")
.values_list("id", flat=True)
)
admin_list = (
queryset.filter(display_rank="admin")
.exclude(id__in=friend_list)
.exclude(id__in=recent_profile_ids)
.values_list("id", flat=True)
)
@ -405,7 +415,6 @@ def get_status_context(profile, include_ignored=False):
queryset.filter(last_access__gte=last_5_minutes)
.annotate(is_online=Case(default=True, output_field=BooleanField()))
.order_by("-rating")
.exclude(id__in=friend_list)
.exclude(id__in=admin_list)
.exclude(id__in=recent_profile_ids)
.values_list("id", flat=True)[:30]
@ -416,10 +425,6 @@ def get_status_context(profile, include_ignored=False):
"title": "Recent",
"user_list": get_online_status(profile, recent_profile_ids, recent_rooms),
},
{
"title": "Following",
"user_list": get_online_status(profile, friend_list),
},
{
"title": "Admin",
"user_list": get_online_status(profile, admin_list),
@ -488,18 +493,9 @@ def get_or_create_room(request):
def get_unread_count(rooms, user):
if rooms:
res = (
UserRoom.objects.filter(user=user, room__in=rooms, unread_count__gt=0)
.select_related("room__user_one", "room__user_two")
.values("unread_count", "room__user_one", "room__user_two")
)
for ur in res:
ur["other_user"] = (
ur["room__user_one"]
if ur["room__user_two"] == user.id
else ur["room__user_two"]
)
return res
return UserRoom.objects.filter(
user=user, room__in=rooms, unread_count__gt=0
).values("unread_count", "room")
else: # lobby
user_room = UserRoom.objects.filter(user=user, room__isnull=True).first()
if not user_room:

View file

@ -5,9 +5,10 @@ from django.db.models.query import QuerySet
import hashlib
MAX_NUM_CHAR = 15
NONE_RESULT = "__None__"
def cache_wrapper(prefix, timeout=86400):
def cache_wrapper(prefix, timeout=None):
def arg_to_str(arg):
if hasattr(arg, "id"):
return str(arg.id)
@ -31,8 +32,11 @@ def cache_wrapper(prefix, timeout=86400):
cache_key = get_key(func, *args, **kwargs)
result = cache.get(cache_key)
if result is not None:
if result == NONE_RESULT:
result = None
return result
if result is None:
result = NONE_RESULT
result = func(*args, **kwargs)
cache.set(cache_key, result, timeout)
return result

View file

@ -47,11 +47,6 @@ else:
"pagedown-extra/Markdown.Extra.js",
"pagedown_init.js",
]
css = {
"all": [
"markdown.css",
]
}
class AdminPagedownWidget(PagedownWidget, admin_widgets.AdminTextareaWidget):
class Media:
@ -60,7 +55,6 @@ else:
"pagedown_widget.css",
"content-description.css",
"admin/css/pagedown.css",
"markdown.css",
"pagedown.css",
]
}
@ -125,7 +119,6 @@ else:
"pygment-github.css",
"table.css",
"ranks.css",
"markdown.css",
"dmmd-preview.css",
]
}

View file

@ -39,15 +39,15 @@
#chat-online {
border-right: 1px solid #ccc;
padding-bottom: 0 !important;
min-width: 25%;
border-bottom: 0;
font-size: 1.2em;
}
#chat-online-content {
margin-bottom: 0;
overflow: hidden;
overflow-wrap: break-word;
overflow-y: auto;
max-height: calc(100% - 44px);
max-height: 100%;
}
#chat-box {
/*border: 1px solid #ccc;*/
@ -75,6 +75,14 @@
padding: 0;
width: 100%;
}
.selected-status-row {
background-color: lightgray;
}
.status_last_message {
color: darkgray;
font-size: 0.8em;
}
@media (min-width: 800px) {
#chat-container {
display: flex;
@ -86,6 +94,10 @@
}
#chat-online {
margin: 0;
width: 35%;
}
#chat-area {
flex-grow: 1;
}
.chat-left-panel, .chat-right-panel {
display: block !important;
@ -138,29 +150,29 @@
transition: 1.5s ease-in-out;
}
.status-pic {
height: 1.3em;
width: 1.3em;
border-radius: 0.3em;
height: 32px;
width: 32px;
border-radius: 50%;
}
.status-container {
position: relative;
display: inline-flex;
flex: 0 0 auto;
}
.status-circle {
position: absolute;
bottom: 0;
right: 0;
cx: 18px;
cy: 18px;
cx: 27px;
cy: 27px;
r: 4.5px;
stroke: white;
stroke-width: 1;
}
.status-row {
display: flex;
font-size: 15px;
padding: 0.2em 0.2em 0.2em 1em;
border-radius: 4px;
padding: 15px;
gap: 0.5em;
}
.status-row:hover {
background: lightgray;
@ -168,6 +180,7 @@
}
.status-list {
padding: 0;
margin: 0;
}
.status-section-title {
cursor: pointer;
@ -200,6 +213,7 @@
background-color: darkcyan;
border-radius: 2px;
padding: 0 0.5em;
align-self: flex-end;
}
#setting-content {
display: none;
@ -225,7 +239,7 @@
@media (max-width: 799px) {
#chat-area {
height: 500px;
height: calc(100vh - 50px);
}
#emoji-button {
display: none;

File diff suppressed because one or more lines are too long

View file

@ -20,7 +20,6 @@
window.lock = false;
window.lock_click_space = false;
window.pushed_messages = new Set();
let isMobile = window.matchMedia("only screen and (max-width: 799px)").matches;
window.load_dynamic_update = function (last_msg) {
var receiver = new EventReceiver(
@ -71,25 +70,20 @@
<div id="chat-container">
<div id="chat-online" class="chat-right-panel sidebox">
<h3>
<i class="fa fa-users"></i>{{_('Online Users')}}
</h3>
<div id="chat-online-content">
<div id="search-container">
<center>
<form id="search-form" name="form" action="{{ url('get_or_create_room') }}" method="post">
{% csrf_token %}
<input id="search-handle" type="text" name="search"
placeholder="{{ _('Search by handle...') }}">
</form>
</center>
<form id="chat-search-form" name="form" action="{{ url('get_or_create_room') }}" method="post">
{% csrf_token %}
<input id="search-handle" type="text" name="search"
placeholder="{{ _('Search by handle...') }}">
</form>
</div>
<div id="chat-online-list">
{% include "chat/online_status.html" %}
</div>
</div>
</div>
<div id="chat-area" class="chat-left-panel" style="width:100%">
<div id="chat-area" class="chat-left-panel">
<div id="chat-info" style="height: 10%">
{% include 'chat/user_online_status.html' %}
</div>

View file

@ -102,12 +102,22 @@
float: inherit;
}
#search-container {
margin-bottom: 0.4em;
padding: 1em;
}
#setting {
position: relative;
}
.status-user {
display: flex;
flex-direction: column;
min-width: 0;
flex-grow: 1;
}
.wrapline {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
@media (min-width: 800px) {
#page-container {

View file

@ -5,6 +5,8 @@
"{{_('Admin')}}",
"{{_('Other')}}",
];
let isMobile = window.matchMedia("only screen and (max-width: 799px)").matches;
function load_next_page(last_id, refresh_html=false) {
var param = {
'last_id': last_id,
@ -82,6 +84,7 @@
register_toggle($(this));
});
register_click_space();
color_selected_room();
}
})
@ -207,6 +210,9 @@
}
function add_message_from_template(body, tmp_id) {
if (window.room_id) {
$("#last_msg-" + window.room_id).html(body);
}
var html = message_template;
html = html.replaceAll('$body', body).replaceAll('$id', tmp_id);
var $html = $(html);
@ -267,6 +273,11 @@
}
}
function color_selected_room() {
$(".status-row").removeClass("selected-status-row");
$("#click_space_" + window.other_user_id).addClass("selected-status-row");
}
function load_room(encrypted_user) {
if (window.lock_click_space) return;
@ -283,6 +294,7 @@
.done(function(data) {
window.room_id = data.room;
window.other_user_id = data.other_user_id;
color_selected_room();
callback();
})
.fail(function() {
@ -292,6 +304,7 @@
else {
window.room_id = '';
window.other_user_id = '';
color_selected_room();
callback();
}
window.lock_click_space = false;
@ -494,7 +507,7 @@
var in_user_redirect = false;
$('#search-handle').select2({
placeholder: '{{ _('Search by handle...') }}',
placeholder: '<i class="fa fa-search"></i> {{ _('Search by handle...') }}',
ajax: {
url: '{{ url('chat_user_search_select2_ajax') }}'
},
@ -544,5 +557,6 @@
})
}
register_setting();
color_selected_room();
});
</script>

View file

@ -27,11 +27,18 @@
fill="{{'green' if user.is_online else 'red'}}"/>
</svg>
</div>
<span style="padding-left:0.3em" class="username {{ user.user.css_class }}">
{{ user.user.username }}
</span>
<span class="spacer">
<span class="unread-count" id="unread-count-{{user.user.id}}">{{user.unread_count if user.unread_count}}</span>
<div class="status-user">
<span class="username {{ user.user.css_class }} wrapline">
{{ user.user.username }}
</span>
{% if user.last_msg %}
<span class="status_last_message wrapline" {% if user.room %}id="last_msg-{{user.room}}"{% endif %}>
{{ user.last_msg }}
</span>
{% endif %}
</div>
<span class="unread-count" id="unread-count-{{user.user.id}}">
{{user.unread_count if user.unread_count}}
</span>
</li>
{% endfor %}