4/26/1
This commit is contained in:
@@ -147,6 +147,10 @@ class AppLink {
|
|||||||
static String uploadImage1 = "$server/uploadImage1.php";
|
static String uploadImage1 = "$server/uploadImage1.php";
|
||||||
static String uploadImagePortrate = "$server/uploadImagePortrate.php";
|
static String uploadImagePortrate = "$server/uploadImagePortrate.php";
|
||||||
static String uploadImageType = "$server/uploadImageType.php";
|
static String uploadImageType = "$server/uploadImageType.php";
|
||||||
|
//=============egypt documents ==============
|
||||||
|
static String uploadEgyptidFront =
|
||||||
|
"$server/EgyptDocuments/uploadEgyptidFront.php";
|
||||||
|
static String uploadEgypt = "$server/uploadEgypt.php";
|
||||||
|
|
||||||
//==================certifcate==========
|
//==================certifcate==========
|
||||||
static String location = '$server/ride/location';
|
static String location = '$server/ride/location';
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ class CarRegistrationRecognizerController extends GetxController {
|
|||||||
}
|
}
|
||||||
// print('jsonOutput------------------------------');
|
// print('jsonOutput------------------------------');
|
||||||
// print(result);
|
// print(result);
|
||||||
Map result2 = await LlamaAi().getCarRegistrationData(result);
|
Map result2 = await LlamaAi().getCarRegistrationData(result,
|
||||||
|
'vin,make,made,year,expiration_date,color,owner,registration_date'); //
|
||||||
|
|
||||||
// Assign the result to the extracted variable
|
// Assign the result to the extracted variable
|
||||||
extracted = result2;
|
extracted = result2;
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ class DriverTipWidget extends StatelessWidget {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(6),
|
padding: const EdgeInsets.all(6),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${controller.totalPassenger * double.parse(box.read(BoxName.tipPercentage))} ${box.read(BoxName.countryCode) == 'Egypt' ? 'LE'.tr : 'JOD'.tr}',
|
'${(controller.totalPassenger) * (double.parse(box.read(BoxName.tipPercentage.toString())))} ${box.read(BoxName.countryCode) == 'Egypt' ? 'LE'.tr : 'JOD'.tr}',
|
||||||
style: AppStyle.title,
|
style: AppStyle.title,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:SEFER/constant/box_name.dart';
|
import 'package:SEFER/constant/box_name.dart';
|
||||||
|
import 'package:SEFER/constant/links.dart';
|
||||||
import 'package:SEFER/main.dart';
|
import 'package:SEFER/main.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:SEFER/env/env.dart';
|
import 'package:SEFER/env/env.dart';
|
||||||
|
|
||||||
import '../../constant/api_key.dart';
|
import '../../constant/api_key.dart';
|
||||||
|
import 'gemeni.dart';
|
||||||
|
import 'llama_ai.dart';
|
||||||
|
import 'upload_image.dart';
|
||||||
|
|
||||||
class CRUD {
|
class CRUD {
|
||||||
Future<dynamic> get({
|
Future<dynamic> get({
|
||||||
@@ -62,21 +66,25 @@ class CRUD {
|
|||||||
Future<dynamic> getLlama({
|
Future<dynamic> getLlama({
|
||||||
required String link,
|
required String link,
|
||||||
required String payload,
|
required String payload,
|
||||||
|
required String prompt,
|
||||||
}) async {
|
}) async {
|
||||||
var url = Uri.parse(
|
var url = Uri.parse(
|
||||||
link,
|
link,
|
||||||
);
|
);
|
||||||
var headers = {
|
var headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization': 'Bearer ${Env.llamaKey}'
|
'Authorization':
|
||||||
|
'Bearer LL-X5lJ0Px9CzKK0HTuVZ3u2u4v3tGWkImLTG7okGRk4t25zrsLqJ0qNoUzZ2x4ciPy'
|
||||||
|
// 'Authorization': 'Bearer ${Env.llamaKey}'
|
||||||
};
|
};
|
||||||
var data = json.encode({
|
var data = json.encode({
|
||||||
"model": "llama-13b-chat",
|
"model": "Llama-3-70b-Inst-FW",
|
||||||
|
// "model": "llama-13b-chat",
|
||||||
"messages": [
|
"messages": [
|
||||||
{
|
{
|
||||||
"role": "user",
|
"role": "user",
|
||||||
"content":
|
"content":
|
||||||
"Extract the desired information from the following passage as json decoded like vin,make,made,year,expiration_date,color,owner,registration_date just in this:\n\n$payload"
|
"Extract the desired information from the following passage as json decoded like $prompt just in this:\n\n$payload"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"temperature": 0.9
|
"temperature": 0.9
|
||||||
@@ -93,6 +101,44 @@ class CRUD {
|
|||||||
return response.statusCode;
|
return response.statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future allMethodForAI(String prompt, linkPHP, imagePath) async {
|
||||||
|
await ImageController().choosImage(linkPHP, imagePath);
|
||||||
|
Future.delayed(const Duration(seconds: 2));
|
||||||
|
String extracted =
|
||||||
|
await arabicTextExtractByVisionAndAI(imagePath: imagePath);
|
||||||
|
await AI().geminiAiExtraction(prompt, extracted);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> arabicTextExtractByVisionAndAI({
|
||||||
|
required String imagePath,
|
||||||
|
}) async {
|
||||||
|
var headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Ocp-Apim-Subscription-Key': '21010e54b50f41a4904708c526e102df'
|
||||||
|
};
|
||||||
|
var url = Uri.parse(
|
||||||
|
'https://ocrhamza.cognitiveservices.azure.com/vision/v2.1/ocr?language=ar',
|
||||||
|
);
|
||||||
|
String imagePathFull =
|
||||||
|
'${AppLink.server}card_image/$imagePath-${box.read(BoxName.driverID) ?? box.read(BoxName.passengerID)}.jpg';
|
||||||
|
|
||||||
|
print('imagePath=$imagePathFull');
|
||||||
|
var requestBody = {"url": imagePathFull};
|
||||||
|
var response = await http.post(
|
||||||
|
url,
|
||||||
|
body: jsonEncode(requestBody), // Encode the JSON object to a string
|
||||||
|
headers: headers,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
var responseBody = jsonDecode(response.body);
|
||||||
|
// print(decode);
|
||||||
|
print('imagePath=$imagePathFull');
|
||||||
|
return responseBody.toString();
|
||||||
|
}
|
||||||
|
return response.statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
Future<dynamic> getChatGPT({
|
Future<dynamic> getChatGPT({
|
||||||
required String link,
|
required String link,
|
||||||
required String payload,
|
required String payload,
|
||||||
|
|||||||
@@ -158,6 +158,82 @@ class AI extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> geminiAiExtraction(String prompt, payload) async {
|
||||||
|
var requestBody = jsonEncode({
|
||||||
|
'contents': [
|
||||||
|
{
|
||||||
|
'parts': [
|
||||||
|
// {
|
||||||
|
// 'inlineData': {
|
||||||
|
// 'mimeType': 'image/jpeg',
|
||||||
|
// 'data': imageData,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
'text':
|
||||||
|
"Extract the desired information from the following passage as json decoded like $prompt just in this:\n\n$payload"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'generationConfig': {
|
||||||
|
'temperature': 0.4,
|
||||||
|
'topK': 32,
|
||||||
|
'topP': 1,
|
||||||
|
'maxOutputTokens': 4096,
|
||||||
|
'stopSequences': [],
|
||||||
|
},
|
||||||
|
'safety_settings': [
|
||||||
|
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
|
||||||
|
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
|
||||||
|
{
|
||||||
|
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
||||||
|
"threshold": "BLOCK_NONE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
||||||
|
"threshold": "BLOCK_NONE"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
print(requestBody);
|
||||||
|
|
||||||
|
final response = await http.post(
|
||||||
|
Uri.parse(
|
||||||
|
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
|
||||||
|
'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=AIzaSyCyoLcSkDzK5_SMe00nhut56SSXWPR074w'),
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: requestBody,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
var responseData = jsonDecode(response.body);
|
||||||
|
// Process the responseData as needed
|
||||||
|
// print(responseData);
|
||||||
|
|
||||||
|
var result = responseData['candidates'][0]['content']['parts'][0]['text'];
|
||||||
|
// print(jsonEncode(result));
|
||||||
|
// print((result));
|
||||||
|
// print(result['dob']);
|
||||||
|
RegExp regex = RegExp(r"```json([^`]*)```");
|
||||||
|
String? jsonString =
|
||||||
|
regex.firstMatch(responseData.toString())?.group(1)?.trim();
|
||||||
|
|
||||||
|
if (jsonString != null) {
|
||||||
|
// Convert the JSON object to a String
|
||||||
|
jsonString = jsonEncode(json.decode(jsonString));
|
||||||
|
print(jsonString);
|
||||||
|
} else {
|
||||||
|
print("JSON string not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rest of your code...
|
||||||
|
} else {
|
||||||
|
print('Request failed with status: ${response.statusCode}');
|
||||||
|
print('Request failed with status: ${response.body}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> getDriverLicenseJordanContent() async {
|
Future<void> getDriverLicenseJordanContent() async {
|
||||||
await pickImage();
|
await pickImage();
|
||||||
isloading = true;
|
isloading = true;
|
||||||
|
|||||||
@@ -2,19 +2,24 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:SEFER/constant/links.dart';
|
import 'package:SEFER/constant/links.dart';
|
||||||
import 'package:SEFER/controller/functions/crud.dart';
|
import 'package:SEFER/controller/functions/crud.dart';
|
||||||
|
import 'package:SEFER/controller/functions/gemeni.dart';
|
||||||
|
|
||||||
class LlamaAi {
|
class LlamaAi {
|
||||||
Future<Map> getCarRegistrationData(String input) async {
|
Future<Map> getCarRegistrationData(String input, prompt) async {
|
||||||
print(true);
|
print(true);
|
||||||
Map exrtatDataFinal = {};
|
Map exrtatDataFinal = {};
|
||||||
String oneLine = input.replaceAll('\n', ' ');
|
String oneLine = input.replaceAll('\n', ' ');
|
||||||
|
// print(oneLine);
|
||||||
// var res = await CRUD().getLlama(link: AppLink.gemini, payload: oneLine);
|
// var res = await CRUD().getLlama(link: AppLink.gemini, payload: oneLine);
|
||||||
var res = await CRUD().getLlama(link: AppLink.llama, payload: oneLine);
|
var res = await CRUD()
|
||||||
var decod = jsonDecode(res);
|
.getLlama(link: AppLink.llama, payload: oneLine, prompt: prompt);
|
||||||
// print(decod);
|
|
||||||
exrtatDataFinal = jsonDecode(
|
print(res);
|
||||||
extractDataFromJsonString(decod['choices'][0]['message']['content']));
|
var decod = jsonDecode(res.toString());
|
||||||
// print(jsonEncode(exrtatDataFinal));
|
print(decod);
|
||||||
|
// exrtatDataFinal = jsonDecode(extractDataFromJsonString(decod['choices']));
|
||||||
|
extractDataFromJsonString(decod['choices'][0]['message']['content']);
|
||||||
|
print(jsonEncode(exrtatDataFinal));
|
||||||
print(false);
|
print(false);
|
||||||
return exrtatDataFinal;
|
return exrtatDataFinal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ class TextToSpeechController extends GetxController {
|
|||||||
Future<void> initTts() async {
|
Future<void> initTts() async {
|
||||||
String? lang =
|
String? lang =
|
||||||
WidgetsBinding.instance.platformDispatcher.locale.countryCode;
|
WidgetsBinding.instance.platformDispatcher.locale.countryCode;
|
||||||
await flutterTts.setLanguage(box.read(BoxName.lang)); //'en-US' Set language
|
await flutterTts
|
||||||
|
.setLanguage(box.read(BoxName.lang).toString()); //'en-US' Set language
|
||||||
// await flutterTts.setLanguage('ar-SA'); //'en-US' Set language
|
// await flutterTts.setLanguage('ar-SA'); //'en-US' Set language
|
||||||
// await flutterTts.setLanguage(lang!); //'en-US' Set language
|
// await flutterTts.setLanguage(lang!); //'en-US' Set language
|
||||||
await flutterTts.setSpeechRate(0.5); // Adjust speech rate
|
await flutterTts.setSpeechRate(0.5); // Adjust speech rate
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'dart:io';
|
|||||||
import 'package:SEFER/constant/api_key.dart';
|
import 'package:SEFER/constant/api_key.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:image_cropper/image_cropper.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
@@ -14,23 +15,56 @@ import '../../main.dart';
|
|||||||
class ImageController extends GetxController {
|
class ImageController extends GetxController {
|
||||||
File? myImage;
|
File? myImage;
|
||||||
bool isloading = false;
|
bool isloading = false;
|
||||||
void choosImage(String link) async {
|
CroppedFile? croppedFile;
|
||||||
XFile? xFile = await ImagePicker().pickImage(source: ImageSource.gallery);
|
final picker = ImagePicker();
|
||||||
myImage = File(xFile!.path);
|
var image;
|
||||||
|
choosImage(String link, String imageType) async {
|
||||||
|
final pickedImage = await picker.pickImage(source: ImageSource.gallery);
|
||||||
|
image = File(pickedImage!.path);
|
||||||
|
croppedFile = await ImageCropper().cropImage(
|
||||||
|
sourcePath: image!.path,
|
||||||
|
aspectRatioPresets: [
|
||||||
|
CropAspectRatioPreset.square,
|
||||||
|
CropAspectRatioPreset.ratio3x2,
|
||||||
|
CropAspectRatioPreset.original,
|
||||||
|
CropAspectRatioPreset.ratio4x3,
|
||||||
|
CropAspectRatioPreset.ratio16x9
|
||||||
|
],
|
||||||
|
uiSettings: [
|
||||||
|
AndroidUiSettings(
|
||||||
|
toolbarTitle: 'Cropper'.tr,
|
||||||
|
toolbarColor: AppColor.blueColor,
|
||||||
|
toolbarWidgetColor: AppColor.yellowColor,
|
||||||
|
initAspectRatio: CropAspectRatioPreset.original,
|
||||||
|
lockAspectRatio: false),
|
||||||
|
IOSUiSettings(
|
||||||
|
title: 'Cropper'.tr,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
myImage = File(pickedImage.path);
|
||||||
isloading = true;
|
isloading = true;
|
||||||
update();
|
update();
|
||||||
var response = await uploadImage(
|
// Save the cropped image
|
||||||
myImage!,
|
File savedCroppedImage = File(croppedFile!.path);
|
||||||
{
|
print('link =$link');
|
||||||
'driverID': box.read(BoxName.driverID).toString(),
|
try {
|
||||||
},
|
await uploadImage(
|
||||||
link,
|
savedCroppedImage,
|
||||||
);
|
{
|
||||||
isloading = false;
|
'driverID':
|
||||||
update();
|
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
|
||||||
if (response['status'] == 'success') {
|
'imageType': imageType
|
||||||
Get.snackbar('Image Uploaded'.tr, 'Sucsses',
|
},
|
||||||
backgroundColor: AppColor.greenColor);
|
link,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
Get.snackbar('Image Upload Failed'.tr, e.toString(),
|
||||||
|
backgroundColor: AppColor.redColor);
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
isloading = false;
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +102,9 @@ class ImageController extends GetxController {
|
|||||||
var res = await http.Response.fromStream(myrequest);
|
var res = await http.Response.fromStream(myrequest);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
return jsonDecode(res.body);
|
return jsonDecode(res.body);
|
||||||
|
} else {
|
||||||
|
throw Exception(
|
||||||
|
'Failed to upload image: ${res.statusCode} - ${res.body}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,8 +107,10 @@ class MapPassengerController extends GetxController {
|
|||||||
bool isDriverInPassengerWay = false;
|
bool isDriverInPassengerWay = false;
|
||||||
bool isDriverArrivePassenger = false;
|
bool isDriverArrivePassenger = false;
|
||||||
bool startLocationFromMap = false;
|
bool startLocationFromMap = false;
|
||||||
|
bool passengerStartLocationFromMap = false;
|
||||||
bool workLocationFromMap = false;
|
bool workLocationFromMap = false;
|
||||||
bool homeLocationFromMap = false;
|
bool homeLocationFromMap = false;
|
||||||
|
bool isPassengerRideLocationWidget = false;
|
||||||
bool startLocationFromMap0 = false;
|
bool startLocationFromMap0 = false;
|
||||||
bool startLocationFromMap1 = false;
|
bool startLocationFromMap1 = false;
|
||||||
bool startLocationFromMap2 = false;
|
bool startLocationFromMap2 = false;
|
||||||
@@ -213,6 +215,7 @@ class MapPassengerController extends GetxController {
|
|||||||
late double totalCostPassenger = 0;
|
late double totalCostPassenger = 0;
|
||||||
late double totalPassengerComfort = 0;
|
late double totalPassengerComfort = 0;
|
||||||
late double totalPassengerComfortDiscount = 0;
|
late double totalPassengerComfortDiscount = 0;
|
||||||
|
late double totalPassengerSpeedDiscount = 0;
|
||||||
late double totalPassengerMotoDelivery = 0;
|
late double totalPassengerMotoDelivery = 0;
|
||||||
late double totalDriver = 0;
|
late double totalDriver = 0;
|
||||||
late double averageDuration = 0;
|
late double averageDuration = 0;
|
||||||
@@ -1403,10 +1406,11 @@ class MapPassengerController extends GetxController {
|
|||||||
Future cancelRide() async {
|
Future cancelRide() async {
|
||||||
//print("rideConfirm=$rideConfirm");
|
//print("rideConfirm=$rideConfirm");
|
||||||
|
|
||||||
if (rideConfirm == false) {
|
if (rideConfirm == false && statusRide != 'Apply') {
|
||||||
clearPlacesDestination();
|
clearPlacesDestination();
|
||||||
clearPolyline();
|
clearPolyline();
|
||||||
// clearPolylineAll();
|
// clearPolylineAll();
|
||||||
|
print('rideConfirm before is $rideConfirm');
|
||||||
data = [];
|
data = [];
|
||||||
changeCancelRidePageShow();
|
changeCancelRidePageShow();
|
||||||
if (rideId != 'yet') {
|
if (rideId != 'yet') {
|
||||||
@@ -1434,6 +1438,7 @@ class MapPassengerController extends GetxController {
|
|||||||
} else {
|
} else {
|
||||||
clearPlacesDestination();
|
clearPlacesDestination();
|
||||||
clearPolyline();
|
clearPolyline();
|
||||||
|
print('rideConfirm is $rideConfirm');
|
||||||
data = [];
|
data = [];
|
||||||
await CRUD().post(link: AppLink.updateDriverOrder, payload: {
|
await CRUD().post(link: AppLink.updateDriverOrder, payload: {
|
||||||
"order_id": rideId.toString(), // Convert to String
|
"order_id": rideId.toString(), // Convert to String
|
||||||
@@ -1484,7 +1489,7 @@ class MapPassengerController extends GetxController {
|
|||||||
} else {
|
} else {
|
||||||
isMainBottomMenuMap = !isMainBottomMenuMap;
|
isMainBottomMenuMap = !isMainBottomMenuMap;
|
||||||
mainBottomMenuMapHeight =
|
mainBottomMenuMapHeight =
|
||||||
isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .45;
|
isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .55;
|
||||||
isWayPointSheet = false;
|
isWayPointSheet = false;
|
||||||
if (heightMenuBool == true) {
|
if (heightMenuBool == true) {
|
||||||
getDrawerMenu();
|
getDrawerMenu();
|
||||||
@@ -2361,17 +2366,22 @@ class MapPassengerController extends GetxController {
|
|||||||
var totalDriver1 = costDistance + costDuration;
|
var totalDriver1 = costDistance + costDuration;
|
||||||
totalCostPassenger = totalDriver1 + (totalDriver1 * kazan / 100);
|
totalCostPassenger = totalDriver1 + (totalDriver1 * kazan / 100);
|
||||||
totalPassenger = costSpeed + (costSpeed * kazan / 100);
|
totalPassenger = costSpeed + (costSpeed * kazan / 100);
|
||||||
totalPassengerComfort = costComfort + (costComfort * kazan / 100);
|
totalPassengerComfort =
|
||||||
totalPassengerSpeed = costSpeed + (costSpeed * kazan / 100);
|
(costComfort + (costComfort * kazan / 100)).ceilToDouble();
|
||||||
|
totalPassengerSpeed =
|
||||||
|
(costSpeed + (costSpeed * kazan / 100)).ceilToDouble();
|
||||||
totalPassengerComfortDiscount =
|
totalPassengerComfortDiscount =
|
||||||
totalPassengerComfort + totalPassengerComfort * (kazan - 10) / 100;
|
totalPassengerComfort + totalPassengerComfort * (kazan - 0) / 100;
|
||||||
totalPassengerMotoDelivery = costDelivery + (costDelivery * kazan / 100);
|
totalPassengerSpeedDiscount =
|
||||||
|
totalPassengerSpeed + totalPassengerSpeed * (kazan - 2) / 100;
|
||||||
|
totalPassengerMotoDelivery =
|
||||||
|
(costDelivery + (costDelivery * kazan / 100)).ceilToDouble();
|
||||||
totalDriver = totalDriver1 + (totalDriver1 * kazan / 100);
|
totalDriver = totalDriver1 + (totalDriver1 * kazan / 100);
|
||||||
tax = totalCostPassenger * kazan / 100;
|
tax = totalCostPassenger * kazan / 100;
|
||||||
totalME = totalCostPassenger - tax;
|
totalME = totalCostPassenger - tax;
|
||||||
costForDriver = fuelPrice * (20 / 210) * distance;
|
costForDriver = fuelPrice * (20 / 210) * distance;
|
||||||
print('cost for driver = $costForDriver');
|
print('cost for driver = $costForDriver');
|
||||||
if (totalCostPassenger < 20) {
|
if (totalPassengerSpeed < 20) {
|
||||||
// for eygpt 20 le open ride
|
// for eygpt 20 le open ride
|
||||||
totalCostPassenger = 20;
|
totalCostPassenger = 20;
|
||||||
totalPassengerSpeed = 20;
|
totalPassengerSpeed = 20;
|
||||||
@@ -2491,7 +2501,7 @@ class MapPassengerController extends GetxController {
|
|||||||
payload: {'country': box.read(BoxName.countryCode).toString()},
|
payload: {'country': box.read(BoxName.countryCode).toString()},
|
||||||
);
|
);
|
||||||
if (res != 'failure') {
|
if (res != 'failure') {
|
||||||
// print(jsonDecode(res));
|
print(jsonDecode(res));
|
||||||
var json = jsonDecode(res);
|
var json = jsonDecode(res);
|
||||||
kazan = double.parse(json['message'][0]['kazan']);
|
kazan = double.parse(json['message'][0]['kazan']);
|
||||||
naturePrice = double.parse(json['message'][0]['naturePrice']);
|
naturePrice = double.parse(json['message'][0]['naturePrice']);
|
||||||
@@ -2511,7 +2521,7 @@ class MapPassengerController extends GetxController {
|
|||||||
payload: {'passenger_id': box.read(BoxName.passengerID)});
|
payload: {'passenger_id': box.read(BoxName.passengerID)});
|
||||||
if (res != 'failure') {
|
if (res != 'failure') {
|
||||||
print(jsonDecode(res)['message']['rating']);
|
print(jsonDecode(res)['message']['rating']);
|
||||||
passengerRate = jsonDecode(res)['message']['rating'];
|
passengerRate = jsonDecode(res)['message']['rating'] ?? 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -567,11 +567,19 @@ class MyTranslation extends Translations {
|
|||||||
"We Are Sorry That we dont have cars in your Location!":
|
"We Are Sorry That we dont have cars in your Location!":
|
||||||
"نعتذر لعدم وجود سيارات في موقعك!",
|
"نعتذر لعدم وجود سيارات في موقعك!",
|
||||||
"Choose from Map": "اختر من الخريطة",
|
"Choose from Map": "اختر من الخريطة",
|
||||||
|
'Pick your ride location on the map - Tap to confirm':
|
||||||
|
'حدد موقع الالتقاء على الخريطة - اضغط للتأكيد',
|
||||||
"To Work": "إلى العمل",
|
"To Work": "إلى العمل",
|
||||||
|
'Closest & Cheapest': ' الأقرب ',
|
||||||
"Work Saved": "تم حفظ العمل",
|
"Work Saved": "تم حفظ العمل",
|
||||||
"To Home": "إلى المنزل",
|
"To Home": "إلى المنزل",
|
||||||
"Home Saved": "تم حفظ المنزل",
|
"Home Saved": "تم حفظ المنزل",
|
||||||
"Click here point": "انقر هنا نقطة",
|
"Destination Selected":
|
||||||
|
"تم تحديد الوجهة:", // "Tam تحديد al-waṣʿah:", (literally "The destination has been determined:")
|
||||||
|
"Now select start pick":
|
||||||
|
"حدد موقع الانطلاق الآن:", // "Ḥaddid mowāqiʿ al-inṭilāq al-ʾān:", (literally "Specify the starting location now:")
|
||||||
|
"Pick from map": "اختيار من الخريطة",
|
||||||
|
"Click here point": "حدد هذا المكان",
|
||||||
"No Car in your site. Sorry!": "لا توجد سيارة في موقعك. آسف!",
|
"No Car in your site. Sorry!": "لا توجد سيارة في موقعك. آسف!",
|
||||||
"Nearest Car for you about ": "أقرب سيارة لك حوالي ",
|
"Nearest Car for you about ": "أقرب سيارة لك حوالي ",
|
||||||
"N/A": "غير متوفر",
|
"N/A": "غير متوفر",
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class DbSql {
|
|||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
latitude REAL,
|
latitude REAL,
|
||||||
longitude REAL,
|
longitude REAL,
|
||||||
name TEXT UNIQUE,
|
name TEXT ,
|
||||||
rate TEXT
|
rate TEXT
|
||||||
)
|
)
|
||||||
''');
|
''');
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:SEFER/views/notification/available_rides_page.dart';
|
|||||||
import 'package:SEFER/views/widgets/mycircular.dart';
|
import 'package:SEFER/views/widgets/mycircular.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||||
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:SEFER/constant/box_name.dart';
|
import 'package:SEFER/constant/box_name.dart';
|
||||||
import 'package:SEFER/constant/colors.dart';
|
import 'package:SEFER/constant/colors.dart';
|
||||||
@@ -110,7 +109,8 @@ class DrawerCaptain extends StatelessWidget {
|
|||||||
top: 0,
|
top: 0,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
imageController.choosImage(AppLink.uploadImage1);
|
imageController.choosImage(
|
||||||
|
AppLink.uploadImage1, 'portrait');
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.edit),
|
icon: const Icon(Icons.edit),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ class OrderRequestPage extends StatelessWidget {
|
|||||||
style: AppStyle.title,
|
style: AppStyle.title,
|
||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: myList[27], style: AppStyle.headTitle2),
|
text: myList[26], style: AppStyle.headTitle2),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ class OrderSpeedRequest extends StatelessWidget {
|
|||||||
text: 'Cost Of Trip IS '.tr,
|
text: 'Cost Of Trip IS '.tr,
|
||||||
style: AppStyle.title,
|
style: AppStyle.title,
|
||||||
children: [
|
children: [
|
||||||
TextSpan(text: myList[27], style: AppStyle.headTitle2),
|
TextSpan(text: myList[26], style: AppStyle.headTitle2),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import 'map_widget.dart/left_main_menu_icons.dart';
|
|||||||
import 'map_widget.dart/main_bottom_menu_map.dart';
|
import 'map_widget.dart/main_bottom_menu_map.dart';
|
||||||
import 'map_widget.dart/map_menu_widget.dart';
|
import 'map_widget.dart/map_menu_widget.dart';
|
||||||
import 'map_widget.dart/menu_map_page.dart';
|
import 'map_widget.dart/menu_map_page.dart';
|
||||||
|
import 'map_widget.dart/passengerRideLoctionWidget.dart';
|
||||||
import 'map_widget.dart/payment_method.page.dart';
|
import 'map_widget.dart/payment_method.page.dart';
|
||||||
import 'map_widget.dart/points_page_for_rider.dart';
|
import 'map_widget.dart/points_page_for_rider.dart';
|
||||||
import 'map_widget.dart/ride_from_start_app.dart';
|
import 'map_widget.dart/ride_from_start_app.dart';
|
||||||
@@ -54,7 +55,9 @@ class MapPagePassenger extends StatelessWidget {
|
|||||||
// timerForCancelTripFromPassenger(),
|
// timerForCancelTripFromPassenger(),
|
||||||
// const DriverTimeArrivePassengerPage(),
|
// const DriverTimeArrivePassengerPage(),
|
||||||
// const TimerToPassengerFromDriver(),
|
// const TimerToPassengerFromDriver(),
|
||||||
const RideBeginPassenger(), const RideFromStartApp(),
|
PassengerRideLocationWidget(),
|
||||||
|
const RideBeginPassenger(),
|
||||||
|
const RideFromStartApp(),
|
||||||
cancelRidePage(),
|
cancelRidePage(),
|
||||||
PointsPageForRider()
|
PointsPageForRider()
|
||||||
],
|
],
|
||||||
@@ -112,7 +115,7 @@ class PickerIconOnMap extends StatelessWidget {
|
|||||||
return GetBuilder<MapPassengerController>(
|
return GetBuilder<MapPassengerController>(
|
||||||
builder: (controller) => controller.isPickerShown
|
builder: (controller) => controller.isPickerShown
|
||||||
? Positioned(
|
? Positioned(
|
||||||
bottom: 0,
|
bottom: Get.height * .2,
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
|
|||||||
@@ -165,80 +165,91 @@ class ApplyOrderWidget extends StatelessWidget {
|
|||||||
Get.defaultDialog(
|
Get.defaultDialog(
|
||||||
title: 'Select one message'.tr,
|
title: 'Select one message'.tr,
|
||||||
titleStyle: AppStyle.title,
|
titleStyle: AppStyle.title,
|
||||||
content: Column(
|
content: Container(
|
||||||
children: [
|
height: Get.height * .5,
|
||||||
InkWell(
|
child: Column(
|
||||||
onTap: () {
|
mainAxisAlignment:
|
||||||
FirebaseMessagesController()
|
MainAxisAlignment.spaceEvenly,
|
||||||
.sendNotificationToAnyWithoutData(
|
children: [
|
||||||
'message From passenger',
|
InkWell(
|
||||||
'Hello, I\'m at the agreed-upon location'
|
onTap: () {
|
||||||
.tr,
|
FirebaseMessagesController()
|
||||||
controller.driverToken);
|
.sendNotificationToAnyWithoutData(
|
||||||
Get.back();
|
'message From passenger',
|
||||||
},
|
'Hello, I\'m at the agreed-upon location'
|
||||||
child: Container(
|
.tr,
|
||||||
decoration:
|
controller
|
||||||
AppStyle.boxDecoration1,
|
.driverToken);
|
||||||
child: Padding(
|
Get.back();
|
||||||
padding:
|
},
|
||||||
const EdgeInsets.all(10),
|
child: Container(
|
||||||
child: Text(
|
decoration:
|
||||||
'Hello, I\'m at the agreed-upon location'
|
AppStyle.boxDecoration1,
|
||||||
.tr,
|
child: Padding(
|
||||||
style: AppStyle.title,
|
padding:
|
||||||
|
const EdgeInsets.all(
|
||||||
|
10),
|
||||||
|
child: Text(
|
||||||
|
'Hello, I\'m at the agreed-upon location'
|
||||||
|
.tr,
|
||||||
|
style: AppStyle.title,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
InkWell(
|
||||||
InkWell(
|
onTap: () {
|
||||||
onTap: () {
|
FirebaseMessagesController()
|
||||||
FirebaseMessagesController()
|
.sendNotificationToAnyWithoutData(
|
||||||
.sendNotificationToAnyWithoutData(
|
'message From passenger',
|
||||||
'message From passenger',
|
'My location is correct. You can search for me using the navigation app'
|
||||||
'My location is correct. You can search for me using the navigation app'
|
.tr,
|
||||||
.tr,
|
controller
|
||||||
controller.driverToken);
|
.driverToken);
|
||||||
Get.back();
|
Get.back();
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration:
|
decoration:
|
||||||
AppStyle.boxDecoration1,
|
AppStyle.boxDecoration1,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.all(10),
|
const EdgeInsets.all(
|
||||||
child: Text(
|
10),
|
||||||
'My location is correct. You can search for me using the navigation app'
|
child: Text(
|
||||||
.tr,
|
'My location is correct. You can search for me using the navigation app'
|
||||||
style: AppStyle.title,
|
.tr,
|
||||||
|
style: AppStyle.title,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
InkWell(
|
||||||
InkWell(
|
onTap: () {
|
||||||
onTap: () {
|
FirebaseMessagesController()
|
||||||
FirebaseMessagesController()
|
.sendNotificationToAnyWithoutData(
|
||||||
.sendNotificationToAnyWithoutData(
|
'message From passenger',
|
||||||
'message From passenger',
|
'I\'m waiting for you'
|
||||||
'I\'m waiting for you'
|
.tr,
|
||||||
.tr,
|
controller
|
||||||
controller.driverToken);
|
.driverToken);
|
||||||
Get.back();
|
Get.back();
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration:
|
decoration:
|
||||||
AppStyle.boxDecoration1,
|
AppStyle.boxDecoration1,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.all(10),
|
const EdgeInsets.all(
|
||||||
child: Text(
|
10),
|
||||||
'I\'m waiting for you'.tr,
|
child: Text(
|
||||||
style: AppStyle.title,
|
'I\'m waiting for you'.tr,
|
||||||
|
style: AppStyle.title,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ List<CarType> carTypes = [
|
|||||||
image: 'assets/images/blob.png'),
|
image: 'assets/images/blob.png'),
|
||||||
CarType(
|
CarType(
|
||||||
carType: 'Speed',
|
carType: 'Speed',
|
||||||
carDetail: 'Better for long trips choice'.tr,
|
carDetail: 'Closest & Cheapest'.tr,
|
||||||
image: 'assets/images/carspeed.png'),
|
image: 'assets/images/carspeed.png'),
|
||||||
CarType(
|
CarType(
|
||||||
carType: 'Delivery',
|
carType: 'Delivery',
|
||||||
@@ -72,6 +72,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
|||||||
final carType = carTypes[index];
|
final carType = carTypes[index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Container(
|
title: Container(
|
||||||
|
width: Get.width,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColor.secondaryColor,
|
color: AppColor.secondaryColor,
|
||||||
borderRadius: const BorderRadius.all(
|
borderRadius: const BorderRadius.all(
|
||||||
@@ -92,11 +93,11 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Image.asset(
|
Image.asset(
|
||||||
carType.image,
|
carType.image,
|
||||||
width: 60,
|
width: 50,
|
||||||
height: 60,
|
height: 50,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: Get.width * .5,
|
width: Get.width * .4,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
@@ -131,7 +132,10 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
|||||||
style: AppStyle.title
|
style: AppStyle.title
|
||||||
.copyWith(fontSize: 20),
|
.copyWith(fontSize: 20),
|
||||||
),
|
),
|
||||||
carType.carType == 'Comfort'
|
carType.carType == 'Comfort' &&
|
||||||
|
(mapPassengerController
|
||||||
|
.totalPassengerSpeed >
|
||||||
|
20)
|
||||||
? Row(
|
? Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
@@ -142,7 +146,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
|||||||
style: AppStyle.subtitle
|
style: AppStyle.subtitle
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: AppColor
|
color: AppColor
|
||||||
.secondaryColor),
|
.greenColor),
|
||||||
)),
|
)),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
@@ -153,15 +157,50 @@ class CarDetailsTypeToChoose extends StatelessWidget {
|
|||||||
.toStringAsFixed(2),
|
.toStringAsFixed(2),
|
||||||
style:
|
style:
|
||||||
AppStyle.title.copyWith(
|
AppStyle.title.copyWith(
|
||||||
|
color: AppColor.redColor,
|
||||||
decoration: TextDecoration
|
decoration: TextDecoration
|
||||||
.lineThrough, // Strikethrough line
|
.lineThrough, // Strikethrough line
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: const SizedBox(
|
: carType.carType == 'Speed' &&
|
||||||
width: 3,
|
(mapPassengerController
|
||||||
),
|
.totalPassengerSpeed >
|
||||||
|
20)
|
||||||
|
? Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: AppStyle
|
||||||
|
.boxDecoration1,
|
||||||
|
child: Text(
|
||||||
|
'-10%',
|
||||||
|
style: AppStyle
|
||||||
|
.subtitle
|
||||||
|
.copyWith(
|
||||||
|
color: AppColor
|
||||||
|
.greenColor),
|
||||||
|
)),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
mapPassengerController
|
||||||
|
.totalPassengerSpeedDiscount
|
||||||
|
.toStringAsFixed(2),
|
||||||
|
style: AppStyle.title
|
||||||
|
.copyWith(
|
||||||
|
color:
|
||||||
|
AppColor.redColor,
|
||||||
|
decoration: TextDecoration
|
||||||
|
.lineThrough, // Strikethrough line
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const SizedBox(
|
||||||
|
width: 3,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
|
|||||||
@@ -26,147 +26,68 @@ GetBuilder<MapPassengerController> formSearchPlacesDestenation() {
|
|||||||
padding: const EdgeInsets.all(6),
|
padding: const EdgeInsets.all(6),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Container(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
width: Get.width * .9,
|
||||||
children: [
|
height: 40,
|
||||||
Container(
|
decoration:
|
||||||
width: Get.width * .8,
|
const BoxDecoration(color: AppColor.secondaryColor),
|
||||||
height: 40,
|
child: TextField(
|
||||||
decoration: const BoxDecoration(
|
decoration: InputDecoration(
|
||||||
color: AppColor.secondaryColor),
|
border: const OutlineInputBorder(
|
||||||
child: TextField(
|
borderRadius: BorderRadius.only(),
|
||||||
decoration: InputDecoration(
|
gapPadding: 4,
|
||||||
border: const OutlineInputBorder(
|
borderSide: BorderSide(
|
||||||
borderRadius: BorderRadius.only(),
|
color: AppColor.redColor,
|
||||||
gapPadding: 4,
|
width: 2,
|
||||||
borderSide: BorderSide(
|
)),
|
||||||
color: AppColor.redColor,
|
suffixIcon: const Icon(Icons.search),
|
||||||
width: 2,
|
hintText: controller.hintTextDestinationPoint,
|
||||||
)),
|
hintStyle: AppStyle.title,
|
||||||
suffixIcon: const Icon(Icons.search),
|
hintMaxLines: 1,
|
||||||
hintText: controller.hintTextDestinationPoint,
|
prefixIcon: IconButton(
|
||||||
hintStyle: AppStyle.title,
|
onPressed: () {
|
||||||
hintMaxLines: 1,
|
controller.placeDestinationController.clear();
|
||||||
prefixIcon: IconButton(
|
controller.clearPlacesDestination();
|
||||||
onPressed: () {
|
|
||||||
controller.placeDestinationController.clear();
|
|
||||||
controller.clearPlacesDestination();
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
Icons.clear,
|
|
||||||
color: Colors.red[300],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
controller: controller.placeDestinationController,
|
|
||||||
onChanged: (value) {
|
|
||||||
if (controller
|
|
||||||
.placeDestinationController.text.length >
|
|
||||||
5) {
|
|
||||||
controller.getPlaces();
|
|
||||||
controller.changeHeightPlaces();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
// onEditingComplete: () => controller.changeHeight(),
|
icon: Icon(
|
||||||
|
Icons.clear,
|
||||||
|
color: Colors.red[300],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(
|
controller: controller.placeDestinationController,
|
||||||
onPressed: () {
|
onChanged: (value) {
|
||||||
|
if (controller
|
||||||
|
.placeDestinationController.text.length >
|
||||||
|
5) {
|
||||||
|
controller.getPlaces();
|
||||||
|
controller.changeHeightPlaces();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// onEditingComplete: () => controller.changeHeight(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: AppStyle.boxDecoration1,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
controller.changeMainBottomMenuMap();
|
controller.changeMainBottomMenuMap();
|
||||||
controller.changePickerShown();
|
controller.changePickerShown();
|
||||||
},
|
},
|
||||||
icon: const Icon(
|
child: Padding(
|
||||||
Icons.map_outlined,
|
padding: const EdgeInsets.symmetric(
|
||||||
color: AppColor.greenColor,
|
horizontal: 20, vertical: 4),
|
||||||
|
child: Text(
|
||||||
|
'Pick from map'.tr,
|
||||||
|
style: AppStyle.headTitle2,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)),
|
||||||
// IconButton(
|
const SizedBox(
|
||||||
// onPressed: () async {
|
height: 10,
|
||||||
// List recentLocations = await sql.getCustomQuery('''
|
|
||||||
// SELECT * FROM ${TableName.recentLocations}
|
|
||||||
// ORDER BY id DESC
|
|
||||||
// LIMIT 4
|
|
||||||
// ''');
|
|
||||||
// Get.defaultDialog(
|
|
||||||
// title: 'Latest Recent Trip'.tr,
|
|
||||||
// content: recentLocations.isEmpty
|
|
||||||
// ? Center(
|
|
||||||
// child: Column(
|
|
||||||
// mainAxisAlignment:
|
|
||||||
// MainAxisAlignment.center,
|
|
||||||
// children: [
|
|
||||||
// const Icon(
|
|
||||||
// Icons.hourglass_empty_rounded,
|
|
||||||
// size: 99,
|
|
||||||
// color: AppColor.primaryColor,
|
|
||||||
// ),
|
|
||||||
// Text(
|
|
||||||
// 'You Dont Have Any places yet !'.tr,
|
|
||||||
// style: AppStyle.title,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// : SizedBox(
|
|
||||||
// height: Get.width * .5,
|
|
||||||
// width: Get.width * .8,
|
|
||||||
// child: ListView.builder(
|
|
||||||
// itemCount: recentLocations.length,
|
|
||||||
// itemBuilder:
|
|
||||||
// (BuildContext context, int index) {
|
|
||||||
// return Row(
|
|
||||||
// mainAxisAlignment:
|
|
||||||
// MainAxisAlignment.spaceBetween,
|
|
||||||
// children: [
|
|
||||||
// TextButton(
|
|
||||||
// onPressed: () async {
|
|
||||||
// Get.back();
|
|
||||||
// controller
|
|
||||||
// .convertHintTextDestinationNewPlacesFromRecent(
|
|
||||||
// recentLocations,
|
|
||||||
// index);
|
|
||||||
// },
|
|
||||||
// child: Text(
|
|
||||||
// recentLocations[index]
|
|
||||||
// ['name'],
|
|
||||||
// style: AppStyle.title,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// IconButton(
|
|
||||||
// onPressed: () async {
|
|
||||||
// await sql.deleteData(
|
|
||||||
// TableName.placesFavorite,
|
|
||||||
// recentLocations[index]
|
|
||||||
// ['id']);
|
|
||||||
// Get.back();
|
|
||||||
// // ignore: use_build_context_synchronously
|
|
||||||
// Toast.show(
|
|
||||||
// context,
|
|
||||||
// '${'You are Delete'.tr} ${recentLocations[index]['name']} ${'from your list'.tr}',
|
|
||||||
// AppColor.redColor);
|
|
||||||
// // Get.snackbar('Deleted'.tr,
|
|
||||||
// // '${'You are Delete'.tr} ${favoritePlaces[index]['name']} from your list',
|
|
||||||
// // backgroundColor:
|
|
||||||
// // AppColor.accentColor);
|
|
||||||
// },
|
|
||||||
// icon: const Icon(
|
|
||||||
// Icons.favorite_outlined),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// // controller.changeMainBottomMenuMap();
|
|
||||||
// // controller.changePickerShown();
|
|
||||||
// },
|
|
||||||
// icon: const Icon(
|
|
||||||
// Icons.recent_actors,
|
|
||||||
// color: AppColor.blueColor,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
@@ -211,13 +132,14 @@ GetBuilder<MapPassengerController> formSearchPlacesDestenation() {
|
|||||||
color: AppColor.greenColor.withOpacity(.4),
|
color: AppColor.greenColor.withOpacity(.4),
|
||||||
border: Border.all()),
|
border: Border.all()),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Work : ${box.read(BoxName.addWork).toString() == 'addWork' ? 'Add Work' : box.read(BoxName.addWork).toString().split(',')[0] + box.read(BoxName.addWork).toString().split(',')[1]} '),
|
'${'Work :'.tr} ${box.read(BoxName.addWork).toString() == 'addWork' ? 'Add Work' : box.read(BoxName.addWork).toString().split(',')[0] + box.read(BoxName.addWork).toString().split(',')[1]} '),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
Get.defaultDialog(
|
Get.defaultDialog(
|
||||||
title: 'Do you want to change Home location',
|
title:
|
||||||
|
'Do you want to change Home location'.tr,
|
||||||
middleText: '',
|
middleText: '',
|
||||||
confirm: MyElevatedButton(
|
confirm: MyElevatedButton(
|
||||||
title: 'Yes'.tr,
|
title: 'Yes'.tr,
|
||||||
@@ -259,7 +181,7 @@ GetBuilder<MapPassengerController> formSearchPlacesDestenation() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
), //
|
||||||
),
|
),
|
||||||
// controller.placesDestination.isEmpty
|
// controller.placesDestination.isEmpty
|
||||||
// ? InkWell(
|
// ? InkWell(
|
||||||
@@ -296,10 +218,18 @@ GetBuilder<MapPassengerController> formSearchPlacesDestenation() {
|
|||||||
controller.changeHeightPlaces();
|
controller.changeHeightPlaces();
|
||||||
|
|
||||||
controller.passengerLocation = controller.newMyLocation;
|
controller.passengerLocation = controller.newMyLocation;
|
||||||
|
controller.myDestination = LatLng(
|
||||||
|
double.parse(
|
||||||
|
res['geometry']['location']['lat'].toString()),
|
||||||
|
double.parse(
|
||||||
|
res['geometry']['location']['lng'].toString()));
|
||||||
controller.convertHintTextDestinationNewPlaces(index);
|
controller.convertHintTextDestinationNewPlaces(index);
|
||||||
|
|
||||||
controller.placesDestination = [];
|
controller.placesDestination = [];
|
||||||
controller.placeDestinationController.clear();
|
controller.placeDestinationController.clear();
|
||||||
|
controller.changeMainBottomMenuMap();
|
||||||
|
controller.passengerStartLocationFromMap = true;
|
||||||
|
controller.isPickerShown = true;
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
|||||||
@@ -350,6 +350,8 @@ class GoogleMapPassengerWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
if (controller.startLocationFromMap == true) {
|
if (controller.startLocationFromMap == true) {
|
||||||
controller.newStartPointLocation = position.target;
|
controller.newStartPointLocation = position.target;
|
||||||
|
} else if (controller.passengerStartLocationFromMap == true) {
|
||||||
|
controller.newStartPointLocation = position.target;
|
||||||
}
|
}
|
||||||
controller.newMyLocation = position.target;
|
controller.newMyLocation = position.target;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import 'package:SEFER/constant/style.dart';
|
import 'package:SEFER/constant/style.dart';
|
||||||
|
import 'package:SEFER/controller/functions/crud.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import '../../../constant/colors.dart';
|
import '../../../constant/colors.dart';
|
||||||
|
import '../../../constant/links.dart';
|
||||||
import '../../../controller/functions/audio_record1.dart';
|
import '../../../controller/functions/audio_record1.dart';
|
||||||
import '../../../controller/functions/tts.dart';
|
import '../../../controller/functions/tts.dart';
|
||||||
|
import '../../../controller/functions/upload_image.dart';
|
||||||
import '../../../controller/home/map_passenger_controller.dart';
|
import '../../../controller/home/map_passenger_controller.dart';
|
||||||
|
|
||||||
GetBuilder<MapPassengerController> leftMainMenuIcons() {
|
GetBuilder<MapPassengerController> leftMainMenuIcons() {
|
||||||
@@ -83,77 +86,85 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 5,
|
height: 5,
|
||||||
),
|
),
|
||||||
AnimatedContainer(
|
// AnimatedContainer(
|
||||||
duration: const Duration(microseconds: 200),
|
// duration: const Duration(microseconds: 200),
|
||||||
width: controller.widthMapTypeAndTraffic,
|
// width: controller.widthMapTypeAndTraffic,
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
color: AppColor.secondaryColor,
|
// color: AppColor.secondaryColor,
|
||||||
border: Border.all(),
|
// border: Border.all(),
|
||||||
borderRadius: BorderRadius.circular(15)),
|
// borderRadius: BorderRadius.circular(15)),
|
||||||
child: IconButton(
|
// child: IconButton(
|
||||||
onPressed: () async {
|
// onPressed: () async {
|
||||||
await Get.find<AudioRecorderController>().stopRecording();
|
// await Get.find<AudioRecorderController>().stopRecording();
|
||||||
},
|
// },
|
||||||
icon: const Icon(
|
// icon: const Icon(
|
||||||
Icons.voice_chat,
|
// Icons.voice_chat,
|
||||||
size: 29,
|
// size: 29,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
AnimatedContainer(
|
// AnimatedContainer(
|
||||||
duration: const Duration(microseconds: 200),
|
// duration: const Duration(microseconds: 200),
|
||||||
width: controller.widthMapTypeAndTraffic,
|
// width: controller.widthMapTypeAndTraffic,
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
color: AppColor.secondaryColor,
|
// color: AppColor.secondaryColor,
|
||||||
border: Border.all(),
|
// border: Border.all(),
|
||||||
borderRadius: BorderRadius.circular(15)),
|
// borderRadius: BorderRadius.circular(15)),
|
||||||
child: IconButton(
|
// child: IconButton(
|
||||||
onPressed: () async {
|
// onPressed: () async {
|
||||||
// AC credentials = AC();
|
// await CRUD().allMethodForAI(
|
||||||
// String apiKey = AK.payPalSecret;
|
// 'name,fullName,address,idNumber,cardId,dob',
|
||||||
// String convertedStringN = credentials.c(
|
// AppLink.uploadEgypt,
|
||||||
// credentials.c(credentials.c(apiKey, cs), cC), cn);
|
// 'idFront');
|
||||||
// print('Converted v: $convertedStringN');
|
//
|
||||||
|
// // await ImageController().choosImage(
|
||||||
// String retrievedStringS = credentials.r(
|
// // 'https://api.sefer.live/sefer/uploadEgypt.php',
|
||||||
// credentials.r(credentials.r(convertedStringN, cn), cC),
|
// // 'FrontId');
|
||||||
// cs);
|
// // AC credentials = AC();
|
||||||
// print('Retrieved String: $retrievedStringS');
|
// // String apiKey = AK.payPalSecret;
|
||||||
// //
|
// // String convertedStringN = credentials.c(
|
||||||
// if (retrievedStringS == apiKey) {
|
// // credentials.c(credentials.c(apiKey, cs), cC), cn);
|
||||||
// print('same');
|
// // print('Converted v: $convertedStringN');
|
||||||
// }
|
//
|
||||||
|
// // String retrievedStringS = credentials.r(
|
||||||
// print(box.read(BoxName.passengerWalletTotal));
|
// // credentials.r(credentials.r(convertedStringN, cn), cC),
|
||||||
// print(box.read(BoxName.name));
|
// // cs);
|
||||||
// print(box.read(BoxName.phone));
|
// // print('Retrieved String: $retrievedStringS');
|
||||||
// print(box.read(BoxName.email));
|
// // //
|
||||||
// await Get.find<PaymentController>()
|
// // if (retrievedStringS == apiKey) {
|
||||||
// .payWithPayMob(context, '1100', 'EGP');
|
// // print('same');
|
||||||
// Initiates a payment with a card using the FlutterPaymob instance
|
// // }
|
||||||
|
//
|
||||||
// NotificationController()
|
// // print(box.read(BoxName.passengerWalletTotal));
|
||||||
// .showNotification('Order', 'hi this is', 'tone1');
|
// // print(box.read(BoxName.name));
|
||||||
// Get.to(() => DriverCallPage());
|
// // print(box.read(BoxName.phone));
|
||||||
// print(controller.carLocationsModels);
|
// // print(box.read(BoxName.email));
|
||||||
// controller.getKazanPercent();
|
// // await Get.find<PaymentController>()
|
||||||
// PassengerCallPage(
|
// // .payWithPayMob(context, '1100', 'EGP');
|
||||||
// channelName: '',
|
// // Initiates a payment with a card using the FlutterPaymob instance
|
||||||
// token: '',
|
//
|
||||||
// remoteID: '',
|
// // NotificationController()
|
||||||
// )
|
// // .showNotification('Order', 'hi this is', 'tone1');
|
||||||
// Get.to(() => const CallPage());
|
// // Get.to(() => DriverCallPage());
|
||||||
// print(box.read(BoxName.lang));
|
// // print(controller.carLocationsModels);
|
||||||
await Get.find<AudioRecorderController>().startRecording();
|
// // controller.getKazanPercent();
|
||||||
},
|
// // PassengerCallPage(
|
||||||
icon: Icon(
|
// // channelName: '',
|
||||||
Get.put(AudioRecorderController()).isRecording
|
// // token: '',
|
||||||
? Icons.stop
|
// // remoteID: '',
|
||||||
: Icons.start,
|
// // )
|
||||||
size: 29,
|
// // Get.to(() => const CallPage());
|
||||||
),
|
// // print(box.read(BoxName.lang));
|
||||||
),
|
// await Get.find<AudioRecorderController>().startRecording();
|
||||||
),
|
// },
|
||||||
|
// icon: Icon(
|
||||||
|
// Get.put(AudioRecorderController()).isRecording
|
||||||
|
// ? Icons.stop
|
||||||
|
// : Icons.start,
|
||||||
|
// size: 29,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:SEFER/controller/home/map_passenger_controller.dart';
|
|||||||
import 'package:SEFER/main.dart';
|
import 'package:SEFER/main.dart';
|
||||||
import 'package:SEFER/views/home/map_widget.dart/form_search_places_destenation.dart';
|
import 'package:SEFER/views/home/map_widget.dart/form_search_places_destenation.dart';
|
||||||
import 'package:SEFER/views/widgets/elevated_btn.dart';
|
import 'package:SEFER/views/widgets/elevated_btn.dart';
|
||||||
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
|
|
||||||
import '../../../constant/colors.dart';
|
import '../../../constant/colors.dart';
|
||||||
import '../../../constant/table_names.dart';
|
import '../../../constant/table_names.dart';
|
||||||
@@ -78,18 +79,18 @@ class MainBottomMenuMap extends StatelessWidget {
|
|||||||
controller.isMainBottomMenuMap
|
controller.isMainBottomMenuMap
|
||||||
? recentPlacesWidget(controller)
|
? recentPlacesWidget(controller)
|
||||||
: const SizedBox(),
|
: const SizedBox(),
|
||||||
controller.isMainBottomMenuMap
|
// controller.isMainBottomMenuMap
|
||||||
? const SizedBox()
|
// ? const SizedBox()
|
||||||
: InkWell(
|
// : InkWell(
|
||||||
onTap: () async {
|
// onTap: () async {
|
||||||
controller.getCurrentLocationFormString();
|
// controller.getCurrentLocationFormString();
|
||||||
},
|
// },
|
||||||
child: Text(
|
// child: Text(
|
||||||
'From :'.tr +
|
// 'From :'.tr +
|
||||||
' ${controller.currentLocationString}'.tr,
|
// ' ${controller.currentLocationString}'.tr,
|
||||||
style: AppStyle.subtitle,
|
// style: AppStyle.subtitle,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
controller.isMainBottomMenuMap
|
controller.isMainBottomMenuMap
|
||||||
? const SizedBox()
|
? const SizedBox()
|
||||||
: Column(
|
: Column(
|
||||||
@@ -204,7 +205,27 @@ class MainBottomMenuMap extends StatelessWidget {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
controller.clearPolyline();
|
controller.clearPolyline();
|
||||||
controller.data = [];
|
controller.data = [];
|
||||||
if (controller.startLocationFromMap == true) {
|
if (controller.passengerStartLocationFromMap == true) {
|
||||||
|
controller.newMyLocation = controller.newStartPointLocation;
|
||||||
|
controller.changeMainBottomMenuMap();
|
||||||
|
|
||||||
|
await controller.getMap(
|
||||||
|
'${controller.newStartPointLocation.latitude},${controller.newStartPointLocation.longitude}',
|
||||||
|
'${controller.myDestination.latitude},${controller.myDestination.longitude}',
|
||||||
|
);
|
||||||
|
controller.currentLocationToFormPlaces = false;
|
||||||
|
controller.placesDestination = [];
|
||||||
|
// controller.isCancelRidePageShown = true;
|
||||||
|
controller.clearPlacesStart();
|
||||||
|
controller.clearPlacesDestination();
|
||||||
|
controller.passengerStartLocationFromMap = false;
|
||||||
|
controller.isPickerShown = false;
|
||||||
|
// controller.showBottomSheet1();
|
||||||
|
// Get.back();
|
||||||
|
controller.showBottomSheet1();
|
||||||
|
// controller.hintTextStartPoint =
|
||||||
|
// '${controller.newStartPointLocation.latitude.toStringAsFixed(4)} , ${controller.newStartPointLocation.longitude.toStringAsFixed(4)}';
|
||||||
|
} else if (controller.startLocationFromMap == true) {
|
||||||
controller.newMyLocation = controller.newStartPointLocation;
|
controller.newMyLocation = controller.newStartPointLocation;
|
||||||
controller.hintTextStartPoint =
|
controller.hintTextStartPoint =
|
||||||
'${controller.newStartPointLocation.latitude.toStringAsFixed(4)} , ${controller.newStartPointLocation.longitude.toStringAsFixed(4)}';
|
'${controller.newStartPointLocation.latitude.toStringAsFixed(4)} , ${controller.newStartPointLocation.longitude.toStringAsFixed(4)}';
|
||||||
@@ -232,16 +253,36 @@ class MainBottomMenuMap extends StatelessWidget {
|
|||||||
} else {
|
} else {
|
||||||
controller.hintTextDestinationPoint =
|
controller.hintTextDestinationPoint =
|
||||||
'${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}';
|
'${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}';
|
||||||
controller.newMyLocation = controller.newMyLocation;
|
controller.myDestination = controller.newMyLocation;
|
||||||
controller.isPickerShown = false;
|
controller.isPickerShown = false;
|
||||||
|
|
||||||
|
controller.changeMainBottomMenuMap();
|
||||||
|
controller.passengerStartLocationFromMap = true;
|
||||||
|
controller.isPickerShown = true;
|
||||||
|
await controller.mapController?.animateCamera(CameraUpdate.newLatLng(
|
||||||
|
LatLng(controller.passengerLocation.latitude,
|
||||||
|
controller.passengerLocation.longitude)));
|
||||||
|
Get.defaultDialog(
|
||||||
|
title: 'Destination selected'.tr,
|
||||||
|
titleStyle: AppStyle.title,
|
||||||
|
content: Text(
|
||||||
|
'Now select start pick'.tr,
|
||||||
|
style: AppStyle.title,
|
||||||
|
),
|
||||||
|
confirm: MyElevatedButton(
|
||||||
|
title: 'OK'.tr,
|
||||||
|
onPressed: () {
|
||||||
|
Get.back();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.placesDestination = [];
|
controller.placesDestination = [];
|
||||||
controller.placeDestinationController.clear();
|
controller.placeDestinationController.clear();
|
||||||
|
|
||||||
controller.showBottomSheet1();
|
controller.showBottomSheet1();
|
||||||
Get.back();
|
// Get.back();
|
||||||
controller.showBottomSheet1();
|
// controller.showBottomSheet1();
|
||||||
|
|
||||||
controller.changeMainBottomMenuMap();
|
controller.changeMainBottomMenuMap();
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -261,7 +302,9 @@ class MainBottomMenuMap extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"Click here point".tr,
|
controller.passengerStartLocationFromMap
|
||||||
|
? 'Pick your ride location on the map - Tap to confirm'.tr
|
||||||
|
: "Click here point".tr,
|
||||||
style: AppStyle.title,
|
style: AppStyle.title,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:SEFER/constant/style.dart';
|
||||||
|
import 'package:SEFER/controller/home/map_passenger_controller.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class PassengerRideLocationWidget extends StatelessWidget {
|
||||||
|
const PassengerRideLocationWidget({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GetBuilder<MapPassengerController>(
|
||||||
|
builder: (mapPassengerController) {
|
||||||
|
return mapPassengerController.isPassengerRideLocationWidget
|
||||||
|
? Positioned(
|
||||||
|
bottom: 1,
|
||||||
|
right: 1,
|
||||||
|
left: 1,
|
||||||
|
child: Container(
|
||||||
|
height: Get.height * .2,
|
||||||
|
decoration: AppStyle.boxDecoration1,
|
||||||
|
child: Center(
|
||||||
|
child: Text('Choose ride location'.tr),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user