Update: 2026-07-06 04:16:38

This commit is contained in:
Hamza-Ayed
2026-07-06 04:16:38 +03:00
parent cadc26518b
commit e42754bb0e
2 changed files with 115 additions and 86 deletions
@@ -46,7 +46,7 @@ class MapPagePassenger extends StatelessWidget {
// ✅ تهيئة البيانات بعد تسجيل الدخول إن لم تكن قد تهيأت بالفعل // ✅ تهيئة البيانات بعد تسجيل الدخول إن لم تكن قد تهيأت بالفعل
final bool isLoggedIn = box.read(BoxName.isVerified) == '1' && final bool isLoggedIn = box.read(BoxName.isVerified) == '1' &&
box.read(BoxName.passengerID) != null; box.read(BoxName.passengerID) != null;
if (isLoggedIn && !rideLifecycle.isDataInitializedAfterLogin) { if (isLoggedIn && !rideLifecycle.isDataInitializedAfterLogin) {
rideLifecycle.initializeDataAfterLogin(); rideLifecycle.initializeDataAfterLogin();
} }
@@ -56,6 +56,7 @@ class MapPagePassenger extends StatelessWidget {
}); });
return Scaffold( return Scaffold(
backgroundColor: Get.isDarkMode ? const Color(0xFF1E1E1E) : Colors.white,
body: SafeArea( body: SafeArea(
bottom: true, bottom: true,
child: Stack( child: Stack(
@@ -108,22 +109,35 @@ class AttributionMap extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Positioned( return Positioned(
left: 4, left: 12,
bottom: 20, bottom: Get.height * 0.2 + 4,
child: RotatedBox( child: Row(
quarterTurns: 0, // يخلي النص عمودي (من تحت لفوق) mainAxisSize: MainAxisSize.min,
child: Opacity( crossAxisAlignment: CrossAxisAlignment.center,
opacity: 0.7, children: [
child: Text( Image.asset(
"Siro Maps", 'assets/images/logo.png',
// "Siro Maps • © OpenStreetMap contributors", width: 10,
height: 10,
color: Colors.grey.shade500,
),
const SizedBox(width: 4),
Text(
"Intaleq Maps",
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 9,
color: Colors.grey[700], color: Colors.grey.shade500,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w600,
letterSpacing: 0.3,
shadows: [
Shadow(
blurRadius: 3,
color: Colors.black.withValues(alpha: 0.3),
),
],
), ),
), ),
), ],
), ),
); );
} }
@@ -1,3 +1,4 @@
import 'dart:ui' show ImageFilter;
import 'package:siro_rider/print.dart'; import 'package:siro_rider/print.dart';
import 'package:siro_rider/views/widgets/my_textField.dart'; import 'package:siro_rider/views/widgets/my_textField.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@@ -74,18 +75,6 @@ class _D {
stops: const [0.0, 0.5, 1.0], stops: const [0.0, 0.5, 1.0],
); );
static LinearGradient cardGradient() => LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
AppColor.secondaryColor.withValues(alpha: 0.98),
AppColor.secondaryColor
.withBlue(
((AppColor.secondaryColor.b * 255.0).round() + 12).clamp(0, 255),
)
.withValues(alpha: 0.95),
],
);
} }
// ───────────────────────────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────────────────────────
@@ -107,32 +96,38 @@ class MainBottomMenuMap extends StatelessWidget {
bottom: Get.height * .035, bottom: Get.height * .035,
left: 16, left: 16,
right: 16, right: 16,
child: AnimatedContainer( child: ClipRRect(
duration: _D.medium, borderRadius: BorderRadius.circular(_D.radiusCard),
curve: Curves.easeOutQuint, child: BackdropFilter(
constraints: BoxConstraints( filter: ImageFilter.blur(sigmaX: 14, sigmaY: 14),
maxHeight: controller.isMainBottomMenuMap child: AnimatedContainer(
? Get.height * 0.4 duration: _D.medium,
: Get.height * 0.75, // الحد الأقصى للشاشة المفتوحة curve: Curves.easeOutQuint,
), constraints: BoxConstraints(
decoration: BoxDecoration( maxHeight: controller.isMainBottomMenuMap
gradient: _D.cardGradient(), ? Get.height * 0.4
borderRadius: BorderRadius.circular(_D.radiusCard), : Get.height * 0.75,
boxShadow: _D.cardShadow, ),
border: Border.all( decoration: BoxDecoration(
color: Get.isDarkMode color: AppColor.cardColor.withValues(alpha: 0.88),
? Colors.white.withValues(alpha: 0.15) borderRadius: BorderRadius.circular(_D.radiusCard),
: Colors.white.withValues(alpha: 0.65), boxShadow: _D.cardShadow,
width: 1.2, border: Border.all(
), color: Get.isDarkMode
), ? Colors.white.withValues(alpha: 0.15)
child: ClipRRect( : Colors.white.withValues(alpha: 0.65),
borderRadius: BorderRadius.circular(_D.radiusCard), width: 1.2,
child: SingleChildScrollView( ),
physics: const BouncingScrollPhysics(), ),
child: controller.isMainBottomMenuMap child: ClipRRect(
? const _CollapsedView() borderRadius: BorderRadius.circular(_D.radiusCard),
: const _ExpandedView(), child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: controller.isMainBottomMenuMap
? const _CollapsedView()
: const _ExpandedView(),
),
),
), ),
), ),
), ),
@@ -259,8 +254,8 @@ class _CollapsedView extends StatelessWidget {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: locationSearch.recentPlaces.length, itemCount: locationSearch.recentPlaces.length,
separatorBuilder: (_, __) => const SizedBox(width: 10), separatorBuilder: (_, __) => const SizedBox(width: 10),
itemBuilder: (context, index) => itemBuilder: (context, index) => _RecentPlaceChip(
_RecentPlaceChip(locationSearch: locationSearch, index: index), locationSearch: locationSearch, index: index),
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@@ -373,8 +368,9 @@ class _ExpandedView extends StatelessWidget {
...List.generate(locationSearch.activeMenuWaypointCount, (index) { ...List.generate(locationSearch.activeMenuWaypointCount, (index) {
final wpName = locationSearch.menuWaypointNames[index]; final wpName = locationSearch.menuWaypointNames[index];
final isSet = locationSearch.menuWaypoints[index] != null; final isSet = locationSearch.menuWaypoints[index] != null;
final Color accent = final Color accent = index == 0
index == 0 ? Colors.amber.shade600 : Colors.deepPurple.shade400; ? Colors.amber.shade600
: Colors.deepPurple.shade400;
final Color soft = final Color soft =
index == 0 ? Colors.amber.shade50 : Colors.deepPurple.shade50; index == 0 ? Colors.amber.shade50 : Colors.deepPurple.shade50;
@@ -383,10 +379,13 @@ class _ExpandedView extends StatelessWidget {
showTopLine: true, showTopLine: true,
showBottomLine: true, showBottomLine: true,
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), padding:
const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(colors: [
colors: [soft.withValues(alpha: 0.9), soft.withValues(alpha: 0.6)]), soft.withValues(alpha: 0.9),
soft.withValues(alpha: 0.6)
]),
borderRadius: BorderRadius.circular(_D.radiusInner), borderRadius: BorderRadius.circular(_D.radiusInner),
border: Border.all( border: Border.all(
color: isSet color: isSet
@@ -398,8 +397,8 @@ class _ExpandedView extends StatelessWidget {
Container( Container(
width: 26, width: 26,
height: 26, height: 26,
decoration: decoration: BoxDecoration(
BoxDecoration(color: accent, shape: BoxShape.circle), color: accent, shape: BoxShape.circle),
child: Center( child: Center(
child: Text('${index + 1}', child: Text('${index + 1}',
style: const TextStyle( style: const TextStyle(
@@ -421,7 +420,8 @@ class _ExpandedView extends StatelessWidget {
color: isSet color: isSet
? accent.withValues(alpha: 0.9) ? accent.withValues(alpha: 0.9)
: Colors.grey.shade400, : Colors.grey.shade400,
fontWeight: isSet ? FontWeight.w600 : FontWeight.w400, fontWeight:
isSet ? FontWeight.w600 : FontWeight.w400,
), ),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@@ -433,7 +433,8 @@ class _ExpandedView extends StatelessWidget {
width: 28, width: 28,
height: 28, height: 28,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.red.shade50, shape: BoxShape.circle), color: Colors.red.shade50,
shape: BoxShape.circle),
child: Icon(Icons.close_rounded, child: Icon(Icons.close_rounded,
color: Colors.red.shade400, size: 15), color: Colors.red.shade400, size: 15),
), ),
@@ -454,11 +455,12 @@ class _ExpandedView extends StatelessWidget {
onTap: () => locationSearch.addMenuWaypoint(), onTap: () => locationSearch.addMenuWaypoint(),
borderRadius: BorderRadius.circular(_D.radiusInner), borderRadius: BorderRadius.circular(_D.radiusInner),
child: Container( child: Container(
padding: padding: const EdgeInsets.symmetric(
const EdgeInsets.symmetric(horizontal: 16, vertical: 12), horizontal: 16, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(_D.radiusInner), borderRadius: BorderRadius.circular(_D.radiusInner),
border: Border.all(color: Colors.orange.shade200, width: 1.5), border:
Border.all(color: Colors.orange.shade200, width: 1.5),
color: Colors.orange.shade50.withValues(alpha: 0.6), color: Colors.orange.shade50.withValues(alpha: 0.6),
), ),
child: Row( child: Row(
@@ -510,8 +512,8 @@ class _ExpandedView extends StatelessWidget {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: locationSearch.recentPlaces.length, itemCount: locationSearch.recentPlaces.length,
separatorBuilder: (_, __) => const SizedBox(width: 10), separatorBuilder: (_, __) => const SizedBox(width: 10),
itemBuilder: (context, index) => itemBuilder: (context, index) => _RecentPlaceChip(
_RecentPlaceChip(locationSearch: locationSearch, index: index), locationSearch: locationSearch, index: index),
), ),
), ),
@@ -611,7 +613,8 @@ class _ExpandedView extends StatelessWidget {
class _MapPickerOverlay extends StatelessWidget { class _MapPickerOverlay extends StatelessWidget {
const _MapPickerOverlay(); const _MapPickerOverlay();
String _getModeTitle(LocationSearchController locationSearch, BuildContext context) { String _getModeTitle(
LocationSearchController locationSearch, BuildContext context) {
if (locationSearch.isPickingWaypoint) { if (locationSearch.isPickingWaypoint) {
return 'Move map to set stop'.tr + return 'Move map to set stop'.tr +
' ${locationSearch.pickingWaypointIndex + 1}'.tr; ' ${locationSearch.pickingWaypointIndex + 1}'.tr;
@@ -634,7 +637,8 @@ class _MapPickerOverlay extends StatelessWidget {
return 'Move map to select destination'.tr; return 'Move map to select destination'.tr;
} }
String _getConfirmLabel(LocationSearchController locationSearch, BuildContext context) { String _getConfirmLabel(
LocationSearchController locationSearch, BuildContext context) {
if (locationSearch.isPickingWaypoint) return 'Set as Stop'.tr; if (locationSearch.isPickingWaypoint) return 'Set as Stop'.tr;
if (locationSearch.passengerStartLocationFromMap) { if (locationSearch.passengerStartLocationFromMap) {
return 'Confirm Pickup Location'.tr; return 'Confirm Pickup Location'.tr;
@@ -656,7 +660,8 @@ class _MapPickerOverlay extends StatelessWidget {
Color _getModeColor(LocationSearchController locationSearch) { Color _getModeColor(LocationSearchController locationSearch) {
if (locationSearch.isPickingWaypoint) return Colors.orange.shade600; if (locationSearch.isPickingWaypoint) return Colors.orange.shade600;
if (locationSearch.passengerStartLocationFromMap) return Colors.green.shade600; if (locationSearch.passengerStartLocationFromMap)
return Colors.green.shade600;
if (locationSearch.workLocationFromMap) return Colors.blue.shade600; if (locationSearch.workLocationFromMap) return Colors.blue.shade600;
if (locationSearch.homeLocationFromMap) return Colors.orange.shade600; if (locationSearch.homeLocationFromMap) return Colors.orange.shade600;
return AppColor.primaryColor; return AppColor.primaryColor;
@@ -678,14 +683,16 @@ class _MapPickerOverlay extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Container( Container(
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 14), padding:
const EdgeInsets.symmetric(horizontal: 18, vertical: 14),
decoration: BoxDecoration( decoration: BoxDecoration(
color: modeColor, color: modeColor,
borderRadius: BorderRadius.circular(_D.radiusCard), borderRadius: BorderRadius.circular(_D.radiusCard),
), ),
child: Row( child: Row(
children: [ children: [
Icon(_getModeIcon(locationSearch), color: Colors.white, size: 19), Icon(_getModeIcon(locationSearch),
color: Colors.white, size: 19),
const SizedBox(width: 14), const SizedBox(width: 14),
Expanded( Expanded(
child: Text( child: Text(
@@ -713,7 +720,8 @@ class _MapPickerOverlay extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(20, 18, 20, 2), padding: const EdgeInsets.fromLTRB(20, 18, 20, 2),
child: Row( child: Row(
children: [ children: [
Icon(Icons.gps_fixed_rounded, color: modeColor, size: 16), Icon(Icons.gps_fixed_rounded,
color: modeColor, size: 16),
const SizedBox(width: 14), const SizedBox(width: 14),
Expanded( Expanded(
child: Text( child: Text(
@@ -737,7 +745,8 @@ class _MapPickerOverlay extends StatelessWidget {
child: OutlinedButton( child: OutlinedButton(
onPressed: () { onPressed: () {
mapEngine.isPickerShown = false; mapEngine.isPickerShown = false;
locationSearch.passengerStartLocationFromMap = false; locationSearch.passengerStartLocationFromMap =
false;
locationSearch.startLocationFromMap = false; locationSearch.startLocationFromMap = false;
locationSearch.workLocationFromMap = false; locationSearch.workLocationFromMap = false;
locationSearch.homeLocationFromMap = false; locationSearch.homeLocationFromMap = false;
@@ -758,10 +767,12 @@ class _MapPickerOverlay extends StatelessWidget {
Expanded( Expanded(
flex: 3, flex: 3,
child: ElevatedButton( child: ElevatedButton(
onPressed: () => _onConfirmTap(mapEngine, locationSearch, context), onPressed: () => _onConfirmTap(
mapEngine, locationSearch, context),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: modeColor), backgroundColor: modeColor),
child: Text(_getConfirmLabel(locationSearch, context), child: Text(
_getConfirmLabel(locationSearch, context),
style: const TextStyle(color: Colors.white)), style: const TextStyle(color: Colors.white)),
), ),
), ),
@@ -778,16 +789,18 @@ class _MapPickerOverlay extends StatelessWidget {
); );
} }
Future<void> _onConfirmTap( Future<void> _onConfirmTap(MapEngineController mapEngine,
MapEngineController mapEngine, LocationSearchController locationSearch, BuildContext context) async { LocationSearchController locationSearch, BuildContext context) async {
final rideLifecycle = Get.find<RideLifecycleController>(); final rideLifecycle = Get.find<RideLifecycleController>();
Log.print( Log.print(
'🔘 _onConfirmTap: isPickingWaypoint=${locationSearch.isPickingWaypoint}, newMyLocation=${locationSearch.newMyLocation}'); '🔘 _onConfirmTap: isPickingWaypoint=${locationSearch.isPickingWaypoint}, newMyLocation=${locationSearch.newMyLocation}');
await Future.delayed(const Duration(milliseconds: 280)); await Future.delayed(const Duration(milliseconds: 280));
final LatLng currentCameraPosition = LatLng( final LatLng currentCameraPosition = LatLng(
locationSearch.newMyLocation.latitude, locationSearch.newMyLocation.longitude); locationSearch.newMyLocation.latitude,
locationSearch.newMyLocation.longitude);
if (locationSearch.isPickingWaypoint && locationSearch.pickingWaypointIndex >= 0) { if (locationSearch.isPickingWaypoint &&
locationSearch.pickingWaypointIndex >= 0) {
locationSearch.setMenuWaypointFromMap( locationSearch.setMenuWaypointFromMap(
locationSearch.pickingWaypointIndex, currentCameraPosition); locationSearch.pickingWaypointIndex, currentCameraPosition);
mySnackbarSuccess('Waypoint has been set successfully'.tr); mySnackbarSuccess('Waypoint has been set successfully'.tr);
@@ -810,7 +823,8 @@ class _MapPickerOverlay extends StatelessWidget {
mapEngine.mainBottomMenuMapHeight = Get.height * .22; mapEngine.mainBottomMenuMapHeight = Get.height * .22;
mapEngine.update(); mapEngine.update();
locationSearch.update(); locationSearch.update();
await rideLifecycle.getDirectionMap('${start.latitude},${start.longitude}', await rideLifecycle.getDirectionMap(
'${start.latitude},${start.longitude}',
'${locationSearch.myDestination.latitude},${locationSearch.myDestination.longitude}'); '${locationSearch.myDestination.latitude},${locationSearch.myDestination.longitude}');
rideLifecycle.showBottomSheet1(); rideLifecycle.showBottomSheet1();
return; return;
@@ -953,7 +967,8 @@ class _RecentPlaceChip extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon(Icons.history_rounded, Icon(Icons.history_rounded,
size: 14, color: AppColor.primaryColor.withValues(alpha: 0.7)), size: 14,
color: AppColor.primaryColor.withValues(alpha: 0.7)),
const SizedBox(width: 7), const SizedBox(width: 7),
Text(place['name'] ?? '', Text(place['name'] ?? '',
style: TextStyle( style: TextStyle(
@@ -1147,8 +1162,8 @@ class FaviouratePlacesDialog extends StatelessWidget {
), ),
), ),
), ),
confirm: confirm: MyElevatedButton(
MyElevatedButton(title: 'Back'.tr, onPressed: () => Get.back()), title: 'Back'.tr, onPressed: () => Get.back()),
); );
}, },
child: Padding( child: Padding(