feat(messages): display attachments in message view and list indicators

- Add attachment display section in view.html with inline image thumbnails and document download links
- Add eager loading of attachments in inbox, sent, and view queries
- Add paperclip emoji indicator in inbox and sent message lists

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-03-11 17:58:31 +01:00
parent 644dfae3ed
commit f683ad3dbb
4 changed files with 40 additions and 5 deletions

View File

@ -11,6 +11,7 @@ from flask import render_template, request, redirect, url_for, flash, jsonify
from flask_login import login_required, current_user
from . import bp
from sqlalchemy.orm import joinedload
from database import SessionLocal, User, Company, UserCompanyPermissions, PrivateMessage, UserNotification, UserBlock, Classified
from extensions import limiter
from utils.helpers import sanitize_input
@ -33,11 +34,13 @@ def messages_inbox():
db = SessionLocal()
try:
query = db.query(PrivateMessage).filter(
query = db.query(PrivateMessage).options(
joinedload(PrivateMessage.attachments)
).filter(
PrivateMessage.recipient_id == current_user.id
).order_by(PrivateMessage.created_at.desc())
total = query.count()
total = db.query(PrivateMessage).filter(PrivateMessage.recipient_id == current_user.id).count()
messages = query.limit(per_page).offset((page - 1) * per_page).all()
unread_count = db.query(PrivateMessage).filter(
@ -65,11 +68,13 @@ def messages_sent():
db = SessionLocal()
try:
query = db.query(PrivateMessage).filter(
query = db.query(PrivateMessage).options(
joinedload(PrivateMessage.attachments)
).filter(
PrivateMessage.sender_id == current_user.id
).order_by(PrivateMessage.created_at.desc())
total = query.count()
total = db.query(PrivateMessage).filter(PrivateMessage.sender_id == current_user.id).count()
messages = query.limit(per_page).offset((page - 1) * per_page).all()
return render_template('messages/sent.html',
@ -286,7 +291,9 @@ def messages_view(message_id):
"""Czytaj wiadomość"""
db = SessionLocal()
try:
message = db.query(PrivateMessage).filter(
message = db.query(PrivateMessage).options(
joinedload(PrivateMessage.attachments)
).filter(
PrivateMessage.id == message_id
).first()

View File

@ -217,6 +217,9 @@
B2B
</span>
{% endif %}
{% if msg.attachments %}
<span style="color: var(--text-secondary); margin-left: 4px;" title="{{ msg.attachments|length }} zalacznik{{ 'ow' if msg.attachments|length > 1 else '' }}">📎</span>
{% endif %}
</div>
<div class="message-preview">{{ msg.content[:80] }}{% if msg.content|length > 80 %}...{% endif %}</div>
</div>

View File

@ -214,6 +214,9 @@
B2B
</span>
{% endif %}
{% if msg.attachments %}
<span style="color: var(--text-secondary); margin-left: 4px;" title="{{ msg.attachments|length }} zalacznik{{ 'ow' if msg.attachments|length > 1 else '' }}">📎</span>
{% endif %}
</div>
<div class="message-preview">{{ msg.content[:80] }}{% if msg.content|length > 80 %}...{% endif %}</div>
</div>

View File

@ -224,6 +224,28 @@
</div>
<div class="message-body">{{ message.content }}</div>
{% if message.attachments %}
<div style="margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border);">
<div style="font-size: var(--font-size-sm); color: var(--text-secondary); margin-bottom: 8px; font-weight: 500;">Zalaczniki ({{ message.attachments|length }})</div>
{% for att in message.attachments %}
{% set is_image = att.mime_type and att.mime_type.startswith('image/') %}
<div style="display: flex; align-items: center; gap: 10px; padding: 8px 0; {% if not loop.last %}border-bottom: 1px solid var(--border);{% endif %}">
{% if is_image %}
<a href="/static/uploads/messages/{{ att.created_at.strftime('%Y/%m') }}/{{ att.stored_filename }}" target="_blank">
<img src="/static/uploads/messages/{{ att.created_at.strftime('%Y/%m') }}/{{ att.stored_filename }}" alt="{{ att.filename }}" style="max-width: 300px; max-height: 200px; border-radius: var(--radius); border: 1px solid var(--border);">
</a>
{% else %}
<span style="font-size: 20px;">📄</span>
<div>
<a href="/static/uploads/messages/{{ att.created_at.strftime('%Y/%m') }}/{{ att.stored_filename }}" download="{{ att.filename }}" style="color: var(--primary); font-weight: 500;">{{ att.filename }}</a>
<span style="font-size: var(--font-size-xs); color: var(--text-secondary); margin-left: 8px;">{{ (att.file_size / 1024)|round(0)|int }} KB</span>
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
</div>
<!-- Odpowiedź -->