225 lines
7.6 KiB
Markdown
225 lines
7.6 KiB
Markdown
# Контекстное меню сообщений
|
||
|
||
## ✅ Реализовано
|
||
|
||
Добавлено современное контекстное меню для сообщений (как в Telegram/WhatsApp/Viber).
|
||
|
||
---
|
||
|
||
## 🎯 Функционал
|
||
|
||
### Открытие меню
|
||
|
||
#### На десктопе (ПК)
|
||
- **Правый клик** на сообщении → открывается контекстное меню
|
||
|
||
#### На мобильных устройствах
|
||
- **Долгое нажатие** (500ms) на сообщении → вибрация → открывается контекстное меню
|
||
- Если палец двигается при нажатии → долгое нажатие отменяется
|
||
|
||
### Содержимое меню
|
||
|
||
#### 1. Быстрые реакции (верхняя секция)
|
||
```
|
||
👍 ❤️ 😂 😮 😢 🙏 👏 🔥
|
||
```
|
||
- Одним тапом можно поставить реакцию
|
||
- Круглые кнопки с анимацией увеличения при нажатии
|
||
|
||
#### 2. Действия с сообщением (нижняя секция)
|
||
|
||
**Для всех сообщений:**
|
||
- 🔄 **Ответить** - цитировать сообщение
|
||
- 📋 **Копировать** - скопировать текст в буфер обмена
|
||
- ↗️ **Переслать** - переслать в другой чат
|
||
|
||
**Только для своих сообщений:**
|
||
- ✏️ **Редактировать** - изменить текст
|
||
- 🗑️ **Удалить** - удалить сообщение (красная кнопка)
|
||
|
||
### Закрытие меню
|
||
|
||
- Клик вне меню
|
||
- Нажатие клавиши **Escape**
|
||
- Скролл страницы
|
||
- После выбора любого действия
|
||
|
||
---
|
||
|
||
## 📁 Файлы
|
||
|
||
### JavaScript
|
||
```
|
||
backend/static/js/components/messageContextMenu.js (311 строк)
|
||
```
|
||
- Класс `MessageContextMenu`
|
||
- Обработка долгого нажатия
|
||
- Обработка правого клика
|
||
- Позиционирование меню
|
||
- Вибрация на мобильных
|
||
|
||
### CSS
|
||
```
|
||
backend/static/css/message-context-menu.css (225 строк)
|
||
```
|
||
- Стили меню
|
||
- Анимации появления/исчезания
|
||
- Адаптивность для мобильных
|
||
- Тёмная тема
|
||
- Toast уведомления
|
||
|
||
### Интеграция
|
||
```
|
||
backend/static/js/chat-detail-enhanced.js
|
||
backend/templates/communications/chat_detail.html
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 Дизайн
|
||
|
||
### Десктоп
|
||
- Округлое меню с тенью
|
||
- Позиционируется рядом с курсором
|
||
- Минимальная ширина 280px
|
||
|
||
### Мобильные
|
||
- Меню растягивается на всю ширину экрана (с отступами 16px)
|
||
- Закреплено внизу экрана
|
||
- Увеличенные кнопки (48x48px) для удобства тапов
|
||
- Анимация появления снизу вверх
|
||
|
||
### Эффекты
|
||
- Подсветка выбранного сообщения
|
||
- Плавные анимации (transform + opacity)
|
||
- Вибрация при долгом нажатии (мобильные)
|
||
- Toast уведомление "Текст скопирован"
|
||
|
||
### Тёмная тема
|
||
- Автоматическое определение через `prefers-color-scheme`
|
||
- Тёмный фон (#2b2d31)
|
||
- Светлый текст (#dbdee1)
|
||
|
||
---
|
||
|
||
## 🔧 API
|
||
|
||
### Инициализация
|
||
```javascript
|
||
const contextMenu = new MessageContextMenu({
|
||
currentUserId: 123,
|
||
emojis: ['👍', '❤️', '😂', ...],
|
||
onReactionSelect: (messageId, emoji) => { ... },
|
||
onEdit: (messageId) => { ... },
|
||
onDelete: (messageId) => { ... },
|
||
onReply: (messageId) => { ... },
|
||
onForward: (messageId) => { ... }
|
||
});
|
||
```
|
||
|
||
### Подключение к сообщению
|
||
```javascript
|
||
const messageElement = document.querySelector('[data-message-id="123"]');
|
||
contextMenu.attachToMessage(messageElement);
|
||
```
|
||
|
||
### Методы
|
||
- `showMenu(element, messageId, isOwn, x, y)` - показать меню
|
||
- `closeMenu()` - закрыть меню
|
||
- `handleAction(action, messageId, emoji)` - обработать действие
|
||
- `showToast(message)` - показать уведомление
|
||
|
||
---
|
||
|
||
## 📱 UX особенности
|
||
|
||
### Предотвращение конфликтов
|
||
- Долгое нажатие отменяется если палец двигается (скролл)
|
||
- Клик по сообщению не открывает меню (только долгое нажатие)
|
||
- Меню автоматически закрывается при скролле
|
||
|
||
### Позиционирование
|
||
- Меню не выходит за границы экрана
|
||
- Автоматическое смещение если не помещается
|
||
- На мобильных всегда внизу экрана
|
||
|
||
### Тактильная обратная связь
|
||
- Вибрация 50ms при открытии меню (мобильные)
|
||
- Hover эффекты на кнопках (десктоп)
|
||
- Active состояния для тапов (мобильные)
|
||
|
||
---
|
||
|
||
## 🚀 Использование
|
||
|
||
### Пользователь на ПК
|
||
1. Навести курсор на сообщение
|
||
2. Правый клик мыши
|
||
3. Выбрать действие из меню
|
||
|
||
### Пользователь на телефоне
|
||
1. Нажать и держать палец на сообщении ~0.5 секунды
|
||
2. Почувствовать вибрацию
|
||
3. Увидеть меню внизу экрана
|
||
4. Тапнуть на нужное действие
|
||
|
||
---
|
||
|
||
## ✨ Фишки
|
||
|
||
1. **Быстрые реакции** - 8 самых популярных эмодзи в один клик
|
||
2. **Умное позиционирование** - меню всегда на экране
|
||
3. **Подсветка** - видно какое сообщение выбрано
|
||
4. **Вибрация** - тактильная обратная связь
|
||
5. **Toast** - уведомления о копировании
|
||
6. **Адаптивность** - разный UX для десктопа и мобилок
|
||
7. **Темная тема** - автоматическая поддержка
|
||
8. **Анимации** - плавное появление/исчезновение
|
||
|
||
---
|
||
|
||
## 🔄 Интеграция с существующим кодом
|
||
|
||
### Реакции
|
||
При выборе эмодзи в меню вызывается:
|
||
```javascript
|
||
await reactions.addReaction(messageId, emoji);
|
||
```
|
||
|
||
### Действия
|
||
Используются существующие функции:
|
||
```javascript
|
||
window.editMessage(messageId);
|
||
window.deleteMessage(messageId);
|
||
window.setReplyTo(messageId);
|
||
window.forwardMessage(messageId);
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 Совместимость
|
||
|
||
- ✅ Chrome/Edge (Desktop & Mobile)
|
||
- ✅ Firefox (Desktop & Mobile)
|
||
- ✅ Safari (Desktop & Mobile)
|
||
- ✅ Работает без JavaScript (graceful degradation)
|
||
- ✅ Поддержка touch событий
|
||
- ✅ Поддержка pointer events
|
||
|
||
---
|
||
|
||
## 📝 TODO (опционально)
|
||
|
||
- [ ] Добавить haptic feedback для iOS
|
||
- [ ] Добавить звук при открытии меню
|
||
- [ ] Кастомизация списка эмодзи
|
||
- [ ] Недавние эмодзи (история)
|
||
- [ ] Анимация выбора реакции
|
||
- [ ] Swipe для быстрого ответа
|
||
- [ ] Превью текста при пересылке
|
||
|
||
---
|
||
|
||
**Дата**: 2025-11-30
|
||
**Версия**: 1.0.0
|