65 Commits

Author SHA1 Message Date
bf83336bbc WIP: MapScreen.kt changes 2026-04-19 10:00:06 +02:00
89ce2e1afa fix(manage): use account-scoped device sync and remove mock device source
Preserve Manage device state across resume while preventing cross-account cache leaks by tracking synced user IDs and clearing stale local device data on account changes. Replace the mock device remote data source with Apollo-backed API queries/mutations using me.locations so Manage only shows devices belonging to the authenticated user.

Made-with: Cursor
2026-04-07 18:04:42 +02:00
0a79ee5e04 Fix city selection vs dashboard; Map/Manage updates; workspace and API logging
Made-with: Cursor
2026-04-06 23:49:35 +02:00
34ad7e4af7 feat(sdk): AuthGoogleApp mutation and Google ID token auth without Firebase
Made-with: Cursor
2026-04-06 22:48:37 +02:00
9165d26b72 refactor(auth): token store, Apollo auth, and email UI
Update ApiTokenStore, AuthServiceImpl, and interceptor; adjust login/register screens, dashboard, chart, and Firebase auth tests.

Made-with: Cursor
2026-04-06 22:20:13 +02:00
d34b3bf70e feat(map): load device time series for map panel chart
Add LocationTimeSeries GraphQL query and DeviceTimeSeriesRepository.

Extend DevicePanelState with chart data/loading/offset; MapViewModel fetches via location _id and maps with DashboardChartMapper.

Wire MapScreen preview with sample chart data.

Made-with: Cursor
2026-04-06 22:20:04 +02:00
9cbc521a0d fix(city): persist full city list and re-emit dashboard context on re-selection
- Map cityList rows without coordinates; fall back en/ru/be for display names
- Replace local city cache on sync when opening city screen
- Use SharedFlow + prefs reads so re-selecting the same city (e.g. Minsk) notifies dashboard

Made-with: Cursor
2026-04-06 22:19:42 +02:00
3057d9c2d4 fix(map): clip chart sensor selector ripple to pill shape
Made-with: Cursor
2026-04-06 22:13:27 +02:00
ac334db940 Harden Google sign-in when backend auth fails
Sign out of Firebase and clear API and local profile if the GraphQL exchange or token save fails after Firebase Google sign-in, so the user is not left in a half-authenticated state. Rename the exchange helper to exchangeFirebaseIdTokenWithBackend for clarity.

Login: ignore duplicate Google taps while loading and disable the Google button during the flow. Credential Manager: treat GetCredentialInterruptedException as cancellation and rethrow CancellationException so coroutines cancel correctly.

Tests: assert signOut is invoked when the backend exchange fails.
Made-with: Cursor
2026-04-06 20:50:20 +02:00
200ce74cb5 Add email registration screen with AuthService integration
Introduce EmailRegisterScreen (Compose) with contract, validation, and
loading UX matching the email sign-in layout. Register submits via
AuthService.registerWithEmail; success navigates to Manage and clears
the login stack.

Email login Register action opens the new route instead of handling
registration on the same screen.

Made-with: Cursor
2026-04-06 19:55:32 +02:00
9869ad2476 feat(auth): email sign-in and register via GraphQL
Add loginLocal and register Apollo mutations, LocalEmailAuthStore for profile snapshot when not using Firebase, extend AuthService/FirebaseAuthService with session handoff vs Google, wire EmailLoginViewModel, refresh Manage on resume, and expand unit tests.

Made-with: Cursor
2026-04-06 19:30:31 +02:00
df4e6f9c56 feat(dashboard): city average GraphQL, metrics repository, and wiring
Adds CityAverage operations and DashboardMetricsRepository, extends CityService, updates dashboard contract/VM and chart mapping, refreshes schema, tweaks map screen and Apollo logging, and adds debug manifest.

Made-with: Cursor
2026-04-06 17:02:19 +02:00
35d23110d7 feat(map): add OSMDroid heatmap with legacy dust tiers
Port legacy Google Maps heatmap behavior: PM2.5-style buckets, tier colors, halos under markers. Draw halos in Overlay.draw with live projection so heat tracks during pan (no debounced bitmap). Radioactivity uses single green tier to match marker styling.

Made-with: Cursor
2026-03-24 00:21:00 +01:00
fc034ad520 fix(chart): clear tap marker when dataset changes
LaunchedEffect(data) resets marker state so stale selection is not shown after refresh or sensor switch.

Made-with: Cursor
2026-03-24 00:05:40 +01:00
24c5731c69 Add OSMDroid map marker clustering with gentler merge thresholds.
Group nearby markers into count bubbles; cluster tap zooms to member bounds.
Rebuild overlays on a debounced map listener so clusters track pan and zoom.
Add cluster bubble layout, strings, and pixel-distance clustering with a 48dp
base threshold scaled down when zoomed in so clustering stays less aggressive.

Made-with: Cursor
2026-03-24 00:01:16 +01:00
c05dd31e95 fix(dashboard): city chip as gradient-outline capsule
- Replace three vector segments with transparent pill + horizontal gradient border

- Size chip to city label, centered; add theme colors; remove unused drawables

Made-with: Cursor
2026-03-23 23:16:49 +01:00
49b9ab5617 fix(map): hide OSMDroid zoom buttons and lower location FAB padding
Made-with: Cursor
2026-03-23 22:59:29 +01:00
49318e87a5 fix(map): center osmdroid marker anchor on coordinates
Made-with: Cursor
2026-03-23 22:56:05 +01:00
ca3804195d chore(sdk): point GraphQL API to apitest.tartak.by
Made-with: Cursor
2026-03-23 22:53:08 +01:00
c29ba88fec feat: add city selector frame assets 2026-03-16 16:49:09 +01:00
fee67c35af feat: add AQI/RAD help dialog on map screen 2026-03-16 16:45:48 +01:00
3c41b0d487 feat: integrate city selection into dashboard, nav and settings 2026-03-16 16:45:33 +01:00
11a515b588 feat: implement city selection flow with auto-detect 2026-03-16 16:45:13 +01:00
88ebc14d24 feat: add location dependencies and permissions 2026-03-16 16:44:58 +01:00
0519936531 feat(device): add visibility/luftdata/narodmon settings, device model icons, SDK refactor
- Add SetDeviceVisibilityUseCase, SetLuftdataUseCase, SetNarodmonUseCase

- Introduce DeviceModel enum (Basic, Mobile, Solar, Radiation, Custom)

- Add device-type drawables (active/inactive icons for each model)

- Refactor Device SDK: repository, DAO, database, local/remote data sources

- Update DeviceSettingsScreen, ManageViewModel, theme colors

- Add/update string resources (default, ru, be)

Made-with: Cursor
2026-03-06 20:01:24 +01:00
7815f151f1 chore: ignore IDE-specific .idea files and stop tracking them
Made-with: Cursor
2026-03-05 22:05:36 +01:00
ce3bdd3d72 feat(map): device panel contract, view model, arrow and close icons
Made-with: Cursor
2026-03-05 21:38:07 +01:00
c2eb2df8c0 feat(map): dark status bar on map screen, white on dashboard/manage; faster map animations
Made-with: Cursor
2026-03-05 21:36:02 +01:00
863961405d fix(map): chart fill padding and dropdown selected border
- AirMQChart: add bottom padding so fill extends below line and thick line stays in bounds
- DeviceSensorDropdown: show border on selected item when dropdown is opened

Made-with: Cursor
2026-03-04 22:41:26 +01:00
e29e6ef498 feat(map): dropdown overlay above chart, sensor-based chart colors, supported sensors
Made-with: Cursor
2026-03-04 22:25:21 +01:00
8c54921661 feat(dashboard): add DashboardViewModel, metric gauge pager, chart integration
- Add DashboardScreenContract and DashboardViewModel with dummy data
- Extend MetricGauge with pager, page indicators, sensor config
- Integrate AirMQChart and city selector
- ManageScreen: scaffold contentWindowInsets for edge-to-edge header
- Add compose-foundation dependency for HorizontalPager

Made-with: Cursor
2026-03-04 20:28:53 +01:00
c9c7cedd55 fix(ui): status bar layout and icons for Map, Dashboard, Manage
- Dashboard: apply background before statusBarsPadding so gradient extends under status bar
- Map: add statusBarsPadding to layer selector so it no longer overlaps status bar
- NavGraph: set white status bar icons (isAppearanceLightStatusBars=false) on main tab screens

Made-with: Cursor
2026-03-04 20:25:06 +01:00
e59e5aa060 feat(device): implement Device feature with SSOT, offline support, and settings screen
- Add domain layer: Device, PendingMutation, DeviceRepository
- Add Room DB: DeviceEntity, PendingMutationEntity, DAOs, DeviceLocalDataSource
- Add mock DeviceRemoteDataSource and DeviceSubscriptionManager
- Implement DeviceRepositoryImpl with optimistic updates and mutation queue
- Add UseCases: GetMyDevices, Rename, SetLocation, SetDataSharing, TriggerFirmware
- Implement DeviceSettingsScreen with rename, location, data sharing, firmware
- Wire ManageScreen to GetMyDevicesUseCase and DeviceSubscriptionManager
- Update navigation to pass deviceId and show DeviceSettingsScreen
- Add Room 2.7.0-alpha11 and Room dependencies to SDK

Made-with: Cursor
2026-03-04 19:35:07 +01:00
ca5cf8c439 feat(metric): reimplement RoundedDiagram/RingDiagram in Compose
- Add MetricGauge, RingGauge, MetricGaugeRow composables
- Add MetricGaugeContract with SensorType enum and AQI color mapping
- Add AQI colors (SensorGreen, SensorYellow, etc.) to theme
- Copy ic_temperature, ic_humidity, ic_pressure drawables from legacy
- Integrate MetricGaugeRow into DashboardScreen
- Add 9 preview composables for portfolio readiness

Made-with: Cursor
2026-03-04 19:34:59 +01:00
00ad737e7e feat(chart): implement AirMQChart component with legacy design
- Add AirMQChart Composable with 4-segment background, rounded corners, fake piece
- Support single-line and multiline datasets with cubic Bezier curves
- Add value labels (max, mid, min) on left, last value on right
- Add bottom row with time labels and center label (e.g. sensor name)
- Include touch marker, empty state (threshold 3 points), multiline preview
- Add ChartConfig, ChartData, ChartDataGenerator, ChartUtils
- Add chart/sensor colors to Color.kt
- Integrate test chart in DashboardScreen, use in MapUiComponents device panel

Made-with: Cursor
2026-03-04 19:18:03 +01:00
b607d0198b feat(manage): rework Manage screen layout and device list
- Match device item design to reference (ic_chip, status chips, trailing icon)
- Add header (Your devices) and footer to device list
- CTA at bottom, centered 46% width, same style for Sign in/Add device
- Window background #FAFAFA, LegacyBackground on list area
- No spacing between device items, no horizontal margin on list
- Add DeviceItem.extra, ic_go_to_location drawable
- Replace personal data with User/user@example.com
- Strengthen app-recreation-core rule: path check before edits
- Restore real auth logic in ManageViewModel

Made-with: Cursor
2026-03-02 21:51:50 +01:00
9a80ce5dff feat(login): replace Facebook with email-password auth screen
- Remove Facebook provider from Login flow
- Add EmailLoginScreen with gradient background, email/password fields
- Add EmailLoginScreenContract and EmailLoginViewModel with stub logic
- Add navigation: Sign in with email -> EmailLoginScreen
- Use back arrow icon instead of back text
- Move header above email field, add Register button
- Update run command to launch app after install
- Add ic_arrow_back drawable, update strings

Made-with: Cursor
2026-03-02 20:38:09 +01:00
f4b6df10ac Fix Manage screen header size 2026-03-02 20:23:38 +01:00
c96a433307 Add new Cursor commands 2026-03-02 20:23:02 +01:00
31f723cbd6 Implement Google->Firebase->Backend auth flow
- Add authGoogleNew GraphQL mutation and token exchange in AuthServiceImpl
- Add ApiTokenStore and SharedPreferencesApiTokenStore for API token persistence
- Add ApolloAuthInterceptor to inject Bearer token on GraphQL requests
- Introduce FirebaseSessionManager for testable Firebase auth orchestration
- Update LoginViewModel to surface backend auth errors
- Add unit tests for Firebase failure, backend failure, and auth state

Made-with: Cursor
2026-03-02 20:19:54 +01:00
436e165679 Point SDK GraphQL to api-app and switch map markers query to getMarkers.
This aligns the app with the new backend endpoint/schema and keeps map marker mapping compatible with the new response shape.

Made-with: Cursor
2026-03-02 19:22:03 +01:00
8bf076697e Refine social auth UI and simplify manage auth state.
Extract Google sign-in into a dedicated manager with explicit cancel handling, update shared social button variants, and switch manage UI state from enum modes to a direct authorization flag.

Made-with: Cursor
2026-03-02 03:16:46 +01:00
28ad63fb4a Wire Firebase auth state into settings/logout and refresh Google sign-in config.
This updates the settings account section to show/logout based on authenticated user state, refines auth service naming, and aligns app signing/Firebase config changes needed for successful Google authentication.

Made-with: Cursor
2026-03-01 21:40:58 +01:00
91a9521f3e Implement Firebase Google sign-in with enum-based auth contracts.
Refactor AuthService to use AuthProvider and User, add Firebase-backed auth wiring for login/manage flows, and fix app-level Google services configuration so Credential Manager sign-in works reliably.

Made-with: Cursor
2026-03-01 21:15:09 +01:00
90792c601c Recreate legacy login screen in Compose.
Port the old sign-in UI and behavior (gradient, branded social buttons, policy footer, and continue-anonymous dialog) and add Login contract/ViewModel stubs while keeping unauthorized Manage-to-Login navigation intact.

Made-with: Cursor
2026-03-01 19:34:29 +01:00
7c00163304 Refine Compose manage UI parity and button behavior.
Apply legacy-accurate manage header/CTA styling, add reusable button icon support with previews, and include related map/navigation polish updates in this working tree.

Made-with: Cursor
2026-03-01 19:02:13 +01:00
9885162c4e Add firebase project 2026-03-01 18:39:56 +01:00
a2cbb181d5 Migrate legacy localized strings and remove runtime hardcoded UI text.
This copies old locale resources into the 2026 app, reuses legacy string keys where possible, and moves user-facing runtime text to string resources with missing entries added for all supported locales.

Made-with: Cursor
2026-03-01 15:07:26 +01:00
1823d0bf1b Port manage/settings flows to Compose and wire settings persistence.
Add contract-driven state/action/event view models for manage and settings, migrate settings UI toward legacy preference rows (with anonymous stub behavior), and back SettingsServiceImpl with SharedPreferences for real toggle/city storage.

Made-with: Cursor
2026-03-01 15:00:34 +01:00
c155a3cc2e Expose per-setting SettingsService getters/setters and wire map offline visibility to GraphQL.
This moves offline filtering to the API query path so map data respects settings at source instead of client-side post-filtering.

Made-with: Cursor
2026-03-01 00:28:43 +01:00