fix marker rendering & modernize riding widgets for dark mode - 2026-04-11

This commit is contained in:
Hamza-Ayed
2026-04-11 01:14:09 +03:00
parent 3f03f25142
commit 454276d1e0
88 changed files with 50376 additions and 23310 deletions

View File

@@ -7,12 +7,22 @@ import 'package:maplibre_gl/maplibre_gl.dart';
import 'navigation_controller.dart';
// ─── Brand colours ───────────────────────────────────────────────────────────
const Color _kBlue = Color(0xFF1A73E8);
const Color _kBlueDark = Color(0xFF0D47A1);
const Color _kSurface = Color(0xFFFFFFFF);
const Color _kText = Color(0xFF1C1C1E);
const Color _kSubtext = Color(0xFF6B7280);
const Color _kGreen = Color(0xFF34A853);
// ─── Theme-aware Brand colours ──────────────────────────────────────────────
Color get _kBlue => const Color(0xFF1A73E8);
Color get _kBlueDark => const Color(0xFF0D47A1);
Color get _kSurface =>
Get.isDarkMode ? const Color(0xFF1E1E1E) : const Color(0xFFFFFFFF);
Color get _kText =>
Get.isDarkMode ? const Color(0xFFF5F5F7) : const Color(0xFF1C1C1E);
Color get _kSubtext =>
Get.isDarkMode ? Colors.white60 : const Color(0xFF6B7280);
Color get _kGreen => const Color(0xFF34A853);
Color get _kGlassSurface => Get.isDarkMode
? Colors.black.withOpacity(0.7)
: Colors.white.withOpacity(0.92);
Color get _kGlassBorder => Get.isDarkMode
? Colors.white.withOpacity(0.12)
: Colors.white.withOpacity(0.5);
class NavigationView extends StatelessWidget {
const NavigationView({super.key});
@@ -33,7 +43,9 @@ class NavigationView extends StatelessWidget {
onMapCreated: c.onMapCreated,
onStyleLoadedCallback: c.onStyleLoaded,
onMapLongClick: c.onMapLongPressed,
styleString: "assets/style.json",
styleString: Get.isDarkMode
? "assets/style_dark.json"
: "assets/style.json",
initialCameraPosition: CameraPosition(
target: c.myLocation ?? const LatLng(33.5138, 36.2765),
zoom: 16.0,
@@ -106,7 +118,7 @@ class _SearchBar extends StatelessWidget {
controller: controller.placeDestinationController,
onChanged: controller.onSearchChanged,
textInputAction: TextInputAction.search,
style: const TextStyle(
style: TextStyle(
fontSize: 16,
color: _kText,
fontWeight: FontWeight.w500),
@@ -167,8 +179,10 @@ class _SearchResults extends StatelessWidget {
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.zero,
itemCount: controller.placesDestination.length,
separatorBuilder: (_, __) =>
Divider(height: 1, color: Colors.grey[100], indent: 56),
separatorBuilder: (_, __) => Divider(
height: 1,
color: Get.isDarkMode ? Colors.white12 : Colors.grey[100],
indent: 56),
itemBuilder: (_, i) {
final place = controller.placesDestination[i];
final dist = place['distanceKm'] as double?;
@@ -187,8 +201,8 @@ class _SearchResults extends StatelessWidget {
color: _kBlue.withOpacity(0.08),
shape: BoxShape.circle,
),
child: const Icon(Icons.place_rounded,
color: _kBlue, size: 18),
child:
Icon(Icons.place_rounded, color: _kBlue, size: 18),
),
const SizedBox(width: 12),
Expanded(
@@ -196,7 +210,7 @@ class _SearchResults extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(place['name'] ?? '',
style: const TextStyle(
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14.5,
color: _kText),
@@ -222,7 +236,7 @@ class _SearchResults extends StatelessWidget {
),
child: Text(
'${dist.toStringAsFixed(1)} كم',
style: const TextStyle(
style: TextStyle(
color: _kBlue,
fontSize: 12,
fontWeight: FontWeight.w600),
@@ -259,11 +273,14 @@ class _TurnBanner extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(12, 10, 12, 0),
child: Container(
decoration: BoxDecoration(
color: _kBlueDark,
color: Get.isDarkMode
? Colors.grey[900]?.withOpacity(0.95)
: _kBlueDark,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: _kBlueDark.withOpacity(0.35),
color: (Get.isDarkMode ? Colors.black : _kBlueDark)
.withOpacity(0.35),
blurRadius: 20,
offset: const Offset(0, 6)),
],
@@ -274,14 +291,14 @@ class _TurnBanner extends StatelessWidget {
children: [
// Turn arrow icon
Container(
width: 52,
height: 52,
width: 64,
height: 64,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
borderRadius: BorderRadius.circular(14),
borderRadius: BorderRadius.circular(16),
),
child: const Icon(Icons.turn_right_rounded,
color: Colors.white, size: 30),
color: Colors.white, size: 40),
),
const SizedBox(width: 14),
@@ -293,16 +310,16 @@ class _TurnBanner extends StatelessWidget {
Text(
controller.distanceToNextStep,
style: const TextStyle(
color: Colors.white70,
fontSize: 13,
fontWeight: FontWeight.w500),
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600),
),
const SizedBox(height: 2),
const SizedBox(height: 4),
Text(
controller.currentInstruction,
style: const TextStyle(
color: Colors.white,
fontSize: 19,
fontSize: 26,
fontWeight: FontWeight.bold,
height: 1.2),
maxLines: 2,
@@ -429,7 +446,7 @@ class _RouteSummaryCard extends StatelessWidget {
left: 0,
right: 0,
child: Container(
decoration: const BoxDecoration(
decoration: BoxDecoration(
color: _kSurface,
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
boxShadow: [
@@ -520,20 +537,20 @@ class _InfoPill extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
decoration: BoxDecoration(
color: color.withOpacity(0.08),
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: color.withOpacity(0.2)),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, color: color, size: 15),
const SizedBox(width: 5),
Icon(icon, color: color, size: 22),
const SizedBox(width: 8),
Text(label,
style: TextStyle(
color: color, fontSize: 13.5, fontWeight: FontWeight.w700)),
color: color, fontSize: 18, fontWeight: FontWeight.w800)),
],
),
);
@@ -577,22 +594,27 @@ class _NavigationHUD extends StatelessWidget {
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: const Color(0xFFF8F9FA),
color: Get.isDarkMode
? Colors.white.withOpacity(0.05)
: const Color(0xFFF8F9FA),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey.withOpacity(0.15)),
border: Border.all(
color: Get.isDarkMode
? Colors.white10
: Colors.grey.withOpacity(0.15)),
),
child: Row(
children: [
Icon(Icons.arrow_forward_rounded,
size: 15, color: _kSubtext),
const SizedBox(width: 8),
size: 20, color: _kSubtext),
const SizedBox(width: 10),
Expanded(
child: Text(
controller.nextInstruction,
style: TextStyle(
color: _kSubtext,
fontSize: 13,
fontWeight: FontWeight.w500),
color: _kText,
fontSize: 16,
fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
@@ -636,13 +658,13 @@ class _NavigationHUD extends StatelessWidget {
child: Row(
children: [
const Icon(Icons.stop_rounded,
color: Colors.redAccent, size: 16),
const SizedBox(width: 5),
color: Colors.redAccent, size: 24),
const SizedBox(width: 6),
const Text('إيقاف',
style: TextStyle(
color: Colors.redAccent,
fontSize: 13,
fontWeight: FontWeight.w700)),
fontSize: 18,
fontWeight: FontWeight.bold)),
],
),
),
@@ -669,44 +691,61 @@ class _SpeedBadge extends StatelessWidget {
final bool fast = kmh > 100;
return Positioned(
bottom: MediaQuery.of(context).padding.bottom + 130,
left: 14,
child: Container(
width: 62,
height: 62,
decoration: BoxDecoration(
color: fast ? const Color(0xFFD93025) : _kSurface,
shape: BoxShape.circle,
border: Border.all(
color: fast ? Colors.red.withOpacity(0.3) : Colors.grey[200]!,
width: 2),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.12),
blurRadius: 12,
offset: const Offset(0, 4)),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'$kmh',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: fast ? Colors.white : _kText,
height: 1),
bottom: MediaQuery.of(context).padding.bottom + 150,
left: 16,
child: Stack(
alignment: Alignment.center,
children: [
// Circular progress mimicking a speedometer
SizedBox(
width: 86,
height: 86,
child: CircularProgressIndicator(
value: (kmh / 140.0)
.clamp(0.0, 1.0), // Assuming 140 is max speed shown
strokeWidth: 6,
backgroundColor: Get.isDarkMode
? Colors.white10
: Colors.grey.withOpacity(0.3),
valueColor: AlwaysStoppedAnimation<Color>(
fast ? Colors.redAccent : _kBlue),
),
Text(
'كم/س',
style: TextStyle(
fontSize: 9,
color: fast ? Colors.white70 : _kSubtext,
fontWeight: FontWeight.w500),
),
Container(
width: 74,
height: 74,
decoration: BoxDecoration(
color: fast ? const Color(0xFFD93025) : _kSurface,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 16,
offset: const Offset(0, 6)),
],
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'$kmh',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w900,
color: fast ? Colors.white : _kText,
height: 1),
),
Text(
'كم/س',
style: TextStyle(
fontSize: 13,
color: fast ? Colors.white70 : _kSubtext,
fontWeight: FontWeight.w600),
),
],
),
),
],
),
);
}
@@ -735,7 +774,7 @@ class _LoadingOverlay extends StatelessWidget {
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(_kBlue),
strokeWidth: 3,
),
@@ -777,14 +816,14 @@ class _GlassCard extends StatelessWidget {
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.92),
color: _kGlassSurface,
borderRadius: BorderRadius.circular(borderRadius),
border: Border.all(color: Colors.white.withOpacity(0.5)),
border: Border.all(color: _kGlassBorder),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.07),
color: Colors.black.withOpacity(Get.isDarkMode ? 0.4 : 0.07),
blurRadius: 16,
offset: const Offset(0, 4)),
offset: const Offset(0, 8)),
],
),
padding: padding,