Skip to content

Feature/practices#59

Open
nmanachinsky wants to merge 11 commits intomasterfrom
feature/practices
Open

Feature/practices#59
nmanachinsky wants to merge 11 commits intomasterfrom
feature/practices

Conversation

@nmanachinsky
Copy link
Copy Markdown
Owner

No description provided.

…tBleManager` к `AmuletDevice`)

В этом коммите проведена масштабная реструктуризация модуля `core:ble`. Монолитный интерфейс `AmuletBleManager` заменен на более гранулярную архитектуру, где функциональность разделена между специализированными менеджерами и сервисами, объединенными в интерфейсе `AmuletDevice`.

Ключевые изменения включают в себя:

*   **Новая архитектура и интерфейсы**:
    *   Введен интерфейс `AmuletDevice`, который объединяет функции подключения (`DeviceConnectionManager`), управления состоянием (`DeviceStateManager`) и отправки команд (`DeviceCommandSender`).
    *   Создан `AmuletProtocolParser` для централизованной обработки входящих GATT-событий и их преобразования в доменные модели (ответы на команды, уведомления, статус устройства).
    *   Выделены отдельные сервисы для сложных операций: `AnimationUploadService` и `OtaUpdateService`.

*   **Уровень транспорта и протокола**:
    *   Введен `BleGattClient` для инкапсуляции низкоуровневой работы с Android Bluetooth GATT, включая управление очередью записи (`pendingWrites`) и настройку уведомлений для характеристик.
    *   Реализован механизм `waitForCommandResponse` в парсере для синхронизации отправки команд и получения ответов от устройства.

*   **Изменения в логике OTA**:
    *   Обновлен `OtaBleDataSource`: загрузка бинарных данных прошивки теперь должна выполняться на уровне данных перед вызовом BLE-сервиса.
    *   В `OtaUpdateService` передается готовый `ByteArray` с прошивкой, что устраняет сетевую зависимость из BLE-модуля.

*   **Улучшения стабильности и очистка**:
    *   Удален старый `AmuletBleManagerImpl` в пользу композитной реализации `AmuletDeviceImpl`.
    *   Добавлена поддержка мьютексов (`commandMutex`) для предотвращения одновременной отправки нескольких команд.
    *   Улучшена обработка ошибок и таймаутов на всех этапах взаимодействия с устройством.

*   **Внедрение зависимостей**:
    *   Обновлен `BleModule.kt` для связывания новых интерфейсов с их реализациями.

*   **Инфраструктура**:
    *   Добавлен вспомогательный скрипт `collect_ble_code.py` для сборки кода модуля в единый markdown-файл для документации.
…озитории и обновление BLE-протокола

В этом коммите проведена масштабная реструктуризация модуля устройств. Монолитный `DevicesRepository` разделен на три узкоспециализированных интерфейса для улучшения разделения ответственности (SoC) и упрощения тестирования. Также обновлена логика формирования команд для BLE-устройств.

Ключевые изменения:

*   **Рефакторинг репозиториев**:
    *   `DevicesRepository` удален. Вместо него внедрены:
        *   `DeviceRegistryRepository`: CRUD-операции и управление списком устройств в локальной БД.
        *   `DeviceConnectionRepository`: сканирование, подключение и мониторинг состояния BLE-соединения.
        *   `DeviceControlRepository`: отправка команд, управление яркостью/вибрацией и загрузка планов анимаций/скриптов.
    *   Соответствующим образом обновлены реализации (`Impl`) и зависимости в `DevicesDataModule` и `SharedModules.kt`.

*   **Изменения в доменной модели и UseCases**:
    *   Модель `AmuletCommand` и сопутствующая логика маппинга (`toCommandString`) перенесены из доменного слоя (`shared`) в уровень BLE (`core:ble`), так как они специфичны для протокола.
    *   Обновлен формат команд в `toCommandString`: теперь параметры разделяются запятыми, а названия некоторых команд приведены к виду `*_SCRIPT` (например, `BEGIN_PRACTICE_SCRIPT`).
    *   `DeviceAnimationPlan` теперь оперирует списком `DeviceTimelineSegment` вместо сырых `ByteArray`, перенося сборку байтов в data-слой.
    *   Все сценарии использования (UseCases), связанные с устройствами, переведены на использование новых специализированных репозиториев.

*   **Улучшения в OTA (Over-the-Air) обновлениях**:
    *   В `OtaRemoteDataSource` добавлен метод `downloadFirmware` для предварительного скачивания прошивки.
    *   `OtaRepositoryImpl` теперь включает этап подготовки (`PREPARING`) и скачивания данных перед началом передачи прошивки через BLE.

*   **Очистка и исправления**:
    *   Удалены неиспользуемые импорты и устаревшие зависимости в `KoinBridgeModule`.
    *   `PatternPlaybackService` теперь корректно использует новые репозитории для прелоада и воспроизведения паттернов.
    *   В `.gitignore` добавлены исключения для IDE-папок (`.windsurf/`) и скриптов.
В этом коммите логика сериализации данных и обработки специфичных для устройства уведомлений перенесена из доменного слоя в слой данных. Это очищает доменные модели и сценарии использования от низкоуровневых деталей реализации BLE.

Ключевые изменения включают в себя:

*   **Перенос логики сериализации**:
    *   Метод `toByteArray()` и вспомогательные функции для записи байтов (little-endian) удалены из доменной модели `DeviceTimelineSegment`.
    *   Логика бинарной сериализации сегментов (согласно структуре `SegmentLinearRgbV2`) теперь реализована в `DeviceControlRepositoryImpl` в методе `segmentToByteArray`.

*   **Рефакторинг `DeviceControlRepository`**:
    *   В интерфейс репозитория добавлен новый метод `awaitPlaybackStarted`, который скрывает детали ожидания BLE-уведомлений.
    *   В `DeviceControlRepositoryImpl` реализовано ожидание уведомления `NOTIFY:PATTERN:STARTED` с обработкой таймаутов и возвратом специфичных ошибок `BleError`.

*   **Упрощение сценариев использования и сервисов**:
    *   `PlayPracticeScriptOnDeviceUseCase` и `PatternPlaybackService` теперь используют высокоуровневый метод `awaitPlaybackStarted` вместо прямой фильтрации потока уведомлений и ручной обработки `withTimeout`.
    *   Удалены неиспользуемые импорты (`NotificationType`, `first`, `withTimeout`) в слое `domain`, что снижает связность кода.

*   **Чистота моделей**:
    *   `DeviceTimelineSegment` теперь представляет собой чистый `data class` без методов сериализации.
    *   Обновлена документация в коде, указывающая на то, что сериализация теперь находится в слое данных.
В этом коммите внедрен централизованный механизм скачивания файлов и обновлена логика получения прошивок в модуле OTA. Это позволяет унифицировать сетевые операции и улучшить тестируемость кода за счет абстрагирования процесса загрузки.

Ключевые изменения включают в себя:

*   **Новый функционал сетевого уровня**:
    *   Добавлен интерфейс `FileDownloader` и его реализация `OkHttpFileDownloader` для эффективной загрузки файлов в виде `ByteArray`.
    *   Реализована обработка ошибок сети (`AppError.Network`) и неизвестных исключений при скачивании.
    *   В `NetworkModule` добавлен провайдер для `FileDownloader`.

*   **Обновление OTA API**:
    *   В `OtaApiService` добавлен метод `downloadFirmware` с аннотацией `@Streaming` для поддержки скачивания файлов по динамическим URL.

*   **Рефакторинг уровня данных**:
    *   `OtaRemoteDataSourceImpl` теперь использует `FileDownloader` вместо ручного управления `HttpURLConnection`. Это устраняет низкоуровневый код обработки соединений и таймаутов в источнике данных.
    *   Упрощена сигнатура метода `downloadFirmware` за счет использования внедренной зависимости.
…зависимостей

В этом коммите добавлен `DeviceControlRepository` в конфигурацию Koin, что обеспечивает доступ к функционалу управления устройствами через мост между Koin и Hilt. Это позволяет использовать репозиторий в общих сценариях использования (UseCases).

Ключевые изменения:
*   **Внедрение зависимостей (Koin)**:
    * В `SharedModules.kt` добавлена регистрация `DeviceControlRepository` как `single` компонента.
    * В `KoinBridgeModule.kt` добавлен импорт `DeviceControlRepository`, обеспечивающий связь между платформенной реализацией и общим кодом.
…иев устройств и корутин

В этом коммите обновлены модули внедрения зависимостей (Koin и Dagger/Hilt) для интеграции новых интерфейсов репозиториев устройств, оптимизации работы с корутинами и очистки неиспользуемых привязок в BLE-модуле.

Ключевые изменения включают в себя:

*   **Уровень Shared (DI)**:
    *   В `SharedModules.kt` добавлен провайдер `CoroutineDispatcher` (по умолчанию `Dispatchers.Default`) для использования в общих сценариях использования (UseCases).

*   **Интеграция с Android (Koin Bridge)**:
    *   В `KoinBridgeModule.kt` расширена функция инициализации Koin: добавлены зависимости для `DeviceControlRepository`, `DeviceConnectionRepository` и `DeviceRegistryRepository`.
    *   Добавлен метод `@Provides` для `DeviceHugSendListener`, позволяющий использовать его в Android-части приложения через Dagger/Hilt.

*   **Оптимизация BLE-модуля**:
    *   В `BleModule.kt` удалена избыточная привязка `AmuletProtocolParser`, что упрощает конфигурацию зависимостей Bluetooth-слоя.

*   **Исправление импортов**:
    *   Добавлены необходимые импорты для новых репозиториев и корутин в затронутых модулях.
…произведения

Этот коммит заменяет специализированный `PatternPlaybackService` на универсальный `DevicePlaybackEngine`, объединяя логику воспроизведения одиночных паттернов, превью и сценариев практик (practice scripts) в единый механизм управления состоянием.

Ключевые изменения включают в себя:

*   **Новый уровень воспроизведения**:
    *   Добавлен интерфейс `DevicePlaybackEngine` и его реализация `DevicePlaybackEngineImpl`, которые управляют жизненным циклом воспроизведения через состояния: `IDLE`, `COMPILING`, `UPLOADING`, `PLAYING`, `ERROR`.
    *   Введена запечатанная иерархия `PlayableMedia` (`Preview`, `SinglePattern`, `PracticeScript`) для типизации контента, отправляемого на устройство.

*   **Рефакторинг `PracticeSessionManager`**:
    *   Значительно упрощена логика запуска сессий. Громоздкая предварительная загрузка паттернов и скриптов вынесена из менеджера сессий в `DevicePlaybackEngine`.
    *   Удалены зависимости от множества мелких сценариев использования (`UploadPracticeScriptToDeviceUseCase`, `PlayPracticeScriptOnDeviceUseCase` и др.) в пользу единого вызова `playbackEngine.play(media)`.

*   **Обновление сценариев использования**:
    *   `PreviewPatternOnDeviceUseCase`: теперь возвращает поток состояний `PlaybackState` вместо кастомного `PreviewProgress`.
    *   `ExecuteRemoteHugCommandUseCase`: переведен на использование `DevicePlaybackEngine` для воспроизведения «удаленных объятий».
    *   `ClearCurrentDevicePatternUseCase`: теперь использует метод `engine.stop()` для очистки состояния устройства.

*   **Внедрение зависимостей**:
    *   В `SharedModules.kt` удалена регистрация `PatternPlaybackService`.
    *   Добавлен синглтон `DevicePlaybackEngine`, который внедряется во все связанные компоненты (сессии, объятия, паттерны).

*   **Очистка кода**:
    *   Удален `PatternPlaybackService.kt`.
    *   Логика компиляции таймлайнов и повторных попыток загрузки (`uploadPlanWithRetry`) инкапсулирована внутри реализации движка воспроизведения.
…gine` и обновление логики воспроизведения

В этом коммите произведена замена устаревшего сервиса `PatternPlaybackService` на универсальный движок `DevicePlaybackEngine`. Изменения затрагивают уровень внедрения зависимостей, обработку фоновых действий и логику презентации предпросмотра паттернов.

**Ключевые изменения:**

*   **Уровень домена и инфраструктуры (DI):**
    *   В `KoinBridgeModule` удален провайдер `PatternPlaybackService` и добавлен `DevicePlaybackEngine`.
    *   В `SharedModules.kt` очищены неиспользуемые отступы в конфигурации `DevicePlaybackEngine`.

*   **Интеграция с устройствами и фоновыми задачами:**
    *   В `AmuletForegroundService` обновлен метод `previewPattern`: удален неиспользуемый параметр `deviceId` и закомментированный код, теперь используется упрощенный вызов `previewPatternOnDeviceUseCase`.
    *   В `HugDevicePlayActionProcessor` (обработка действий «объятий») зависимость `PatternPlaybackService` заменена на `DevicePlaybackEngine`.
    *   Метод воспроизведения в процессоре переведен на использование `PlayableMedia.Preview`, а логика обработки специфичных BLE-ошибок (перевод в `AppError.Network` для ретраев) упрощена.

*   **Реализация `DevicePlaybackEngineImpl`:**
    *   Добавлен `Mutex` для обеспечения потокобезопасности методов `play` и `stop` (предотвращение одновременных операций управления устройством).
    *   Операции теперь выполняются внутри блока `withLock`.

*   **Уровень презентации (Pattern Preview):**
    *   В `PatternPreviewViewModel` и `PatternPreviewState` произведен переход от специфичного `PreviewProgress` к общему `PlaybackState`.
    *   Добавлено управление жизненным циклом джоба воспроизведения (`previewJob`), что позволяет корректно отменять предыдущие запросы при запуске нового предпросмотра.
    *   Обновлен интерфейс `PatternPreviewScreen`: логика отображения прогресса теперь опирается на состояния `PlaybackState` (COMPILING, UPLOADING, PLAYING, ERROR).
    *   Упрощен компонент индикатора загрузки: `LinearProgressIndicator` теперь работает в неопределенном режиме (без явного процента) во время загрузки.

*   **Очистка:**
    *   Удалены устаревшие комментарии и неиспользуемые импорты (включая `PatternPlaybackService`).
    *   Параметр `deviceId` удален из `PreviewPatternOnDeviceUseCase` (через вызовы в UI и сервисах), так как выбор устройства теперь подразумевается на уровне движка или текущего соединения.
…уска сервиса

В этом коммите произведена очистка неиспользуемых зависимостей в `CalendarViewModel` и оптимизирована логика запуска фоновой службы в `MainActivity`.

Ключевые изменения:

*   **Уровень представления (`CalendarViewModel`)**:
    *   Удалены неиспользуемые зависимости из конструктора: `DeletePracticeScheduleUseCase` и `PracticeSessionManager`.
    *   Очищены неиспользуемые импорты, связанные с управлением сессиями практик и расширениями времени.
*   **Уровень приложения (`MainActivity`)**:
    *   Упрощен запуск `AmuletForegroundService`. Удалена проверка версии SDK (`Build.VERSION_CODES.O`), теперь используется прямой вызов `startForegroundService`, что предполагает повышение минимальной поддерживаемой версии API или использование совместимого метода.
*   **Очистка кода**:
    *   Удалены неиспользуемые импорты моделей и сценариев использования в модуле функций практик.
…ground-сервиса практик

В этом коммите реализовано автоматическое завершение сеансов практик на уровне домена, улучшена стабильность работы foreground-сервиса и добавлена поддержка Deep Links для перехода к активным сессиям.

Ключевые изменения:

*   **Доменная логика (`PracticeSessionManagerImpl`)**:
    *   Логика автозавершения перенесена из ViewModel в `PracticeSessionManagerImpl`. Теперь сессия автоматически останавливается со статусом `completed = true`, когда прошедшее время достигает общей длительности.

*   **Foreground-сервис (`AmuletForegroundService`)**:
    *   Удален `AmuletControl` и механизм `Binder`. Взаимодействие с сервисом теперь полностью оркеструется через `PracticeForegroundController`.
    *   Оптимизировано управление ресурсами: в `PracticeForegroundController` реализовано пересоздание `CoroutineScope`, если предыдущий был отменен.
    *   Улучшена обработка уведомлений: добавлена принудительная очистка уведомлений при отсутствии активной сессии (`stopForeground` и `cancel`), чтобы предотвратить «зависание» UI.
    *   Реализован переход из уведомления в конкретную сессию практики через Deep Link вместо простого запуска приложения.

*   **Инфраструктура Android**:
    *   В `AndroidManifest.xml` добавлены Intent-фильтры для схем `amulet://practices/session` и `https://amulet.app/practices/session`, обеспечивающие навигацию по прямым ссылкам.

*   **Презентационный уровень (`PracticeSessionViewModel`)**:
    *   **Инверсия контроля запуска**: Метод `practiceForegroundLauncher.ensureServiceStarted()` теперь вызывается мгновенно при старте практики. Это защищает процесс от уничтожения ОС еще до начала выполнения тяжелых операций (BLE, загрузка паттернов).
    *   Удалена избыточная логика автозавершения (теперь обрабатывается в домене).
    *   Исправлена обработка ошибок при остановке сессии: ошибка `AppError.NotFound` теперь трактуется как успех (сессия уже остановлена).
    *   Обновлена логика отображения: при навигации назад сессия больше не останавливается принудительно, позволяя практике продолжаться в фоне.

*   **UI (`PracticeSessionRoute`)**:
    *   Удален автоматический вызов `Stop` при нажатии кнопки «Назад», что обеспечивает корректную работу фонового режима.
В этом коммите из модуля `feature:hugs` полностью удален функционал просмотра истории объятий. Это упрощает текущую реализацию главного экрана, фокусируясь на актуальных взаимодействиях и управлении парой.

Ключевые изменения включают в себя:

*   **Удаление компонентов истории**:
    *   Полностью удалены файлы презентационного слоя истории: `HugsHistoryContract.kt`, `HugsHistoryRoute.kt` и `HugsHistoryViewModel.kt`.
    *   Из навигации (`HugsNavigation.kt`) удалены маршрут `hugs/history`, метод расширения `navigateToHugsHistory` и соответствующий `composable` узел.

*   **Обновление главного экрана (`HugsRoute`)**:
    *   Из интерфейса удалена карточка быстрого действия «История» (`ActionCard`).
    *   Удален параметр `onOpenHistory` из функции `HugsRoute`.
    *   В `HugsHomeViewModel` количество отображаемых на главном экране объятий ограничено 15 (вместо 20).

*   **Очистка контрактов**:
    *   Из `HugsHomeIntent` удалено намерение `OpenHistory`.
    *   Из `HugsHomeEffect` удалено событие навигации `NavigateToHistory`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant