Tags: yrkan/KPedal
Tags
Polish all DataType layouts, fix text truncation - v1.8.2
DataType layout improvements across all 19 Glance DataTypes:
SMALL layouts:
- Remove all labels to maximize value readability
- Bump primary font sizes for arm's-length visibility
- Split combined balance strings into separate ValueText elements
to prevent Glance maxLines=1 truncation ("49/..." bug)
SMALL_WIDE layouts:
- Remove redundant labels (BAL, TE, HR, SYM, GRADE, etc.) from 8 DataTypes
- Labels waste vertical space in 58-73sp usable height
- Keep only unit suffixes (w, rpm) where helpful
- Bump font sizes for consistency (18-20sp → 20-24sp)
LARGE layouts:
- Remove decorative name headers from 5 DataTypes (Climbing Mode,
Sprint Mode, HR Efficiency, Symmetry Index, Pedaling Score)
- Headers wasted a full row on names users already know from setup
- Move activity indicators inline (▲ with grade, ● with power, etc.)
- Bump primary metrics to 34-40sp, secondary to 24-28sp
NARROW layouts:
- Bump secondary values (3s/10s averages, TE/PS, balance) by 4-6sp
- Ensure readability at arm's length during rides
Other:
- Fix FullOverview SMALL balance truncation (single "49/51" ValueText
exceeded half-width cell, now split into 3 elements)
- Fix PowerBalance SMALL_WIDE separator padding ("|" with 8dp → "/" compact)
- Fix PS validation upper bound in SyncService (40 → 30)
- Bump version to 1.8.2 (versionCode 19)
Prepare for Hammerhead App Store, improve DataType layouts - v1.8.1 ## Hammerhead App Store Integration - Add karoo-app-manifest.json with app metadata for store listing - Add MANIFEST_URL meta-data to AndroidManifest.xml for auto-updates - Change APK output filename to stable kpedal.apk (enables latest release URL) - Add assets/icon.png (512x512) and icon.svg for store listing - Add screenshots/ folder with 10 app screenshots ## Full Overview DataType Improvements - Fix SMALL layout: balance text "48:52" was truncating to "..." - Split into separate L|R values with smaller fonts (12sp) - Add individual colors for left/right imbalance indication - Fix LARGE layout: values were too close to vertical dividers - Add 8dp padding between values and dividers - Align values toward divider with proper spacing ## Live DataType Improvements - Redesign Time In Zone section in LARGE layout - Replace simple status bar with professional segmented progress bar - Add ZoneSegmentedBar component showing proportional zone widths - Add ZoneChip component with colored dot + percentage - Show all three zones (optimal/attention/problem) with visual indicators ## New Glance Components - ZoneSegmentedBar: horizontal bar with colored segments for each zone - ZoneChip: colored indicator dot with percentage value ## Version Updates (1.8.0 → 1.8.1) - app/build.gradle.kts: versionCode 17→18, versionName 1.8.1 - karoo-app-manifest.json: latestVersion 1.8.1, latestVersionCode 18 - web/api/package.json, web/app/package.json: version 1.8.1 - All 17 locale files: updated version strings - AboutSection.svelte: Version 1.8.1
Migrate DataTypes to Glance, add 15 new layouts, fix sync reliability…
… - v1.8.0
SYNC RELIABILITY FIXES:
- Failed syncs (syncStatus=2) are now automatically retried on each sync attempt
- Added getRidesNeedingSync(), getDrillsNeedingSync(), getAchievementsNeedingSync()
DAO queries that include both PENDING (0) and FAILED (2) status items
- Added getFailedSyncCountFlow() for reactive UI updates showing failed count
- Added getNeedingSyncCountFlow() for total count of items needing sync
- Added resetFailedToPending() for manual retry functionality
- Fixed isApplyingCloudSettings flag getting stuck by using NonCancellable context
in finally block (prevents flag from remaining true if coroutine is cancelled)
- Added cloud settings validation with coerceIn() for balance targets and thresholds
- SyncState now includes failedCount field for UI feedback
- SettingsScreen shows failed count with problem color when sync has failed items
- Sync button retries all failed items organically (no separate retry button needed)
DATATYPE MIGRATION TO GLANCE:
- Migrated all 7 existing DataTypes from RemoteViews XML to Jetpack Glance
- GlanceDataType base class creates fresh RemoteViews on each compose() call
- This eliminates RemoteViews action accumulation that caused crashes after 10-15 min
- Old approach: single RemoteViews accumulated 900 updates × 25 actions = 22,500 actions
- New approach: fresh RemoteViews per update, max ~25 actions per instance
- Deleted old DataType classes: BalanceTrendDataType, EfficiencyDataType,
FullOverviewDataType, LiveDataType, PowerBalanceDataType, QuickGlanceDataType,
SingleBalanceDataType, TextSizeCalculator, AspectRatio
- Deleted all datatype_*.xml layout files (35 files)
- Deleted related drawable XMLs: balance_bar_progress, te_bar_progress, ps_bar_progress,
zone_optimal_bar, zone_attention_bar, zone_problem_bar, ic_check, ic_warning
NEW DATATYPES (15 new layouts, total now 22):
- Pedaling Score: Overall pedaling quality score 0-100
- Fatigue Indicator: Shows fatigue level based on metric trends over ride
- Cadence + Balance: RPM display with L/R balance
- Delta vs Average: Current metrics compared to ride average with +/- indicators
- Left Leg Focus: All metrics for left leg (balance %, TE, PS)
- Right Leg Focus: All metrics for right leg
- Climbing Mode: Grade, elevation gain, and power for climbs
- Sprint Mode: Large power display optimized for sprints and intervals
- Power Focus: Power as primary metric with pedaling quality secondary
- HR + Efficiency: Heart rate with TE/PS efficiency metrics
- Symmetry Index: Balance shown as symmetry percentage (100% = perfect 50/50)
- Compact Multi: Maximum pedaling info in minimum screen space
NEW GLANCE ARCHITECTURE:
- GlanceDataType.kt: Base class handling lifecycle, metrics collection, and rendering
- GlanceColors.kt: Theme colors (optimal/attention/problem) for Glance composables
- GlanceComponents.kt: Reusable UI components (labels, values, bars, indicators)
- Each DataType has dedicated Glance file (e.g., LiveGlance.kt, EfficiencyGlance.kt)
- Adaptive layouts based on ViewConfig.viewSize using when() expressions
- 1Hz update throttling to match Karoo SDK limits
UI IMPROVEMENTS:
- HomeScreen: Added score hero display with color-coded quality label
- HomeScreen: Added zone distribution bar showing time in optimal/attention/problem
- LayoutsScreen: Reorganized with categories (Core, Analysis, Focus, With Context)
- LayoutsScreen: Added preview cards for all 22 layouts
- LayoutScreens.kt: Detailed layout preview screens with size-adaptive demos
LOCALIZATION:
- Added settings_failed translation ("%d failed") in all 17 Android locales
- Added 15 new DataType name/description strings in all locales
- Added layout category strings (Core, Analysis, Focus, With Context)
- Added score label strings (Excellent, Great, Good, Improving, Needs Work)
- Updated layouts_count from "6 layouts" to "19 layouts"
- Updated version strings in all 16 web locales (app.version, landing.hero.version)
VERSION UPDATES:
- Android: versionCode 16 → 17, versionName 1.7.6 → 1.8.0
- Web API: 1.7.6 → 1.8.0
- Web App: 1.7.6 → 1.8.0
- extension_info.xml: Added 15 new DataType definitions
OTHER:
- LiveDataCollector: Added score field to accumulator state
- AccumulatorState: Added score field for checkpoint serialization
- AlertManager: Minor code cleanup
- MainActivity: Updated for new DataType registration
- KPedalExtension: Register all 22 GlanceDataType instances
Fix data field freezes and sync issues, bump to v1.7.5 Bug fixes: - Fix data fields freezing during rides (catch Throwable instead of Exception) - Properly rethrow CancellationException for clean coroutine cancellation - Fix sync staying blocked forever if ride save fails (use finally block) Affected files: - BaseDataType.kt: Catch Throwable in update loop - LiveDataType.kt: Same fix for its own update loop - RideStateMonitor.kt: Move notifyRideStateChanged to finally block
Add crash recovery checkpoints, update privacy policy - v1.7.4 Crash recovery: - Add checkpoint system to protect ride data from app crashes - Save checkpoint every 1 minute during rides - Auto-restore on app restart (silent, no dialog) - Checkpoints expire after 24 hours - Emergency save on service destroy New files: - RideCheckpointEntity, RideCheckpointDao (Room) - AccumulatorState, CheckpointDecider, RideCheckpointManager - CheckpointDeciderTest (23 unit tests) Database: - Migration v10 → v11 for ride_checkpoint table Privacy policy: - Add crash recovery checkpoints to local-only data section - Add retention period (until ride ends or 24 hours) - Update last modified date to January 3, 2026 - Translations for all 17 languages
Add sync on app launch with testable decision logic - v1.7.3 Sync improvements: - Add syncOnAppLaunch() triggered when user opens app - Add SyncOnLaunchDecider: pure logic class for testable sync decisions - Conditions checked in priority: login → network → recording → cooldown → pending - 5-minute cooldown prevents excessive syncs on app switches - Syncs pending rides, drills, and achievements Testing: - Add SyncOnLaunchDeciderTest with 24 unit tests - Tests cover all decision paths, cooldowns, edge cases, priority order Documentation: - Add sync decision flow diagram to README - Document cooldown periods and pending data detection - Update sync triggers table with conditions
Auto-sync on network restore, bump to v1.7.2 Sync improvements: - Add NetworkCallback to auto-sync when network becomes available after offline ride - Add 60s cooldown between network-triggered syncs - Block sync during active rides (isRecording flag) - Add notifyRideStateChanged() for ride state tracking Documentation: - Add detailed ride sync flow diagram to README - Document sync triggers, offline scenario, error handling - Update CLAUDE.md with NetworkCallback gotcha Other: - Fix ChallengeTest.kt for i18n (nameRes instead of name) - Update hono 4.11.0 → 4.11.3 - Update @cloudflare/workers-types to 4.20260101.0
Fix data fields freezing during rides - v1.7.1 - Move try-catch inside update loop in BaseDataType and LiveDataType - Previously, a single exception in updateViews() or emitter.updateView() would kill the entire polling loop, freezing the data field permanently - Now errors are logged but the loop continues, preventing freeze - Affects all 7 DataTypes: PowerBalance, SingleBalance, FullOverview, QuickGlance, BalanceTrend, Efficiency, Live
RTL support, localization fixes, DataType translations - v1.7.0 RTL Support: - Add RTL layout direction for Hebrew and Arabic - Add LocaleHelper.isRtl() check - Apply CompositionLocalProvider for RTL in MainActivity Date Localization: - Fix dates showing in system locale instead of app locale - Use LocaleHelper.getCurrentLocale() in all date formatters - Update 8 screens: Dashboard, Home, RideDetail, History, Achievements, DrillHistory, Settings, Analytics DataType Translations: - Add getString() helper to BaseDataType for programmatic localization - Update all 7 DataTypes to use getString() for labels - Fix RemoteViews labels not translating in Karoo data fields
PreviousNext