Corp/backend/docs/guides/SMART_AUTOSCROLL.md

7.6 KiB
Raw Blame History

Умный автоскролл в чате

✅ Реализовано

Добавлен "умный автоскролл" по аналогии с современными мессенджерами (Telegram, WhatsApp, Discord).

🎯 Как это работает

Логика автоскролла при получении нового сообщения:

НОВОЕ СООБЩЕНИЕ ПРИШЛО
    ↓
Проверяем условия:
    ↓
    ├─ Это МОЁ сообщение? → ДА → Скролл вниз ✅
    │
    └─ Это ЧУЖОЕ сообщение?
           ↓
           ├─ Я внизу чата (< 100px)? → ДА → Скролл вниз ✅
           │
           └─ Читаю историю? → ДА → Показать индикатор "Новые сообщения" 🔔

Три сценария:

  1. Я отправил сообщение → всегда скроллим вниз
  2. Пришло чужое сообщение + я внизу → скроллим вниз (активно читаю)
  3. Пришло чужое сообщение + читаю историю → показываем индикатор

📁 Изменённые файлы

1. chatController.js - основная логика

Добавлено:

  • Свойства newMessagesCount и newMessagesBtn в конструктор
  • Метод _showNewMessagesIndicator() - показать индикатор
  • Метод _hideNewMessagesIndicator() - скрыть индикатор
  • Метод _findOrCreateNewMessagesButton() - создать кнопку
  • Метод _initScrollWatcher() - отслеживание скролла
  • Вызов _initScrollWatcher() в init()

Изменено:

  • _handleMessageAdded() - умная логика автоскролла:
// ДО (неправильно):
const shouldScroll = message.author_id === this.currentUserId;

// ПОСЛЕ (правильно):
const isMyMessage = message.author_id === this.currentUserId;
const isAtBottom = this.scrollManager.isNearBottom();
const shouldScroll = isMyMessage || isAtBottom;

if (shouldScroll) {
    this.scrollManager.scrollToBottom({ instant: false });
    this._hideNewMessagesIndicator();
} else {
    this._showNewMessagesIndicator();
}

2. chat-new-messages-indicator.css - стили

Создан новый файл: backend/static/css/components/chat-new-messages-indicator.css

Включает:

  • Позиционирование кнопки (правый нижний угол)
  • Анимацию появления/исчезновения
  • Hover/Active эффекты
  • Адаптив для мобильных
  • Поддержку тёмной темы

3. chat_detail.html - подключение стилей

Добавлено:

<link rel="stylesheet" href="{% static 'css/components/chat-new-messages-indicator.css' %}">

🔧 Технические детали

Порог "близко к низу"

// ScrollManager.js
BOTTOM_THRESHOLD: 100  // пикселей

Если пользователь в пределах 100px от низа чата - считается что "внизу".

Кнопка индикатора

Создаётся автоматически в JS:

<button id="new-messages-btn" class="new-messages-indicator">
    <svg>↓</svg>
    <span class="badge">3</span> новых сообщения
</button>

При клике:

  • Скроллит вниз с force: true
  • Сбрасывает счётчик
  • Скрывает кнопку

Автоматическое скрытие

При ручном скролле вниз (debounce 150ms):

if (this.scrollManager.isNearBottom()) {
    this._hideNewMessagesIndicator();
}

🎨 Внешний вид

Кнопка:

  • 📍 Позиция: правый нижний угол (20px отступ)
  • 🎨 Цвет: синий (primary)
  • 📏 Размер: 180px × 40px
  • ✨ Анимация: плавное появление с pulse эффектом
  • 🔢 Счётчик: бейдж с количеством новых сообщений

Адаптив:

  • На мобильных: меньше размер, меньше отступы
  • Тёмная тема: более тёмный синий фон

📊 Сравнение с популярными мессенджерами

Мессенджер Порог Индикатор Наша реализация
Telegram ~150px "↓ 5 новых" ✅ 100px + счётчик
WhatsApp ~100px Зелёная стрелка ✅ Синяя с счётчиком
Discord ~50px "New Messages" ✅ "X новых сообщения"
Slack ~100px "Jump" button ✅ Скролл вниз

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

Сценарий 1: Отправка своего сообщения

  1. Прокрутить вверх (история)
  2. Отправить сообщение
  3. ✅ Должен автоматически скроллить вниз

Сценарий 2: Получение чужого сообщения (внизу)

  1. Находиться внизу чата
  2. Получить чужое сообщение
  3. ✅ Должен автоматически скроллить вниз

Сценарий 3: Получение чужого сообщения (читаю историю)

  1. Прокрутить вверх на 200px+
  2. Получить чужое сообщение
  3. ✅ Должна появиться кнопка "X новых сообщения"

Сценарий 4: Клик по индикатору

  1. Показан индикатор
  2. Кликнуть по кнопке
  3. ✅ Скроллит вниз + кнопка исчезает

Сценарий 5: Ручной скролл вниз

  1. Показан индикатор
  2. Вручную прокрутить вниз
  3. ✅ Кнопка автоматически исчезает

🐛 Известные особенности

  1. Кнопка создаётся динамически в JS (не в HTML шаблоне)
  2. Счётчик увеличивается на каждое новое сообщение пока читаем историю
  3. Сбрасывается при скролле вниз или клике по кнопке

🔄 Связанные файлы

  • backend/static/js/controllers/chatController.js - основная логика
  • backend/static/js/managers/scrollManager.js - isNearBottom()
  • backend/static/css/components/chat-new-messages-indicator.css - стили
  • backend/templates/communications/chat_detail.html - подключение CSS

📝 Логирование

Все действия логируются в консоль:

[ChatController] New message: {
    id: 123,
    isMyMessage: false,
    isAtBottom: false,
    shouldScroll: false
}
[ChatController] New messages indicator shown: 1

🚀 Следующие шаги (опционально)

  • Добавить звуковое уведомление при новом сообщении
  • Добавить вибрацию на мобильных
  • Сделать порог настраиваемым (в настройках пользователя)
  • Добавить плавную анимацию скролла (smooth scroll)
  • Показывать preview последнего сообщения в индикаторе