Corp/docs/completed/MESSAGE_SELECTION_FORWARDING.md
Игорь Надеин ee6e840252 Реорганизация документации и скриптов проекта
- Создана структура docs/ с категориями: completed, guides, architecture, diagnostic, in-progress, reports
- Перемещено 47+ MD файлов из корня проекта в docs/
- Удалено 6 устаревших/дублирующихся файлов
- Создана структура backend/scripts/ для тестов и утилит
- Перемещено 35 Python скриптов в backend/scripts/
- Создана структура backend/docs/ для технической документации
- Перемещено 12 MD файлов backend в backend/docs/
- Перемещены LDAP тестовые данные в backend/tests/fixtures/
- Добавлены README файлы для навигации
- Добавлены правила в .github/copilot-instructions.md для размещения документации

Результат:
- Корень проекта: только README.md
- Корень backend/: только manage.py и Django приложения
- Вся документация организована в структурированные папки
2025-12-26 13:49:51 +03:00

11 KiB
Raw Blame History

Реализация выделения и пересылки сообщений

Описание

Реализована полная функциональность выделения множественных сообщений и их пересылки в другие чаты, аналогично современным мессенджерам (Telegram, WhatsApp).

Функциональность

1. Режим выделения

Вход в режим:

  • Долгое нажатие на сообщение (500мс) на мобильных устройствах
  • Пункт "Выбрать" в контекстном меню (правый клик / долгое нажатие)

Возможности:

  • Клик по сообщению или чекбоксу для выделения/снятия выделения
  • Визуальная подсветка выделенных сообщений
  • Счетчик выделенных сообщений
  • Автоматический выход при снятии всех выделений
  • Выход по кнопке "Отмена" или клавише ESC

2. Панель действий

При активном режиме выделения внизу экрана появляется панель с:

  • Счетчиком выделенных сообщений
  • Кнопкой "Переслать" - открывает диалог выбора чата
  • Кнопкой "Удалить" - удаляет выделенные сообщения (только свои)
  • Кнопкой "Отмена" - выход из режима

3. Диалог пересылки

Компоненты:

  • Заголовок с количеством сообщений
  • Поисковая строка для фильтрации чатов
  • Список доступных чатов (исключая текущий)
  • Аватары и названия чатов
  • Превью последнего сообщения

Функции:

  • Поиск чата по названию
  • Клик по чату для пересылки
  • Автоматическая загрузка списка чатов
  • Обработка ошибок

4. Backend API

Endpoints:

POST /api/v1/communications/messages/forward/

Пересылка сообщений в другой чат.

Request:

{
  "message_ids": [1, 2, 3],
  "target_chat_id": 5
}

Response:

{
  "ok": true,
  "forwarded_count": 3,
  "message_ids": [10, 11, 12]
}

Проверки:

  • Доступ к целевому чату
  • Права на отправку сообщений в целевой чат
  • Доступ к исходным сообщениям
  • Копирование вложений

POST /api/v1/communications/messages/bulk-delete/

Массовое удаление сообщений.

Request:

{
  "message_ids": [1, 2, 3]
}

Response:

{
  "ok": true,
  "deleted_count": 3
}

Ограничения:

  • Можно удалять только свои сообщения

5. Модель данных

Новые поля в Message:

is_forwarded = BooleanField(default=False)
forwarded_from_message_id = IntegerField(null=True, blank=True)
forwarded_from_author = ForeignKey(User, null=True, blank=True)

Сериализация:

{
  "id": 123,
  "content": "Текст сообщения",
  "is_forwarded": true,
  "forwarded_from": {
    "author_id": 5,
    "author_name": "Иван Иванов",
    "message_id": 100
  }
}

Файлы

Frontend

CSS:

  • backend/static/css/message-selection.css - стили режима выделения

JavaScript:

  • backend/static/js/components/messageSelection.js - логика выделения и пересылки
  • backend/static/js/components/messageContextMenu.js - добавлен пункт "Выбрать"
  • backend/static/js/chat-detail-enhanced.js - интеграция модуля выделения

Backend

Models:

  • backend/communications/models.py - добавлены поля пересылки

Views:

  • backend/api/v1/communications/views.py - API endpoints для пересылки и удаления

URLs:

  • backend/api/v1/urls.py - маршруты API

Consumers:

  • backend/communications/consumers.py - сериализация информации о пересылке

Migrations:

  • communications/migrations/0017_add_forward_fields.py - миграция для новых полей

Templates

  • backend/templates/communications/chat_detail.html - подключен CSS

Использование

Как выделить сообщения

На мобильных:

  1. Долго нажать на сообщение (500мс)
  2. Появятся чекбоксы у всех сообщений
  3. Тапать по сообщениям для выделения

На десктопе:

  1. Правый клик на сообщении
  2. Выбрать "Выбрать" в меню
  3. Кликать по сообщениям для выделения

Как переслать

  1. Выделить сообщения
  2. Нажать "Переслать" в панели внизу
  3. Выбрать чат из списка
  4. Сообщения автоматически отправятся

Как удалить

  1. Выделить свои сообщения
  2. Нажать "Удалить" (кнопка появится только для своих сообщений)
  3. Подтвердить удаление
  4. Сообщения удалятся

WebSocket события

При пересылке отправляется обычное событие chat_message с флагом is_forwarded:

{
  "type": "chat_message",
  "payload": {
    "id": 123,
    "content": "...",
    "is_forwarded": true,
    "forwarded_from": {
      "author_name": "Иван Иванов",
      "message_id": 100
    }
  }
}

При удалении:

{
  "type": "chat_message_deleted",
  "message_id": 123
}

UI/UX особенности

Визуальные эффекты

  • Анимация появления панели действий (slideUp)
  • Подсветка выделенных сообщений
  • Hover эффекты на чекбоксах
  • Вибрация при долгом нажатии (мобильные)

Метка пересылки

Переслаанные сообщения отображаются с меткой:

→ Переслано от Иван Иванов
[Содержимое сообщения]

Адаптивность

  • На мобильных: уменьшенные кнопки и чекбоксы
  • Чекбоксы справа для своих сообщений, слева для чужих
  • Модальное окно на весь экран на маленьких устройствах

Безопасность

Проверки доступа:

  1. Пользователь должен иметь доступ к исходным сообщениям
  2. Пользователь должен иметь доступ к целевому чату
  3. Пользователь должен иметь права на отправку в целевой чат
  4. Можно удалять только свои сообщения

CSRF защита:

  • Все POST запросы требуют CSRF токен
  • Декоратор @csrf_protect на всех endpoints

Авторизация:

  • Декоратор @login_required на всех endpoints
  • Проверка через user_can_access_chat()

Расширение функциональности

Добавление новых действий

В messageSelection.js можно добавить методы:

copySelected() { /* копирование текста */ }
pinSelected() { /* закрепление */ }
markAsImportant() { /* пометка важным */ }

Добавление фильтров чатов

В loadChats() можно добавить параметры:

const response = await fetch('/api/v1/communications/chats/?type=group');

Пересылка с комментарием

Модифицировать forwardToChat():

body: JSON.stringify({
  message_ids: messageIds,
  target_chat_id: targetChatId,
  comment: "Дополнительный текст"
})

Тестирование

Сценарии для тестирования:

  1. Выделение

    • Долгое нажатие на сообщение
    • Выделение нескольких сообщений
    • Снятие выделения
    • Выход по ESC
  2. Пересылка

    • Пересылка 1 сообщения
    • Пересылка нескольких сообщений
    • Пересылка с вложениями
    • Пересылка в группу
    • Пересылка в личный чат
  3. Удаление

    • Удаление своих сообщений
    • Попытка удалить чужие (кнопка не должна появиться)
    • Массовое удаление
  4. Поиск чатов

    • Поиск по названию
    • Фильтрация результатов
    • Пустой результат
  5. Ошибки

    • Нет доступа к чату
    • Нет прав на отправку
    • Сетевая ошибка

Известные ограничения

  1. Нельзя пересылать удаленные сообщения
  2. Нельзя пересылать системные сообщения
  3. Лимит на количество сообщений (определяется backend)
  4. История пересылок не отслеживается (можно расширить)

Совместимость

  • ✅ Chrome 90+
  • ✅ Firefox 88+
  • ✅ Safari 14+
  • ✅ Edge 90+
  • ✅ Mobile Safari (iOS 14+)
  • ✅ Chrome Mobile (Android 10+)

Производительность

  • Ленивая загрузка чатов (только при открытии диалога)
  • Делегирование событий (один обработчик на контейнер)
  • Минимальное использование DOM манипуляций
  • Оптимизированные CSS transitions

Отладка

Console логи:

// В messageSelection.js
console.log('Messages forwarded:', messageIds, 'to chat:', targetChatId);

Network мониторинг:

  • Проверить запросы к /api/v1/communications/messages/forward/
  • Проверить WebSocket события chat_message

DOM инспектор:

  • .selection-mode класс на контейнере
  • .selected класс на выделенных сообщениях
  • .selection-actions-bar.active панель действий