1026 lines
61 KiB
Markdown
1026 lines
61 KiB
Markdown
# Android Changelog
|
||
|
||
## 2026-03-08
|
||
### Step 1 - Build and app wiring
|
||
- Added Android project plugin configuration for Hilt and Kotlin serialization.
|
||
- Added dependency repositories and explicit app module include in settings.
|
||
- Added app dependencies for Retrofit/OkHttp, DataStore, coroutines, Hilt, and unit testing.
|
||
- Enabled INTERNET permission and registered MessengerApplication in manifest.
|
||
- Added MessengerApplication with HiltAndroidApp.
|
||
|
||
### Step 2 - Network/data core + DI
|
||
- Fixed DTO/Auth API serialization annotations and endpoint declarations for `/api/v1/auth/login`, `/api/v1/auth/refresh`, `/api/v1/auth/me`.
|
||
- Implemented DataStore-based token persistence with a corrected `getTokens()` read path.
|
||
- Added auth network stack: bearer interceptor, 401 authenticator with refresh flow and retry guard.
|
||
- Added clean-layer contracts and implementations: `domain/common`, `domain/auth`, `data/auth/repository`.
|
||
- Wired dependencies with Hilt modules for DataStore, OkHttp/Retrofit, and repository bindings.
|
||
|
||
### Step 3 - Minimal auth UI and navigation
|
||
- Replaced Phase 0 placeholder UI with Compose auth flow (`AuthViewModel` + login screen).
|
||
- Added loading/error states for login and startup session restore.
|
||
- Added navigation graph: `AuthGraph (login)` to placeholder `Chats` screen after successful auth.
|
||
- Implemented automatic session restore on app start using stored tokens.
|
||
|
||
### Step 4 - Unit tests
|
||
- Added `DataStoreTokenRepositoryTest` for token save/read and clear behavior.
|
||
- Added `NetworkAuthRepositoryTest` for login success path and 401 -> `InvalidCredentials` error mapping.
|
||
|
||
### Step 5 - Chat Room models and persistence core
|
||
- Added domain chat model (`ChatItem`) for chat list rendering concerns.
|
||
- Added Room entities: `chats`, `users_short` with sort-friendly indices.
|
||
- Added `ChatDao` with `observeChats()`, `upsertChats()`, and transactional `clearAndReplaceChats()`.
|
||
- Added `MessengerDatabase` and Hilt database wiring (`DatabaseModule`).
|
||
|
||
### Step 6 - Chat API and repository sync
|
||
- Added chat REST API client for `/api/v1/chats` and `/api/v1/chats/{chat_id}`.
|
||
- Added chat DTOs and remote/local mappers (`ChatReadDto -> ChatEntity/UserShortEntity -> ChatItem`).
|
||
- Implemented `NetworkChatRepository` with cache-first flow strategy (Room first, then server sync).
|
||
- Added chat domain contracts/use-cases (`ChatRepository`, observe/refresh use-cases).
|
||
- Wired chat API/repository via Hilt modules.
|
||
|
||
### Step 7 - Realtime manager and chat list updates
|
||
- Added a unified realtime manager abstraction and WebSocket implementation for `/api/v1/realtime/ws?token=...`.
|
||
- Implemented auto-reconnect with exponential backoff and max cap.
|
||
- Added realtime event parser for `receive_message`, `message_updated`, `message_deleted`, `chat_updated`, `chat_deleted`, `user_online`, `user_offline`.
|
||
- Added use-case level realtime event handling that updates Room and triggers repository refreshes when needed.
|
||
- Wired realtime manager into DI.
|
||
|
||
### Step 8 - Chat list UI and navigation
|
||
- Added Chat List screen with tabs (`All` / `Archived`), local search filter, pull-to-refresh, and state handling (loading/empty/error).
|
||
- Added chat row rendering for unread badge, mention badge (`@`), pinned/muted marks, and message preview by media type.
|
||
- Added private chat presence display (`online` / `last seen recently` fallback).
|
||
- Connected Chat List to ViewModel/use-cases with no business logic inside composables.
|
||
- Added chat click navigation to placeholder `ChatScreen(chatId)`.
|
||
|
||
### Step 9 - Tests and checklist updates
|
||
- Added unit test for chat cache-first sync strategy (`NetworkChatRepositoryTest`).
|
||
- Added unit test for realtime event parsing (`RealtimeEventParserTest`).
|
||
- Added DAO test (`ChatDaoTest`) using in-memory Room + Robolectric.
|
||
- Updated Android checklist status in `docs/android-checklist.md`.
|
||
|
||
### Step 10 - Build stabilization fixes
|
||
- Switched Android API base URL to `https://chat.daemonlord.ru/`.
|
||
- Added cleartext traffic flag in manifest for local/dev compatibility.
|
||
- Fixed Hilt dependency cycle by separating refresh `AuthApiService` with a dedicated qualifier.
|
||
- Added `CoroutineDispatcher` DI provider and qualifier for repositories.
|
||
- Fixed Material3 experimental API opt-in and removed deprecated `StateFlow.distinctUntilChanged()` usage.
|
||
|
||
### Step 11 - Sprint A / 1) Message Room + models
|
||
- Added message domain model (`MessageItem`) for chat screen rendering.
|
||
- Added Room entities `messages` and `message_attachments` with chat-history indexes.
|
||
- Added `MessageDao` with observe/pagination/upsert/delete APIs.
|
||
- Updated `MessengerDatabase` schema to include message tables and DAO.
|
||
- Added Hilt DI provider for `MessageDao`.
|
||
|
||
### Step 12 - Sprint A / 2) Message API + repository
|
||
- Added message REST API client for history/send/edit/delete endpoints.
|
||
- Added message DTOs and mappers (`MessageReadDto -> MessageEntity -> MessageItem`).
|
||
- Added `MessageRepository` contracts/use-cases for observe/sync/pagination/send/edit/delete.
|
||
- Implemented `NetworkMessageRepository` with cache-first observation and optimistic text send.
|
||
- Wired message API and repository into Hilt modules.
|
||
|
||
### Step 13 - Sprint A / 3) Message realtime integration
|
||
- Extended realtime event model/parser with message-focused events (`message_delivered`, `message_read`, `typing_start`, `typing_stop`) and richer message payload mapping.
|
||
- Updated unified realtime handler to write `receive_message`, `message_updated`, `message_deleted` into `messages` Room state.
|
||
- Added delivery/read status updates in Room for message status events.
|
||
- Kept chat list sync updates in the same manager/use-case pipeline for consistency.
|
||
|
||
### Step 14 - Sprint A / 4) Message UI core
|
||
- Replaced chat placeholder with a real message screen route + ViewModel.
|
||
- Added message list rendering with Telegram-like bubble alignment and status hints.
|
||
- Added input composer with send flow, reply/edit modes, and inline action cancellation.
|
||
- Added long-press actions (`reply`, `edit`, `delete`) for baseline message operations.
|
||
- Added manual "load older" pagination trigger and chat back navigation integration.
|
||
|
||
### Step 15 - Sprint A / 5) Message tests and docs
|
||
- Added unit tests for `NetworkMessageRepository` sync/send flows.
|
||
- Added DAO test for message scoped replace behavior in Room.
|
||
- Expanded realtime parser tests with rich `receive_message` mapping coverage.
|
||
- Updated `docs/android-checklist.md` for completed message-core items.
|
||
|
||
### Step 16 - Sprint B / 1-2) Media data layer + chat integration
|
||
- Added media API/DTO layer for upload URL and attachment creation.
|
||
- Added `MediaRepository` + `UploadAndAttachMediaUseCase` and network implementation with presigned PUT upload.
|
||
- Extended `MessageRepository` with media send flow (`sendMediaMessage`) and optimistic local update behavior.
|
||
- Wired media API/repository through Hilt modules.
|
||
- Integrated file picking and media sending into Android `ChatScreen`/`ChatViewModel` with upload state handling.
|
||
|
||
### Step 17 - Sprint B / media tests
|
||
- Added `NetworkMediaRepositoryTest` for successful upload+attach flow.
|
||
- Added error-path coverage for failed presigned upload handling.
|
||
|
||
## 2026-03-09
|
||
### Step 18 - Sprint P0 / 1) Message core completion
|
||
- Extended message API/data contracts with `messages/status`, `forward`, and reaction endpoints.
|
||
- Added message domain support for forwarded message metadata and attachment waveform payload.
|
||
- Implemented repository operations for delivery/read acknowledgements, forward, and reactions.
|
||
- Updated Chat ViewModel/UI with forward flow, reaction toggle, and edit/delete-for-all edge-case guards.
|
||
- Added automatic delivered/read acknowledgement for latest incoming message in active chat.
|
||
- Fixed outgoing message detection by resolving current user id from JWT `sub` claim.
|
||
|
||
### Step 19 - Sprint P0 / 2) Media UX after send
|
||
- Added media endpoint mapping for chat attachments (`GET /api/v1/media/chats/{chat_id}/attachments`).
|
||
- Extended Room message observation to include attachment relations via `MessageLocalModel`.
|
||
- Synced and persisted message attachments during message refresh/pagination and after media send.
|
||
- Extended message domain model with attachment list payload.
|
||
- Added message attachment rendering in Chat UI: inline image preview, minimal image viewer overlay, and basic audio play/pause control.
|
||
|
||
### Step 20 - Sprint P0 / 3) Roles/permissions baseline
|
||
- Extended chat data/domain models with `my_role` and added `observeChatById` stream in Room/repository.
|
||
- Added `ObserveChatUseCase` to expose per-chat permission state to message screen.
|
||
- Implemented channel send restrictions in `ChatViewModel`: sending/attach disabled for `member` role in `channel` chats.
|
||
- Added composer-level restriction hint in Chat UI to explain blocked actions.
|
||
|
||
### Step 21 - Sprint P0 / 4) Invite join flow (minimum)
|
||
- Added chat API contracts for invite actions: `POST /api/v1/chats/{chat_id}/invite-link` and `POST /api/v1/chats/join-by-invite`.
|
||
- Added domain model/use-cases for invite-link creation and join-by-invite.
|
||
- Extended chat repository with invite operations and local chat upsert on successful join.
|
||
- Added minimal Chat List UI flow for join-by-invite token input with loading/error handling and auto-open of joined chat.
|
||
|
||
### Step 22 - Sprint P0 / 5) Realtime stability and reconcile
|
||
- Added heartbeat in WebSocket manager (`ping` interval + `pong` timeout detection) with forced reconnect on stale link.
|
||
- Improved socket lifecycle hygiene by cancelling heartbeat on close/failure/disconnect paths.
|
||
- Added `connect` event mapping and centralized reconcile trigger in realtime handler.
|
||
- On realtime reconnect, chat repository now refreshes `all` and `archived` snapshots to reduce stale state after transient disconnects.
|
||
|
||
### Step 23 - Sprint P0 / 6) Auth hardening foundation
|
||
- Extended auth API/repository contracts with sessions management endpoints:
|
||
- `GET /api/v1/auth/sessions`
|
||
- `DELETE /api/v1/auth/sessions/{jti}`
|
||
- `DELETE /api/v1/auth/sessions`
|
||
- Added domain model and use-cases for listing/revoking sessions.
|
||
- Added unit coverage for session DTO -> domain mapping in `NetworkAuthRepositoryTest`.
|
||
|
||
### Step 24 - Sprint P0 / 7) Quality pass
|
||
- Added realtime parser unit coverage for `connect` event mapping.
|
||
- Extended message DAO tests with attachment relation verification.
|
||
- Added Android smoke and baseline document (`docs/android-smoke.md`) with test matrix and performance targets.
|
||
- Updated Android checklist quality section with initial performance baseline completion.
|
||
|
||
### Step 25 - UI safe insets fix
|
||
- Enabled edge-to-edge mode in `MainActivity` via `enableEdgeToEdge()`.
|
||
- Added safe area insets handling (`WindowInsets.safeDrawing`) for login, chat list, session-check and chat screens.
|
||
- Added bottom composer protection in chat screen with `navigationBarsPadding()` and `imePadding()`.
|
||
- Fixed UI overlap with status bar and navigation bar on modern Android devices.
|
||
|
||
### Step 26 - Core base / bulk forward foundation
|
||
- Added message API/data contracts for bulk forward (`POST /api/v1/messages/{message_id}/forward-bulk`).
|
||
- Extended `MessageRepository` with `forwardMessageBulk(...)`.
|
||
- Implemented bulk-forward flow in `NetworkMessageRepository` with Room/chat last-message updates.
|
||
- Added `ForwardMessageBulkUseCase` for future multi-select message actions.
|
||
- Updated message repository unit test fakes to cover new API surface.
|
||
|
||
### Step 27 - Core base / message action state machine
|
||
- Added reusable `MessageActionState` reducer with explicit selection modes (`NONE`, `SINGLE`, `MULTI`).
|
||
- Added action-intent contract for message operations (reply/edit/forward/delete/reaction/clear).
|
||
- Integrated `ChatViewModel` with reducer-backed selection logic while preserving current UI behavior.
|
||
- Added base ViewModel handlers for entering/toggling multi-select mode (`onEnterMultiSelect`, `onToggleMessageMultiSelection`, `onClearSelection`).
|
||
- Added unit tests for reducer transitions and available intents (`MessageActionStateTest`).
|
||
|
||
### Step 28 - Core base / Android multi-forward execution
|
||
- Switched chat forward state from single-message payload to `forwardingMessageIds` set.
|
||
- Extended `ChatViewModel` forward flow: multi-select now forwards multiple source messages in one action.
|
||
- Wired `ForwardMessageBulkUseCase` for multi-message forwarding (sequential safe execution with error short-circuit).
|
||
- Updated chat action bar and forward sheet labels for multi-selection count.
|
||
|
||
### Step 29 - Core base / multi-select delete execution
|
||
- Fixed multi-select delete behavior in `ChatViewModel`: `Delete` now applies to all selected messages, not only focused one.
|
||
- Added explicit guard for `Delete for all` in multi-select mode (single-message only).
|
||
|
||
### Step 30 - Core base / reply-forward preview data foundation
|
||
- Extended message DTO/Room/domain models with optional preview metadata:
|
||
- `replyPreviewText`, `replyPreviewSenderName`
|
||
- `forwardedFromDisplayName`
|
||
- sender profile fields from API payload (`senderDisplayName`, `senderUsername`, `senderAvatarUrl`)
|
||
- Added Room self-relation in `MessageLocalModel` to resolve reply preview fallback from referenced message.
|
||
- Updated message mappers and repository/realtime temporary entity creation for new model fields.
|
||
- Bumped Room schema version to `7`.
|
||
|
||
### Step 31 - Chat UI / reply-forward bubble blocks
|
||
- Added inline forwarded header rendering in message bubbles with display-name fallback.
|
||
- Added inline reply preview block in message bubbles (author + snippet) based on new preview fields/fallbacks.
|
||
- Updated Telegram UI batch-2 checklist items for reply-preview and forwarded header.
|
||
|
||
### Step 32 - Chat UI / pinned message bar
|
||
- Added `pinned_message_id` support in chat DTO/local/domain models and DAO selects.
|
||
- Extended `ChatViewModel` state with pinned message id + resolved pinned message object.
|
||
- Rendered pinned message bar under chat app bar with hide action.
|
||
- Updated Telegram UI batch-2 checklist item for pinned message block.
|
||
|
||
### Step 33 - Chat UI / top app bar restructuring
|
||
- Extended chat UI state with resolved chat header fields (`chatTitle`, `chatSubtitle`, `chatAvatarUrl`).
|
||
- Updated chat top app bar layout to Telegram-like structure: back, avatar, title, status, call action, menu action.
|
||
- Kept load-more behavior accessible via menu placeholder action button.
|
||
- Updated Telegram UI batch-2 checklist item for chat top app bar.
|
||
|
||
### Step 34 - Chat UI / composer restyling
|
||
- Reworked chat composer into rounded Telegram-like container with emoji slot, text input, attach button, and send/voice state button.
|
||
- Preserved send/upload state guards and existing insets handling (`navigationBarsPadding` + `imePadding`).
|
||
- Updated Telegram UI batch-2 checklist composer-related items.
|
||
|
||
### Step 35 - Chat UI / multi-select bars and overlays
|
||
- Split message selection UX into dedicated top selection bar (count/close/delete/edit/reactions) and bottom action bar (reply/forward).
|
||
- Enhanced selected bubble visual state with explicit selected marker text.
|
||
- Updated Telegram UI batch-2 checklist items for multi-select mode.
|
||
|
||
### Step 36 - Chat list / advanced states baseline
|
||
- Added chat-list local type filters (`All`, `People`, `Groups`, `Channels`) with new `ChatListFilter` UI state.
|
||
- Added archive statistics stream in `ChatListViewModel` and special archive top-row entry in `All` tab.
|
||
- Extended list preview formatting with media-type markers and retained unread/mention/pinned indicators.
|
||
- Updated Telegram UI checklists for chat-list advanced states (batch 2 and batch 3).
|
||
|
||
### Step 37 - Chat UI / wallpaper-aware readability
|
||
- Added gradient wallpaper-like chat background layer in `ChatScreen`.
|
||
- Kept pinned/composer/action surfaces on semi-transparent containers to preserve readability over wallpaper.
|
||
- Updated Telegram UI checklist items for wallpaper and overlay readability.
|
||
|
||
### Step 38 - Quality/docs / mapper fallback coverage
|
||
- Added `MessageMappersTest` to verify reply preview fallback resolution from Room self-relation (`reply_to_message_id`).
|
||
- Updated Android master checklist for completed chat list tabs/filters coverage.
|
||
|
||
### Step 39 - Android scope / remove calls UI
|
||
- Removed chat top-bar `Call` action from Android `ChatScreen`.
|
||
- Updated Android UI checklist wording to reflect chat header without calls support.
|
||
|
||
### Step 40 - Invite deep link flow (app links)
|
||
- Added Android App Links intent filter for `https://chat.daemonlord.ru/join...`.
|
||
- Added invite token extraction from incoming intents (`query token` and `/join/{token}` path formats).
|
||
- Wired deep link token into `MessengerNavHost -> ChatListRoute -> ChatListViewModel` auto-join flow.
|
||
- Removed manual `Invite token` input row from chat list screen.
|
||
|
||
### Step 41 - Chat UI / long-press action menu
|
||
- Added long-press message action card in `ChatScreen` with quick reactions.
|
||
- Added context actions from long-press: reply, edit, forward, delete, select, close.
|
||
- Added placeholder disabled pin action in the menu to keep action set consistent with Telegram-like flow.
|
||
- Updated Telegram UI batch-2 checklist items for long-press reactions and context menu.
|
||
|
||
### Step 42 - Chat list / row and FAB parity pass
|
||
- Updated chat list rows with avatar rendering, trailing message time, and richer right-side metadata layout.
|
||
- Kept unread/mention/pinned/muted indicators while aligning row structure closer to Telegram list pattern.
|
||
- Added floating compose FAB placeholder at bottom-right in chat list screen.
|
||
- Updated Telegram UI batch-2 checklist chat-list parity items.
|
||
|
||
### Step 43 - Chat list / floating bottom navigation shell
|
||
- Added floating rounded bottom navigation container on chat list screen.
|
||
- Added active tab visual state (Chats selected) with pill styling.
|
||
- Updated Telegram UI checklists for bottom-nav shell parity (batch 1 and batch 2).
|
||
|
||
### Step 44 - Chat UI / bubble density pass
|
||
- Updated message bubble shapes for incoming/outgoing messages to denser rounded Telegram-like contours.
|
||
- Kept bottom-right time + delivery state rendering in bubble footer after time formatting update.
|
||
- Updated Telegram UI batch-2 checklist item for message bubble parity.
|
||
|
||
### Step 45 - Chat UI / media bubble improvements
|
||
- Added richer video attachment card rendering in message bubbles.
|
||
- Added file-list style attachment rows (icon + filename + type/size metadata).
|
||
- Upgraded non-voice audio attachment player with play/pause, progress bar, and current/total duration labels.
|
||
- Updated Telegram UI batch-2 checklist media-bubble items.
|
||
|
||
### Step 46 - Media viewer / header and gallery navigation
|
||
- Upgraded chat image viewer to use global image gallery state (`index / total`) instead of a single URL.
|
||
- Added fullscreen viewer header with close, index, share placeholder, and delete placeholder actions.
|
||
- Added image navigation controls (`Prev`/`Next`) for gallery traversal.
|
||
- Updated Telegram UI batch-2 checklist for fullscreen media header support.
|
||
|
||
### Step 47 - Notifications foundation (FCM + channels + deep links)
|
||
- Added Firebase Messaging dependency and Android manifest wiring for `POST_NOTIFICATIONS`.
|
||
- Added notification channels (`messages`, `mentions`, `system`) with startup initialization in `MessengerApplication`.
|
||
- Added push service (`MessengerFirebaseMessagingService`) + payload parser + notification dispatcher.
|
||
- Added notification tap deep-link handling to open target chat from `MainActivity` via nav host.
|
||
- Added runtime notification permission request flow (Android 13+) in `MessengerNavHost`.
|
||
- Added parser unit test (`PushPayloadParserTest`).
|
||
|
||
### Step 48 - Foreground local notifications from realtime
|
||
- Added `ActiveChatTracker` to suppress local notifications for currently opened chat.
|
||
- Wired realtime receive-message handling to trigger local notification via `NotificationDispatcher` when chat is not active.
|
||
- Added chat title lookup helper in `ChatDao` for notification titles.
|
||
- Added explicit realtime stop in `ChatViewModel.onCleared()` to avoid stale collectors.
|
||
|
||
### Step 49 - Mention override for muted chats
|
||
- Extended realtime receive-message model/parsing with `isMention` flag support.
|
||
- Added muted-chat guard in realtime notification flow: muted chats stay silent unless message is a mention.
|
||
- Routed mention notifications to mentions channel/priority via `NotificationDispatcher`.
|
||
- Added parser unit test for mention-flag mapping.
|
||
|
||
### Step 50 - Notification settings storage (DataStore)
|
||
- Added domain notification settings models/repository contracts (global + per-chat override).
|
||
- Added `DataStoreNotificationSettingsRepository` with persistence for global flags and per-chat override mode.
|
||
- Added `ShouldShowMessageNotificationUseCase` and wired realtime notifications through it.
|
||
- Added unit tests for DataStore notification settings repository and notification visibility use case.
|
||
|
||
### Step 51 - Logout with full local cleanup
|
||
- Added `LogoutUseCase` with centralized sign-out flow: disconnect realtime, clear active chat, clear auth session, and clear local cached data.
|
||
- Added `SessionCleanupRepository` + `DefaultSessionCleanupRepository` to wipe Room tables and clear per-chat notification overrides.
|
||
- Added logout action in chat list UI and wired it to `AuthViewModel`, with automatic navigation back to login via auth state.
|
||
- Added unit tests for logout use case orchestration and notification override cleanup.
|
||
|
||
### Step 52 - Settings/Profile shell and logout relocation
|
||
- Added dedicated `Settings` and `Profile` routes/screens with mobile-safe insets and placeholder content.
|
||
- Removed direct logout action from chat list and moved logout action to `Settings`.
|
||
- Wired bottom navigation pills in chats to open `Settings` and `Profile`.
|
||
|
||
### Step 53 - Secure token storage (Keystore-backed)
|
||
- Added `EncryptedPrefsTokenRepository` backed by `EncryptedSharedPreferences` and Android `MasterKey` (Keystore).
|
||
- Switched DI token binding from DataStore token repository to encrypted shared preferences repository.
|
||
- Kept DataStore for non-token app settings and renamed preferences file to `messenger_preferences.preferences_pb`.
|
||
|
||
### Step 54 - Message interactions: tap menu vs long-press select
|
||
- Updated chat message gesture behavior to match Telegram pattern:
|
||
- tap opens contextual message menu with reactions/actions,
|
||
- long-press enters multi-select mode directly.
|
||
- Hid single-selection action bars while contextual menu is visible to avoid mixed UX states.
|
||
- Improved multi-select visual affordance with per-message selection indicator circles.
|
||
|
||
### Step 55 - Chat multi-select action cleanup
|
||
- Removed duplicate forward action in multi-select mode (`Forward selected`), leaving a single clear forward action button.
|
||
|
||
### Step 56 - Unified API error handling
|
||
- Added shared API error mapper (`ApiErrorMapper`) with mode-aware mapping (`DEFAULT`, `LOGIN`).
|
||
- Switched auth/chat/message/media repositories to a single `Throwable -> AppError` mapping source.
|
||
- Kept login-specific invalid-credentials mapping while standardizing unauthorized/server/network handling for other API calls.
|
||
|
||
### Step 57 - Offline-first message history reading
|
||
- Added paged local history reading path by introducing configurable message observe limit (`observeMessages(chatId, limit)`).
|
||
- Updated chat screen loading strategy to expand local Room-backed history first when loading older messages.
|
||
- Added network-failure fallback in message sync/load-more: if network is unavailable but local cache exists, chat remains readable without blocking error.
|
||
|
||
### Step 58 - Keep authenticated session when offline at app start
|
||
- Updated auth restore flow in `AuthViewModel`: network errors during session restore no longer force logout when local tokens exist.
|
||
- App now opens authenticated flow in offline mode instead of redirecting to login.
|
||
|
||
### Step 59 - Deferred message action queue (send/edit/delete)
|
||
- Added Room-backed pending action queue (`pending_message_actions`) for message operations that fail due to network issues.
|
||
- Implemented enqueue + optimistic behavior for `sendText`, `editMessage`, and `deleteMessage` on network failures.
|
||
- Added automatic pending-action flush on chat sync/load-more and before new message operations.
|
||
- Kept non-network server failures as immediate errors (no queueing), while allowing offline continuation.
|
||
|
||
### Step 60 - Media cache foundation (Coil + Exo cache)
|
||
- Added global Coil image loader cache policy in `MessengerApplication` (memory + disk cache).
|
||
- Added Media3 `SimpleCache` singleton module for media stream/file caching foundation.
|
||
- Added Media3/Coil core dependencies and configured cache sizes for mobile usage.
|
||
|
||
### Step 61 - Compose UI tests baseline
|
||
- Added instrumented Compose UI tests for login and chat list states.
|
||
- Added Android test dependencies for Compose test runner (`ui-test-junit4`) and test infra.
|
||
- Covered key visual states: auth error rendering, chat list loading state, and empty state.
|
||
|
||
### Step 62 - Android CI pipeline
|
||
- Added dedicated Android CI workflow for `main` branch and PRs.
|
||
- CI now runs Android build, unit tests, lint, and androidTest assemble.
|
||
- Added optional detekt execution step (auto-skipped when detekt task is not configured).
|
||
|
||
### Step 63 - Integration tests for auth/chat/realtime
|
||
- Kept repository-level integration coverage for auth/chat data flows (MockWebServer + in-memory storage).
|
||
- Added `RealtimePipelineIntegrationTest` to validate realtime event handling pipeline (`receive_message` -> Room state update).
|
||
- Consolidated quality checklist integration test coverage for auth/chat/realtime.
|
||
|
||
### Step 64 - Android release workflow
|
||
- Added dedicated release workflow (`.github/workflows/android-release.yml`) for `main` branch pushes.
|
||
- Adapted version extraction for Kotlin DSL (`android/app/build.gradle.kts`) and guarded release by existing git tag.
|
||
- Wired release build, git tag push, and Gitea release publication with APK artifact upload.
|
||
|
||
### Step 65 - Account and media parity foundation (checklist 1-15)
|
||
- Introduced `:core:common` module and moved base `AppError`/`AppResult` contracts out of `:app`.
|
||
- Added structured app logging (`Timber`) and crash reporting baseline (`Firebase Crashlytics`) with app startup wiring.
|
||
- Added API version header interceptor + build-time feature flags and DI provider.
|
||
- Added account network layer for auth/account management:
|
||
- verify email, password reset request/reset,
|
||
- sessions list + revoke one/all,
|
||
- 2FA setup/enable/disable + recovery status/regenerate,
|
||
- profile/privacy update and blocked users management.
|
||
- Added deep-link aware auth routes for `/verify-email` and `/reset-password`.
|
||
- Reworked Settings/Profile screens from placeholders to editable account management screens.
|
||
- Added avatar upload with center square crop (`1:1`) before upload.
|
||
- Upgraded message attachment rendering with in-bubble multi-image gallery and unified attachment context actions (open/copy/close).
|
||
|
||
### Step 66 - Voice recording controls + global audio focus
|
||
- Added microphone permission (`RECORD_AUDIO`) and in-chat voice recording flow based on press-and-hold gesture.
|
||
- Implemented Telegram-like gesture controls for voice button:
|
||
- hold to record,
|
||
- slide up to lock recording,
|
||
- slide left to cancel recording.
|
||
- Added minimum voice length validation (`>= 1s`) before sending.
|
||
- Integrated voice message sending via existing media upload path (`audio/mp4` attachment).
|
||
- Added process-wide audio focus coordinator to enforce single active audio source:
|
||
- attachment player pauses when another source starts,
|
||
- recording requests focus and stops competing playback.
|
||
|
||
### Step 67 - Group/channel management baseline in Chat List
|
||
- Extended chat API/repository layer with management operations:
|
||
- create group/channel,
|
||
- discover + join/leave chats,
|
||
- invite link create/regenerate,
|
||
- members/bans listing and admin actions (add/remove/ban/unban/promote/demote).
|
||
- Added domain models for discover/member/ban items and repository mappings.
|
||
- Added in-app management panel in `ChatListScreen` (FAB toggle) for:
|
||
- creating group/channel,
|
||
- joining discovered chats,
|
||
- loading chat members/bans by chat id,
|
||
- executing admin/member visibility actions from one place.
|
||
|
||
### Step 68 - Search, inline jump, theme toggle, accessibility pass
|
||
- Added global search baseline in chat list:
|
||
- users search (`/users/search`),
|
||
- messages search (`/messages/search`),
|
||
- chat discovery integration (`/chats/discover`).
|
||
- Added inline search in chat screen with jump navigation (prev/next) and automatic scroll to matched message.
|
||
- Added highlighted message state for active inline search result.
|
||
- Added theme switching controls in settings (Light/Dark/System) via `AppCompatDelegate`.
|
||
- Added accessibility refinements for key surfaces and controls:
|
||
- explicit content descriptions for avatars and tab-like controls,
|
||
- voice record button semantic label for TalkBack.
|
||
|
||
### Step 69 - Bugfix pass: voice recording, theme apply, profile avatar UX
|
||
- Fixed voice recording start on Android by switching `VoiceRecorder` to compatible `MediaRecorder()` initialization.
|
||
- Fixed microphone permission flow: record action now triggers runtime permission request reliably and auto-starts recording after grant.
|
||
- Fixed theme switching application by introducing app-level `MessengerTheme` and switching app manifest base theme to DayNight.
|
||
- Fixed profile screen usability after avatar upload:
|
||
- enabled vertical scrolling with safe insets/navigation padding,
|
||
- constrained avatar preview to a centered circular area instead of full-screen takeover.
|
||
|
||
### Step 70 - Chat interaction consistency: gestures + sheets/dialogs
|
||
- Reworked single-message actions to open in `ModalBottomSheet` (tap action menu) instead of inline action bars.
|
||
- Reworked forward target chooser to `ModalBottomSheet` for consistent overlay behavior across chat actions.
|
||
- Added destructive action confirmation via `AlertDialog` before delete actions.
|
||
- Reduced gesture conflicts by removing attachment-level long-press handlers that collided with message selection gestures.
|
||
- Improved voice hold gesture reliability by handling consumed pointer down events (`requireUnconsumed = false`).
|
||
|
||
### Step 71 - Voice playback waveform/speed + circle video playback
|
||
- Added voice-focused audio playback mode with waveform rendering in message bubbles.
|
||
- Added playback speed switch for voice messages (`1.0x -> 1.5x -> 2.0x`).
|
||
- Added view-only circle video renderer for `video_note` messages with looped playback.
|
||
- Kept regular audio/video attachment rendering for non-voice/non-circle media unchanged.
|
||
|
||
### Step 72 - Adaptive layout baseline (phone/tablet) + voice release fix
|
||
- Added tablet-aware max-width layout constraints across major screens (login, verify/reset auth, chats list, chat, profile, settings).
|
||
- Kept phone layout unchanged while centering content and limiting line width on larger displays.
|
||
- Fixed voice hold-to-send gesture reliability by removing pointer-input restarts during active recording, so release consistently triggers send path.
|
||
|
||
### Step 73 - Voice message send/playback bugfixes
|
||
- Fixed voice media type mapping in message repository: recorded files with `voice_*.m4a` are now sent as message type `voice` (not generic `audio`).
|
||
- Fixed audio replay behavior: when playback reaches the end, next play restarts from `0:00`.
|
||
- Improved duration display in audio/voice player by adding metadata fallback when `MediaPlayer` duration is not immediately available.
|
||
|
||
### Step 74 - UI references consolidation (Batch 4)
|
||
- Added full Telegram reference mapping checklist (`docs/android-ui-batch-4-checklist.md`) with screenshot-by-screenshot description.
|
||
- Added explicit icon policy: no emoji icons in production UI components, Material Icons/vector icons only.
|
||
- Updated UI checklist index with Batch 4 entry.
|
||
|
||
### Step 75 - Material Icons migration (Batch 1 start)
|
||
- Replaced symbol/emoji-based UI controls in chat surfaces with Material Icons:
|
||
- chat header/menu/search controls (`more`, `up/down`),
|
||
- image viewer actions (`close`, `forward`, `delete`),
|
||
- multi-select markers (`radio checked/unchecked`, `selected` check),
|
||
- attachment/media markers (`movie`, `attach file`).
|
||
- Replaced chat list management FAB glyph toggle (`+`/`×`) with Material `Add`/`Close` icons.
|
||
- Added `androidx.compose.material:material-icons-extended` dependency for consistent icon usage.
|
||
|
||
### Step 76 - Shared main tabs shell with scroll-aware visibility
|
||
- Moved `Chats / Contacts / Settings / Profile` bottom panel to a shared navigation shell (`AppNavGraph`) so it behaves as global page navigation.
|
||
- Added dedicated `Contacts` page route and wired it into main tabs.
|
||
- Removed local duplicated bottom panel from chat list screen.
|
||
- Implemented scroll-direction behavior for all 4 main pages:
|
||
- hide panel on downward scroll,
|
||
- show panel on upward scroll / at top.
|
||
|
||
### Step 77 - Main tabs bar UX/layout fix
|
||
- Replaced custom pill-row main bar with compact `NavigationBar` inside rounded container for stable 4-tab layout on small screens.
|
||
- Added bottom content paddings for `Chats/Contacts/Settings/Profile` pages so content is not obscured by the floating main bar.
|
||
- Raised chats management FAB offset to avoid overlap with the global bottom bar.
|
||
|
||
### Step 78 - Telegram-like bottom tabs visual tuning
|
||
- Tuned shared main bar visual style to better match Telegram references:
|
||
- rounded floating container with subtle elevation,
|
||
- unified selected/unselected item colors,
|
||
- stable 4-item navigation with icons + labels.
|
||
- Kept scroll-hide/show behavior and page-level navigation unchanged.
|
||
|
||
### Step 79 - Main pages app bars + safe-area pass
|
||
- Added top app bars for all 4 main pages (`Chats`, `Contacts`, `Settings`, `Profile`) to make them feel like proper standalone sections.
|
||
- Moved chats management toggle action into chats app bar.
|
||
- Kept safe-area handling and bottom insets consistent with shared floating tabs bar to avoid overlap.
|
||
|
||
### Step 80 - Top bar offset consistency fix
|
||
- Unified top bar alignment across `Chats`, `Contacts`, `Settings`, and `Profile`:
|
||
- removed extra outer paddings that shifted headers down/right on some pages,
|
||
- separated content padding from top app bar container.
|
||
- Result: consistent title baseline and horizontal alignment between main pages.
|
||
|
||
### Step 81 - Chats bottom gap fix when tabs bar hidden
|
||
- Fixed blank gap at the bottom of chats list when global tabs bar auto-hides on scroll.
|
||
- Chats screen bottom padding is now dynamic and applied only while tabs bar is visible.
|
||
|
||
### Step 82 - Chats list header closer to Telegram reference
|
||
- Removed `Archived` top tab from chats list UI.
|
||
- Added search action in top app bar and unified single search field with leading search icon.
|
||
- Kept archive as dedicated row inside chats list; opening archive now happens from that row and back navigation appears in app bar while archive is active.
|
||
|
||
### Step 83 - Chats header realtime connection status
|
||
- Added realtime connection state stream (`Disconnected/Connecting/Reconnecting/Connected`) to `RealtimeManager`.
|
||
- Wired websocket lifecycle into that state in `WsRealtimeManager`.
|
||
- Bound chats top bar title to realtime state:
|
||
- shows `Connecting...` while reconnect/initial connect is in progress,
|
||
- shows regular page title once connected.
|
||
|
||
### Step 84 - Chats list preview icon policy cleanup
|
||
- Updated chat last-message preview text to remove emoji prefixes.
|
||
- Switched media-type preview prefixes to plain text labels (`Photo`, `Video`, `Voice`, etc.) to match Material-icons-only UI policy.
|
||
|
||
### Step 85 - Unread counter fix for active/read chats
|
||
- Added `ChatDao.markChatRead(chatId)` to clear `unread_count` and `unread_mentions_count` in Room.
|
||
- Applied optimistic local unread reset on `markMessageRead(...)` in message repository.
|
||
- Fixed realtime unread logic: incoming messages in currently active chat no longer increment unread badge.
|
||
|
||
### Step 86 - Chats list visual pass toward Telegram reference
|
||
- Updated chats list row density: tighter vertical rhythm, larger avatar, stronger title hierarchy, cleaner secondary text.
|
||
- Restyled archive as dedicated list row with leading archive icon avatar, subtitle, and unread badge.
|
||
- Kept search in top app bar action and changed search field default to collapsed (opens via search icon).
|
||
- Returned message-type emoji markers in chat previews:
|
||
- `🖼` photo, `🎤` voice, `🎵` audio, `🎥` video, `⭕` circle video, `🔗` links.
|
||
|
||
### Step 87 - Chats list micro-typography and time formatting
|
||
- Refined chat row typography hierarchy to be closer to Telegram density:
|
||
- title/body/presence font scale aligned and single-line ellipsis for long values.
|
||
- Tightened unread/mention badge sizing and spacing for compact right-side metadata.
|
||
- Updated trailing time formatter:
|
||
- today: `HH:mm`,
|
||
- this week: localized short weekday,
|
||
- older: `dd.MM.yy`.
|
||
|
||
### Step 88 - Chats list interaction states (menu/select/search)
|
||
- Added default overflow menu (`⋮`) state in chats header with Telegram-like quick actions UI.
|
||
- Added long-press multi-select mode for chat rows with:
|
||
- top selection bar (`count`, action icons),
|
||
- dedicated overflow menu for selected chats.
|
||
- Added dedicated search-mode state in chats screen:
|
||
- search field + section chips (`Chats/Channels/Apps/Posts`),
|
||
- horizontal recent avatars strip,
|
||
- list filtered by active query.
|
||
|
||
### Step 89 - Chats actions wiring + duplicate menu fix
|
||
- Removed duplicated overflow action in chats top bar (single `⋮` remains in default mode).
|
||
- Wired selection actions to behavior:
|
||
- delete selected -> leave selected chats,
|
||
- archive selected -> switch to archived section,
|
||
- non-implemented bulk actions now show explicit user feedback.
|
||
- Wired default menu actions:
|
||
- create group/channel -> open management panel,
|
||
- saved -> open saved chat if present,
|
||
- unsupported items show clear feedback instead of silent no-op.
|
||
|
||
### Step 90 - Fullscreen chats search redesign (Telegram-like)
|
||
- Reworked chats search mode into a fullscreen flow:
|
||
- top rounded search field with inline clear button,
|
||
- horizontal category chips (`Chats`, `Channels`, `Apps`, `Posts`),
|
||
- dedicated recent avatars row for the active category.
|
||
- Added search-mode content states:
|
||
- empty query -> `Recent` list block (history-style chat rows),
|
||
- non-empty query -> local matches + `Global search` and `Messages` sections.
|
||
- Kept search action in chats top bar; while search mode is active, app bar switches to back-navigation + empty title (content drives the page).
|
||
|
||
### Step 91 - Search history/recent persistence + clear action
|
||
- Added `ChatSearchRepository` abstraction and `DataStoreChatSearchRepository` implementation.
|
||
- Persisted chats search metadata in `DataStore`:
|
||
- recent opened chats list,
|
||
- search history list (bounded).
|
||
- Wired chats fullscreen search to persisted data:
|
||
- green recent avatars strip now reads saved recent chats,
|
||
- red `Recent` list now reads saved history with fallback.
|
||
- Connected `Очистить` action to real history cleanup in `DataStore`.
|
||
- On opening a chat from search results/messages/history, the chat is now stored in recent/history.
|
||
|
||
### Step 92 - Search filter leak fix on exit
|
||
- Fixed chats search state leak: leaving fullscreen search now resets local/global query.
|
||
- Main chats list no longer stays filtered by previous search input after returning from search mode.
|
||
|
||
### Step 93 - Fullscreen search UX polish
|
||
- Added system back-handler for search mode with safe query reset.
|
||
- Improved fullscreen search result sections:
|
||
- `Показать больше / Свернуть` toggle for global users,
|
||
- `Показать больше / Свернуть` toggle for message results.
|
||
- Added explicit empty-state text when local/global/message search sections all have no results.
|
||
|
||
### Step 94 - Pinned-only drag markers in selection mode
|
||
- Updated chats multi-select row UI: drag markers are now shown only for pinned chats.
|
||
- Non-pinned chats no longer render reorder marker in selection mode.
|
||
|
||
### Step 95 - Selection badge on avatar (Telegram-like)
|
||
- Added explicit selection indicator directly on chat avatars in multi-select mode:
|
||
- selected chat -> colored circle with check icon,
|
||
- unselected chat -> empty outlined circle.
|
||
- This matches the reference behavior and makes selected rows easier to scan.
|
||
|
||
### Step 96 - Selection menu labels and behavior polish
|
||
- Updated multi-select top actions/menu to be closer to Telegram reference in wording.
|
||
- Added dynamic `Закрепить/Открепить` label in selection overflow based on selected chats pinned state.
|
||
- Kept non-supported actions explicit with user feedback (Toast), avoiding silent no-op behavior.
|
||
|
||
### Step 97 - Chats popup/select actions wired to backend API
|
||
- Extended Android chat data layer with missing parity endpoints:
|
||
- `archive/unarchive`
|
||
- `pin-chat/unpin-chat`
|
||
- `clear`
|
||
- `delete (for_all=false)`
|
||
- `chat notifications get/update`
|
||
- Added repository methods and `ViewModel` actions for those operations.
|
||
- Replaced chats multi-select UI stubs with real API calls:
|
||
- mute/unmute selected chats,
|
||
- archive/unarchive selected chats,
|
||
- pin/unpin selected chats,
|
||
- clear selected chats,
|
||
- delete selected chats for current user.
|
||
|
||
### Step 98 - Realtime sync fix for pin/archive updates
|
||
- Improved `chat_updated` handling in realtime flow:
|
||
- now refreshes both active and archived chats lists to sync user-scoped flags (`pinned`, `archived`) immediately.
|
||
- Added parser fallback for realtime chat events to support payloads with either `chat_id` or `id`.
|
||
|
||
### Step 99 - Saved chat API parity
|
||
- Added Android support for `GET /api/v1/chats/saved`.
|
||
- Wired chats overflow `Saved` action to real backend request (instead of local title heuristic).
|
||
- Saved chat is now upserted into local Room cache and opened via normal navigation flow.
|
||
|
||
### Step 100 - Android image compression before upload
|
||
- Added pre-upload image compression in Android media pipeline (`NetworkMediaRepository`).
|
||
- For non-GIF images:
|
||
- decode + resize with max side `1920`,
|
||
- re-encode as `image/jpeg` with quality `82`,
|
||
- keep original bytes if compression does not reduce payload size.
|
||
- Upload request and attachment metadata now use actual prepared payload (`fileName`, `fileType`, `fileSize`), matching web behavior.
|
||
|
||
### Step 101 - Chat title/profile API parity
|
||
- Added Android API integration for:
|
||
- `PATCH /api/v1/chats/{chat_id}/title`
|
||
- `PATCH /api/v1/chats/{chat_id}/profile`
|
||
- Extended `ChatRepository`/`NetworkChatRepository` with `updateChatTitle(...)` and `updateChatProfile(...)`.
|
||
- Wired these actions into the existing Chat Management panel:
|
||
- edit selected chat title,
|
||
- edit selected chat profile fields (title/description).
|
||
|
||
### Step 102 - Global search + message thread parity
|
||
- Added Android data-layer integration for unified backend global search:
|
||
- `GET /api/v1/search`
|
||
- new `SearchRepository` + `SearchApiService` returning `users/chats/messages`.
|
||
- Switched chats fullscreen search flow to use unified backend search instead of composed per-domain calls.
|
||
- Extended message data layer with:
|
||
- `GET /api/v1/messages/{message_id}/thread`
|
||
- `MessageRepository.getMessageThread(...)` for thread/replies usage in upcoming UI steps.
|
||
|
||
### Step 103 - Contacts API parity + real Contacts screen
|
||
- Added Android integration for contacts endpoints:
|
||
- `GET /api/v1/users/contacts`
|
||
- `POST /api/v1/users/{user_id}/contacts`
|
||
- `POST /api/v1/users/contacts/by-email`
|
||
- `DELETE /api/v1/users/{user_id}/contacts`
|
||
- Extended `AccountRepository` + `NetworkAccountRepository` with contacts methods.
|
||
- Replaced placeholder Contacts screen with real stateful flow (`ContactsViewModel`):
|
||
- load contacts from backend,
|
||
- user search + add contact,
|
||
- add contact by email,
|
||
- remove contact,
|
||
- loading/refresh/error/info states.
|
||
|
||
### Step 104 - Push token sync (Android + backend)
|
||
- Added backend push token lifecycle API and storage:
|
||
- `POST /api/v1/notifications/push-token`
|
||
- `DELETE /api/v1/notifications/push-token`
|
||
- new table `push_device_tokens` (+ Alembic migration `0027_push_device_tokens`).
|
||
- Added Android push token sync manager:
|
||
- registers FCM token on app start and after auth refresh/login,
|
||
- updates backend token on `FirebaseMessagingService.onNewToken`,
|
||
- unregisters token on logout.
|
||
- Added backend FCM delivery in Celery notification tasks:
|
||
- sends to registered user device tokens,
|
||
- auto-removes invalid/unregistered tokens,
|
||
- safe fallback logs when Firebase is not configured.
|
||
|
||
### Step 105 - Web Firebase push registration
|
||
- Added web-side Firebase Messaging bootstrap (env-driven, no hardcoded secrets):
|
||
- fetch web push token and register in backend via `/notifications/push-token`,
|
||
- unregister token on logout,
|
||
- handle foreground push payload via existing notification service worker.
|
||
- Added required env keys to `web/.env.example` and backend Firebase env keys to root `.env.example`.
|
||
|
||
### Step 106 - Unread counter stabilization in Chat screen
|
||
- Fixed read acknowledgement strategy in `ChatViewModel`:
|
||
- read status is now acknowledged by the latest visible message id in chat (not only latest incoming),
|
||
- delivery status still uses latest incoming message.
|
||
- This removes cases where unread badge reappears after chat list refresh because the previous read ack used an outdated incoming id.
|
||
|
||
### Step 107 - Read-on-visible + cross-device unread sync
|
||
- Implemented read acknowledgement from actual visible messages in `ChatScreen`:
|
||
- tracks visible `LazyColumn` rows and sends read up to max visible incoming message id.
|
||
- unread now drops as messages appear on screen while scrolling.
|
||
- Improved cross-device sync (web <-> android):
|
||
- `message_read` realtime event now parses `user_id` and `last_read_message_id`.
|
||
- on `message_read`, Android refreshes chat snapshot from backend to keep unread counters aligned across devices.
|
||
|
||
### Step 108 - Strict read boundary by visible incoming only
|
||
- Removed fallback read-pointer advancement in `ChatViewModel.acknowledgeLatestMessages(...)` that previously moved `lastReadMessageId` by latest loaded message id.
|
||
- Read pointer is now advanced only via `onVisibleIncomingMessageId(...)` from visible incoming rows in `ChatScreen`.
|
||
- This prevents read acknowledgements from overshooting beyond what user actually saw during refresh/recompose scenarios.
|
||
|
||
### Step 109 - Telegram-like Settings/Profile visual refresh
|
||
- Redesigned `SettingsScreen` to Telegram-inspired dark card layout:
|
||
- profile header card with avatar/name/email/username,
|
||
- grouped settings rows with material icons,
|
||
- appearance controls (Light/Dark/System),
|
||
- quick security/help sections and preserved logout/back actions.
|
||
- Redesigned `ProfileScreen` to Telegram-inspired structure:
|
||
- gradient hero header with centered avatar, status, and action buttons,
|
||
- primary profile info card,
|
||
- tab-like section (`Posts/Archived/Gifts`) with placeholder content,
|
||
- inline edit card (name/username/bio/avatar URL) with existing save/upload behavior preserved.
|
||
|
||
### Step 110 - Multi-account foundation (switch active account)
|
||
- Extended `TokenRepository` to support account list and active-account switching:
|
||
- observe/list stored accounts,
|
||
- get active account id,
|
||
- switch/remove account,
|
||
- clear all tokens.
|
||
- Reworked `EncryptedPrefsTokenRepository` storage model:
|
||
- stores tokens per `userId` and account metadata list in encrypted prefs,
|
||
- migrates legacy single-account keys on first run,
|
||
- preserves active account pointer.
|
||
- `NetworkAuthRepository` now upserts account metadata after auth/me calls.
|
||
- Added `Settings` UI account section:
|
||
- shows saved accounts,
|
||
- allows switch/remove,
|
||
- triggers auth recheck + chats reload on switch.
|
||
|
||
### Step 111 - Real Settings + persistent theme + add-account UX
|
||
- Implemented persistent app theme storage via DataStore (`ThemeRepository`) and applied theme mode on app start in `MainActivity`.
|
||
- Reworked `SettingsScreen` to contain only working settings and actions:
|
||
- multi-account list (`Switch`/`Remove`) + `Add account` dialog with email/password sign-in,
|
||
- appearance (`Light`/`Dark`/`System`) wired to persisted theme,
|
||
- notifications (`global` + `preview`) wired to `NotificationSettingsRepository`,
|
||
- privacy update, blocked users management, sessions revoke/revoke-all, 2FA controls.
|
||
- Updated `ProfileScreen` to follow current app theme colors instead of forced dark palette.
|
||
|
||
### Step 112 - Settings cleanup (privacy dropdowns + removed extra blocks)
|
||
- Replaced free-text privacy inputs with dropdown selectors (`everyone`, `contacts`, `nobody`) for:
|
||
- private messages,
|
||
- last seen,
|
||
- avatar visibility,
|
||
- group invites.
|
||
- Removed direct `block by user id` controls from Settings UI as requested.
|
||
- Removed extra bottom Settings actions (`Profile` row and `Back to chats` button) and kept categorized section layout.
|
||
|
||
### Step 113 - Auth flow redesign (email -> password/register -> 2FA) + startup no-flicker
|
||
- Added step-based auth domain/use-cases for:
|
||
- `GET /api/v1/auth/check-email`
|
||
- `POST /api/v1/auth/register`
|
||
- login with optional `otp_code` / `recovery_code`.
|
||
- Updated Android login UI to multi-step flow:
|
||
- step 1: email input,
|
||
- step 2: password for existing account or register form (`name`, `username`, `password`) for new account,
|
||
- step 3: 2FA OTP/recovery code when backend requires it.
|
||
- Improved login error mapping for 2FA-required responses, so app switches to OTP step instead of generic invalid-password message.
|
||
- Removed auth screen flash on startup:
|
||
- introduced dedicated `startup` route with session-check loader,
|
||
- delayed auth/chats navigation until session check is finished.
|
||
- Added safe fallback in `MainActivity` theme bootstrap to prevent crash if `ThemeRepository` injection is unexpectedly unavailable during startup.
|
||
|
||
### Step 114 - Multi-account switch sync fix (chats + realtime)
|
||
- Fixed account switch flow to fully rebind app data context:
|
||
- restart realtime socket on new active account token,
|
||
- force refresh chats for both `archived=false` and `archived=true` right after switch.
|
||
- Fixed navigation behavior on account switch to avoid noisy `popBackStack ... not found` and stale restored stack state.
|
||
|
||
### Step 115 - Settings UI restructured into Telegram-like folders
|
||
- Reworked Settings into a menu-first screen with Telegram-style grouped rows.
|
||
- Added per-item folder pages (subscreens) for:
|
||
- Account
|
||
- Chat settings
|
||
- Privacy
|
||
- Notifications
|
||
- Devices
|
||
- Data/Chat folders/Power/Language placeholders
|
||
- Kept theme logic intact and moved appearance controls into `Chat settings` folder.
|
||
|
||
### Step 116 - Profile cleanup (remove non-working extras)
|
||
- Removed non-functional profile tabs and placeholder blocks:
|
||
- `Posts`
|
||
- `Archived`
|
||
- `Gifts`
|
||
- Removed `Settings` hero button from profile header.
|
||
- Removed bottom `Back to chats` button from profile screen.
|
||
- Simplified profile layout so the editable profile form is the primary secondary section toggled by `Edit`.
|
||
- Updated `ProfileRoute` navigation contract to match the simplified screen API.
|
||
|
||
### Step 117 - Settings folders cleanup (remove back button action)
|
||
- Removed `Back to chats` button from all Settings folder pages.
|
||
- Simplified Settings navigation contract by removing unused `onBackToChats` parameter from:
|
||
- `SettingsRoute`
|
||
- `SettingsScreen`
|
||
- `SettingsFolderView`
|
||
- Updated `AppNavGraph` Settings destination call-site accordingly.
|
||
|
||
### Step 118 - Android push notifications grouped by chat
|
||
- Reworked `NotificationDispatcher` to aggregate incoming messages into one notification per chat:
|
||
- stable notification id per `chatId`,
|
||
- per-chat unread counter,
|
||
- multi-line inbox preview of recent messages.
|
||
- Added app-level summary notification that groups all active chat notifications.
|
||
- Added deduplication guard for repeated push deliveries of the same `messageId`.
|
||
- Added notification cleanup on chat open:
|
||
- when push-open intent targets a chat in `MainActivity`,
|
||
- when `ChatViewModel` enters a chat directly from app UI.
|
||
|
||
### Step 119 - Chat screen visual baseline (Telegram-like start)
|
||
- Reworked chat top bar:
|
||
- icon back button instead of text button,
|
||
- cleaner title/subtitle styling,
|
||
- dedicated search icon in top bar (inline search is now collapsible).
|
||
- Updated pinned message strip:
|
||
- cleaner card styling,
|
||
- close icon action instead of full text button.
|
||
- Updated composer baseline:
|
||
- icon-based emoji/attach/send/mic controls,
|
||
- cleaner container styling closer to Telegram-like bottom bar.
|
||
|
||
### Step 120 - Message bubble layout pass (Telegram-like geometry)
|
||
- Reworked `MessageBubble` structure and density:
|
||
- cleaner outgoing/incoming bubble geometry,
|
||
- improved max width and alignment behavior,
|
||
- tighter paddings and spacing for mobile density.
|
||
- Redesigned forwarded/reply blocks:
|
||
- compact forwarded caption styling,
|
||
- reply block with accent stripe and nested preview text.
|
||
- Improved message meta line:
|
||
- cleaner time + status line placement and contrast.
|
||
- Refined reactions and attachments rendering inside bubbles:
|
||
- chip-like reaction containers,
|
||
- rounded image/file/media surfaces closer to Telegram-like visual rhythm.
|
||
|
||
### Step 121 - Chat selection and message action UX cleanup
|
||
- Added Telegram-like multi-select top bar in chat:
|
||
- close selection,
|
||
- selected counter,
|
||
- quick forward/delete actions.
|
||
- Simplified tap action menu flow for single message:
|
||
- richer reaction row (`❤️ 👍 👎 🔥 🥰 👏 😁`),
|
||
- reply/edit/forward/delete actions kept in one sheet.
|
||
- Removed duplicate/conflicting selection controls between top and bottom action rows.
|
||
|
||
### Step 122 - Chat 3-dot menu + chat info media tabs shell
|
||
- Added chat header `3-dot` popup menu with Telegram-like actions:
|
||
- `Chat info`
|
||
- `Search`
|
||
- `Notifications`
|
||
- `Change wallpaper`
|
||
- `Clear history`
|
||
- Added `Chat info` bottom sheet with tabbed sections:
|
||
- `Media`
|
||
- `Files`
|
||
- `Links`
|
||
- `Voice`
|
||
- Implemented local tab content from current loaded chat messages/attachments to provide immediate media/files/links/voice overview.
|
||
|
||
### Step 123 - Chat info visual pass (Telegram-like density)
|
||
- Updated `Chat info` tabs to pill-style horizontal chips with tighter Telegram-like spacing.
|
||
- Improved tab content rendering:
|
||
- `Media` now uses a 3-column thumbnail grid.
|
||
- `Files / Links / Voice` use denser card rows with icon+meta layout.
|
||
- `Voice` rows now show a dedicated play affordance.
|
||
- Refined menu order in chat `3-dot` popup and kept actions consistent with current no-calls scope.
|
||
|
||
### Step 124 - Inline search close fix + message menu visual pass
|
||
- Fixed inline chat search UX:
|
||
- added explicit close button in the search row,
|
||
- closing search now also clears active query/filter without re-entering chat.
|
||
- Added automatic inline-search collapse when entering multi-select mode.
|
||
- Reworked message tap action sheet to Telegram-like list actions with icons and clearer destructive `Delete` row styling.
|
||
|
||
### Step 125 - Chat header/top strips visual refinement
|
||
- Refined chat header density and typography to be closer to Telegram-like proportions.
|
||
- Updated pinned strip visual:
|
||
- accent vertical marker,
|
||
- tighter spacing,
|
||
- cleaner title/content hierarchy.
|
||
- Added top mini audio strip under pinned area:
|
||
- shows latest audio/voice context from loaded chat,
|
||
- includes play affordance, speed badge, and dismiss action.
|
||
|
||
### Step 126 - Message bubble/composer micro-polish
|
||
- Updated message bubble sizing and density:
|
||
- reduced bubble width for cleaner conversation rhythm,
|
||
- tighter vertical spacing,
|
||
- text style adjusted for better readability.
|
||
- Refined bottom composer visuals:
|
||
- switched to Telegram-like rounded input container look,
|
||
- emoji/attach/send buttons now use circular tinted surfaces,
|
||
- text input moved to filled style with hidden indicator lines.
|
||
|
||
### Step 127 - Top audio strip behavior fix (playback-driven)
|
||
- Reworked top audio strip logic to be playback-driven instead of always-on:
|
||
- strip appears only when user starts audio/voice playback,
|
||
- strip switches to the currently playing file,
|
||
- strip auto-hides when playback stops.
|
||
- Added close (`X`) behavior that hides the strip and force-stops the currently playing source.
|
||
|
||
### Step 128 - Parity docs update: text formatting gap
|
||
- Synced Android parity documentation with web-core status:
|
||
- added explicit `Text formatting parity` gap to `docs/android-checklist.md`,
|
||
- added dedicated Android gap block in `docs/backend-web-android-parity.md` for formatting parity.
|
||
- Marked formatting parity as part of highest-priority Android parity block.
|
||
|
||
### Step 129 - Parity block (1/3/4/5/6): formatting, notifications inbox, resend verification, push sync
|
||
- Completed Android text formatting parity in chat:
|
||
- composer toolbar actions for `bold/italic/underline/strikethrough`,
|
||
- spoiler, inline code, code block, quote, link insertion,
|
||
- message bubble rich renderer for web-style markdown tokens and clickable links.
|
||
- Added server notifications inbox flow in account/settings:
|
||
- API wiring for `GET /api/v1/notifications`,
|
||
- domain mapping and recent-notifications UI section.
|
||
- Added resend verification support on Android:
|
||
- API wiring for `POST /api/v1/auth/resend-verification`,
|
||
- Verify Email screen action for resending link by email.
|
||
- Hardened push token lifecycle sync:
|
||
- token registration dedupe by `(userId, token)`,
|
||
- marker cleanup on logout,
|
||
- best-effort re-sync after account switch.
|
||
- Notification delivery polish (foundation):
|
||
- foreground notification body now respects preview setting and falls back to media-type labels when previews are disabled.
|
||
- Verified with successful `:app:compileDebugKotlin` and `:app:assembleDebug`.
|
||
|
||
### Step 130 - Chat UX pack: video viewer, emoji/GIF/sticker picker, day separators
|
||
- Added chat timeline day separators with Telegram-like chips:
|
||
- `Сегодня`, `Вчера`, or localized date labels.
|
||
- Added fullscreen video viewer:
|
||
- video attachments now open in a fullscreen overlay with close action.
|
||
- Added composer media picker sheet:
|
||
- tabs: `Эмодзи`, `GIF`, `Стикеры`,
|
||
- emoji insertion at cursor,
|
||
- remote GIF/sticker selection with download+send flow.
|
||
- Extended media type mapping in message send pipeline:
|
||
- GIFs now sent as `gif`,
|
||
- sticker-like payloads sent as `sticker` (filename/mime detection).
|
||
- Added missing fallback resource theme declarations (`themes.xml`) to stabilize clean debug assembly on local builds.
|
||
|
||
### Step 131 - Channel chat Telegram-like visual alignment
|
||
- Added channel-aware chat rendering path:
|
||
- `MessageUiState` now carries `chatType` from `ChatViewModel`,
|
||
- channel timeline bubbles are rendered as wider post-like cards (left-aligned feed style).
|
||
- Refined channel message status presentation:
|
||
- post cards now show cleaner timestamp-only footer instead of direct-message style checks.
|
||
- Added dedicated read-only channel bottom bar (for non owner/admin):
|
||
- compact Telegram-like controls with search + centered `Включить звук` action + notifications icon.
|
||
- Kept existing full composer for roles allowed to post in channels (owner/admin).
|
||
|
||
### Step 132 - Voice recording composer overlap fix
|
||
- Fixed composer overlap during voice recording:
|
||
- recording status/hint is now rendered in a dedicated top block inside composer,
|
||
- formatting toolbar is hidden while recording is active.
|
||
- Prevented controls collision for locked-recording actions:
|
||
- `Cancel/Send` now render on a separate row in locked state.
|
||
|
||
### Step 133 - Video/audio player controls upgrade
|
||
- Upgraded fullscreen video viewer controls:
|
||
- play/pause button,
|
||
- seek slider (scrubbing),
|
||
- current time / total duration labels.
|
||
- Upgraded attachment audio player behavior (voice + audio):
|
||
- added seek slider for manual rewind/fast-forward,
|
||
- unified speed toggle for both `voice` and `audio` playback.
|
||
|
||
### Step 134 - Hilt startup crash fix (`MessengerApplication_GeneratedInjector`)
|
||
- Fixed startup crash:
|
||
- `NoClassDefFoundError: MessengerApplication_GeneratedInjector`.
|
||
- Root cause observed in build pipeline:
|
||
- `MessengerApplication_GeneratedInjector.class` existed after `javac`,
|
||
- but was missing in `transformDebugClassesWithAsm/dirs` before dexing.
|
||
- Added Gradle backfill task for `debug/release` variants:
|
||
- copies `*Application_GeneratedInjector.class` from `intermediates/javac/.../classes`
|
||
into `intermediates/classes/.../transform...ClassesWithAsm/dirs` if missing,
|
||
- wired task as dependency of `dexBuilder<Variant>`.
|
||
|
||
### Step 135 - AppCompat launch crash fix (theme mismatch)
|
||
- Fixed `MainActivity` startup crash:
|
||
- `IllegalStateException: You need to use a Theme.AppCompat theme`.
|
||
- Root cause:
|
||
- `Theme.AppCompat.DayNight.NoActionBar` was accidentally overridden in app resources
|
||
with non-AppCompat parent (`Theme.DeviceDefault.NoActionBar`).
|
||
- Fix applied:
|
||
- introduced dedicated app theme `Theme.Messenger` with parent `Theme.AppCompat.DayNight.NoActionBar`,
|
||
- switched `AndroidManifest.xml` application theme to `@style/Theme.Messenger`.
|
||
|
||
### Step 136 - Message context menu dismiss selection fix
|
||
- Fixed chat bug after closing message context menu by tapping outside:
|
||
- selection state now clears on `ModalBottomSheet` dismiss,
|
||
- prevents stale single-selection action bar from appearing after menu close.
|
||
|
||
### Step 137 - Telegram-like message actions cleanup
|
||
- Removed legacy single-selection bottom action bar (`Close/Delete/Del for all/Edit`) in chat.
|
||
- Message actions are now driven by Telegram-like context UI:
|
||
- tap -> context sheet actions,
|
||
- long-press -> selection mode flow.
|
||
|
||
### Step 138 - Multi-select UX closer to Telegram
|
||
- Refined selection top bar:
|
||
- removed extra overflow/load action from selection mode,
|
||
- kept focused actions only: close, selected count, forward, delete.
|
||
- In `MULTI` selection mode, composer is now replaced with a compact bottom action row:
|
||
- `Reply` (enabled for single selected message),
|
||
- `Forward`.
|