recommendedCrossSection now satisfies two criteria and takes whichever
demands more copper: the voltage-drop budget, and an ampacity at least
as high as the fuse protecting the circuit (ABYC E-11: the OCP rating
must not exceed the conductor's ampacity). Ampacity comes from ABYC
E-11 Table 6A for AWG and ISO 13297 Table A1 for mm², both 105 °C.
Before this, a 40 A load over 0.5 m was sized 1.5 mm² / AWG 16 next to
a 50 A fuse: a cable the fuse can never protect. Long runs stay
voltage-drop driven and unchanged.
The drop budget is now stored per system (3 / 5 / 10 %) and editable in
the system editor, with a global default in Settings that the
standalone calculator uses and new systems inherit.
Cross-sections are derived, never entered by the user, so LoadCableSync
re-derives them when a system opens and when its budget changes.
Library loads are computed instead of being stored as a 1.0 mm²
placeholder. LoadConfigurationStatus therefore reports only what the
user can actually fix: missing length or current.
Also removes the dead cable.pro.* strings and folds three copies of the
mm²-to-AWG conversion into ElectricalCalculations.nearestAWG.
Title, short description, localised full descriptions and the 1.8.0
release notes for en-US, de-DE, es-ES, fr-FR and nl-NL, ready for
`fastlane supply`. The service account key stays out of the repo.
Cold starts ran unoptimised: no profileinstaller dependency and no
profile in the bundle, so ART interpreted Compose on first launch
(class verification measured at 128 bytecodes/s in an emulator ANR).
Add the androidx.baselineprofile producer module with an AOSP managed
device, a generator covering startup plus the four detail tabs, and
commit the generated baseline and startup profiles.
android/gradle/wrapper only held the properties file, so the project
could not be built from the command line at all. Generate the wrapper
for the pinned 8.11.1 distribution and ignore the .kotlin scratch dir.
QLPreviewController only renders its share, print and open-in actions
when it is inside a navigation controller, so diagram and report
previews were dead ends. Wrap it in one, add an explicit Done button
and assert both in a UI test.
The Overview share menu offered a wiring diagram and a full report even
for an empty system. Gate it on loads, batteries or chargers being
present (iOS + Android) and add UI tests for both states.
ComponentLibraryItem gained componentCategory, which left the test
target uncompilable. Add the argument to all call sites and a
regression test for displayVoltage skipping a zero voltageIn.
.quickLookPreview() is a macOS-only SwiftUI modifier, so the app target
did not compile for iOS at all. Present QLPreviewController through a
UIViewControllerRepresentable in a sheet instead; clearing previewURL
still triggers cleanup and the review prompt.
PocketBase stores battery nominal voltage in voltage_out while
voltage_in is 0.0 (not null). The nil-coalescing operator only
skips null, so 0.0 was returned instead of the real voltage.
Skip zero values when resolving displayVoltage on both platforms.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
iOS: route exports through QLPreviewController so users can inspect
before sharing. Android: add a zoomable full-screen diagram preview
with a share button; PDF still goes straight to the share sheet.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
iOS: moved registerSuccessfulExport() into onDismiss so it fires
after the share sheet closes, not while it is still open.
Android: hold launchReview() until the activity is RESUMED so the
dialog cannot overlap the share chooser.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Overview PDF: usable energy summary, cable length, power loss,
usable energy rows (matching iOS tables)
- Analytics: align event names and properties with iOS
- Localize default component names and editor dialog labels
- Unit system default via device measurement system (API 28+)
- Preserve BOM/affiliate fields when editing batteries/chargers
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Request an App Store / Play Store review after a successful export
(Overview PDF, BOM PDF, or wiring diagram). A shared gate keeps prompts
rare: >=2 successful exports, >=3 days since install, >=120 days since the
last prompt, and at most once per app version. A one-time migration
backdates existing users so the prompt can fire on their first export
after updating. Logs a "Review Prompt Requested" analytics event.
iOS uses StoreKit's AppStore.requestReview(in:) with UserDefaults state;
Android uses the Play In-App Review API with DataStore state.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cross-platform refinements to appearance/battery/charger editors, tabs
and navigation, plus persistence, screenshot previews and CLAUDE.md docs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fetch the wiring diagram from the VoltPlan API and share it as a
standalone PNG from the Overview share menu on both platforms, with a
localized error when the diagram cannot be generated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tweaks to the PocketBase-backed component library: item parsing,
repository/view-model fetching, and the library screen UI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bundle the rotating onboarding illustrations (light/dark) and wire them
into the Android onboarding info component, matching the iOS carousel.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add density-specific launcher PNGs with a new foreground, a monochrome
layer for themed icons, and a light background; drop the old vector
foreground.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Read upload-keystore credentials from a gitignored keystore.properties
(falling back to unsigned release when absent), bundle full native debug
symbols for Play crash symbolication, and ignore keystore secrets.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace preview-based screenshot rendering with simulator XCUITests
driven by shooter.sh (per-language locale + status bar overrides,
xcparse extraction). Add batteries-list accessibility identifier and
update CLAUDE.md screenshot docs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace client-side Amazon affiliate resolution with server-side
redirects via voltplan.app/{componentId} and voltplan.app/search?q=.
Remove AmazonAffiliate, affiliate link fetching, and per-model
affiliate fields in favor of a single componentID.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full feature-parity port of the iOS app under ./android (package
app.voltplan.cable): Systems, bottom-nav system detail (Overview,
Components, Batteries, Chargers), calculator/loads, battery & charger
editors, overview with runtime/charge goals, Bill of Materials with PDF
export, VoltPlan PocketBase component library, and Aptabase analytics.
Room persistence, 5-language localization. Verified to build (assembleDebug).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Fix AWG 0/00/000/0000 bug (all resolved to 0 in Swift) using negative
int convention (-1 through -4) with formatAWG() for 1/0–4/0 display
- Add 7.5A fuse size and change fuse type from Int to Double
- Add alternator power source type with distinct bolt.car.fill icon
- Migrate all NSLocalizedString calls to String(localized:defaultValue:)
- Update translations for runtime subtitle (ES/FR/NL: current→maximum),
usable capacity footer text, and NL override wording
- Store length always in meters, convert at display time in CalculatorView
- Add preview-friendly inits for ComponentLibraryView and LoadsView
- Expand test coverage for calculations, fuses, AWG, and edge cases
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add first launch event, share tracking for overview PDF and diagram
exports. Add SystemOverviewPDFExporter for A4 PDF generation. Update
charger model with new configuration fields and localization for all
5 languages. Refresh app icon assets and CLAUDE.md build instructions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Show BOM button for unsaved loads (no longer requires save first)
- Set US fallback affiliate tag for unknown countries
- Localize Amazon search queries in all 5 languages (EN/DE/ES/FR/NL)
- Add affiliate URL/country fields to SavedBattery model
- Auto-detect unit system (imperial for US locale, metric otherwise)
- Set charger input voltage based on locale (120V US, 230V EU)
- Remove StoreKitManager and CableProPaywallView
- Add CLAUDE.md project instructions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add dutyCyclePercent and defaultUtilizationFactorPercent to ComponentLibraryItem
with normalization logic and backend field fetching
- Change default dailyUsageHours from 1h to 24h
- Replace goal editor stepper with day/hour/minute wheel pickers
- Update app icon colors and remove duplicate icon assets
- Move SavedBattery.swift into Batteries/ directory, remove Pods group
- Add iPad-only flag and start frame support to screenshot framing scripts
- Rework localized App Store screenshot titles across all languages
- Add runtime goals and BOM completed items to sample data
- Bump version to 1.5.1 (build 41)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>