Skip to content

Releases: vizenturelabs/cypride

CypRide-v1.1.4

Choose a tag to compare

@vizenturelabs vizenturelabs released this 25 Sep 10:14

Theming & UI Enhancements:

  • Dark Mode & AMOLED: Full dark theme support, including a dedicated pure-black AMOLED toggle for OLED displays.
  • Dynamic Colors: Material You integration that automatically adapts the app's color palette to your Android wallpaper.
  • Appearance Settings: New dedicated controls to seamlessly toggle between Light, Dark, System Default, Dynamic Colors, and AMOLED modes.

Improvements & Fixes:

  • Smart System Sync: Theme toggles now accurately reflect real-time system appearance changes.
  • Global UI Polish: All screens, navigation drawers, maps, and bottom sheets are now fully theme-aware.
  • Codebase Cleanup: Resolved Flutter deprecation warnings by migrating legacy withOpacity calls to withAlpha/withValues.

CypRide-v1.1.3

Choose a tag to compare

@vizenturelabs vizenturelabs released this 22 Sep 15:25

ISSUE: Manually forcing play-services-auth:22.0.0 in build.gradle.kts overrode the Flutter plugin's native dependency, breaking the OAuth bridge.
SOL: Removed the explicit play-services-auth declaration so the google_sign_in plugin can automatically manage its own compatible version.

  • Domain Blocking: Intercepted Google-owned domains (@gmail.com, @googlemail.com, @google.com) from requesting magic links.
  • UX Redirection: Added a UI banner (SnackBar) that prompts users with these domains to use the native "Continue with Google" button instead.
  • Database Integrity: Prevents the creation of duplicate Firebase authentication providers (Email Link vs. Google OAuth) for the exact same Google account.
  • Added _isInCyprus Helper Method: Uses a bounding box (Latitude 34.50° to 35.80°, Longitude 32.00° to 35.00°) to verify if the GPS coordinates sit within or immediately around the island of Cyprus.
  • Updated Initialization Logic (_getLocationAndInitialize): If the user grants location permissions but is detected abroad, the app immediately snaps the map back to the Republic of Cyprus center coordinates (34.83, 33.28), triggers the "You are not based in Cyprus" snackbar message, and sets _isLocationPermissionGranted to false.
  • Dynamic UI Guardrail: Because _isLocationPermissionGranted becomes false for users abroad, the FloatingActionButton (geo-location button) is automatically hidden, satisfying the requirement to disable the feature and lock the map view securely.
  • Double-Layer Protection: Added the same validation logic inside the FAB's onPressed callback just in case a user travels abroad while the app is already open in the background.

CypRide-v1.1.2

Choose a tag to compare

@vizenturelabs vizenturelabs released this 20 Sep 09:50
5f49954

Summary of Security Updates:

  1. Deep Link Validation (lib/main.dart): Hardened the cypride:// scheme handler to strictly verify the decoded Firebase link against the trusted domain before passing it to the authentication flow.
  2. ADB Data Extraction Prevention (AndroidManifest.xml): Disabled Android auto-backup (android:allowBackup="false", android:fullBackupContent="false") to protect local storage (Hive/SharedPreferences) from physical extraction on rooted devices.
  3. R8/ProGuard Rules (proguard-rules.pro): Scoped rules to protect essential Flutter engine, platform channels, and secure storage classes from being aggressively stripped, while safely ignoring missing optional dependencies to prevent build failures.
  4. Client-Side Rate Limiting (lib/auth_page.dart): Implemented a 30-second cooldown on magic link requests to prevent API quota exhaustion and email spam.
  5. Network Security Baseline (AndroidManifest.xml + network_security_config.xml): Enforced a strict HTTPS-only policy and prepared the foundation for future native certificate pinning.

CypRide-v1.1.1

Choose a tag to compare

@vizenturelabs vizenturelabs released this 12 Sep 08:34
719d08b

Fixed missing version indicator on drawer menu (CypRide v1.1.1) - no minor update.

CypRide-v1.1.0

Choose a tag to compare

@vizenturelabs vizenturelabs released this 10 Sep 09:58
Immutable release. Only release title and notes can be modified.
719d08b

Authentication Overhaul: Passwordless Email Link & Google Sign-In

✨ New Features

Passwordless Email Sign-In: Added secure Magic Link authentication as a frictionless alternative to Google Sign-In.
Google Sign-In v7 Support: Upgraded the OAuth implementation to fully support the latest asynchronous google_sign_in v7.x API.

🛠️ Critical Fixes & Architecture Improvements

Gmail App Link Bypass: Solved a major blocker where mobile email clients (like Gmail) intercept and block direct App Links. Implemented a Firebase Hosting web interceptor (/auth-action) that securely captures the Firebase oobCode and bridges back to the app via a custom URL scheme (cypride://).

Cold-Start Race Condition: Fixed a critical bug where clicking the magic link from a completely closed state left users stuck on the login screen. Added a localized authStateChanges listener in the Auth UI to force seamless navigation to the Home screen the exact millisecond background verification completes.
Smart Routing Integration: Implemented GoRouterRefreshStream to ensure global route guards instantly react to background authentication events without requiring manual app restarts.

This release also includes a comprehensive overhaul of the Android build pipeline to ensure stability, optimize release builds, and resolve compatibility issues with the latest Android Gradle Plugin (AGP) and Gradle versions.

AGP 9.x & Gradle 9.x Compatibility
Resolved critical class-cast exceptions and DSL conflicts introduced by AGP 9.x.
Configured gradle.properties to bypass strict new DSL checks and built-in Kotlin enforcement, ensuring full compatibility with the Flutter Gradle Plugin without downgrading the build tools.
Suppressed legacy DSL deprecation warnings to maintain a clean build output while awaiting official Flutter ecosystem updates for

AGP 9 native support.
Kotlin & Gradle DSL Modernization
Migrated from the deprecated kotlinOptions block to the modern Kotlin compilerOptions DSL.
Replaced legacy rootProject.buildDir properties with the modern layout.buildDirectory API.
Centralized repository management using dependencyResolutionManagement in settings.gradle.kts, removing obsolete allprojects blocks.

R8 Minification & ProGuard Optimization
Implemented a strictly scoped proguard-rules.pro to prevent R8 from aggressively stripping critical code during release builds.
Added targeted keep rules for Flutter embedding engines, Firebase initialization providers (FirebaseInitProvider), and legacy Play Core split-install tasks.
Resolved "overly broad" lint warnings and missing class errors by replacing hard keeps with -dontwarn directives for optional networking and JSON libraries.

Dependency & SDK Alignment
Synchronized targetSdk with compileSdk (API 36) to eliminate compatibility mode warnings.
Resolved strict AAR metadata conflicts by aligning AndroidX Core dependencies to versions that natively support API 36.
Corrected the Firebase Bill of Materials (BoM) implementation by wrapping it in the platform() DSL to ensure consistent version resolution across all Firebase services.
Explicitly declared the required NDK version (28.x) to resolve backward compatibility mismatches with third-party JNI plugins.

Build Pipeline Stability
Fixed stale GeneratedPluginRegistrant compilation errors by enforcing deep clean protocols during dependency upgrades.
Ensured the Google Services plugin is correctly applied in the modern plugins {} block to guarantee seamless Firebase initialization in minified release builds.

CypRide-v1.0.0

Choose a tag to compare

@vizenturelabs vizenturelabs released this 06 Jun 11:05
Immutable release. Only release title and notes can be modified.
1694284

ISSUE: The application encountered a critical [cloud_firestore/permission-denied] error when fetching the active rides list. This was caused by Firestore's strict query-matching behavior, where security read rules must perfectly mirror the constraints of the client-side query.

SOL: Resolved Firestore permission-denied Query Trap

  • Rule Optimization: Removed the server-time validation (departureTime > request.time) from the read rule. Firestore evaluates read rules against the entire query result; if the client query lacks the exact time filter, the entire request is blocked to prevent potential data leakage.
  • Data Integrity Maintained: Shifted the strict time validation to the create rule. Unlike read rules, create rules evaluate single document payloads, allowing us to safely block the creation of past rides without breaking list queries.
  • Client-Side Alignment: Optimized the Flutter data layer by splitting the queries to perfectly align with the updated security rules:
    Public Feed: Queries strictly for isActive == true.
    Driver History: Queries strictly for driverUid == currentUser.uid.
  • Architecture Preserved: Successfully resolved the bottleneck while maintaining CypRide's strict schema validation (keys().hasOnly), immutable field protections, and privacy-first decentralized messaging architecture.

CypRide-v1.0.0-rc.2

CypRide-v1.0.0-rc.2 Pre-release
Pre-release

Choose a tag to compare

@vizenturelabs vizenturelabs released this 19 May 14:40
Immutable release. Only release title and notes can be modified.
e48d122
  • Reviewed and fixed standard compliance with AndroidManifest.xml, MainActivity.kt and build.gradle.
  • Added missing Channel details in "Driver Information" of Favorite.
  • Added helperText: 'Please include your country code first' in ride_screen.

CypRide-v1.0.0-rc.1

CypRide-v1.0.0-rc.1 Pre-release
Pre-release

Choose a tag to compare

@vizenturelabs vizenturelabs released this 17 May 12:11
Immutable release. Only release title and notes can be modified.
f76fcdf

ISSUE: The profile picture does not update in the Drawer on home_screen.dart after being changed in profile_screen.dart because:

  • HomeScreen loads the profile image only once in initState() via _loadProfileImage(), and never listens for changes.
    Even though:
  • You correctly store the image path in FlutterSecureStorage
  • You correctly notify a ProfileProvider (via profileProvider.updateProfileImagePath())
    ...the HomeScreen does not use or listen to ProfileProvider at all. It reads from secure storage only once, so it has no way of knowing the image changed unless the app restarts (which triggers initState again).

SOL: You already have a well-structured ProfileProvider. The fix is to consume it in HomeScreen instead of relying solely on local state + one-time load.

  • Update HomeScreen to use ProfileProvider
    Replace the current _profileImagePath logic with a Consumer or context.watch().
    Since HomeScreen is a StatefulWidget, the cleanest approach is to watch the provider inside build.
  • Remove redundant _loadProfileImage() and _profileImagePath state
    Because the provider will now manage this, you don’t need to manually load or store it in HomeScreen's state.

ISSUE: After picture upload: The ProfileProvider is updated → HomeScreen rebuilds → image shows. But after app restart: ProfileProvider starts with _profileImagePath = null → even though the path exists in FlutterSecureStorage, it’s never loaded into the provider on startup. So the provider has no knowledge of the persisted image path when the app launches fresh.

SOL: Initialize ProfileProvider from Secure Storage on App Start. You must preload the profile image path into ProfileProvider during app initialization, just like you do in ProfileScreen.initState().

CypRide-v1.0.0-beta.7

CypRide-v1.0.0-beta.7 Pre-release
Pre-release

Choose a tag to compare

@vizenturelabs vizenturelabs released this 14 May 11:00
Immutable release. Only release title and notes can be modified.
9b6a429

ISSUE: bug due to a new TextEditingController instance on every rebuild:

  1. Every time Flutter rebuilds the widget (which happens on every setState() call)
  2. A new TextEditingController is created with the current _otherCarBrand value
  3. The text field loses its cursor position and internal state
  4. When you type, the new controller starts from position 0, causing characters to appear in reverse order
  5. Backspace/delete doesn't work properly because the controller has no memory of previous interactions

SOL: use a persistent TextEditingController that lives for the entire lifetime of the widget:

  • Persistent Controller: The same TextEditingController instance is used throughout the widget's lifecycle
  • Proper State Management: The controller maintains cursor position, selection, and internal text state
  • Synchronized Data: The _otherCarBrand variable stays in sync with the controller's text
  • Normal Text Input: Characters appear in the correct order and deletion works properly

CypRide-v1.0.0-beta.6

CypRide-v1.0.0-beta.6 Pre-release
Pre-release

Choose a tag to compare

@vizenturelabs vizenturelabs released this 12 May 20:28
Immutable release. Only release title and notes can be modified.
c5d7eac

Fixed small issue with GitHub URL CypRide project incorrectly implemented in the code.