Commit Graph

217 Commits

Author SHA1 Message Date
Davide Ferrari
bcec8b1a28 fix: show green steering wheel icon when driving
The status icon in the dashboard was showing a grey power button when the
car was in 'driving' state. Now it properly shows a green steering wheel
icon, consistent with the driving state.

Changes:
- Added isDriving state check
- Include driving in isAwake states for green tint
- Show SteeringWheel icon instead of PowerSettingsNew when driving
- Use localized 'driving' string for tooltip
2026-01-19 11:22:31 +01:00
Davide Ferrari
ab3e883c03 docs: add multi-language feature to README 2026-01-19 10:45:56 +01:00
Davide Ferrari
75d14500b8 chore: release v0.11.0 v0.11.0 2026-01-19 10:44:29 +01:00
Davide Ferrari
fd17a2f615 docs: improve release skill instructions 2026-01-19 10:43:40 +01:00
Davide Ferrari
37389a83a6 feat: add Claude Code skills for common tasks
- check-api: Query Teslamate API to inspect JSON response format
- release: Bump version, update changelog, tag and push
- translate: Add strings to all 4 locale files
- new-screen: Scaffold a new Compose screen

Also adds .env.example for API URL configuration and fixes
.gitignore to allow .claude/skills/release/ directory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:24:18 +01:00
Davide Ferrari
4203962ce7 ci: add changelog to Google Play uploads
Use whatsNewDirectory parameter to send fastlane changelogs
to Google Play for both alpha and production tracks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:19:19 +01:00
Davide Ferrari
e78cc5e582 fix: hide charger section and charts for DC charging sessions (#73)
Fixes #65

Contributed by @MARMdeveloper - this PR applies their changes from #66 with conflicts resolved.
2026-01-19 10:09:12 +01:00
Davide Ferrari
76a8ed84a3 fix: translation fixes and power icon green when charging
- Add translated strings for 'Charging' and 'Online' states
- Power icon now green when charging (vehicle is awake)
- Fix Italian: Locked='Chiusa', Unlocked='Aperta'
- Fix Spanish: Plugged in='Enchufado'
- Fix Catalan: Plugged in='Endollat'

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 09:38:45 +01:00
Davide Ferrari
ec72e13839 fix: show total battery consumed instead of average per drive (#71)
The battery percentage in daily mileage cards now shows the sum of
battery consumed across all drives in a day, rather than the average
per drive. This is more intuitive for users and correctly shows
values over 100% for long journeys with multiple drives.

Also removed the Ø (average) prefix from the battery stat chips
since this is now a total value.
2026-01-18 22:56:14 +01:00
Davide Ferrari
205ad10ddd style: add spacing between status icons and sleep duration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:49:07 +01:00
Davide Ferrari
ca25ec5e94 feat: show sleep duration and bedtime icon when car is asleep (#70)
* feat: show sleep duration and bedtime icon when car is asleep

- Show bedtime/moon icon instead of power icon when asleep
- Display duration since car went to sleep (XXm or XXh YYm format)
- Parse state_since ISO timestamp to calculate duration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: remove icon from sleep duration label

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: show sleep start time in tooltip

Tooltip now shows 'Asleep since HH:mm' when car is asleep.
Added translations for EN and CA.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: show date in sleep tooltip for older timestamps

- Today: 'Asleep since HH:mm'
- Yesterday: 'Asleep since yesterday HH:mm'
- Older: 'Asleep since DD/MM HH:mm'

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:34:34 +01:00
Davide Ferrari
20e5226062 feat: improve dashboard status indicators with chips and new icons (#69)
* feat: improve dashboard status indicators with chips and new icons

- Add StatusChip composable for pill-style status indicators
- Use distinct icons for temperatures: car icon (inside), sun icon (outside)
- Add Driving status with DriveEta icon when vehicle is driving
- Add red sentry mode dot next to lock indicator when active
- Add i18n strings for driving, sentry_mode_active, inside_temp, outside_temp

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: simplify status indicators to icon-only with tooltips

- Replace chip-style indicators with simple icons
- Add tooltips on tap for all status icons
- Power icon: green when online, grey otherwise
- Lock icon: grey when locked, light red when unlocked
- Sentry mode: red dot shown when active
- Plug icon: grey, shown when plugged in
- Temperatures: "Ext:" and "Int:" labels with thermometer
- Int label and value bold when climate is on

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: make status icon tooltips show on tap instead of long-press

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: make Int temperature green when climate is active

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add climate status tooltip to temperature indicators

Tapping on either Ext or Int temperature now shows tooltip
indicating whether climate is active or inactive.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 20:52:12 +01:00
Davide Ferrari
6afc5bd328 docs: improve layout 2026-01-18 19:08:50 +01:00
Davide Ferrari
968ce3b304 docs: add Buy Me a Coffee badge to README
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 19:06:39 +01:00
Davide Ferrari
903e352687 feat: Add internationalization (i18n) support (#67)
* feat(i18n): add localization support for DashboardScreen

- Set up localization infrastructure with values-it, values-es, values-ca folders
- Extract all hardcoded strings from DashboardScreen to strings.xml
- Add Italian, Spanish, and Catalan translations
- Include contextual comments for translators

Supported languages: English (default), Italian, Spanish, Catalan

* feat(i18n): add localization for SettingsScreen

- Extract all hardcoded strings from SettingsScreen
- Add Italian, Spanish, and Catalan translations
- Include contextual comments for server settings, display settings,
  and advanced options

* feat(i18n): add localization for DrivesScreen

- Extract all hardcoded strings from DrivesScreen
- Add localized filter labels for date and distance filters
- Add Italian, Spanish, and Catalan translations for:
  - Screen title and navigation
  - Summary card labels
  - Drive stat labels
  - Chart titles (drives/time/distance/speed per day/week/month)
  - Filter chip labels

* feat(i18n): add localization for DriveDetailScreen

- Extract all hardcoded strings from DriveDetailScreen
- Add Italian, Spanish, and Catalan translations for:
  - Screen title and navigation
  - Route header (from/to, started/ended)
  - Stats section titles and labels
  - Chart titles (speed/power/battery/elevation profiles)

* feat(i18n): localize ChargesScreen strings

Extract and translate all user-facing strings from ChargesScreen:
- Screen title and section headers
- Summary card labels (Total Sessions, Total Energy, Total Cost, etc.)
- Charge item stat labels (Added, Duration, Cost, Battery)
- Empty state message
- Chart titles for energy/cost/charges per day/week/month
- Filter labels using helper functions for DateFilter and ChargeTypeFilter

Translations provided for Italian (it), Spanish (es), and Catalan (ca).

* feat(i18n): localize ChargeDetailScreen strings

Extract and translate all user-facing strings from ChargeDetailScreen:
- Screen title and header labels (Location, Started, Ended)
- Stats section titles (Energy, Battery, Power, Charger, Temperature, Cost)
- Stats labels (voltage/current max/min/avg, efficiency, etc.)
- Chart titles (Power Profile, Voltage Profile, Current Profile, Battery Level)
- Map marker title
- AC/DC badge text

Translations provided for Italian (it), Spanish (es), and Catalan (ca).

* feat(i18n): localize BatteryScreen strings

Extract and translate all user-facing strings from BatteryScreen:
- Screen titles (Battery Health, Battery Detail)
- Capacity section (Usable new/now, Rated)
- Degradation section (Estimated degradation, Loss kWh/%)
- Range section (Max Range new/now, Range loss)
- Current charge section
- Range information section (Estimated, Rated, Ideal ranges)
- Estimated total capacity section
- Info dialog titles and messages with explanatory content
- Common dialog button text (Got it)

Translations provided for Italian (it), Spanish (es), and Catalan (ca).

* feat(i18n): localize StatsScreen

- Add strings for stats title, sync messages, progress indicators
- Localize drives overview and charges overview sections
- Localize all record labels (longest drive, top speed, etc.)
- Add category names (Drives, Battery, Weather & Altitude, Distances)
- Localize temperature extremes and AC/DC ratio cards
- Add dialog strings for sync logs, gap records, range records
- Add translations for Italian, Spanish, and Catalan

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(i18n): localize MileageScreen

- Add strings for mileage title, chart titles (by year/month/day)
- Localize empty states (no data, no data for year)
- Add summary labels (Total, Avg/Year, Avg/Month, # of drives)
- Localize info dialog explaining average per year calculation
- Add "Recent trips" and "Drives" section headers
- Localize all "View details" content descriptions
- Add translations for Italian, Spanish, and Catalan

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(i18n): localize SoftwareVersionsScreen

- Add strings for software title, overview card labels
- Localize date filter labels (Last 6 months, Last year, All time)
- Add update history header and empty state message
- Localize version card labels (Current version, Installed, Days, Duration)
- Add strings for longest installed badge
- Localize chart title and format strings
- Add translations for Italian, Spanish, and Catalan

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(i18n): localize common components and weather card

- Add fullscreen/exit fullscreen content descriptions
- Localize WeatherAlongTheWayCard title, loading, and empty states
- Localize weather table headers (Time, Distance, Weather)
- Localize weather condition descriptions (Clear sky, Partly cloudy, etc.)
- Localize distance markers (Start, End)
- Add translations for Italian, Spanish, and Catalan

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add localization instructions to DEVELOPMENT.md

- Document supported languages (English, Italian, Spanish, Catalan)
- Add string naming conventions (snake_case)
- Explain how to add new strings with context comments
- Document format strings with placeholders
- Add instructions for adding new languages
- Include testing tips for translations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(i18n): enable per-app language selection (Android 13+)

- Add locale_config.xml declaring supported languages (en, it, es, ca)
- Reference locale config in AndroidManifest.xml
- Users can now change app language without changing system language

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(i18n): keep AC/DC untranslated in all languages

Technical terms AC (Alternating Current) and DC (Direct Current) are
universally understood and should not be translated to CA/CC.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* ci: add lint check for hardcoded strings

- Configure Android Lint to treat HardcodedText and SetTextI18n as errors
- Add CI workflow that runs lint on every push/PR to main
- Build job depends on lint passing
- Upload lint report as artifact on failure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add localization rules to CLAUDE.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* ci: combine lint and build into single job

Lint requires compilation anyway, so running them in one job allows
Gradle to reuse artifacts and is more efficient than two separate jobs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: increase JVM heap to prevent OOM in CI

- Increase Gradle daemon heap from 2GB to 4GB
- Add HeapDumpOnOutOfMemoryError for debugging
- Set test JVM max heap to 1GB

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 19:03:30 +01:00
MARMdeveloper
754360c4a5 Ajuste del número de columnas en vistas de detalle (#63)
* Set variable n. of columns in the detail views depending on screen size
2026-01-18 16:46:51 +01:00
Davide Ferrari
eb6ebdaa91 ci: change Play Store upload from internal to alpha (closed testing) track
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 12:55:13 +01:00
Davide Ferrari
bd68a9be6d ci: split Play Store upload into internal and production tracks
- Internal testing track: always uploads when secrets are configured
- Production track: only uploads when PLAY_STORE_PRODUCTION_ENABLED var is 'true'

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
v0.10.0
2026-01-17 12:06:23 +01:00
Davide Ferrari
8c60ded4dc chore: release v0.10.0
- Fullscreen mode for line charts
- Weather Along the Way in Drive details
- Optimized chart rendering with LTTB downsampling
- Improved chart labels (time and value axes)
- Filter and scroll state persistence fixes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 11:17:02 +01:00
Davide Ferrari
025f4dae4d feat: add fullscreen mode for line charts in Drive and Charge details (#61)
* feat: add fullscreen mode for line charts in Drive and Charge details

- Add FullscreenLineChart component with fullscreen icon in lower-right corner
- Tap icon to expand chart to fullscreen in landscape orientation
- Add back arrow button in top-left corner to exit fullscreen
- Chart automatically scales to fill available screen space
- Lock screen to landscape mode while in fullscreen

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: improve fullscreen chart experience

- Hide system bars (status bar, navigation) for better fullscreen
- Force dialog window to MATCH_PARENT dimensions
- Restore portrait mode and system bars when exiting fullscreen

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 10:50:51 +01:00
Davide Ferrari
857b7df431 build: include native debug symbols in release bundle 2026-01-16 16:49:20 +01:00
Davide Ferrari
1689682ad3 docs: add F-Droid badge to README (#60) 2026-01-16 16:12:54 +01:00
Davide Ferrari
88bdc2764e ci: fix secrets check and add AAB to artifacts 2026-01-16 13:06:43 +01:00
Davide Ferrari
90296b8f7b ci: add Google Play Store publishing to release workflow 2026-01-16 12:39:51 +01:00
Davide Ferrari
b7866f2ce4 docs: improve Play Store full description 2026-01-16 11:46:56 +01:00
Davide Ferrari
2ef4dbf784 docs: add privacy policy for Google Play submission 2026-01-16 11:25:45 +01:00
Davide Ferrari
6f09e1b00a docs: fix changelog links for v0.9.4
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 11:02:24 +01:00
Davide Ferrari
2a50ea7f94 perf(charts): optimize line charts with LTTB downsampling for smooth scrolling (#59)
* perf(charts): optimize line charts with LTTB downsampling for smooth scrolling

Long trips (>100km) and charging sessions could have hundreds or thousands
of data points, causing scroll stutter when rendering charts.

Changes:
- Add OptimizedLineChart component with LTTB (Largest Triangle Three Buckets)
  downsampling algorithm
- Reduce data points to max 150 while preserving visual shape
- Use Path-based drawing instead of individual line segments
- Cache computed values with remember() to prevent recalculation during scroll
- Support tap-to-show-tooltip functionality
- Support time labels on X-axis for charge detail charts

Both DriveDetailScreen and ChargeDetailScreen now use the optimized component.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(charts): add proper axis labels following chart guidelines

Apply chart guidelines from CLAUDE.md:

Y-axis labels:
- Show 4 labels at: 1st quarter (25%), half (50%), 3rd quarter (75%), end (100%)
- Skip the minimum (0%) label at top

X-axis time labels:
- Show 5 labels at: start (0%), 1st quarter (25%), half (50%), 3rd quarter (75%), end (100%)
- Added time label extraction for DriveDetailScreen charts
- Updated ChargeDetailScreen to use 5 labels instead of 4

Both screens now follow the standardized chart guidelines for consistent UX.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 11:01:52 +01:00
Davide Ferrari
2a6c5a6c78 fix(drives): preserve filters and scroll position on navigation (#58)
Fixes issue where date/distance filters and scroll position were reset
when navigating back from drive details:

- Move date filter state from composable to ViewModel
- Add scroll position tracking in ViewModel
- Only apply default 7-day filter on first initialization
- Restore scroll position when returning to drives list

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 09:50:17 +01:00
Davide Ferrari
83ab18ea3f feat(drives): add Weather Along the Way to drive details (#57)
* feat(drives): add Weather Along the Way to drive details

Shows historical weather conditions along the drive route using the
Open-Meteo API. Weather point frequency adapts to drive length:
- Under 10 km: destination only
- Under 30 km: start and end
- Under 150 km: every 25 km
- Over 150 km: every 35 km

Displays time, distance, weather icon, and temperature in a table.
Weather conditions: Clear, Partly Cloudy, Fog, Drizzle, Rain, Snow,
Thunderstorm.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(weather): show "End" label for last weather point

- Last weather point now displays "End" instead of distance
- Intermediate points show distance in km or miles based on user setting
- First point shows "Start" as before

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(weather): move icon to right-most position in weather column

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 09:32:18 +01:00
Davide Ferrari
a6bd609269 feat(settings): add secondary server URL with fallback and reorganize settings UI (#56)
* feat(settings): add secondary server URL with fallback and reorganize settings UI

- Add optional secondary server URL for fallback when primary is unreachable
- Implement automatic fallback logic for network-level errors (timeout, connection refused, DNS failure)
- Reorganize Settings screen with collapsible sections:
  - "Advanced network settings" (collapsed): secondary URL, API token, certificate toggle
  - "Display Settings": currency, Teslamate base URL
  - "Extra settings" (collapsed): show short drives toggle, force resync button
- Update TeslamateApiFactory to cache multiple API instances for both servers
- Update all tests for new settings structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(settings): test both primary and secondary servers in connection test

- Update TestResult to show individual results for each server
- Test Connection button now tests both servers when secondary is configured
- UI shows both server results with clear labels and status
- Add new tests for dual-server connection testing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 21:38:41 +01:00
Davide Ferrari
0b65c0f3c8 feat: use dark blue color for map route path (#54)
* feat: use dark blue color for map route path

Change the route path color from the theme primary color (grey) to a
dark blue color (0xFF2962FF) for better visibility on map tiles.

This addresses the feedback from Discussion #53 where the current
light grey route color was hard to see on the map.

The new color is similar to Tesla's navigator blue and provides much
better contrast against the OpenStreetMap tiles.

Closes: #53

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: use car palette accent color for map route path

Use the car's palette accent color for the route path instead of the
theme's primary color (grey). This ensures the route color matches
the car:
- Blue car → blue route
- Red car → red route
- White car → warm accent route
- etc.

The original code incorrectly used MaterialTheme.colorScheme.primary
(a generic grey) instead of the car-specific palette.accent color.

Addresses: Discussion #53

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 13:17:30 +01:00
Davide Ferrari
fe5e2dfee5 Merge branch 'main' of github.com:vide/matedroid v0.9.4 2026-01-14 09:31:58 +01:00
Davide Ferrari
b1e59baf0c fix(stats): show driving days count when filtering by year (#55)
* build: add make targets for release APK build and install

* fix(stats): show driving days count when filtering by year

The "Driving Days" stat in Stats for Nerds was showing "Null" when
filtering by a specific year because the value was explicitly set to
null in the repository.

Changes:
- Add countDrivingDaysInRange() query to DriveSummaryDao
- Use it in StatsRepository for year-filtered stats
- Add null-safe display in StatsScreen UI (defensive)

Fixes #52

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: lower minSdk to API 28 (Android 9)

The minSdk was unnecessarily bumped to 29 for SQLite window functions,
but those were never actually used - the driving streak calculation
is done in Kotlin instead.

All SQL queries use only julianday() and DATE() functions which are
available on all SQLite versions. The foreground service code already
has proper fallbacks for pre-Android 10 devices.

This restores support for Android 9 devices.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: release v0.9.4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 09:31:46 +01:00
Davide Ferrari
79958eec8c build: add make targets for release APK build and install 2026-01-13 13:59:18 +01:00
Davide Ferrari
d748c50f12 chore: release v0.9.3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
v0.9.3
2026-01-13 08:28:30 +01:00
Davide Ferrari
2c145d6ab4 fix(settings): Force Full Resync now properly clears all cached data (#51)
The Force Full Resync button was only resetting sync state flags without
actually deleting cached drives, charges, and aggregates. This caused
the sync to only retry unprocessed items rather than fetching everything
fresh from the API.

Changes:
- Add AggregateDao to SyncManager for clearing aggregates
- Add fullResetSync() method that deletes all cached data:
  - drives_summary
  - charges_summary
  - drive_detail_aggregates
  - charge_detail_aggregates
- Update forceResync() to call fullResetSync() instead of resetSync()
- Add warning icon and red "DELETE" text to confirmation dialog

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 08:27:46 +01:00
Davide Ferrari
baa4875d59 chore: release v0.9.2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
v0.9.2
2026-01-13 07:32:59 +01:00
Davide Ferrari
96d67e9cb9 fix(dashboard): don't double-convert tire pressure when unit is PSI (#49)
TeslamateAPI returns pressure already in the user's preferred unit.
Remove incorrect bar→PSI conversion that caused 42 PSI to display as 610 PSI.

Fixes #46
2026-01-13 07:32:12 +01:00
Davide Ferrari
70ae969d0c fix(stats,dashboard): scale UI with system font size (#48)
- Stats: Record cards height now scales with fontScale to prevent vertical text clipping
- Stats: Added TextOverflow.Ellipsis for horizontal overflow fallback
- Dashboard: Elevation label no longer wraps unit to next line

Fixes #47
v0.9.1
2026-01-12 21:48:13 +01:00
Davide Ferrari
8d3eaba273 chore: release v0.9.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
v0.9.0
2026-01-11 21:50:01 +01:00
Davide Ferrari
0021c06e40 fix(stats): move Most Distance Day to Distances, add gap record dialog (#45)
- Move "Most Distance Day" record from Drives to Distances category
- Make gap records (Longest w/o Charging, Longest w/o Driving) tappable
- Add GapRecordDialog showing duration and start/end dates

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 21:48:51 +01:00
Davide Ferrari
a80433d00d feat(stats): add new records and categorized swipeable UI (#44)
* feat(stats): add new records and categorized swipeable UI

- Add new records: longest gap without charging, longest gap without
  driving, longest driving streak, biggest battery gain, biggest
  battery drain
- Organize records into 4 swipeable categories: Drives, Battery,
  Weather & Altitude, Distances
- Add horizontal pager with emoji+label indicators
- Compute driving streak in Kotlin (Room doesn't support window
  functions in CTEs)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(stats): fixed page height with 6 records per page constraint

- Each page now displays exactly 6 record slots (3 rows × 2 columns)
- Categories with more than 6 records are split into multiple pages
- Added page indicator dots for multi-page categories
- Added RECORDS_PER_PAGE constant with comment documenting the hard
  constraint for future updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(stats): enforce fixed row height for consistent page size

- Set RECORD_CARD_HEIGHT = 72.dp for each row
- Each row now has fixed height regardless of content
- Empty placeholder boxes fill the same space as cards
- Prevents page resizing when swiping between categories

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(stats): remove redundant category title from record pages

The swipe indicator already shows current category, no need for title

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: update changelog with swipeable record categories

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 21:38:33 +01:00
Davide Ferrari
5a2e3df4ae feat(stats): add "Longest Range" record (max distance between charges) (#41)
* chore: bump minSdk from API 26 to API 29

This enables SQLite window functions (LAG, LEAD, etc.) for efficient
record calculations without requiring sync pre-computation.

Android 10 (API 29) was released in September 2019 and covers 95%+
of active Android devices as of 2026.

* feat(stats): add SQL query for max distance between charges

Uses SQLite LAG window function to efficiently find the maximum
distance traveled between consecutive charges. Includes both
all-time and date-range variants for year filtering support.

* feat(stats): add MaxDistanceBetweenChargesRecord domain model

Add new record type to QuickStats for tracking the maximum distance
driven between two consecutive charging sessions.

* feat(stats): integrate max distance between charges in repository

Wire up the new DAO query to QuickStats for both all-time and
year-filtered views. No sync required - data is computed instantly
from the existing charges summary table.

* feat(stats): display max distance between charges in Records UI

Add 'Longest Range' record showing the maximum distance traveled
between two consecutive charges. Displays with battery emoji and
date range, tapping navigates to the ending charge detail.

* feat(stats): add SQL query for max distance between charges

Uses a self-join with correlated subquery to efficiently find the
maximum distance traveled between consecutive charges. Includes both
all-time and date-range variants for year filtering support.

* fix(stats): use sum of drives instead of odometer diff for longest range

The odometer difference between charges can include unlogged drives
(e.g., when TeslaMate was down). Now we sum actual logged drives
between charges, which gives accurate results even with data gaps.

* feat(stats): add popup dialog for longest range record details

When tapping the 'Longest Range' record, show a dialog with:
- Total distance and date range summary
- Scrollable list of all drives that make up the record
- Each drive is tappable to navigate to drive details

This provides full context about what drove the record instead
of just navigating to a single charge.

* docs: simplify changelog entries for users
2026-01-11 18:37:46 +01:00
Davide Ferrari
c6b1fec3e3 fix(stats): use configured currency instead of hardcoded EUR (#37)
Stats for Nerds now displays costs in the user's configured currency
instead of always showing EUR. This affects:
- Total Cost in Charges Overview
- Avg Cost/kWh in Charges Overview
- Most Expensive charge record
- Priciest/kWh charge record

Cherry-picked from hotfix/0.8.3 (v0.8.3)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:45:15 +01:00
Davide Ferrari
2ba225873c feat(dashboard): add charging glow effect around car image (#39)
* feat(dashboard): add charging glow effect around car image

When the car is charging, a glowing effect now appears around the car
image on the dashboard. The glow:
- Follows the exact shape of the car (extracted from PNG alpha channel)
- Uses the palette accent color matching the car's exterior
- Has a 70px blur radius for a soft, attractive effect
- Only appears when actively charging

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(dashboard): add breathing glow animation when charging

The car image now displays a breathing glow effect when the vehicle
is charging:
- Glow pulses smoothly in opacity (30% to 90%) with sine easing
- Color shifts subtly from accent color toward AC/DC charging color
- AC charging: shifts toward green (StatusSuccess)
- DC charging: shifts toward orange (StatusWarning)
- 2 second animation cycle
- Glow follows the exact shape of the car using alpha channel extraction

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add breathing glow effect to changelog

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:31:11 +01:00
Davide Ferrari
de068b90c4 feat(drives): add top speed histogram chart (#35)
* feat(drives): add top speed histogram chart

Add a fourth swipeable chart to the Drives view showing maximum speed
per day/week/month. The speed is displayed in km/h or mph depending
on the user's measurement system preference.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: update changelog with filter and chart improvements

- Charges AC/DC filter now applies to summary card and charts
- Drives distance filter now applies to summary card and charts
- Drives now has a fourth chart showing Top Speed per period

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:25:12 +01:00
Davide Ferrari
2cbef9d887 feat(drives): apply distance filter to summary card and charts (#34)
The distance filter (Commute/Day trip/Road trip) now affects all
components in the Drives view:
- Summary card shows totals for filtered distance category only
- Histogram charts display data for filtered distance category only
- Drive list continues to show filtered results

This provides a consistent view when analyzing specific trip types.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:12:50 +01:00
Davide Ferrari
ebff335976 feat(charges): apply AC/DC filter to summary card and charts (#33)
The AC/DC filter now affects all components in the Charges view:
- Summary card shows totals for filtered charge type only
- Histogram charts display data for filtered charge type only
- Charge list continues to show filtered results

This provides a consistent view when analyzing AC-only or DC-only
charging sessions.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:05:47 +01:00
Davide Ferrari
9c5cb99636 feat(charges,drives): add swipeable charts for multiple metrics (#32)
* feat(charges): add swipeable charts for energy, cost, and count

Add HorizontalPager with three swipeable chart views:
- Energy per Day/Week/Month (existing)
- Cost per Day/Week/Month (new)
- Number of Charges per Day/Week/Month (new)

Charts are grouped by the same time granularity based on the selected
date filter. Page indicator dots below the chart show current position.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(drives): add swipeable charts for count, time, and distance

Add HorizontalPager with three swipeable chart views:
- Number of Drives per Day/Week/Month (existing)
- Time Spent Driving per Day/Week/Month (new)
- Distance Travelled per Day/Week/Month (new)

Charts are grouped by the same time granularity based on the selected
date filter. Distance chart respects metric/imperial unit setting.
Page indicator dots below the chart show current position.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(drives): rename time chart to 'Driving time per...'

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:48:03 +01:00