Migrate to Kotlin DSL, Compose, and modern Android stack#209
Open
codebutler wants to merge 100 commits intomasterfrom
Open
Migrate to Kotlin DSL, Compose, and modern Android stack#209codebutler wants to merge 100 commits intomasterfrom
codebutler wants to merge 100 commits intomasterfrom
Conversation
…P 9.0 Convert the entire build system from Groovy to Kotlin DSL. Add a Gradle version catalog (libs.versions.toml) for centralized dependency management. Update all dependencies to latest stable versions. Key version changes: - Kotlin: 2.3.0 - Android Gradle Plugin: 9.0.0 - Compose Multiplatform: 1.10.0 - kotlinx-serialization: 1.10.0 - kotlinx-coroutines: 1.10.2 - kotlinx-datetime: 0.7.1 - SQLDelight: 2.2.1 - Koin: 4.1.1 - Compile SDK: 35, Min SDK: 23
…restructure Migrate all core modules to Kotlin Multiplatform with commonMain/androidMain/iosMain source sets. Convert all remaining Java files to Kotlin. Absorb nfc-felica-lib submodule into farebot-card-felica. Major changes: - farebot-app renamed to farebot-android - Replace Hilt DI with Koin (cross-platform) - Replace Gson with kotlinx.serialization - Replace custom ByteArray wrapper with kotlin.ByteArray + extension functions - Remove Room, use SQLDelight for cross-platform persistence - Add MDST (Metrodroid Station Data Table) reader for protobuf station databases - Add NFC abstraction layer for KMP readiness (CardTransceiver, NfcTechnology) - Add StringResource abstraction for cross-platform string formatting - Add TransitCurrency, TransitBalance, Transaction, TransactionTrip abstractions - Add MDST station databases (38 files) for worldwide transit station lookups - Add 220+ tests across 29 test files
Ported from Metrodroid (https://github.com/metrodroid/metrodroid) to Kotlin Multiplatform. Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
Ported from Metrodroid (https://github.com/metrodroid/metrodroid) to Kotlin Multiplatform. Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
Ported from Metrodroid (https://github.com/metrodroid/metrodroid) to Kotlin Multiplatform. Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
Ported from Metrodroid (https://github.com/metrodroid/metrodroid) to Kotlin Multiplatform. Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
For transit systems where only the card serial number can be read, with a reason code (LOCKED, NOT_STORED, MORE_RESEARCH_NEEDED). Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
Shared framework for ERG-based transit systems (used by Australian and New Zealand systems like Opal, SmartRider, seq:go). Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
Shared framework for Cubic Nextfare-based transit systems. Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Wilbert Duijvenvoorde <w.a.n.duijvenvoorde@gmail.com>
Ported from Metrodroid (https://github.com/metrodroid/metrodroid)
Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
…Zealand) Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Michael Farrell <micolous+git@gmail.com>
New farebot-shared module with cross-platform UI shared between Android and iOS: - Compose Multiplatform screens: Home, History, Card Details, Keys, Settings, Help, Trip Map - MVVM architecture with StateFlow and SharedFlow - Jetpack Navigation with typed routes - Koin dependency injection (sharedModule) - Card artwork drawables for all supported transit systems - Comprehensive string resources
Xcode project for the iOS app using Compose Multiplatform for shared UI. - Swift entry point with ComposeView bridge - CoreNFC integration for reading transit cards - iOS NFC abstractions: IosCardTransceiver, IosNfcFTechnology - App entitlements for NFC tag reading - Bundled FeliCa station database
- CLAUDE.md: Project rules and development guidelines - REMAINING-WORK.md: Metrodroid port status tracking - metrodroid-analysis.md: Comprehensive FareBot vs Metrodroid comparison - tools/local_proxy.py: Local proxy script for development
Port ISO7816Protocol from Metrodroid for APDU communication with ISO7816-4 cards. Add ISO7816CardReader to read files, records, and balances from ISO7816 applications (China transit, KSX6924/T-Money). Update TagReaderFactory (Android) and IosNfcScanner (iOS) to try ISO7816 SELECT BY NAME for known AIDs before falling back to DESFire protocol. This enables reading balances from China and KSX6924 cards that were previously always returning zero. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tralia) DESFire/EN1545-based transit card for Adelaide Metro (buses, trams, trains). Supports trip history, subscriptions, purse balance display, and serial number. Also registers Pisa and Venezia Ultralight transit factory variants. Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…fik) Multi-operator MIFARE Classic framework for Scandinavian transit cards. Supports Rejsekort (Denmark), SL Access (Stockholm), and Västtrafik (Gothenburg). Full trip history, purse balance, subscription parsing, and multi-leg trip support. Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…odroid Ported from Metrodroid (https://github.com/metrodroid/metrodroid)
Add JVM compilation target for all KMP modules with SQLDelight SQLite driver. Improve test asset loading on iOS (read from source tree instead of NSBundle). Remove skippable test guards in favor of proper assertions. Add string resources for Japan IC cards to TestStringResource. Remove obsolete felica_stations.db3 from Xcode project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend FlipperNfcParser to handle Mifare DESFire and FeliCa card dumps in addition to Classic and Ultralight. Add integration tests with sample Flipper dump files for Clipper (DESFire), ORCA (DESFire), and Japanese IC cards (FeliCa: ICOCA, PASMO, Suica). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use safe casts (as?) for DESFire file reads in Clipper to handle locked or unreadable files gracefully. Fix EasyCard timestamp parsing to treat raw values as Taipei local time rather than UTC. Update EasyCard test station name expectations to match MDST database values. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full rewrite of Helsinki transit card support to use the EN1545 framework. Adds V1, V2, and Waltti variant detection and parsing. New files: HSLTransaction, HSLArvo (value tickets), HSLKausi (season passes), HSLLookup (zone/area names), HSLVariant (variant enum). HSL Ultralight factory now imports shared code from farebot-transit-hsl instead of duplicating ~300 lines. Adds Oulu/Lahti Waltti zones, MDST region lookup, proper pluralization, and purchase date display. Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full rewrite of Dutch OV-chipkaart support to use the EN1545 framework. OVChipTransaction and OVChipSubscription now extend En1545Transaction and En1545Subscription respectively. New OvcLookup provides MDST station lookup with agency-based station IDs and 25 Dutch subscription names. Trip deduplication uses TransactionTripLastPrice.merge(). Adds autocharge info, banned status, and BCD birthdate display. Removes 6 legacy helper files (OVChipParser, OVChipPreamble, OVChipCredit, OVChipInfo, OVChipUtil, OVChipTrip) replaced by EN1545 framework. Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Snapper serial-only stub with full KSX6924 implementation. Adds NZD balance reading, trip parsing with tap-on/tap-off merging (paired SFI 3+4 records via TransactionTrip.merge()), and purse info display. New files: SnapperTransaction (extends Transaction with journey grouping), SnapperPurseInfoResolver (issuer mapping). Move Snapper registration after KROCAP for correct KSX6924 detection ordering. Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
KMT: Display transaction counter and last transaction amount in card info, matching Metrodroid. SeqGo: Add system code verification in factory check(), pass refills to SeqGoTransitInfo constructor. Ported from Metrodroid (https://github.com/metrodroid/metrodroid) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document file-by-file audit of all 66 FareBot transit modules against their Metrodroid counterparts. 63 modules pass faithfully, 2 have acceptable minor differences (Clipper extra enhancement, Manly legacy ERG architecture). All previously identified FAIL and KNOWN LIMITATION items have been resolved. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace smoke tests with exact assertions on balances, trip counts, fares, modes, timestamps, station names, agency names, and route names for all 5 Flipper card dumps (ORCA, Clipper, Suica, PASMO, ICOCA). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move each ultralight factory to live alongside its parent transit system: - Troika UL -> farebot-transit-troika - HSL UL -> farebot-transit-hsl - OVChip UL -> farebot-transit-ovc - Pisa/Venezia UL -> farebot-transit-calypso - Amiibo -> new farebot-transit-amiibo module - Blank/Locked UL + MRT -> farebot-transit-serialonly - Blank/Unauthorized Classic/DESFire -> farebot-transit-serialonly Net -1 module (deleted 2, created 1). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parse EMV BER-TLV tags from NDEF payload and display additional card fields (full PAN, issuer country, expiration/effective dates, interchange control, Kyiv Digital UID) matching Metrodroid's PiletTransitData.TAG_MAP. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Myki: extend SerialOnlyTransitInfo with Reason.LOCKED, add moreInfoPage URL - LAX TAP: add onlineServicesPage URL - SeqGo: add moreInfoPage and onlineServicesPage URLs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add architectural differences table, document resolved Pilet, Myki, LaxTap, SeqGo, MRT Ultralight, and Subscription findings. Add transit system coverage table. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
09a4ebf to
1292b12
Compare
Replace legacy record parsing with ERG base classes, matching the CHC Metrocard pattern. ManlyFastFerryTransitInfo now extends ErgTransitInfo, ManlyFastFerryTrip extends ErgTrip, and ManlyFastFerryRefill extends ErgRefill. Deleted 6 redundant record classes that duplicated ERG framework logic. Added agency ID 0x0227 check for proper card detection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add missing Metrodroid test coverage: - Suica: Hayakaken/NIMOCA card detection with full service ID sets, ambiguous service ID edge case (falls back to Japan IC) - EasyCard: route name assertion (Bannan line), Chinese locale test - Myki: DESFire application ID verification (4594, 15732978) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Station.Builder only accepted a single lineName(), so all 11 call sites using .lineName(result.lineNames.firstOrNull()) silently discarded multi-line station data from MDST. This broke Trip.getRouteName() which relies on finding common lines between start/end stations. Fix: Replace Builder.lineName(String?) with Builder.lineNames(List<String>) and update all 11 call sites to pass the full list. Also fix MdstStationLookup.getStation() to prefer short line names (matching Metrodroid's selectBestName(isShort=true) for lines), so e.g. EasyCard shows "Red" instead of "Tamsui-Xinyi". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is a major modernization of the FareBot build system and Android codebase. The project has been migrated from Groovy-based Gradle to Kotlin DSL, updated to use Jetpack Compose for UI, and upgraded all dependencies to current versions. The build now uses Koin for dependency injection instead of Dagger, and Kotlinx Serialization instead of Gson.
Key Changes
Build System & Dependencies
build.gradle→build.gradle.kts(Kotlin DSL)dependencies.gradleand inlined dependency managementDependency Injection
AndroidModule.ktwith all Android-specific bindingsFareBotApplicationto use Koin'sstartKoin()DaggerFareBotApplicationComponentSerialization
KotlinxCardKeysSerializerfor card key serializationInstantinstead ofjava.util.DateUI & Platform
AndroidPlatformActionsfor platform-specific operations (clipboard, file picker, NFC settings, etc.)StringResourceabstraction instead of AndroidContextNfcStreamto use Kotlin Flow for reactive tag eventsManifest & Configuration
android:exported="true"to activities (required for API 31+)farebot-android/build.gradle.ktswith modern Android DSLDocumentation
CLAUDE.mdwith proxy configuration guide for authenticated HTTP proxy environmentsCleanup
.gitmodules(nfc-felica-lib submodule).kotlinto.gitignoreNotable Implementation Details
CLAUDE.mddocuments a sophisticated local proxy setup for environments behind authenticated HTTP proxies, with health checks and credential rotation supporthttps://claude.ai/code/session_016GBryRuV3PUzuQhuW2gArG