- кнопка распознавания в плеере: видна только на музыкальных станциях без
метаданных эфира (track == null), показывает спиннер и результат через Toast
- распознанный трек отображается в плеере и пишется в ОТДЕЛЬНУЮ историю
распознанных (не дублируется в историю эфирных треков — гейт по ключу)
- экран Истории: переключатель «Треки эфира | Распознанные», два списка
- Room: таблица recognized_track (миграция 7→8), DAO/репозиторий
- ShazamRepository → POST /shazam/recognize/{stationId}, маппинг 503/400 в текст
- MusicGenres.isMusicStation — клиентский гейт (синхронизирован с бэкендом)
- bump backend submodule (модуль shazam)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Раньше пресет эквалайзера в настройках был косметикой (лежал в DataStore, к звуку
не подключён). Теперь — реальные системные эффекты на фикс. аудиосессии плеера:
- AudioEffectsController: графический Equalizer (полосы устройства), BassBoost,
Virtualizer (объём), LoudnessEnhancer (громкость тихих, до +12 дБ). Привязка к
generateAudioSessionId() в PlayerController, переживает смену станций. Применение
в реальном времени, сохранение в DataStore (commit на отпускании слайдера).
- Отдельный экран EqualizerScreen (Настройки → ЗВУК → Эквалайзер): тумблер,
системные пресеты + «Свой», слайдеры полос (±дБ), bass/virtualizer/loudness.
- Эффекты best-effort: при отсутствии поддержки блок недоступен (null), UI скрывает.
- Убран фейковый чип-пресет Flat/Rock/Pop/Jazz/Bass.
8 тёмных палитр (Лес/Океан/Закат/Аметист/Неон/Янтарь/Лёд/Роза) в Palettes.kt.
RadiolaColors теперь несёт все токены + градиент; RadiolaTheme(palette) строит из
неё и RadiolaColors, и Material ColorScheme — всё приложение берёт цвета через
RadiolaTheme.colors, поэтому смена палитры перекрашивает мгновенно. Бренд-марка
(AppMark/Wordmark) тоже следует теме. Выбор в DataStore (theme_palette, дефолт
forest), читается в MainActivity и подаётся в тему. Секция «ТЕМА ОФОРМЛЕНИЯ» в
настройках — горизонтальный ряд свотчей с превью (фон+акцент+градиент).
Обложки наливались общей очередью (1.5с) — играющий трек ждал свою очередь.
Добавлена приоритетная дорожка: трек, который слушают сейчас, обогащается
первым (PlayerViewModel → NowPlayingRepository.enrichCoverNow). Троттл общей
очереди ускорен 1.5с→0.8с. Дедуп разнесён на enqueued/processed, чтобы
дорожки не дублировали работу.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Radio ROKS и Kiss FM (TavR Media, хосты radioroks.ua / kissfm.ua) недоступны
с российских IP без VPN. Теперь для пользователей из РФ они полностью скрыты
— и сами станции (везде, где используется список), и их чипы-категории.
Страна определяется по IP (api.country.is → ipapi.co; при VPN вернёт страну
выходного узла, тогда станции доступны и НЕ скрываются), с фолбэком на страну
SIM/сети/локали устройства, если IP-сервис недоступен (в РФ часто заблокирован).
Код страны кэшируется (DataStore). Фильтр в GetStationsUseCase (combine со
страной) + чипы в StationsViewModel. id 741 «Радио РОКС» (stream.roks.com) —
российская, под правило не попадает.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Перепроверены все 594 рабочие станции на наличие битрейт-вариантов
потока (скрипт-пробер). У 71 станции найдено по 2–4 качества
(Record-флагманы 96/64/32, zaycev 256/128/48, ВГТРК 192/128/64,
НАШЕ/Орфей/Шансон HQ и др.) — записаны в поле qualities в stations.json.
HLS (EMG) и Love (UID-привязка) корректно пропущены.
Клиент: модель StreamQuality, хранение в Room (миграция v5),
предпочтение битрейта в настройках. На экране плеера — чип текущего
качества (виден только если вариантов ≥2) и шторка «Качество звука»
со ступенями; переключение на лету без сброса now-playing, выбор
запоминается между станциями.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Станции с одинаковым именем в разных сетях (напр. «Deep» у Record и DFM)
показывали один и тот же трек — матч был по lowercase-имени. Каталожный id
(== station.id) уникален и совпадает со stationId в /now-playing, поэтому
матчим по id. Убран весь by-name путь (репозиторий, плеер, карточки).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Плеер искал now-playing по числовому id станции, а у локальных станций (DFM)
id не совпадает с каталожным → API-путь с обложкой не срабатывал, плеер падал
на ICY из потока (без обложки). Теперь getNowPlaying матчит по id, затем по
имени станции (как карточки). DFM-обложки появляются и в плеере.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Подтягиваем обогащённые данные с бэкенда (Discogs): genre/styles/label/year
в чартах и детальной странице.
- ChartEntry/TrackStats + DTO: добавлены genre/styles/label/year
- RadiolaApi: getCharts(?genre=), новый getGenres()
- ChartsViewModel: состояние выбранного жанра + список жанров, перезагрузка
- ChartsScreen: ряд чипов-фильтров по жанру (Все + жанры),
жанр/стили чипами и «Лейбл · Год» на детальной
- убран демо-fallback (SAMPLE_CHARTS) — бэкенд живой
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Для станций без своей обложки (и для Radio Record — единый стиль) карточка
показывает обложку играющего трека с тёмным градиентом и подписью трек/исполнитель.
Источник — /now-playing (теперь с name станции), матч по имени, обновление 20с.
Приоритет: трек -> логотип станции -> фирменная плитка.