mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
chat - tidy up and nav improvements
This commit is contained in:
parent
e840db1991
commit
a566c40913
18 changed files with 65 additions and 36 deletions
|
@ -12,7 +12,7 @@ from app.user.routes import show_profile
|
|||
from app.constants import POST_TYPE_LINK, POST_TYPE_IMAGE, SUBSCRIPTION_MEMBER
|
||||
from app.models import User, Community, CommunityJoinRequest, CommunityMember, CommunityBan, ActivityPubLog, Post, \
|
||||
PostReply, Instance, PostVote, PostReplyVote, File, AllowedInstances, BannedInstances, utcnow, Site, Notification, \
|
||||
ChatMessage
|
||||
ChatMessage, Conversation
|
||||
from app.activitypub.util import public_key, users_total, active_half_year, active_month, local_posts, local_comments, \
|
||||
post_to_activity, find_actor_or_create, default_context, instance_blocked, find_reply_parent, find_liked_object, \
|
||||
lemmy_site_data, instance_weight, is_activitypub_request, downvote_post_reply, downvote_post, upvote_post_reply, \
|
||||
|
@ -380,14 +380,22 @@ def process_inbox_request(request_json, activitypublog_id, ip_address):
|
|||
recipient_ap_id = request_json['object']['to'][0]
|
||||
recipient = find_actor_or_create(recipient_ap_id)
|
||||
if sender and recipient and recipient.is_local():
|
||||
if sender.created_recently() or sender.reputation < 10:
|
||||
if sender.created_recently() or sender.reputation <= -10:
|
||||
activity_log.exception_message = "Sender not eligible to send"
|
||||
elif recipient.has_blocked_user(sender.id) or recipient.has_blocked_instance(sender.instance_id):
|
||||
activity_log.exception_message = "Sender blocked by recipient"
|
||||
else:
|
||||
# Find existing conversation to add to
|
||||
existing_conversation = Conversation.find_existing_conversation(recipient=recipient, sender=sender)
|
||||
if not existing_conversation:
|
||||
existing_conversation = Conversation(user_id=sender.id)
|
||||
existing_conversation.members.append(recipient)
|
||||
existing_conversation.members.append(sender)
|
||||
db.session.add(existing_conversation)
|
||||
db.session.commit()
|
||||
# Save ChatMessage to DB
|
||||
encrypted = request_json['object']['encrypted'] if 'encrypted' in request_json['object'] else None
|
||||
new_message = ChatMessage(sender_id=sender.id, recipient_id=recipient.id,
|
||||
new_message = ChatMessage(sender_id=sender.id, recipient_id=recipient.id, conversation_id=existing_conversation.id,
|
||||
body=request_json['object']['source']['content'],
|
||||
body_html=allowlist_html(markdown_to_html(request_json['object']['source']['content'])),
|
||||
encrypted=encrypted)
|
||||
|
@ -396,10 +404,11 @@ def process_inbox_request(request_json, activitypublog_id, ip_address):
|
|||
|
||||
# Notify recipient
|
||||
notify = Notification(title=shorten_string('New message from ' + sender.display_name()),
|
||||
url=f'/chat/{new_message.id}', user_id=recipient.id,
|
||||
url=f'/chat/{existing_conversation.id}', user_id=recipient.id,
|
||||
author_id=sender.id)
|
||||
db.session.add(notify)
|
||||
recipient.unread_notifications += 1
|
||||
existing_conversation.read = False
|
||||
db.session.commit()
|
||||
activity_log.result = 'success'
|
||||
else:
|
||||
|
|
|
@ -5,7 +5,7 @@ from sqlalchemy import desc, or_, and_, text
|
|||
|
||||
from app import db, celery
|
||||
from app.chat.forms import AddReply, ReportConversationForm
|
||||
from app.chat.util import send_message, find_existing_conversation
|
||||
from app.chat.util import send_message
|
||||
from app.models import Site, User, Report, ChatMessage, Notification, InstanceBlock, Conversation, conversation_member
|
||||
from app.user.forms import ReportUserForm
|
||||
from app.utils import render_template, moderating_communities, joined_communities
|
||||
|
@ -28,6 +28,7 @@ def chat_home(conversation_id=None):
|
|||
return redirect(url_for('chat.chat_home', conversation_id=conversations[0].id))
|
||||
else:
|
||||
conversation = Conversation.query.get_or_404(conversation_id)
|
||||
conversation.read = True
|
||||
if not current_user.is_admin() and not conversation.is_member(current_user):
|
||||
abort(400)
|
||||
if conversations:
|
||||
|
@ -65,7 +66,7 @@ def new_message(to):
|
|||
return redirect(url_for('chat.denied'))
|
||||
if recipient.has_blocked_user(current_user.id) or current_user.has_blocked_user(recipient.id):
|
||||
return redirect(url_for('chat.blocked'))
|
||||
existing_conversation = find_existing_conversation(recipient=recipient, sender=current_user)
|
||||
existing_conversation = Conversation.find_existing_conversation(recipient=recipient, sender=current_user)
|
||||
if existing_conversation:
|
||||
return redirect(url_for('chat.chat_home', conversation_id=existing_conversation.id, _anchor='message'))
|
||||
form = AddReply()
|
||||
|
|
|
@ -60,23 +60,3 @@ def send_message(form, conversation_id: int) -> ChatMessage:
|
|||
flash(_('Message sent.'))
|
||||
return reply
|
||||
|
||||
|
||||
def find_existing_conversation(recipient, sender):
|
||||
sql = """SELECT
|
||||
c.id AS conversation_id,
|
||||
c.created_at AS conversation_created_at,
|
||||
c.updated_at AS conversation_updated_at,
|
||||
cm1.user_id AS user1_id,
|
||||
cm2.user_id AS user2_id
|
||||
FROM
|
||||
public.conversation AS c
|
||||
JOIN
|
||||
public.conversation_member AS cm1 ON c.id = cm1.conversation_id
|
||||
JOIN
|
||||
public.conversation_member AS cm2 ON c.id = cm2.conversation_id
|
||||
WHERE
|
||||
cm1.user_id = :user_id_1 AND
|
||||
cm2.user_id = :user_id_2 AND
|
||||
cm1.user_id <> cm2.user_id;"""
|
||||
ec = db.session.execute(text(sql), {'user_id_1': recipient.id, 'user_id_2': sender.id}).fetchone()
|
||||
return Conversation.query.get(ec[0]) if ec else None
|
||||
|
|
|
@ -121,6 +121,27 @@ class Conversation(db.Model):
|
|||
retval.append(member.instance)
|
||||
return retval
|
||||
|
||||
@staticmethod
|
||||
def find_existing_conversation(recipient, sender):
|
||||
sql = """SELECT
|
||||
c.id AS conversation_id,
|
||||
c.created_at AS conversation_created_at,
|
||||
c.updated_at AS conversation_updated_at,
|
||||
cm1.user_id AS user1_id,
|
||||
cm2.user_id AS user2_id
|
||||
FROM
|
||||
public.conversation AS c
|
||||
JOIN
|
||||
public.conversation_member AS cm1 ON c.id = cm1.conversation_id
|
||||
JOIN
|
||||
public.conversation_member AS cm2 ON c.id = cm2.conversation_id
|
||||
WHERE
|
||||
cm1.user_id = :user_id_1 AND
|
||||
cm2.user_id = :user_id_2 AND
|
||||
cm1.user_id <> cm2.user_id;"""
|
||||
ec = db.session.execute(text(sql), {'user_id_1': recipient.id, 'user_id_2': sender.id}).fetchone()
|
||||
return Conversation.query.get(ec[0]) if ec else None
|
||||
|
||||
|
||||
conversation_member = db.Table('conversation_member',
|
||||
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
|
||||
|
|
|
@ -140,9 +140,9 @@
|
|||
<li class="nav-item dropdown{% if active_parent == 'home' %} active{% endif %}">
|
||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="/home" aria-haspopup="true" aria-expanded="false">{{ _('Home') }}</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item{% if active_child == 'popular' %} active{% endif %}" href="/home"><span class="fe fe-home"></span>{{ _('Home') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'home' %} active{% endif %}" href="/home"><span class="fe fe-home"></span>{{ _('Home') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'popular' %} active{% endif %}" href="/popular"><span class="fe fe-popular"></span>{{ _('Popular') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'all_posts' %} active{% endif %}" href="/all"><span class="fe fe-all"></span>{{ _('All posts') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'all' %} active{% endif %}" href="/all"><span class="fe fe-all"></span>{{ _('All posts') }}</a></li>
|
||||
</ul>
|
||||
<li class="nav-item dropdown{% if active_parent == 'communities' %} active{% endif %}">
|
||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="/topics" aria-haspopup="true" aria-expanded="false">{{ _('Topics') }}</a>
|
||||
|
@ -151,14 +151,14 @@
|
|||
<li><a class="dropdown-item{% if active_child == 'list_topics' %} active{% endif %}" href="/communities">{{ _('All communities') }}</a></li>
|
||||
{% if moderating_communities %}
|
||||
<li><h6 class="dropdown-header">{{ _('Moderating') }}</h6></li>
|
||||
{% for community in moderating_communities %}
|
||||
<li class="pl-2"><a class="dropdown-item" href="/c/{{ community.link() }}">{{ community.title }}</a></li>
|
||||
{% for community_menu_item in moderating_communities %}
|
||||
<li class="pl-2"><a class="dropdown-item{% if community and community.id == community_menu_item.id%} active{% endif %}" href="/c/{{ community_menu_item.link() }}">{{ community_menu_item.title }}</a></li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if joined_communities %}
|
||||
<li><h6 class="dropdown-header">{{ _('Joined communities') }}</h6></li>
|
||||
{% for community in joined_communities %}
|
||||
<li class="pl-2"><a class="dropdown-item" href="/c/{{ community.link() }}">{{ community.title }}</a></li>
|
||||
{% for community_menu_item in joined_communities %}
|
||||
<li class="pl-2"><a class="dropdown-item{% if community and community.id == community_menu_item.id%} active{% endif %}" href="/c/{{ community_menu_item.link() }}">{{ community_menu_item.title }}</a></li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -168,6 +168,7 @@
|
|||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item{% if active_child == 'view_profile' %} active{% endif %}" href="/u/{{ current_user.user_name }}">{{ _('View profile') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'edit_profile' %} active{% endif %}" href="/u/{{ current_user.user_name }}/profile">{{ _('Edit profile') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'chats' %} active{% endif %}" href="/chat">{{ _('Chats') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'settings' %} active{% endif %}" href="/user/settings">{{ _('Settings') }}</a></li>
|
||||
<li><a class="dropdown-item{% if active_child == 'filters' %} active{% endif %}" href="/user/settings/filters">{{ _('Filters') }}</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{% else %}
|
||||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% set active_child = 'chats' %}
|
||||
{% from 'bootstrap/form.html' import render_form %}
|
||||
|
||||
{% block app_content %}
|
||||
|
|
|
@ -3,19 +3,25 @@
|
|||
{% else %}
|
||||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% set active_child = 'chats' %}
|
||||
{% from 'bootstrap/form.html' import render_form %}
|
||||
|
||||
{% macro conversation_members(conversation) %}
|
||||
{% if len(conversation.members) == 2 %}
|
||||
{% for member in conversation.members %}
|
||||
{% if member.id != current_user.id %}
|
||||
<img src="{{ member.avatar_thumbnail() }}" loading="lazy" /> {{ member.display_name() }}
|
||||
<img src="{{ member.avatar_thumbnail() }}" loading="lazy" />
|
||||
{% if not conversation.read %}<strong>{% endif %}
|
||||
{{ member.display_name() }}
|
||||
{% if not conversation.read %}</strong>{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for member in conversation.members %}
|
||||
{% if member.id != current_user.id %}
|
||||
{{ member.display_name() }}
|
||||
{% if not conversation.read %}<strong>{% endif %}
|
||||
{{ member.display_name() }}
|
||||
{% if not conversation.read %}</strong>{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{% else %}
|
||||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% set active_child = 'chats' %}
|
||||
{% from 'bootstrap/form.html' import render_form %}
|
||||
|
||||
{% block app_content %}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{% else %}
|
||||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% set active_child = 'chats' %}
|
||||
{% from 'bootstrap/form.html' import render_form %}
|
||||
|
||||
{% block app_content %}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% endif %}
|
||||
{% from 'bootstrap5/form.html' import render_form %}
|
||||
{% set active_child = type %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% from 'bootstrap5/form.html' import render_form %}
|
||||
{% set active_child = 'list_communities' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="row g-2 justify-content-between mt-2">
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% from 'bootstrap5/form.html' import render_form %}
|
||||
{% set active_child = 'list_topics' %}
|
||||
|
||||
{% block app_content %}
|
||||
{% if len(topics) > 0 %}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% from 'bootstrap/form.html' import render_field %}
|
||||
{% set active_child = 'filters' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{% else %}
|
||||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% set active_child = 'edit_profile' %}
|
||||
{% from 'bootstrap/form.html' import render_field %}
|
||||
|
||||
{% block app_content %}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% from 'bootstrap/form.html' import render_field %}
|
||||
{% set active_child = 'settings' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% from 'bootstrap/form.html' import render_field %}
|
||||
{% set active_child = 'filters' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
{% extends "base.html" %}
|
||||
{% endif %} %}
|
||||
{% from 'bootstrap/form.html' import render_form %}
|
||||
|
||||
{% if current_user.is_authenticated() and user.id == current_user.id %}
|
||||
{% set active_child = 'view_profile' %}
|
||||
{% endif %}
|
||||
{% block app_content %}
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 position-relative main_pane">
|
||||
|
|
|
@ -13,7 +13,6 @@ import flask
|
|||
from bs4 import BeautifulSoup, NavigableString
|
||||
import requests
|
||||
import os
|
||||
import imghdr
|
||||
from flask import current_app, json, redirect, url_for, request, make_response, Response, g
|
||||
from flask_login import current_user
|
||||
from sqlalchemy import text, or_
|
||||
|
|
Loading…
Reference in a new issue