feat(social): add listening activity, shared rooms and modern chat
ci / api / api (push) Canceled after 0s
ci / module boundaries / boundaries (push) Canceled after 0s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Canceled after 11m29s
ci / db / db (push) Canceled after 11m22s
ci / mobile / mobile (Metro-бандл Android) (push) Canceled after 6m43s
ci / recommender / recommender (push) Canceled after 6m47s
ci / ts / ts (packages + web) (push) Canceled after 1s

This commit is contained in:
mrleo1nid committed 2026-10-23 10:45:40 +03:00
1 parent 0a05bfe2cd
commit 11a16cd023
59 files changed
+5022 -542

No files matched your search

+52 -1
View File
@@ -31,7 +31,7 @@
В скрытой вкладке и в фоне Android автоматического подтверждения нет.
Сейчас это уведомления **внутри работающего приложения**, с обновлением центра каждые 15 секунд
и открытого чата каждые 8 секунд. Web использует стандартную приостановку фонового polling
и открытого чата каждые 3 секунды. Web использует стандартную приостановку фонового polling
React Query; Android останавливает polling при уходе приложения в фон. Уведомления ОС при
закрытом клиенте (Web Push/FCM/нативный desktop) в эту реализацию не входят.
@@ -56,3 +56,54 @@ React Query; Android останавливает polling при уходе при
`pnpm --filter @pipu/web test src/App.test.tsx -t 'social|playlist sharing'`,
`pnpm --filter @pipu/web test:e2e e2e/social.spec.ts e2e/playlists.spec.ts`.
Интеграционный сценарий включён в `ci-db`.
## Активность и приватность
В разделе друзей настройка «Показывать мой статус» принимает значения «Никому»
(по умолчанию), «Друзьям», «Всем». Сервер проверяет аудиторию, дружбу и блокировки.
При «Никому» сведения о текущем прослушивании не сохраняются. Переключение на это
значение удаляет активность всех устройств. Публикация имеет последовательный номер
и срок жизни 90 секунд; пауза снимает статус, потерянное соединение не оставляет вечный статус.
Карточка показывает трек и контекст: «Моя волна», плейлист или обычное прослушивание.
Трек открывается в каталоге. Плейлист доступен для чтения, пока активность видима:
этот переход не создаёт постоянной ссылки общего доступа и не раскрывает существующую.
## Совместное прослушивание
«Подключиться» отправляет запрос хозяину и оставляет управление у него.
«Пригласить на мой стрим» создаёт собственную комнату: приглашённый становится слушателем.
Один пользователь состоит в одной комнате; несколько слушателей могут подключиться к хозяину.
Настройки приёма запросов/приглашений и автоматического принятия независимы,
обе по умолчанию «Никто». Автопринятие применяется только внутри разрешённой аудитории.
Дополнительная настройка управляет запуском звука при подключении.
Только исходное устройство хозяина публикует состояние комнаты. Слушатели получают
трек, паузу и позицию с поправкой на серверное время каждые 2 секунды. Обычные кнопки
управления, очередь и перемотка заблокированы; громкость, реакции и выход доступны.
Это синхронизация собственных потоков из каталога с допуском дрейфа 1,5 секунды,
а не ретрансляция аудиобайта хозяина. Браузер может потребовать нажатия «Включить звук».
После 10 секунд потери связи слушатель ставится на паузу, комната истекает через 30 секунд
без хозяина, отсутствующий слушатель удаляется через 60 секунд, запрос действует 2 минуты.
## Чат
Web и desktop используют выдвижную панель справа снизу, Android — общую нижнюю панель.
Поддерживаются текст и музыка, ответы с цитатой, шесть реакций, редактирование своих
сообщений, удаление для всех, поиск по тексту, история, даты, прочтение и индикатор набора.
Удаление очищает исходный текст и музыкальное вложение. Черновики разделены по серверу,
пользователю и собеседнику. Скрытая панель не отмечает переписку прочитанной.
Анимации учитывают системное уменьшение движения. Фото, файлы и голосовые не входят в версию.
Миграции `00020`–`00022` добавляют активность, комнаты и возможности чата.
Уведомления дополнены запросом, приглашением и принятием совместного прослушивания.
## Сигнал друзей в рекомендациях
В настройках рекомендаций можно отключить влияние друзей. Используется только их
текущая видимая активность с учётом аудитории и блокировок, без скрытой истории.
Go передаёт до 30 допустимых треков; Python добавляет до 10 кандидатов, небольшой бонус
с учётом выбранного контекста и не более одного кандидата с источником `friends` на выдачу.
Дизлайки, недоступные треки и недавние повторы исключаются прежними фильтрами.
При недоступном рекомендателе резервный подбор добавляет не более одного такого трека
в каждую вторую выдачу; тематические волны с seed сохраняют свой сценарий.