- Исправлен PollSerializer для создания опросов с опциями
- Добавлено поле read_only_fields для корректной валидации
- Реализована отправка WebSocket уведомлений при создании опроса
- Исправлен импорт serialize_message из communications.serialization
- Добавлен обработчик poll_update в UserConsumer для WebSocket событий
- Исправлен эндпоинт /results/ для возврата user_voted_option_ids
- Добавлено поле voters в PollOptionSerializer для списка проголосовавших
- Реализована инициализация poll виджетов после рендера сообщений
- Добавлено игнорирование poll_update в notification-manager
- Исправлены стили для request list badges (height, word-break, flex)
- Восстановлены стили team-wheel (.wheel-focus, .scroll-arc) из git истории
- Реализовано отображение forwarded message info в messageRendererV2
- Множественные улучшения UI и UX для опросов
Fixes: создание опросов, голосование, отображение результатов, список проголосовавших
ГЛУБОКИЙ АУДИТ выявил корневые причины прыжков:
НАЙДЕННЫЕ ПРОБЛЕМЫ:
1. chatMarkRead делал свою прокрутку ПОСЛЕ handleInitialMessages
- mark.scrollIntoView() или autoscroll() в requestAnimationFrame
- Конфликтовал с уже установленной прокруткой
2. Дублирование обработчика кнопки 'вниз':
- chatMarkRead.js: btn.addEventListener
- chat-detail-enhanced.js: scrollBtn.addEventListener
- Два обработчика на одну кнопку!
3. Излишняя сложность в scrollToBottom():
- Вызывал markReadApi.autoscroll() вместо прямой установки
- Дополнительный уровень косвенности = источник багов
ИСПРАВЛЕНИЯ:
1. chatMarkRead НЕ скроллит при инициализации:
- Divider создается, но не скроллится к нему
- Прокрутка управляется ТОЛЬКО из handleInitialMessages
- Единая точка ответственности
2. Убрано дублирование кнопки:
- Удален обработчик из chat-detail-enhanced.js
- Остался только в chatMarkRead.js
3. Упрощен scrollToBottom():
- Прямая установка scrollTop вместо вызова markReadApi
- Поддержка instant режима (без анимации)
- Предсказуемое поведение
4. Добавлены комментарии и документация:
- Пояснено почему НЕ скроллим в chatMarkRead
- Описано назначение каждой функции прокрутки
- Создан полный аудит в docs/completed/SCROLL_CONFLICTS_AUDIT.md
АРХИТЕКТУРА ПРОКРУТКИ:
✅ При загрузке: ТОЛЬКО handleInitialMessages
✅ Кнопка вниз: chatMarkRead.autoscroll()
✅ Новые сообщения: ТОЛЬКО если свое ИЛИ уже внизу
✅ Ввод текста: autoscroll() если внизу
РЕЗУЛЬТАТ:
✅ Нет прыжков - единая точка управления прокруткой
✅ Нет конфликтов - каждая функция делает одно
✅ Нет дублирования - один обработчик на событие
✅ Предсказуемость - прямые вызовы вместо косвенных
Файлы:
- userWebSocket.js: упрощен scrollToBottom
- chatMarkRead.js: убрана автопрокрутка при инициализации
- chat-detail-enhanced.js: убран дублирующий обработчик
- docs/completed/SCROLL_CONFLICTS_AUDIT.md: полный аудит
- ApiClient теперь обрабатывает 401 и 403 ошибки для обновления токена
- Добавлен JWTRefreshMiddleware для проактивного обновления токенов за 5 минут до истечения
- Добавлена настройка JWT_REFRESH_THRESHOLD_MINUTES (по умолчанию 5)
- Исправлена проблема с периодическими 403 ошибками после истечения access token