Files
docupulse/templates/conversations/conversation.html

207 lines
13 KiB
HTML

{% extends "common/base.html" %}
{% from "components/header.html" import header %}
{% block title %}{{ conversation.name }} - {% if site_settings.company_name %}DocuPulse for {{ site_settings.company_name }}{% else %}DocuPulse{% endif %}{% endblock %}
{% block extra_css %}
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.3.0/dist/select2-bootstrap-5-theme.min.css" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/conversation.css') }}">
{% endblock %}
{% block content %}
{{ header(
title=conversation.name,
description=conversation.description or "No description",
button_text="Back to Conversations",
button_url=url_for('conversations.conversations'),
icon="fa-comments",
button_class="btn-secondary",
button_icon="fa-arrow-left"
) }}
<div class="container-fluid py-4">
<div class="row">
<!-- Main Chat Area -->
<div class="col-md-8">
<div class="card shadow-sm">
<div class="card-body">
<div class="chat-messages" style="min-height: 400px; max-height: 600px; overflow-y: auto;" id="chatMessages">
{% if messages %}
{% for message in messages %}
<div class="message {% if message.user.id == current_user.id %}sent{% else %}received{% endif %}" data-message-id="{{ message.id }}">
{% if message.user.id != current_user.id %}
<img src="{{ url_for('profile_pic', filename=message.user.profile_picture) if message.user.profile_picture else url_for('static', filename='default-avatar.png') }}"
alt="{{ message.user.username }}"
class="rounded-circle me-2"
style="width: 40px; height: 40px; object-fit: cover;">
{% endif %}
<div class="message-content">
<div class="message-info">
<span class="fw-medium">{{ message.user.username }} {{ message.user.last_name }}</span>
<span class="text-muted ms-2">{{ message.created_at.strftime('%b %d, %Y %H:%M') }}</span>
</div>
{{ message.content }}
{% if message.attachments %}
<div class="attachments mt-2">
{% for attachment in message.attachments %}
<div class="attachment mb-1">
<a href="{{ url_for('conversations.download_attachment', message_id=message.id, attachment_index=loop.index0) }}" class="btn btn-sm">
<i class="fas fa-paperclip me-1"></i>
{{ attachment.name }}
<small class="ms-1">({{ (attachment.size / 1024)|round|int }} KB)</small>
</a>
</div>
{% endfor %}
</div>
{% endif %}
</div>
{% if message.user.id == current_user.id %}
<img src="{{ url_for('profile_pic', filename=message.user.profile_picture) if message.user.profile_picture else url_for('static', filename='default-avatar.png') }}"
alt="{{ message.user.username }}"
class="rounded-circle ms-2"
style="width: 40px; height: 40px; object-fit: cover;">
{% endif %}
</div>
{% endfor %}
{% else %}
<div class="text-center text-muted py-5">
<i class="fas fa-comments fa-3x mb-3"></i>
<p>No messages yet. Start the conversation!</p>
</div>
{% endif %}
</div>
<div class="card-footer bg-white border-top">
<form id="messageForm" class="d-flex flex-column gap-2">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div class="d-flex gap-2 align-items-center">
<input type="text" class="form-control" id="messageInput" placeholder="Type your message..." required style="min-width:0; height: 38px;">
<label for="fileInput" class="btn btn-outline-secondary btn-sm mb-0 d-flex align-items-center justify-content-center" style="height: 38px; width: 38px;">
<i class="fas fa-paperclip"></i>
</label>
<input type="file" id="fileInput" class="d-none" multiple accept=".pdf,.docx,.doc,.txt,.rtf,.odt,.md,.csv,.xlsx,.xls,.ods,.xlsm,.pptx,.ppt,.odp,.jpg,.jpeg,.png,.gif,.bmp,.svg,.webp,.tiff,.zip,.rar,.7z,.tar,.gz,.py,.js,.html,.css,.json,.xml,.sql,.sh,.bat,.mp3,.wav,.ogg,.m4a,.flac,.mp4,.avi,.mov,.wmv,.flv,.mkv,.webm,.dwg,.dxf,.ai,.psd,.eps,.indd,.eml,.msg,.vcf,.ics">
<button type="submit" class="btn btn-primary d-flex align-items-center justify-content-center" style="height: 38px; width: 38px;">
<i class="fas fa-paper-plane"></i>
<i class="fas fa-circle-notch fa-spin ms-1 d-none" style="font-size: 0.875rem;"></i>
</button>
</div>
<div class="d-flex align-items-center" style="min-height: 1.2em;">
<small id="selectedFiles" class="text-muted"></small>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Members Sidebar -->
<div class="col-md-4">
<div class="card shadow-sm">
<div class="card-header bg-white d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">
<i class="fas fa-users me-2"></i>Members
</h5>
{% if current_user.is_admin %}
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#manageMembersModal">
<i class="fas fa-user-edit me-1"></i>Manage Members
</button>
{% endif %}
</div>
<div class="card-body">
<div class="list-group list-group-flush">
{% for member in conversation.members %}
<div class="list-group-item d-flex align-items-center">
<img src="{{ url_for('profile_pic', filename=member.profile_picture) if member.profile_picture else url_for('static', filename='default-avatar.png') }}"
alt="{{ member.username }}"
class="rounded-circle me-2"
style="width: 40px; height: 40px; object-fit: cover;">
<div class="flex-grow-1">
<div class="fw-medium">{{ member.username }} {{ member.last_name }}</div>
<div class="text-muted small">{{ member.email }}</div>
</div>
{% if member.id == conversation.created_by %}
<span class="badge bg-primary">
<i class="fas fa-crown me-1"></i>Creator
</span>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% if current_user.is_admin %}
<!-- Manage Members Modal -->
<div class="modal fade" id="manageMembersModal" tabindex="-1" aria-labelledby="manageMembersModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="manageMembersModalLabel">Manage Members</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="POST" action="{{ url_for('conversations.edit_conversation', conversation_id=conversation.id, redirect=url_for('conversations.conversation', conversation_id=conversation.id)) }}" id="membersForm">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div class="mb-3">
<label for="user_id" class="form-label">Select User</label>
<select class="form-select select2" id="user_id" name="user_id">
<option value="">Search for a user...</option>
{% for user in all_users %}
{% if user.id != current_user.id %}
<option value="{{ user.id }}" data-email="{{ user.email }}" data-avatar="{{ url_for('profile_pic', filename=user.profile_picture) if user.profile_picture else url_for('static', filename='default-avatar.png') }}">{{ user.username }} {{ user.last_name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<button type="button" class="btn btn-primary w-100 mb-3" id="addMemberBtn">
<i class="fas fa-user-plus me-2"></i>Add Member
</button>
<div class="list-group" id="selectedMembersList">
<!-- Render all current members -->
{% for member in conversation.members %}
<div class="list-group-item d-flex align-items-center member-row" data-user-id="{{ member.id }}">
<img class="member-avatar" src="{{ url_for('profile_pic', filename=member.profile_picture) if member.profile_picture else url_for('static', filename='default-avatar.png') }}">
<div class="flex-grow-1">
<div class="fw-bold">{{ member.username }} {{ member.last_name }}</div>
<div class="text-muted small">{{ member.email }}</div>
</div>
{% if member.id == conversation.created_by %}
<span class="badge badge-creator ms-2"><i class="fas fa-user"></i> Creator</span>
{% else %}
<button type="button" class="btn btn-remove-member ms-2">
<i class="fas fa-user-minus me-1"></i>Remove
</button>
{% endif %}
</div>
{% endfor %}
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" form="membersForm" class="btn btn-primary">Save Changes</button>
</div>
</div>
</div>
</div>
{% endif %}
{% block extra_js %}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
<script>
// Set global variables needed by the JavaScript files
window.conversationId = "{{ conversation.id }}";
window.currentUserId = "{{ current_user.id }}";
window.sendMessageUrl = "{{ url_for('conversations.send_message', conversation_id=conversation.id) }}";
</script>
<script src="{{ url_for('static', filename='js/chat-manager.js') }}"></script>
<script src="{{ url_for('static', filename='js/conversation.js') }}"></script>
<script src="{{ url_for('static', filename='js/member-management.js') }}"></script>
{% endblock %}
{% endblock content %}