9/10/1
This commit is contained in:
@@ -98,18 +98,19 @@ class LoginController extends GetxController {
|
||||
'token': box.read(BoxName.tokenFCM),
|
||||
'passengerID': box.read(BoxName.passengerID).toString()
|
||||
});
|
||||
Get.defaultDialog(
|
||||
title: 'Device Change Detected'.tr,
|
||||
middleText:
|
||||
'You can only use one device at a time. This device will now be set as your active device.'
|
||||
.tr,
|
||||
textConfirm: 'OK'.tr,
|
||||
confirmTextColor: Colors.white,
|
||||
onConfirm: () {
|
||||
Get.back();
|
||||
Get.offAll(() => const MapPagePassenger());
|
||||
},
|
||||
);
|
||||
// Get.defaultDialog(
|
||||
// title: 'Device Change Detected'.tr,
|
||||
// middleText:
|
||||
// 'You can only use one device at a time. This device will now be set as your active device.'
|
||||
// .tr,
|
||||
// textConfirm: 'OK'.tr,
|
||||
// confirmTextColor: Colors.white,
|
||||
// onConfirm: () {
|
||||
// Get.back();
|
||||
// Get.offAll(() => const MapPagePassenger());
|
||||
// },
|
||||
// );
|
||||
// Get.snackbar('title', 'message');
|
||||
}
|
||||
}
|
||||
Get.offAll(() => const MapPagePassenger());
|
||||
|
||||
@@ -20,7 +20,8 @@ import '../functions/sms_controller.dart';
|
||||
class RegisterController extends GetxController {
|
||||
final formKey = GlobalKey<FormState>();
|
||||
final formKey3 = GlobalKey<FormState>();
|
||||
|
||||
List<String> countryCodes = ['+1', '+91', '+44'];
|
||||
String selectedCountryCode = '+1';
|
||||
TextEditingController firstNameController = TextEditingController();
|
||||
TextEditingController lastNameController = TextEditingController();
|
||||
TextEditingController emailController = TextEditingController();
|
||||
@@ -40,6 +41,11 @@ class RegisterController extends GetxController {
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
void updateCountryCode(String newCode) {
|
||||
selectedCountryCode = newCode;
|
||||
update();
|
||||
}
|
||||
|
||||
void startTimer() {
|
||||
_timer?.cancel(); // Cancel any existing timer
|
||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
|
||||
@@ -11,9 +11,10 @@ class AccessTokenManager {
|
||||
|
||||
factory AccessTokenManager(String jsonKey) {
|
||||
if (_instance._isServiceAccountKeyInitialized()) {
|
||||
// Prevent re-initialization
|
||||
print('Service account key already initialized.');
|
||||
return _instance;
|
||||
}
|
||||
print('Initializing service account key.');
|
||||
_instance.serviceAccountJsonKey = jsonKey;
|
||||
return _instance;
|
||||
}
|
||||
@@ -28,23 +29,45 @@ class AccessTokenManager {
|
||||
}
|
||||
|
||||
Future<String> getAccessToken() async {
|
||||
if (_accessToken != null && DateTime.now().isBefore(_expiryDate!)) {
|
||||
return _accessToken!.data;
|
||||
}
|
||||
print('Attempting to get a new access token...');
|
||||
|
||||
try {
|
||||
// Parse service account credentials from JSON
|
||||
print('Parsing service account credentials...');
|
||||
final serviceAccountCredentials = ServiceAccountCredentials.fromJson(
|
||||
json.decode(serviceAccountJsonKey));
|
||||
|
||||
// Log service account email (or other non-sensitive information)
|
||||
print('Service account email: ${serviceAccountCredentials.email}');
|
||||
|
||||
// Create an authenticated client via the service account
|
||||
print('Creating authenticated client via service account...');
|
||||
final client = await clientViaServiceAccount(
|
||||
serviceAccountCredentials,
|
||||
['https://www.googleapis.com/auth/firebase.messaging'],
|
||||
);
|
||||
|
||||
// Log successful client creation
|
||||
print('Authenticated client created successfully.');
|
||||
|
||||
// Update the access token and expiry date
|
||||
_accessToken = client.credentials.accessToken;
|
||||
_expiryDate = client.credentials.accessToken.expiry;
|
||||
|
||||
// Log the obtained token and expiry time
|
||||
print('Access token obtained: ${_accessToken!.data}');
|
||||
print('Token expiry date: $_expiryDate');
|
||||
|
||||
// Close the client to prevent resource leaks
|
||||
print('Closing authenticated client...');
|
||||
client.close();
|
||||
|
||||
// Return the newly fetched access token
|
||||
return _accessToken!.data;
|
||||
} catch (e) {
|
||||
throw Exception('Failed to obtain access token');
|
||||
// Log error if token fetch fails
|
||||
print('Failed to obtain a new access token: $e');
|
||||
throw Exception('Failed to obtain a new access token: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,13 +610,27 @@ class FirebaseMessagesController extends GetxController {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print(
|
||||
'Notification sent successfully. Status code: ${response.statusCode}');
|
||||
print('Notification sent successfully.');
|
||||
print('Response body: ${response.body}');
|
||||
} else {
|
||||
print(
|
||||
'Failed to send notification. Status code: ${response.statusCode}');
|
||||
print('Response body: ${response.body}');
|
||||
|
||||
// Parse the response body to handle specific errors like 'UNREGISTERED'
|
||||
final responseBody = jsonDecode(response.body);
|
||||
if (responseBody['error'] != null &&
|
||||
responseBody['error']['status'] == 'NOT_FOUND' &&
|
||||
responseBody['error']['details'] != null) {
|
||||
for (var detail in responseBody['error']['details']) {
|
||||
if (detail['errorCode'] == 'UNREGISTERED') {
|
||||
print(
|
||||
'FCM token is unregistered or invalid. Consider removing this token.');
|
||||
// Remove the unregistered token from your database here.
|
||||
// Example: removeTokenFromDatabase(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error sending notification: $e');
|
||||
@@ -721,15 +735,27 @@ class FirebaseMessagesController extends GetxController {
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print(
|
||||
'Notification sent successfully. Status code: ${response.statusCode}');
|
||||
print('Notification sent successfully.');
|
||||
print('Response body: ${response.body}');
|
||||
} else {
|
||||
print(
|
||||
'Failed to send notification. Status code: ${response.statusCode}');
|
||||
print('Response body: ${response.body}');
|
||||
|
||||
// Parse the response body to handle specific errors like 'UNREGISTERED'
|
||||
final responseBody = jsonDecode(response.body);
|
||||
if (responseBody['error'] != null &&
|
||||
responseBody['error']['status'] == 'NOT_FOUND' &&
|
||||
responseBody['error']['details'] != null) {
|
||||
for (var detail in responseBody['error']['details']) {
|
||||
if (detail['errorCode'] == 'UNREGISTERED') {
|
||||
print(
|
||||
'FCM token is unregistered or invalid. Consider removing this token.');
|
||||
// Remove the unregistered token from your database if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error sending notification: $e');
|
||||
@@ -785,10 +811,26 @@ class FirebaseMessagesController extends GetxController {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Notification sent successfully
|
||||
print('Notification sent successfully.');
|
||||
print('Response body: ${response.body}');
|
||||
} else {
|
||||
// Handle error response
|
||||
'Failed to send notification. Status code: ${response.statusCode}';
|
||||
print(
|
||||
'Failed to send notification. Status code: ${response.statusCode}');
|
||||
print('Response body: ${response.body}');
|
||||
|
||||
// Parse the response body to handle specific errors like 'UNREGISTERED'
|
||||
final responseBody = jsonDecode(response.body);
|
||||
if (responseBody['error'] != null &&
|
||||
responseBody['error']['status'] == 'NOT_FOUND' &&
|
||||
responseBody['error']['details'] != null) {
|
||||
for (var detail in responseBody['error']['details']) {
|
||||
if (detail['errorCode'] == 'UNREGISTERED') {
|
||||
print(
|
||||
'FCM token is unregistered or invalid. Consider removing this token.');
|
||||
// Remove the unregistered token from your database if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle other exceptions
|
||||
|
||||
@@ -3758,7 +3758,7 @@ class MapPassengerController extends GetxController {
|
||||
addCustomStepIcon();
|
||||
addCustomStartIcon();
|
||||
addCustomEndIcon();
|
||||
getLocation();
|
||||
await getLocation();
|
||||
|
||||
// await addToken();
|
||||
getKazanPercent();
|
||||
|
||||
@@ -596,7 +596,7 @@ iOS [https://getapp.cc/app/6458734951]
|
||||
'الرَّجَاء التَّحَرُّك إِلَى السَّيَّارَة الآن',
|
||||
'You will receive a code in WhatsApp Messenger':
|
||||
"سوف تتلقى رمزًا في واتساب ماسنجر",
|
||||
'Balash': 'أوفر كار',
|
||||
'Awfar Car': 'أوفر كار',
|
||||
"Old and affordable, perfect for budget rides.":
|
||||
"سيارة ميسورة التكلفة، مثالية للرحلات الاقتصادية.",
|
||||
" If you need to reach me, please contact the driver directly at":
|
||||
|
||||
@@ -104,20 +104,20 @@ class MyApp extends StatelessWidget {
|
||||
LocaleController localController = Get.put(LocaleController());
|
||||
|
||||
return GetMaterialApp(
|
||||
title: AppInformation.appName,
|
||||
translations: MyTranslation(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
locale: localController.language,
|
||||
theme: localController.appTheme,
|
||||
key: UniqueKey(),
|
||||
// routes: {'/':const HomePage()},
|
||||
// home: LoginCaptin());
|
||||
initialRoute: '/',
|
||||
getPages: [
|
||||
GetPage(name: '/', page: () => SplashScreen()),
|
||||
GetPage(name: '/tripmonitor', page: () => const TripMonitor()),
|
||||
],
|
||||
// home: SplashScreen()
|
||||
);
|
||||
title: AppInformation.appName,
|
||||
translations: MyTranslation(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
locale: localController.language,
|
||||
theme: localController.appTheme,
|
||||
key: UniqueKey(),
|
||||
// routes: {'/':const HomePage()},
|
||||
home: SplashScreen()
|
||||
// initialRoute: '/',
|
||||
// getPages: [
|
||||
// GetPage(name: '/', page: () => SplashScreen()),
|
||||
// GetPage(name: '/tripmonitor', page: () => const TripMonitor()),
|
||||
// ],
|
||||
// home: SplashScreen()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ class SmsSignupEgypt extends StatelessWidget {
|
||||
body: [
|
||||
GetBuilder<RegisterController>(builder: (registerController) {
|
||||
return ListView(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Logo at the top
|
||||
Padding(
|
||||
@@ -48,44 +47,68 @@ class SmsSignupEgypt extends StatelessWidget {
|
||||
style: AppStyle.title,
|
||||
),
|
||||
),
|
||||
// Phone number input field
|
||||
// Phone number input field with country code dropdown
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: !registerController.isSent
|
||||
? Form(
|
||||
key: registerController.formKey3,
|
||||
child: MyTextForm(
|
||||
controller: registerController.phoneController,
|
||||
label: 'Enter your phone number'.tr,
|
||||
hint: 'Enter your phone number'.tr,
|
||||
type: TextInputType.phone),
|
||||
)
|
||||
: Container(
|
||||
decoration: AppStyle.boxDecoration1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
registerController.phoneController.text,
|
||||
style: AppStyle.title,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: !registerController.isSent
|
||||
? Form(
|
||||
key: registerController.formKey3,
|
||||
child: Row(
|
||||
children: [
|
||||
// Country Code Dropdown
|
||||
DropdownButton<String>(
|
||||
value: registerController.selectedCountryCode,
|
||||
items: registerController.countryCodes
|
||||
.map((String code) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: code,
|
||||
child: Text(code),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (String? newValue) {
|
||||
registerController.updateCountryCode(newValue!);
|
||||
},
|
||||
),
|
||||
// Spacer
|
||||
const SizedBox(width: 10),
|
||||
// Phone Number Input Field
|
||||
Expanded(
|
||||
child: MyTextForm(
|
||||
controller:
|
||||
registerController.phoneController,
|
||||
label: 'Enter your phone number'.tr,
|
||||
hint: 'Enter your phone number'.tr,
|
||||
type: TextInputType.phone),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
decoration: AppStyle.boxDecoration1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
registerController.phoneController.text,
|
||||
style: AppStyle.title,
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
if (registerController.isSent)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: registerController.isSent
|
||||
? Form(
|
||||
key: registerController.formKey3,
|
||||
child: MyTextForm(
|
||||
controller: registerController.verifyCode,
|
||||
label: '5 digit'.tr,
|
||||
hint: '5 digit'.tr,
|
||||
type: TextInputType.number),
|
||||
)
|
||||
: const SizedBox()),
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Form(
|
||||
key: registerController.formKey3,
|
||||
child: MyTextForm(
|
||||
controller: registerController.verifyCode,
|
||||
label: '5 digit'.tr,
|
||||
hint: '5 digit'.tr,
|
||||
type: TextInputType.number),
|
||||
),
|
||||
),
|
||||
// Submit button
|
||||
MyElevatedButton(
|
||||
onPressed: () async {
|
||||
|
||||
@@ -36,7 +36,7 @@ List<CarType> carTypes = [
|
||||
image: 'assets/images/carspeed.png',
|
||||
),
|
||||
CarType(
|
||||
carType: 'Balash',
|
||||
carType: 'Awfar Car',
|
||||
carDetail: "Old and affordable, perfect for budget rides.".tr,
|
||||
image: 'assets/images/balash.png',
|
||||
),
|
||||
@@ -55,6 +55,11 @@ List<CarType> carTypes = [
|
||||
carDetail: 'Mishwar Vip without end point'.tr,
|
||||
image: 'assets/images/freeRide.png',
|
||||
),
|
||||
CarType(
|
||||
carType: 'Scooter Lady',
|
||||
carDetail: 'Scooter Lady'.tr,
|
||||
image: 'assets/images/moto.png',
|
||||
),
|
||||
];
|
||||
|
||||
class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
@@ -74,12 +79,12 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
image: 'assets/images/roundtrip.png',
|
||||
),
|
||||
);
|
||||
if (carTypes.length > 7) {
|
||||
carTypes.removeRange(7, carTypes.length);
|
||||
if (carTypes.length > 8) {
|
||||
carTypes.removeRange(8, carTypes.length);
|
||||
}
|
||||
} // Create a Set to remove duplicates based on the `carType` field
|
||||
else if (carTypes.length > 6) {
|
||||
carTypes.removeRange(6, carTypes.length);
|
||||
else if (carTypes.length > 7) {
|
||||
carTypes.removeRange(7, carTypes.length);
|
||||
}
|
||||
Set<CarType> uniqueCarTypes = {};
|
||||
uniqueCarTypes.addAll(carTypes);
|
||||
@@ -157,7 +162,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
? mapPassengerController
|
||||
.totalPassengerSpeed
|
||||
.toStringAsFixed(2)
|
||||
: carType.carType == 'Balash'
|
||||
: carType.carType == 'Awfar Car'
|
||||
? mapPassengerController
|
||||
.totalPassengerBalash
|
||||
.toStringAsFixed(2)
|
||||
@@ -170,12 +175,18 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
.totalPassengerLady
|
||||
.toStringAsFixed(2)
|
||||
: carType.carType ==
|
||||
'Rayeh Gai'
|
||||
'Scooter'
|
||||
? mapPassengerController
|
||||
.totalPassengerRayehGaiBalash
|
||||
.totalPassengerScooter
|
||||
.toStringAsFixed(
|
||||
2)
|
||||
: '50',
|
||||
: carType.carType ==
|
||||
'Rayeh Gai'
|
||||
? mapPassengerController
|
||||
.totalPassengerRayehGaiBalash
|
||||
.toStringAsFixed(
|
||||
2)
|
||||
: '50',
|
||||
style:
|
||||
AppStyle.title.copyWith(fontSize: 20),
|
||||
),
|
||||
@@ -247,7 +258,8 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
)
|
||||
],
|
||||
)
|
||||
: carType.carType == 'Balash' &&
|
||||
: carType.carType ==
|
||||
'Awfar Car' &&
|
||||
(mapPassengerController
|
||||
.totalPassengerBalash >
|
||||
20)
|
||||
@@ -487,7 +499,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
mapPassengerController
|
||||
.totalPassengerBalash;
|
||||
Get.defaultDialog(
|
||||
title: 'Balash'.tr,
|
||||
title: 'Awfar Car'.tr,
|
||||
titleStyle: AppStyle.title,
|
||||
content: CarDialogue(
|
||||
textToSpeechController:
|
||||
@@ -556,6 +568,39 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
}));
|
||||
} else if (mapPassengerController
|
||||
.selectedIndex ==
|
||||
4) {
|
||||
box.write(BoxName.carType, 'ScooterLady');
|
||||
mapPassengerController.totalPassenger =
|
||||
mapPassengerController
|
||||
.totalPassengerScooter;
|
||||
Get.defaultDialog(
|
||||
title: 'Scooter Lady'.tr,
|
||||
titleStyle: AppStyle.title,
|
||||
content: CarDialogue(
|
||||
textToSpeechController:
|
||||
textToSpeechController,
|
||||
image: 'assets/images/moto.png',
|
||||
text: 'This is only for Scooter Lady.'
|
||||
.tr),
|
||||
confirm: MyElevatedButton(
|
||||
kolor: AppColor.greenColor,
|
||||
title: 'Next'.tr,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
mapPassengerController
|
||||
.isBottomSheetShown = false;
|
||||
mapPassengerController.update();
|
||||
mapPassengerController
|
||||
.changeCashConfirmPageShown();
|
||||
}),
|
||||
cancel: MyElevatedButton(
|
||||
title: 'Cancel'.tr,
|
||||
kolor: AppColor.redColor,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
}));
|
||||
} else if (mapPassengerController
|
||||
.selectedIndex ==
|
||||
6) {
|
||||
@@ -698,7 +743,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Text('Balash'.tr),
|
||||
Text('Awfar Car'.tr),
|
||||
Text(mapPassengerController
|
||||
.totalPassengerRayehGaiBalash
|
||||
.toString() +
|
||||
@@ -828,7 +873,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
||||
Future<dynamic> balashDialougRayehGai(
|
||||
MapPassengerController mapPassengerController) {
|
||||
return Get.defaultDialog(
|
||||
title: 'Balash'.tr,
|
||||
title: 'Awfar Car'.tr,
|
||||
content: Column(
|
||||
children: [
|
||||
SizedBox(height: 60, child: HourPickerExample()),
|
||||
|
||||
@@ -90,33 +90,33 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
// AnimatedContainer(
|
||||
// duration: const Duration(microseconds: 200),
|
||||
// width: controller.widthMapTypeAndTraffic,
|
||||
// decoration: BoxDecoration(
|
||||
// color: AppColor.secondaryColor,
|
||||
// border: Border.all(),
|
||||
// borderRadius: BorderRadius.circular(15)),
|
||||
// child: IconButton(
|
||||
// onPressed: () async {
|
||||
// FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
// 'Order'.tr,
|
||||
// 'from: ',
|
||||
// // jsonDecode(value)['message'].toString(),
|
||||
// 'dEugS-JOT4Ka5riF4s5TEN:APA91bEDL_W7BuEQGbyL-RMaKiMWDlURXhFuaybe5WurTUV8K5eIooSGe22yY22_U2hEZcfPr46ig1v--l00dbOGiivazxvmTyhUyQQW6lJsuIN-wordGtBxtREyeYtEKvxIa1J4ApEu',
|
||||
// 'order.wav'
|
||||
AnimatedContainer(
|
||||
duration: const Duration(microseconds: 200),
|
||||
width: controller.widthMapTypeAndTraffic,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.secondaryColor,
|
||||
border: Border.all(),
|
||||
borderRadius: BorderRadius.circular(15)),
|
||||
child: IconButton(
|
||||
onPressed: () async {
|
||||
FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
'Order'.tr,
|
||||
'from: ',
|
||||
// jsonDecode(value)['message'].toString(),
|
||||
'fBJObfCd9kHxnzMsEzeh2R:APA91bEE435Fvg1ixHs2_GPJJzz5CztswczqAi-PJfS6gSzg5U0eHvOi_v2J3imqPeWvkic-Dhhq2Pzrva2LncvS3MofCTJyM8AVScktGUuB6NvgyeK_5er8yDPrp2-2fqUz7VOXflni',
|
||||
'order.wav'
|
||||
|
||||
// // polylineCoordinates.toString()
|
||||
// );
|
||||
// // print(box.read(BoxName.tokenFCM));
|
||||
// //
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.voice_chat,
|
||||
// size: 29,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// polylineCoordinates.toString()
|
||||
);
|
||||
// print(box.read(BoxName.tokenFCM));
|
||||
//
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.voice_chat,
|
||||
size: 29,
|
||||
),
|
||||
),
|
||||
),
|
||||
// AnimatedContainer(
|
||||
// duration: const Duration(microseconds: 200),
|
||||
// width: controller.widthMapTypeAndTraffic,
|
||||
|
||||
Reference in New Issue
Block a user