feat: add vehicle customization, Arabic search normalization, and smooth movement interpolation

This commit is contained in:
Hamza-Ayed
2026-09-19 12:34:25 +03:00
parent 43ad2e0ad4
commit 55830beee8
16 changed files with 2295 additions and 393 deletions
+38 -5
View File
@@ -1,9 +1,18 @@
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
namespace = "com.siro_map.siro_maps"
compileSdk = flutter.compileSdkVersion
@@ -15,20 +24,43 @@ android {
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.siro_map.siro_maps"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 23
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String?
keyPassword = keystoreProperties["keyPassword"] as String?
val storeFilePath = keystoreProperties["storeFile"] as String?
if (storeFilePath != null) {
storeFile = file(storeFilePath)
}
storePassword = keystoreProperties["storePassword"] as String?
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
val hasReleaseKey = keystorePropertiesFile.exists() && keystoreProperties["storeFile"] != null
signingConfig = if (hasReleaseKey) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
// Enable R8 / ProGuard Code Optimization & Shrinking
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
debug {
signingConfig = signingConfigs.getByName("debug")
}
}
@@ -36,6 +68,7 @@ android {
dependencies {
implementation("androidx.car.app:app:1.4.0")
implementation("androidx.car.app:app-projected:1.4.0")
}
kotlin {
+65
View File
@@ -0,0 +1,65 @@
# ==============================================================================
# Siro Maps (map-saas) ProGuard & R8 Optimization Rules
# ==============================================================================
# ── 1. FLUTTER EMBEDDING & NATIVE CHANNELS ────────────────────────────────────
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-keepattributes Signature
-keepattributes InnerClasses,EnclosingMethod
# Keep native methods used by Flutter engine
-keepclasseswithmembers class * {
native <methods>;
}
# ── 2. ANDROID AUTO (CAR APP LIBRARY) ─────────────────────────────────────────
-keep class androidx.car.app.** { *; }
-keep interface androidx.car.app.** { *; }
-keep class androidx.car.app.model.** { *; }
-keep class androidx.car.app.navigation.** { *; }
-keep class androidx.car.app.navigation.model.** { *; }
-keep class androidx.car.app.validation.** { *; }
# Keep our custom CarAppService, Session, Screen and State models
-keep class com.siro_map.siro_maps.car.** { *; }
-keepclassmembers class com.siro_map.siro_maps.car.** { *; }
-dontwarn androidx.car.app.**
# ── 3. MAPLIBRE GL NATIVE & RENDERING ENGINE ──────────────────────────────────
-keep class org.maplibre.** { *; }
-keep interface org.maplibre.** { *; }
-keep class org.maplibre.android.** { *; }
-keep interface org.maplibre.android.** { *; }
-keep class org.maplibre.android.maps.** { *; }
-keep class org.maplibre.android.geometry.** { *; }
-keep class org.maplibre.android.style.** { *; }
-dontwarn org.maplibre.**
-dontwarn org.maplibre.android.**
# ── 4. SHRED PREFERENCES & DATA MODELS ────────────────────────────────────────
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# ── 5. KOTLIN & COROUTINES ────────────────────────────────────────────────────
-dontwarn kotlin.**
-dontwarn kotlinx.coroutines.**
-keep class kotlin.Metadata { *; }
@@ -35,28 +35,31 @@ class SiroNavScreen(carContext: CarContext) : Screen(carContext) {
.build()
)
// 3. Live Speed
// 3. Live Speed & Heading
paneBuilder.addRow(
Row.Builder()
.setTitle("السرعة الحالية")
.addText(state.formattedSpeed)
.setTitle("السرعة والاتجاه")
.addText("${state.formattedSpeed} • الزاوية ${state.bearing.toInt()}°")
.build()
)
// Stop navigation action button
paneBuilder.addAction(
Action.Builder()
.setTitle("إنهاء الملاحة")
.setOnClickListener {
SiroCarAppService.stopNavigation()
invalidate()
}
.build()
)
// Header Action Strip for seamless access across landscape, portrait, and Coolwalk multi-window
val actionStrip = ActionStrip.Builder()
.addAction(
Action.Builder()
.setTitle("إنهاء الملاحة")
.setOnClickListener {
SiroCarAppService.stopNavigation()
invalidate()
}
.build()
)
.build()
return PaneTemplate.Builder(paneBuilder.build())
.setTitle("ملاحة سيرو • جارية الآن")
.setHeaderAction(Action.APP_ICON)
.setActionStrip(actionStrip)
.build()
}
@@ -66,7 +69,7 @@ class SiroNavScreen(carContext: CarContext) : Screen(carContext) {
paneBuilder.addRow(
Row.Builder()
.setTitle("خرائط سيرو السيادية (Siro Maps)")
.addText("التطبيق متصل بنجاح بشاشة السيارة")
.addText("متصل بشاشة السيارة • جاهز للتوجيه")
.build()
)
@@ -80,7 +83,7 @@ class SiroNavScreen(carContext: CarContext) : Screen(carContext) {
paneBuilder.addRow(
Row.Builder()
.setTitle("بدء الملاحة")
.addText("حدد وجهتك من شاشة الهاتف للانتقال الفوري إلى وضع الملاحة ثلاثية الأبعاد")
.addText("حدد وجهتك من تطبيق الهاتف لبدء الملاحة التفاعلية فوراً")
.build()
)