Browse Source

Clean up & refactoring. Fixes #99

sh4nks 10 years ago
parent
commit
aebb04dcfc

+ 12 - 6
flaskbb/message/forms.py

@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
     flaskbb.message.forms
-    ~~~~~~~~~~~~~~~~~~~~
+    ~~~~~~~~~~~~~~~~~~~~~
 
     It provides the forms that are needed for the message views.
 
@@ -40,11 +40,17 @@ class ConversationForm(Form):
 
     def save(self, from_user, to_user, user_id, unread, as_draft=False,
              shared_id=None):
-        conversation = Conversation(subject=self.subject.data, draft=as_draft,
-                                    shared_id=shared_id)
-        message = Message(message=self.message.data, user_id=from_user)
-        return conversation.save(message=message, from_user=from_user,
-                                 to_user=to_user, user_id=user_id)
+
+        conversation = Conversation(
+            subject=self.subject.data,
+            draft=as_draft,
+            shared_id=shared_id,
+            from_user_id=from_user,
+            to_user_id=to_user,
+            user_id=user_id
+        )
+        message = Message(message=self.message.data)
+        return conversation.save(message=message)
 
 
 class MessageForm(Form):

+ 20 - 20
flaskbb/message/models.py

@@ -1,3 +1,13 @@
+# -*- coding: utf-8 -*-
+"""
+    flaskbb.message.models
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    The models for the conversations and messages are located here.
+
+    :copyright: (c) 2014 by the FlaskBB Team.
+    :license: BSD, see LICENSE for more details.
+"""
 from datetime import datetime
 
 from sqlalchemy_utils import UUIDType
@@ -20,7 +30,7 @@ class Conversation(db.Model):
     unread = db.Column(db.Boolean, nullable=False, default=True)
 
     messages = db.relationship(
-        "Message", lazy="dynamic", backref="conversation",
+        "Message", lazy="joined", backref="conversation",
         primaryjoin="Message.conversation_id == Conversation.id",
         cascade="all, delete-orphan"
     )
@@ -43,27 +53,15 @@ class Conversation(db.Model):
         """Returns the last message object."""
         return self.messages[-1]
 
-    def save(self, message=None, user_id=None, from_user=None, to_user=None):
-        """Saves a conversation.
+    def save(self, message=None):
+        """Saves a conversation and returns the saved conversation object.
 
-        :param message: The Message object.
-        :param user_id: The senders user id - This is the id to which user the
-                        conversation belongs.
-        :param from_user: The user who has created the conversation
-        :param to_user: The user who should recieve the conversation
+        :param message: If given, it will also save the message for the
+                        conversation. It expects a Message object.
         """
-        if self.id:
-            db.session.add(self)
-            db.session.commit()
-            return self
-
         if message is not None:
             # create the conversation
-            self.user_id = user_id
-            self.from_user_id = from_user
-            self.to_user_id = to_user
             self.date_created = datetime.utcnow()
-
             db.session.add(self)
             db.session.commit()
 
@@ -97,14 +95,16 @@ class Message(db.Model):
 
     user = db.relationship("User", lazy="joined")
 
-    def save(self, conversation):
+    def save(self, conversation=None):
         """Saves a private message.
 
         :param conversation_id: The id of the conversation to which the message
                                 belongs to.
         """
-        self.conversation_id = conversation.id
-        self.date_created = datetime.utcnow()
+        if conversation is not None:
+            self.conversation_id = conversation.id
+            self.user_id = conversation.from_user_id
+            self.date_created = datetime.utcnow()
 
         db.session.add(self)
         db.session.commit()

+ 27 - 30
flaskbb/message/views.py

@@ -1,3 +1,13 @@
+# -*- coding: utf-8 -*-
+"""
+    flaskbb.message.views
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    The views for the conversations and messages are located in this module.
+
+    :copyright: (c) 2014 by the FlaskBB Team.
+    :license: BSD, see LICENSE for more details.
+"""
 import uuid
 from datetime import datetime
 
@@ -41,12 +51,9 @@ def inbox():
 @message.route("/<int:conversation_id>/view", methods=["GET", "POST"])
 def view_conversation(conversation_id):
     conversation = Conversation.query.filter_by(
-        id=conversation_id).first_or_404()
-
-    if conversation.user_id != current_user.id:
-        # if a user tries to view a conversation which does not belong to him
-        # just abort with 404
-        abort(404)
+        id=conversation_id,
+        user_id=current_user.id
+    ).first_or_404()
 
     if conversation.unread:
         conversation.unread = False
@@ -171,6 +178,8 @@ def new_conversation():
 def raw_message(message_id):
     message = Message.query.filter_by(id=message_id).first_or_404()
 
+    # abort if the message was not the current_user's one or the one of the
+    # recieved ones
     if not (message.conversation.from_user_id == current_user.id or
             message.conversation.to_user_id == current_user.id):
         abort(404)
@@ -183,12 +192,9 @@ def raw_message(message_id):
 @login_required
 def edit_conversation(conversation_id):
     conversation = Conversation.query.filter_by(
-        id=conversation_id).first_or_404()
-
-    if conversation.user_id != current_user.id:
-        # if a user tries to view a conversation which does not belong to him
-        # just abort with 404
-        abort(404)
+        id=conversation_id,
+        user_id=current_user.id
+    ).first_or_404()
 
     if not conversation.draft:
         flash(_("You cannot edit a sent message."), "danger")
@@ -238,12 +244,9 @@ def edit_conversation(conversation_id):
 @login_required
 def move_conversation(conversation_id):
     conversation = Conversation.query.filter_by(
-        id=conversation_id).first_or_404()
-
-    if conversation.user_id != current_user.id:
-        # if a user tries to view a conversation which does not belong to him
-        # just abort with 404
-        abort(404)
+        id=conversation_id,
+        user_id=current_user.id
+    ).first_or_404()
 
     conversation.trash = True
     conversation.save()
@@ -255,12 +258,9 @@ def move_conversation(conversation_id):
 @login_required
 def restore_conversation(conversation_id):
     conversation = Conversation.query.filter_by(
-        id=conversation_id).first_or_404()
-
-    if conversation.user_id != current_user.id:
-        # if a user tries to view a conversation which does not belong to him
-        # just abort with 404
-        abort(404)
+        id=conversation_id,
+        user_id=current_user.id
+    ).first_or_404()
 
     conversation.trash = False
     conversation.save()
@@ -271,12 +271,9 @@ def restore_conversation(conversation_id):
 @login_required
 def delete_conversation(conversation_id):
     conversation = Conversation.query.filter_by(
-        id=conversation_id).first_or_404()
-
-    if conversation.user_id != current_user.id:
-        # if a user tries to view a conversation which does not belong to him
-        # just abort with 404
-        abort(404)
+        id=conversation_id,
+        user_id=current_user.id
+    ).first_or_404()
 
     conversation.delete()
     return redirect(url_for("message.inbox"))

+ 4 - 0
flaskbb/static/img/avatar.svg

@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="yes"?>
+
+<svg version="1.1" viewBox="0.0 0.0 400.0 400.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 400.0l-400.0 0l0 -400.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 400.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#e3e3e3" d="m-0.0036648293 2.2913386E-4l399.99506 0l0 399.99503l-399.99506 0z" fill-rule="nonzero"></path><path stroke="#e3e3e3" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m-0.0036648293 2.2913386E-4l399.99506 0l0 399.99503l-399.99506 0z" fill-rule="nonzero"></path><path fill="#cccccc" d="m141.69818 86.39831l0 0c0 -32.19582 26.099869 -58.295685 58.295685 -58.295685l0 0c15.460968 0 30.288712 6.1418495 41.221268 17.07441c10.932571 10.932564 17.074417 25.7603 17.074417 41.221275l0 0c0 32.195816 -26.099869 58.295692 -58.295685 58.295692l0 0c-32.195816 0 -58.295685 -26.099876 -58.295685 -58.295692z" fill-rule="nonzero"></path><path stroke="#cccccc" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m141.69818 86.39831l0 0c0 -32.19582 26.099869 -58.295685 58.295685 -58.295685l0 0c15.460968 0 30.288712 6.1418495 41.221268 17.07441c10.932571 10.932564 17.074417 25.7603 17.074417 41.221275l0 0c0 32.195816 -26.099869 58.295692 -58.295685 58.295692l0 0c-32.195816 0 -58.295685 -26.099876 -58.295685 -58.295692z" fill-rule="nonzero"></path><path fill="#cccccc" d="m100.59578 376.67535l0 -110.60422l0 0c0 -61.085052 44.502045 -110.60426 99.39809 -110.60426c54.89604 0 99.39807 49.51921 99.39807 110.60426l0 110.60422z" fill-rule="nonzero"></path><path stroke="#cccccc" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m100.59578 376.67535l0 -110.60422l0 0c0 -61.085052 44.502045 -110.60426 99.39809 -110.60426c54.89604 0 99.39807 49.51921 99.39807 110.60426l0 110.60422z" fill-rule="nonzero"></path></g></svg>
+

BIN
flaskbb/static/img/avatar100x100.png


BIN
flaskbb/static/img/avatar150x150.png


BIN
flaskbb/static/img/avatar400x400.png


BIN
flaskbb/static/img/avatar80x80.png


+ 3 - 2
flaskbb/templates/message/conversation.html

@@ -24,7 +24,8 @@
                         {% if message.user.avatar %}
                             <img class="img-responsive" src="{{ message.user.avatar }}" />
                         {% else %}
-                            <img class="img-responsive" src="http://www.keita-gaming.com/assets/profile/default-avatar-c5d8ec086224cb6fc4e395f4ba3018c2.jpg" />
+                            <!-- "no" avatar proudly made with Google Drawing.. because lol -->
+                            <img src="{{ url_for('static', filename='img/avatar100x100.png') }}" class="img-responsive" alt="avatar" />
                         {% endif %}
                         <figcaption class="text-center"><strong><a href="{{ message.user.url }}" class="conversation-username">{{ message.user.username }}</a></strong></figcaption>
                     </figure>
@@ -53,7 +54,7 @@
                             {% if message.user.avatar %}
                                 <img class="img-responsive" src="{{ message.user.avatar }}" />
                             {% else %}
-                                <img class="img-responsive" src="http://www.keita-gaming.com/assets/profile/default-avatar-c5d8ec086224cb6fc4e395f4ba3018c2.jpg" />
+                                <img src="{{ url_for('static', filename='img/avatar100x100.png') }}" class="img-responsive" alt="avatar" />
                             {% endif %}
                         <figcaption class="text-center"><strong><a href="{{ message.user.url }}" class="conversation-username">{{ message.user.username }}</a></strong></figcaption>
                     </figure>

+ 84 - 0
flaskbb/templates/message/conversation_list.html

@@ -0,0 +1,84 @@
+<div class="panel panel-default conversation">
+    <div class="panel-heading">
+        <span class="glyphicon glyphicon-comment"></span>
+        <h3 class="panel-title">{% trans %}Conversations{% endtrans %}</h3>
+        <span class="label label-info">{{ message_count }}/{{ flaskbb_config["MESSAGE_QUOTA"] }}</span>
+    </div>
+    <div class="panel-body">
+        <ul class="list-group">
+            {% for conversation in conversations.items %}
+            <li class="list-group-item">
+                <div class="row">
+                    <div class="col-xs-2 col-md-1">
+                        {% if conversation.from_user.avatar %}
+                        <img src="{{ conversation.from_user.avatar }}" class="img-circle" alt="avatar" width="65px" height="65px" />
+                        {% else %}
+                        <img src="{{ url_for('static', filename='img/avatar80x80.png') }}" class="img-circle" alt="avatar" width="65px" height="65px" />
+                        {% endif %}
+                    </div>
+                    <div class="col-xs-10 col-md-11">
+                        <div>
+                            <a href="{{ url_for('message.view_conversation', conversation_id=conversation.id) }}">
+                                {% if conversation.unread %}
+                                    <strong>{{ conversation.subject }}</strong>
+                                {% else %}
+                                    {{ conversation.subject }}
+                                {% endif %}
+                            </a>
+                            <div class="mic-info">
+                                By: <a href="#">{{ conversation.from_user.username }}</a> on {{ conversation.date_created|format_date("%d %B %Y - %H:%M") }}
+                            </div>
+                        </div>
+                        <div class="comment-text">
+                            {# the first message of conversation is always the starting message #}
+                            {{ conversation.first_message.message|crop_title(150)|markup|safe }}
+                        </div>
+                        <div class="action">
+                            {% if include_move %}
+                            <form class="inline-form" method="POST" action="{{ url_for('message.move_conversation', conversation_id=conversation.id) }}">
+                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
+                                <button type="submit" class="btn btn-info btn-xs" title="Move to Trash">
+                                    <span class="fa fa-archive"></span>
+                                </button>
+                            </form>
+                            {% endif %}
+
+                            {% if include_delete %}
+                            <form class="inline-form" method="POST" action="{{ url_for('message.delete_conversation', conversation_id=conversation.id) }}">
+                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
+                                <button type="submit" class="btn btn-danger btn-xs" title="Delete">
+                                    <span class="fa fa-trash"></span>
+                                </button>
+                            </form>
+                            {% endif %}
+
+                            {% if include_restore %}
+                            <form class="inline-form" method="POST" action="{{ url_for('message.restore_conversation', conversation_id=conversation.id) }}">
+                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
+                                <button type="submit" class="btn btn-success btn-xs" title="Restore">
+                                    <span class="fa fa-undo"></span>
+                                </button>
+                            </form>
+                            {% endif %}
+
+                            {% if include_edit %}
+                            <a class="btn btn-success btn-xs" alt="Edit" title="Edit" href="{{ url_for('message.edit_conversation', conversation_id = conversation.id) }}">
+                                <span class="fa fa-pencil"></span>
+                            </a>
+                            {% endif %}
+                        </div>
+                    </div>
+                </div>
+            </li>
+            {% else %}
+            <li class="list-group-item">
+                <div class="row">
+                    <div class="col-xs-12">
+                        {% trans %}No conversations found.{% endtrans %}
+                    </div>
+                </div>
+            </li>
+            {% endfor %}
+        </ul>
+    </div>
+</div>

+ 3 - 63
flaskbb/templates/message/drafts.html

@@ -4,69 +4,9 @@
 {% extends theme("message/message_layout.html") %}
 {% block message_content %}
 
-<div class="panel panel-default conversation">
-    <div class="panel-heading">
-        <span class="glyphicon glyphicon-comment"></span>
-        <h3 class="panel-title">{% trans %}Saved Conversations{% endtrans %}</h3>
-        <span class="label label-info">{{ message_count }}/{{ flaskbb_config["MESSAGE_QUOTA"] }}</span>
-    </div>
-    <div class="panel-body">
-        <ul class="list-group">
-            {% for conversation in conversations.items %}
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-2 col-md-1">
-                        {% if conversation.to_user.avatar %}
-                        <img src="{{ conversation.to_user.avatar }}" class="img-circle" alt="avatar" width="65px" height="65px" />
-                        {% else %}
-                        <span class="fa fa-user" style="font-size: 80px; color: #E5E5E5"></span>
-                        {% endif %}
-                    </div>
-                    <div class="col-xs-10 col-md-11">
-                        <div>
-                            <a href="{{ url_for('message.view_conversation', conversation_id=conversation.id) }}">
-                                <strong>{{ conversation.subject }}</strong>
-                            </a>
-                            <div class="mic-info">
-                                To: <a href="#">{{ conversation.to_user.username }}</a> on {{ conversation.date_created|format_date("%d %B %Y - %H:%M") }}
-                            </div>
-                        </div>
-                        <div class="comment-text">
-                            {# the first message of conversation is always the starting message #}
-                            {{ conversation.first_message.message }}
-                        </div>
-                        <div class="action">
-                            <form class="inline-form" method="POST" action="{{ url_for('message.delete_conversation', conversation_id=conversation.id) }}">
-                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-                                <button type="submit" class="btn btn-danger btn-xs" title="Delete">
-                                    <span class="fa fa-trash"></span>
-                                </button>
-                            </form>
-                            <form class="inline-form" method="POST" action="{{ url_for('message.move_conversation', conversation_id=conversation.id) }}">
-                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-                                <button type="submit" class="btn btn-info btn-xs" title="Move to Trash">
-                                    <span class="fa fa-archive"></span>
-                                </button>
-                            </form>
-                            <a class="btn btn-success btn-xs" alt="Edit" href="{{ url_for('message.edit_conversation', conversation_id = conversation.id) }}">
-                                <span class="fa fa-pencil"></span>
-                            </a>
-                        </div>
-                    </div>
-                </div>
-            </li>
-            {% else %}
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-12">
-                        {% trans %}No conversations found.{% endtrans %}
-                    </div>
-                </div>
-            </li>
-            {% endfor %}
-        </ul>
-    </div>
-</div>
+{% set include_move = True %}
+{% set include_edit = True %}
+{% include "message/conversation_list.html" %}
 
 {{ render_pagination(conversations, url_for("message.drafts")) }}
 

+ 2 - 58
flaskbb/templates/message/inbox.html

@@ -4,64 +4,8 @@
 {% extends theme("message/message_layout.html") %}
 {% block message_content %}
 
-<div class="panel panel-default conversation">
-    <div class="panel-heading">
-        <span class="glyphicon glyphicon-comment"></span>
-        <h3 class="panel-title">{% trans %}Conversations{% endtrans %}</h3>
-        <span class="label label-info">{{ message_count }}/{{ flaskbb_config["MESSAGE_QUOTA"] }}</span>
-    </div>
-    <div class="panel-body">
-        <ul class="list-group">
-            {% for conversation in conversations.items %}
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-2 col-md-1">
-                        {% if conversation.from_user.avatar %}
-                        <img src="{{ conversation.from_user.avatar }}" class="img-circle" alt="avatar" width="65px" height="65px" />
-                        {% else %}
-                        <span class="fa fa-user" style="font-size: 80px; color: #E5E5E5"></span>
-                        {% endif %}
-                    </div>
-                    <div class="col-xs-10 col-md-11">
-                        <div>
-                            <a href="{{ url_for('message.view_conversation', conversation_id=conversation.id) }}">
-                                {% if conversation.unread %}
-                                    <strong>{{ conversation.subject }}</strong>
-                                {% else %}
-                                    {{ conversation.subject }}
-                                {% endif %}
-                            </a>
-                            <div class="mic-info">
-                                By: <a href="#">{{ conversation.from_user.username }}</a> on {{ conversation.date_created|format_date("%d %B %Y - %H:%M") }}
-                            </div>
-                        </div>
-                        <div class="comment-text">
-                            {# the first message of conversation is always the starting message #}
-                            {{ conversation.first_message.message|truncate(200)|markup|safe }}
-                        </div>
-                        <div class="action">
-                            <form class="inline-form" method="POST" action="{{ url_for('message.move_conversation', conversation_id=conversation.id) }}">
-                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-                                <button type="submit" class="btn btn-info btn-xs" title="Move to Trash">
-                                    <span class="fa fa-archive"></span>
-                                </button>
-                            </form>
-                        </div>
-                    </div>
-                </div>
-            </li>
-            {% else %}
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-12">
-                        {% trans %}No conversations found.{% endtrans %}
-                    </div>
-                </div>
-            </li>
-            {% endfor %}
-        </ul>
-    </div>
-</div>
+{% set include_move = True %}
+{% include "message/conversation_list.html" %}
 
 {{ render_pagination(conversations, url_for("message.inbox")) }}
 

+ 2 - 61
flaskbb/templates/message/sent.html

@@ -4,67 +4,8 @@
 {% extends theme("message/message_layout.html") %}
 {% block message_content %}
 
-<div class="panel panel-default conversation">
-    <div class="panel-heading">
-        <span class="glyphicon glyphicon-comment"></span>
-        <h3 class="panel-title">{% trans %}Sent Conversations{% endtrans %}</h3>
-        <span class="label label-info">{{ message_count }}/{{ flaskbb_config["MESSAGE_QUOTA"] }}</span>
-    </div>
-    <div class="panel-body">
-        <ul class="list-group">
-            {% for conversation in conversations.items %}
-
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-2 col-md-1">
-                        {% if conversation.to_user.avatar %}
-                        <img src="{{ conversation.to_user.avatar }}" class="img-circle" alt="avatar" width="65px" height="65px" />
-                        {% else %}
-                        <span class="fa fa-user" style="font-size: 80px; color: #E5E5E5"></span>
-                        {% endif %}
-                    </div>
-                    <div class="col-xs-10 col-md-11">
-                        <div>
-                            <a href="{{ url_for('message.view_conversation', conversation_id=conversation.id) }}">
-                                <strong>{{ conversation.subject }}</strong>
-                            </a>
-                            <div class="mic-info">
-                                To: <a href="#">{{ conversation.to_user.username }}</a> on {{ conversation.date_created|format_date("%d %B %Y - %H:%M") }}
-                            </div>
-                        </div>
-                        <div class="comment-text">
-                            {# the first message of conversation is always the starting message #}
-                            {{ conversation.first_message.message }}
-                        </div>
-                        <div class="action">
-                            <form class="inline-form" method="POST" action="{{ url_for('message.delete_conversation', conversation_id=conversation.id) }}">
-                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-                                <button type="submit" class="btn btn-danger btn-xs" title="Delete">
-                                    <span class="fa fa-trash"></span>
-                                </button>
-                            </form>
-                            <form class="inline-form" method="POST" action="{{ url_for('message.restore_conversation', conversation_id=conversation.id) }}">
-                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-                                <button type="submit" class="btn btn-success btn-xs" title="Restore">
-                                    <span class="fa fa-undo"></span>
-                                </button>
-                            </form>
-                        </div>
-                    </div>
-                </div>
-            </li>
-            {% else %}
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-12">
-                        {% trans %}No conversations found.{% endtrans %}
-                    </div>
-                </div>
-            </li>
-            {% endfor %}
-        </ul>
-    </div>
-</div>
+{% set include_move = True %}
+{% include "message/conversation_list.html" %}
 
 {{ render_pagination(conversations, url_for("message.inbox")) }}
 

+ 3 - 61
flaskbb/templates/message/trash.html

@@ -4,67 +4,9 @@
 {% extends theme("message/message_layout.html") %}
 {% block message_content %}
 
-<div class="panel panel-default conversation">
-    <div class="panel-heading">
-        <span class="glyphicon glyphicon-comment"></span>
-        <h3 class="panel-title">{% trans %}Deleted Conversations{% endtrans %}</h3>
-        <span class="label label-info">{{ message_count }}/{{ flaskbb_config["MESSAGE_QUOTA"] }}</span>
-    </div>
-    <div class="panel-body">
-        <ul class="list-group">
-            {% for conversation in conversations.items %}
-
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-2 col-md-1">
-                        {% if conversation.from_user.avatar %}
-                        <img src="{{ conversation.from_user.avatar }}" class="img-circle" alt="avatar" width="65px" height="65px" />
-                        {% else %}
-                        <span class="fa fa-user" style="font-size: 80px; color: #E5E5E5"></span>
-                        {% endif %}
-                    </div>
-                    <div class="col-xs-10 col-md-11">
-                        <div>
-                            <a href="{{ url_for('message.view_conversation', conversation_id=conversation.id) }}">
-                                <strong>{{ conversation.subject }}</strong>
-                            </a>
-                            <div class="mic-info">
-                                By: <a href="#">{{ conversation.from_user.username }}</a> on {{ conversation.date_created|format_date("%d %B %Y - %H:%M") }}
-                            </div>
-                        </div>
-                        <div class="comment-text">
-                            {# the first message of conversation is always the starting message #}
-                            {{ conversation.first_message.message }}
-                        </div>
-                        <div class="action">
-                            <form class="inline-form" method="POST" action="{{ url_for('message.delete_conversation', conversation_id=conversation.id) }}">
-                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-                                <button type="submit" class="btn btn-danger btn-xs" title="Delete">
-                                    <span class="fa fa-trash"></span>
-                                </button>
-                            </form>
-                            <form class="inline-form" method="POST" action="{{ url_for('message.restore_conversation', conversation_id=conversation.id) }}">
-                                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-                                <button type="submit" class="btn btn-success btn-xs" title="Restore">
-                                    <span class="fa fa-undo"></span>
-                                </button>
-                            </form>
-                        </div>
-                    </div>
-                </div>
-            </li>
-            {% else %}
-            <li class="list-group-item">
-                <div class="row">
-                    <div class="col-xs-12">
-                        {% trans %}No conversations found.{% endtrans %}
-                    </div>
-                </div>
-            </li>
-            {% endfor %}
-        </ul>
-    </div>
-</div>
+{% set include_restore = True %}
+{% set include_delete = True %}
+{% include "message/conversation_list.html" %}
 
 {{ render_pagination(conversations, url_for("message.inbox")) }}
 

+ 2 - 2
flaskbb/utils/helpers.py

@@ -255,7 +255,7 @@ def get_online_users(guest=False):  # pragma: no cover
                                for x in minutes])
 
 
-def crop_title(title, suffix="..."):
+def crop_title(title, length=None, suffix="..."):
     """Crops the title to a specified length
 
     :param title: The title that should be cropped
@@ -263,7 +263,7 @@ def crop_title(title, suffix="..."):
     :param suffix: The suffix which should be appended at the
                    end of the title.
     """
-    length = flaskbb_config['TITLE_LENGTH']
+    length = flaskbb_config['TITLE_LENGTH'] if length is None else length
 
     if len(title) <= length:
         return title