Corp/CHAT_LIST_BUGS_FIX.md

10 KiB
Raw Blame History

Исправление багов chat_list.html ✅

🐛 Обнаруженные проблемы

1. Старый WebSocket маршрут

Проблема: chatListRealtime.js создавал собственное WebSocket соединение на /ws/chats/ вместо использования универсального /ws/

Файл: backend/static/js/components/chatListRealtime.js

Решение:

  • ❌ Удалено: new WebSocket('/ws/chats/')
  • ✅ Изменено: Теперь использует userWebSocket из base.html через callback onListUpdate
  • ✅ Архитектура: Один WebSocket на пользователя (/ws/)
// БЫЛО:
const ws = new WebSocket(`${proto}://${location.host}/ws/chats/`);

// СТАЛО:
// Используем userWebSocket через callback onListUpdate
function updateChatCard(chatId, msg) {
  // обновление карточки
}

2. Dropdown меню выходит за границы контейнера

Проблема: Меню действий чата (dropdown-menu) рендерилось с position: absolute относительно родителя, что могло обрезать часть меню

Файл: backend/static/css/components/chat-list-enhanced.css

Решение:

/* БЫЛО */
.chat-actions-menu .dropdown-menu {
    z-index: 1050;
    /* position: absolute - по умолчанию */
}

/* СТАЛО */
.chat-actions-menu .dropdown-menu {
    z-index: 9999; /* Поверх всего! */
    position: fixed !important; /* Относительно viewport */
    /* Bootstrap автоматически вычислит координаты */
}

Эффект:

  • ✅ Меню появляется поверх всех элементов
  • ✅ Не обрезается границами родителя
  • ✅ Bootstrap Dropdown Popper.js правильно позиционирует

3. Контент чата выходит за границы ячейки

Проблема: Длинные названия чатов и сообщения могли растягивать карточку за пределы границ

Файл: backend/static/css/components/chat-list-enhanced.css

Решение:

/* Ограничение карточки */
.chat-row {
    overflow: hidden; /* Предотвращаем overflow */
    min-height: 60px;
}

/* Критично для flex! */
.chat-row .flex-grow-1 {
    min-width: 0; /* Позволяет flex сжиматься */
    overflow: hidden;
}

/* Обрезка заголовка */
.chat-row .flex-grow-1 a,
.chat-row .flex-grow-1 .card-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

/* Обрезка последнего сообщения */
.chat-row [data-last-preview],
.chat-row .card-subtitle {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

Эффект:

  • ✅ Длинные названия обрезаются с многоточием
  • ✅ Последнее сообщение не вылезает за границы
  • ✅ Карточка имеет фиксированную минимальную высоту
  • ✅ Flex-контейнер правильно сжимается

4. Меню действий могло сжиматься

Проблема: При overflow контента меню с "тремя точками" могло уменьшаться

Решение:

.chat-actions-menu {
    flex-shrink: 0; /* Не сжимается при overflow */
}

5. Улучшение Bootstrap Dropdown

Файл: backend/templates/includes/components/chat_menu.html

Изменения:

<!-- БЫЛО -->
<div class="chat-actions-menu position-relative" style="z-index:2;">
  <button data-bs-toggle="dropdown">...</button>
  <ul class="dropdown-menu dropdown-menu-end">

<!-- СТАЛО -->
<div class="chat-actions-menu position-relative">
  <button 
    data-bs-toggle="dropdown" 
    data-bs-auto-close="true">...</button>
  <ul class="dropdown-menu dropdown-menu-end shadow-sm">

Улучшения:

  • ✅ Убран inline z-index (управляется через CSS)
  • ✅ Добавлен data-bs-auto-close="true" - автозакрытие при клике вне
  • ✅ Добавлена тень shadow-sm для лучшего визуала

📊 Техническое резюме

Архитектурные изменения

До:

┌─────────────────┐
│  chat_list.html │
└────────┬────────┘
         │
         ├── WebSocket /ws/ (userWebSocket)
         │
         └── WebSocket /ws/chats/ (chatListRealtime) ❌ ДУБЛИРОВАНИЕ

После:

┌─────────────────┐
│  chat_list.html │
└────────┬────────┘
         │
         └── WebSocket /ws/ (userWebSocket)
                   │
                   └── callback: onListUpdate → chatListRealtime.updateChatCard() ✅

CSS Fixes

Проблема Решение Свойство
Dropdown обрезается position: fixed !important .dropdown-menu
Контент overflow overflow: hidden .chat-row
Flex не сжимается min-width: 0 .flex-grow-1
Длинный текст text-overflow: ellipsis a, .card-title
Меню сжимается flex-shrink: 0 .chat-actions-menu

✅ Проверка

Django Check

$ python manage.py check
System check identified no issues (0 silenced).

✅ PASSED

JavaScript

  • ✅ chatListRealtime.js - синтаксис корректен
  • ✅ Удалены устаревшие ws.addEventListener
  • ✅ API упрощён: { updateChatCard, resortSection, containerForType }

CSS

  • ✅ Все overflow предотвращены
  • ✅ Dropdown positioning исправлен
  • ✅ Flex-контейнеры настроены правильно

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

Что проверить:

1. Dropdown меню

  • Открыть список чатов
  • Навести на карточку чата
  • Кликнуть на три точки
  • Ожидание: Меню появляется поверх всего, не обрезается
  • Кликнуть вне меню
  • Ожидание: Меню закрывается автоматически

2. Overflow контента

  • Создать чат с очень длинным названием (>50 символов)
  • Ожидание: Название обрезается с ...
  • Отправить длинное сообщение (>120 символов)
  • Ожидание: Превью обрезается с ...
  • Ожидание: Карточка не растягивается за границы

3. WebSocket соединение

  • Открыть DevTools → Network → WS
  • Ожидание: Только ОДНО соединение /ws/
  • Ожидание: НЕТ соединения /ws/chats/
  • Отправить сообщение в другом окне
  • Ожидание: Карточка обновляется в списке

4. Real-time обновления

  • Открыть список чатов
  • В другом окне отправить сообщение в чат
  • Ожидание:
    • Время обновилось
    • Автор обновился
    • Превью обновилось
    • Чат переместился вверх списка

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

JavaScript

  1. backend/static/js/components/chatListRealtime.js
    • Удалено создание WebSocket
    • Добавлена функция updateChatCard(chatId, msg)
    • Упрощён API
    • Добавлена поддержка всех 6 типов чатов

CSS

  1. backend/static/css/components/chat-list-enhanced.css
    • Dropdown: position: fixed !important, z-index: 9999
    • Chat row: overflow: hidden, min-height: 60px
    • Flex-grow: min-width: 0, overflow: hidden
    • Text: text-overflow: ellipsis, white-space: nowrap
    • Menu: flex-shrink: 0

HTML

  1. backend/templates/includes/components/chat_menu.html
    • Добавлен data-bs-auto-close="true"
    • Добавлен shadow-sm для dropdown
    • Убран inline z-index

🎯 Результат

Было:

  • ❌ 2 WebSocket соединения (дублирование)
  • ❌ Dropdown обрезается родителем
  • ❌ Длинный текст растягивает карточку
  • ❌ Меню может сжиматься

Стало:

  • ✅ 1 WebSocket соединение (/ws/)
  • ✅ Dropdown поверх всех элементов
  • ✅ Текст обрезается с многоточием
  • ✅ Меню фиксированного размера
  • ✅ Карточки фиксированной высоты

💡 Дополнительные улучшения (будущее)

1. Виртуализация списка

Для больших списков (>100 чатов) можно добавить виртуализацию:

import { VirtualScroller } from 'virtual-scroller';

2. Skeleton Loading

Для плавной загрузки списка:

<div class="chat-row skeleton">
  <div class="skeleton-avatar"></div>
  <div class="skeleton-text"></div>
</div>

3. Infinite Scroll

Для постраничной загрузки:

const observer = new IntersectionObserver(loadMore);
observer.observe(lastChatElement);

Документ создан: 1 декабря 2025 г. Статус: ✅ COMPLETE