diff --git a/android/app/build.gradle b/android/app/build.gradle
index a8d9421..67bde52 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -60,4 +60,6 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
+
}
diff --git a/android/app/google-services.json b/android/app/google-services.json
new file mode 100644
index 0000000..96e3c39
--- /dev/null
+++ b/android/app/google-services.json
@@ -0,0 +1,48 @@
+{
+ "project_info": {
+ "project_number": "60196905754",
+ "project_id": "health-pharma-67443",
+ "storage_bucket": "health-pharma-67443.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:60196905754:android:05ea9ecef5280e578a42a3",
+ "android_client_info": {
+ "package_name": "com.arminta.healthcare_pharmacy"
+ }
+ },
+ "oauth_client": [],
+ "api_key": [
+ {
+ "current_key": "AIzaSyC89L-Xg53Bd_mdCPvKOu7BcC9Ya6UZeds"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": []
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:60196905754:android:a35c084e291315488a42a3",
+ "android_client_info": {
+ "package_name": "com.arminta.healthparma"
+ }
+ },
+ "oauth_client": [],
+ "api_key": [
+ {
+ "current_key": "AIzaSyC89L-Xg53Bd_mdCPvKOu7BcC9Ya6UZeds"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": []
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index bc93226..2914fc7 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -11,6 +11,14 @@
+
+
+
+
+
+
+
+
_initFCMToken() async {
+ // Get the stored FCM token
+ AppSettings.fcmId = await _getStoredFCMToken();
+
+ // If FCM token is not available, request a new one
+ if (AppSettings.fcmId.isEmpty) {
+ await _fcm.getToken().then((token) {
+ print('FCM Token: $token');
+ // Store the FCM token directly in AppSettings
+ AppSettings.fcmId = token!;
+ _storeFCMToken(token);
+ });
+ }
+ }
+
+ Future _storeFCMToken(String token) async {
+ // Store the FCM token using SharedPreferences
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ await prefs.setString('fcmToken', token);
+ }
+
+ Future _getStoredFCMToken() async {
+ // Retrieve the stored FCM token from SharedPreferences
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ return prefs.getString('fcmToken') ?? '';
+ }
+ Future initialize() async {
+ // Request permission for user notifications
+ await _fcm.requestPermission();
+
+ // Get the FCM token and handle incoming messages while the app is in the foreground
+ _fcm.getToken().then((token) {
+ print('FCM Token: $token');
+ // Do something with the token (e.g., send it to your server)
+ });
+
+
+
+ // Listen to incoming messages while the app is in the foreground
+ FirebaseMessaging.onMessage.listen((RemoteMessage message) {
+ print("data::::$message");
+ // var payload = message.data.toString();
+ // // Handle the incoming message
+ // Map notificationPayload = jsonDecode(payload);
+ // Access the extra data using the keys
+ var payload=message.data;
+ var extramessage;
+ if(payload.isNotEmpty){
+ extramessage = message.data['extraKey1'];
+ String? extraValue2 = message.data['extraKey2'];
+
+ }
+
+ // Show a local notification with the received message
+ _showNotification(message.notification?.title, message.notification?.body,extramessage);
+ });
+
+ // Handle messages when the app is in the background or terminated
+ FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
+ var payload = message.data.toString();
+ if (payload != null) {
+ // Parse the JSON payload
+ Map notificationPayload = jsonDecode(payload);
+ // Access the extra data using the keys
+ String? extraValue1 = notificationPayload['extraKey1'];
+ String? extraValue2 = notificationPayload['extraKey2'];
+ // Do something with the extra data, e.g., display it in a dialog or use it in your app logic.
+ }
+
+ // Show a local notification with the received message
+ // _showNotification(message.notification?.title, message.notification?.body);
+ });
+ }
+
+ // Method to show a local notification using flutter_local_notifications
+ Future _showNotification(String? title, String? body,String extramessage) async {
+ const AndroidNotificationDetails androidPlatformChannelSpecifics =
+ AndroidNotificationDetails(
+ 'healthpharma', // Replace with your channel ID
+ 'healthpharmanotifications', // Replace with your channel name
+ importance: Importance.high,
+ priority: Priority.high,
+ showWhen: false,
+ icon: "logo"
+
+ );
+
+ const NotificationDetails platformChannelSpecifics =
+ NotificationDetails(android: androidPlatformChannelSpecifics);
+ Map notificationPayload = {
+ "body": body,
+ "title": title,
+ "extraKey1": extramessage,
+ "extraKey2": "Extra Value 2",
+ // Add more key-value pairs as needed
+ };
+ await _flutterLocalNotificationsPlugin.show(
+ 0, // notification ID (can be any unique ID)
+ title, // notification title
+ body, // notification body
+ platformChannelSpecifics,
+ payload: jsonEncode(notificationPayload), // optional, you can pass data or identifier related to the notification
+ );
+ }
+}
diff --git a/lib/biddingrequests.dart b/lib/biddingrequests.dart
index 76a6437..9619956 100644
--- a/lib/biddingrequests.dart
+++ b/lib/biddingrequests.dart
@@ -5,7 +5,10 @@ import 'package:flutter/services.dart';
import 'package:geolocator/geolocator.dart';
import 'package:healthcare_pharmacy/getmedicines.dart';
import 'package:healthcare_pharmacy/models/biddingrequest_model.dart';
+import 'package:healthcare_pharmacy/models/getdeliveryboy_model.dart';
import 'package:healthcare_pharmacy/settings.dart';
+import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart';
+import 'package:intl/intl.dart';
import 'package:image_picker/image_picker.dart';
import 'package:photo_view/photo_view.dart';
@@ -20,6 +23,12 @@ class BiddingRequests extends StatefulWidget {
class _BiddingRequestsState extends State {
String Url = '';
List prescriptionsList = [];
+ List modeldeliveryboyList = [];
+ var dropdownAllDeliveryBoys;
+ TextEditingController dateController = TextEditingController();
+ var selIOS;
+
+
bool isPrescriptionsDataLoading = false;
bool isSereverIssue = false;
bool isLoading=false;
@@ -51,6 +60,7 @@ class _BiddingRequestsState extends State {
((jsonDecode(response)['data']) as List).map((dynamic model) {
return BiddingRequestsModel.fromJson(model);
}).toList();
+ //String customerId=prescriptionsList[0].customerId.toString();
isPrescriptionsDataLoading = false;
});
@@ -62,59 +72,86 @@ class _BiddingRequestsState extends State {
}
}
-
+ Future getAllDeliveryBoys() async {
+ var response1= await AppSettings.getAllDeliverboy();
+ print(response1);
+ setState(() {
+ modeldeliveryboyList =
+ ((jsonDecode(response1)['deliveryBoys']) as List).map((dynamic model) {
+ return GetDeliveryboyDetailsModel.fromJson(model);
+ }).toList();
+ dropdownAllDeliveryBoys=modeldeliveryboyList[0];
+ });
+ }
@override
void initState() {
getAllPrescriptions();
+ getAllDeliveryBoys();
//getAllPharmaciesData(dropdownArea);
super.initState();
}
- showPicDialog(var imageUrl){
- return showDialog(
+ showPicDialog(List prescriptionPictures) {
+ int currentIndex = 0;
+
+ showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(
- builder: (BuildContext context, StateSetter setState) {
- return AlertDialog(
- title: const Text(''),
- content: SingleChildScrollView(
- child: ListBody(
- children: [
- Container(
- width: MediaQuery.of(context).size.width * .10,
- height: MediaQuery.of(context).size.height * .50,
- child: PhotoView(
- imageProvider: NetworkImage(imageUrl) as ImageProvider,
- maxScale: PhotoViewComputedScale.contained * 4.0,
- minScale: PhotoViewComputedScale.contained,
- initialScale: PhotoViewComputedScale.contained,
- basePosition: Alignment.center,
-
- )
- )
- ],
- ),
+ builder: (BuildContext context, StateSetter setState) {
+ return Dialog(
+ // Your custom dialog design here
+ child: Container(
+ width: double.infinity,
+ height: MediaQuery.of(context).size.height * 0.6,
+ child: Column(
+ children: [
+ Expanded(
+ child: PageView.builder(
+ itemCount: prescriptionPictures.length,
+ controller: PageController(initialPage: currentIndex),
+ onPageChanged: (index) {
+ setState(() {
+ currentIndex = index;
+ });
+ },
+ itemBuilder: (BuildContext context, int index) {
+ return Container(
+ width: double.infinity,
+ height: double.infinity,
+ child: PhotoView(
+ imageProvider: NetworkImage(prescriptionPictures[index].url),
+ maxScale: PhotoViewComputedScale.contained * 4.0,
+ minScale: PhotoViewComputedScale.contained,
+ initialScale: PhotoViewComputedScale.contained,
+ basePosition: Alignment.center,
+ ),
+ );
+ },
+ ),
+ ),
+ TextButton(
+ child: Text('Close'),
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ ],
),
- actions: [
- TextButton(
- child: Text('Close', style: textButtonStyle()),
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- ],
- );
- });
+ ),
+ );
+ },
+ );
},
);
}
+
Widget _allPrescriptions(){
if (prescriptionsList.length != 0) {
return Column(
@@ -124,13 +161,212 @@ class _BiddingRequestsState extends State {
padding: EdgeInsets.all(0),
itemCount: prescriptionsList.length,
itemBuilder: (BuildContext context, int index) {
+
return GestureDetector(
- onTap: (){
+ onTap: () {
+ // Your regular tap action logic goes here
Navigator.push(
context,
new MaterialPageRoute(
- builder: (__) => new GetMedicines(medicinebookingid:prescriptionsList[index].bidding_bookingid)));
+ builder: (__) => new GetMedicines(medicinebookingid:prescriptionsList[index].bookingId)));
+ },
+ onLongPress: () {
+ showDialog(
+ context: context,
+ barrierDismissible: false,
+ builder: (BuildContext context) {
+ return StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return AlertDialog(
+ title: const Text('Assign'),
+ content: SingleChildScrollView(
+ child: ListBody(
+ children: [
+ Container(
+ padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
+ child: DropdownButtonFormField(
+ // Initial Value
+ value: dropdownAllDeliveryBoys,
+ isExpanded: true,
+ decoration: const InputDecoration(
+ prefixIcon: Icon(
+ Icons.water,
+ color: greyColor,
+ ),
+ border: OutlineInputBorder(
+ borderSide: BorderSide(color: greyColor)),
+ focusedBorder: OutlineInputBorder(
+ borderSide: BorderSide(color: greyColor),
+ ),
+ enabledBorder: OutlineInputBorder(
+ borderSide: BorderSide(color: greyColor),
+ ),
+ labelText: 'Select delivery boy',
+ labelStyle: TextStyle(
+ color: greyColor, //<-- SEE HERE
+ ),
+ ),
+
+ hint: Text('Select delivery boy'),
+ // Down Arrow Icon
+ icon: const Icon(Icons.keyboard_arrow_down),
+ items: modeldeliveryboyList
+ .map>(
+ (value) => new DropdownMenuItem(
+ value: value,
+ child: new Text(value.deliveryboy_name),
+ ))
+ .toList(),
+ onChanged: (GetDeliveryboyDetailsModel? newValue) {
+ setState(() {
+ dropdownAllDeliveryBoys = newValue;
+ });
+
+ },
+ ),
+ ),
+
+ SizedBox(
+ height: 05,
+ ),
+ Container(
+ padding: const EdgeInsets.all(10),
+ child: TextFormField(
+ cursorColor: greyColor,
+ enabled: false,
+ controller: dateController,
+ textCapitalization: TextCapitalization.characters,
+ decoration: const InputDecoration(
+ prefixIcon: Icon(
+ Icons.date_range,
+ color: greyColor,
+ ),
+ border: OutlineInputBorder(
+ borderSide: BorderSide(color: greyColor)),
+ focusedBorder: OutlineInputBorder(
+ borderSide: BorderSide(color: greyColor),
+ ),
+ enabledBorder: OutlineInputBorder(
+ borderSide: BorderSide(color: greyColor),
+ ),
+ labelText: 'Select date & time',
+ labelStyle: TextStyle(
+ color: greyColor, //<-- SEE HERE
+ ),
+ ),
+ ),
+ ),
+
+ SizedBox(
+ height: 05,
+ ),
+
+ ],
+ ),
+ ),
+ actions: [
+ TextButton(
+ child: Text('cancel', style: textButtonStyle()),
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ TextButton(
+ child: Text('Assign ', style: textButtonStyle()),
+ onPressed: () async{
+ var payload = new Map();
+ payload["pharmacyname"] =
+ AppSettings.pharmacyName;
+ payload["pharmacyId"] =
+ AppSettings.pharmacyId;
+ payload["customerId"] =
+ prescriptionsList[index].customerId;
+ payload["address"] =
+ prescriptionsList[index]
+ .address;
+ payload["dateOfOrder"] =
+ prescriptionsList[index].bookingId;
+ payload["action"] = "accept";
+ payload["price"] =
+ prescriptionsList[index].amount;
+ payload["delivery_agent"] = dropdownAllDeliveryBoys.deliveryboy_name;
+ payload["agent_mobile"] = dropdownAllDeliveryBoys.deliveryboy_phone;
+ payload["agent_alternative_mobile"] = dropdownAllDeliveryBoys.deliveryboy_alternativeContactNumber;
+ payload["expectedDateOfDelivery"] =dateController.text.toString();
+
+ bool requestStatus =
+ await AppSettings.assignDeliveryboyBookingRequests(
+ prescriptionsList[index].bookingId,
+ payload);
+ if (requestStatus) {
+ Navigator.of(context).pop();
+ AppSettings.longSuccessToast(
+ "Delivery Boy Assigned Successfully");
+ await getAllPrescriptions();
+ } else {}
+ },
+ ),
+
+
+ IconButton(
+ onPressed: () async {
+ DatePicker.showDatePicker(
+ context,
+ dateFormat: 'dd MMMM yyyy HH:mm',
+ initialDateTime: DateTime.now(),
+ minDateTime:DateTime.now(),
+ maxDateTime: DateTime.now().add(Duration(days: 15)),
+ onMonthChangeStartWithFirstDate: true,
+ pickerMode: DateTimePickerMode.datetime,
+ pickerTheme: DateTimePickerTheme(
+ // backgroundColor: Colors.white,
+ cancelTextStyle: labelTextStyle(),
+ confirmTextStyle: labelTextStyle(),
+ // showTitle: true,
+ //title: Text('Pick date and time'),
+ itemTextStyle: valuesTextStyle(),
+ ),
+ onConfirm: (dateTime, List index)async {
+ DateTime selectdate = dateTime;
+ setState(() {
+ selIOS = DateFormat('dd-MMM-yyyy - HH:mm').format(selectdate);
+ });
+
+ if(selIOS!=''){
+ setState(() {
+ dateController.text=selIOS.toString();
+ });
+ }
+ else {
+ AppSettings.longFailedToast('please select date');
+ }
+ },
+ );
+ },
+ icon: Icon(
+ Icons.calendar_month,
+ color: primaryColor,
+ ))
+
+
+
+ ],
+ );
+ });
+ },
+ );
+
+
+
+
+
+
+
+
},
+
+
+
child: Card(
//color: prescriptionsList[index].cardColor,
@@ -145,25 +381,22 @@ class _BiddingRequestsState extends State {
children: [
GestureDetector(
child: Container(
- width: MediaQuery.of(context).size.width * .18,
- height:
- MediaQuery.of(context).size.height * .10,
+ width: MediaQuery.of(context).size.width * 0.18,
+ height: MediaQuery.of(context).size.height * 0.10,
decoration: BoxDecoration(
- shape: BoxShape.circle,
- image: DecorationImage(
- image: (AppSettings.updatedImage != null) ? FileImage(AppSettings.updatedImage!) as ImageProvider : AssetImage("images/mobilebg.png"), // picked file
- fit: BoxFit.cover)),
- /* decoration: BoxDecoration(
- shape: BoxShape.rectangle,
+ shape: BoxShape.circle,
image: DecorationImage(
- image: NetworkImage(prescriptionsList[index].prescription_url) as ImageProvider, // picked file
- fit: BoxFit.contain)),*/
+ image: NetworkImage(prescriptionsList[index].PrescriptionPictures[0].url ?? "images/logo.png"),
+ fit: BoxFit.cover,
+ ),
+ ),
),
- onTap: (){
- // showPicDialog(prescriptionsList[index].prescription_url);
-
+ onTap: () {
+ // Handle onTap event if needed
+ showPicDialog(prescriptionsList[index].PrescriptionPictures);
},
),
+
SizedBox(width:MediaQuery.of(context).size.width * .02,),
Container(
width: MediaQuery.of(context).size.width * .55,
@@ -171,12 +404,11 @@ class _BiddingRequestsState extends State {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Text(prescriptionsList[index].bidding_firstName.toString().toUpperCase(),style: valuesTextStyle()),
- Text(prescriptionsList[index].bidding_contactNumber.toString().toUpperCase(),style: valuesTextStyle()),
- Text(prescriptionsList[index].bidding_bookingid.toString().toUpperCase(),style: valuesTextStyle()),
- Text(prescriptionsList[index].bidding_address.toString().toUpperCase(),style: valuesTextStyle()),
- Text(prescriptionsList[index].custumerid_bidding.toString().toUpperCase(),style: valuesTextStyle()),
- Text(prescriptionsList[index].pharmacyid_bidding.toString().toUpperCase(),style: valuesTextStyle()),
+ Text(prescriptionsList[index].firstName.toString().toUpperCase(),style: valuesTextStyle()),
+ Text(prescriptionsList[index].bookingId.toString().toUpperCase(),style: valuesTextStyle()),
+ Text(prescriptionsList[index].address.toString().toUpperCase(),style: valuesTextStyle()),
+ Text(prescriptionsList[index].customerId.toString().toUpperCase(),style: valuesTextStyle()),
+ Text(prescriptionsList[index].pharmacyId.toString().toUpperCase(),style: valuesTextStyle()),
],
),
@@ -185,7 +417,6 @@ class _BiddingRequestsState extends State {
Visibility(
visible:true ,
-
child: prescriptionsList[index].status.toString().toLowerCase()=='pending'?Column(
children: [
TextButton(
@@ -202,9 +433,8 @@ class _BiddingRequestsState extends State {
payload["action"] = "accept";
bool requestStatus =
await AppSettings.getRequestBiddingDetails(
- prescriptionsList[index].bidding_bookingid,
+ prescriptionsList[index].bookingId,
payload);
-
if (requestStatus) {
// Navigator.of(context).pop();
AppSettings.longSuccessToast(
@@ -229,7 +459,7 @@ class _BiddingRequestsState extends State {
payload["action"] = "reject";
bool requestStatus =
await AppSettings.getRequestBiddingDetails(
- prescriptionsList[index].bidding_bookingid,
+ prescriptionsList[index].bookingId,
payload);
if (requestStatus) {
diff --git a/lib/chat/chat_controller.dart b/lib/chat/chat_controller.dart
new file mode 100644
index 0000000..f20b789
--- /dev/null
+++ b/lib/chat/chat_controller.dart
@@ -0,0 +1,88 @@
+import 'dart:io';
+
+import 'package:firebase_storage/firebase_storage.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'chatmessage.dart';
+
+
+class ChatController extends GetxController {
+ final CollectionReference _messagesCollection =
+ FirebaseFirestore.instance.collection('messages');
+
+ // Observable list of messages
+ RxList messages = [].obs;
+
+ void sendMessage(String messageContent, String messageType, bool isText) async {
+ try {
+ await _messagesCollection.add({
+ 'messageContent': messageContent,
+ 'messageType': messageType,
+ 'isText': isText,
+ 'timestamp': Timestamp.now(),
+ });
+ print("Message sent successfully");
+ } catch (e) {
+ print('Error sending message: $e');
+ }
+ }
+
+ Future uploadImage(File image, String id) async {
+ try {
+ String fileName = DateTime.now().millisecondsSinceEpoch.toString();
+ Reference storageReference =
+ FirebaseStorage.instance.ref().child('products/$fileName');
+ SettableMetadata metadata = SettableMetadata(contentType: 'image/jpeg');
+ UploadTask uploadTask = storageReference.putFile(image, metadata);
+
+ String temporaryMessageId = UniqueKey().toString();
+ messages.add(ChatMessage(
+ messageContent: 'Uploading...',
+ messageType: id,
+ isText: true,
+ temporaryMessageId: temporaryMessageId,
+ ));
+
+ TaskSnapshot taskSnapshot = await uploadTask;
+ String downloadURL = await storageReference.getDownloadURL();
+
+ // Replace the temporary message with the uploaded image
+ int index = messages.indexWhere((message) => message.temporaryMessageId == temporaryMessageId);
+ if (index != -1) {
+ messages[index] = ChatMessage(
+ messageContent: downloadURL,
+ messageType: id,
+ isText: false,
+ temporaryMessageId: '',
+ );
+ }
+
+ print('Image uploaded successfully. Download URL: $downloadURL');
+ return downloadURL;
+ } catch (e) {
+ print('Error uploading image: $e');
+ throw e;
+ }
+ }
+
+ Stream getMessagesStream() {
+ return _messagesCollection.orderBy('timestamp').snapshots();
+ }
+
+ @override
+ void onInit() {
+ super.onInit();
+ // Listen for changes in the messages collection and update the local list
+ getMessagesStream().listen((QuerySnapshot snapshot) {
+ messages.assignAll(snapshot.docs.map((doc) => ChatMessage(
+ messageContent: doc['messageContent'],
+ messageType: doc['messageType'],
+ isText: doc['isText'],
+ temporaryMessageId: '',
+ )));
+ });
+
+
+ }
+}
diff --git a/lib/chat/chatmessage.dart b/lib/chat/chatmessage.dart
new file mode 100644
index 0000000..03695f0
--- /dev/null
+++ b/lib/chat/chatmessage.dart
@@ -0,0 +1,15 @@
+import 'package:flutter/cupertino.dart';
+
+class ChatMessage {
+ String messageContent;
+ String messageType;
+ bool isText;
+ String temporaryMessageId; // New property for temporary message identifier
+
+ ChatMessage({
+ required this.messageContent,
+ required this.messageType,
+ required this.isText,
+ required this.temporaryMessageId, // Include in the constructor
+ });
+}
diff --git a/lib/chat/chatpage.dart b/lib/chat/chatpage.dart
new file mode 100644
index 0000000..beca6d9
--- /dev/null
+++ b/lib/chat/chatpage.dart
@@ -0,0 +1,241 @@
+import 'dart:io';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:healthcare_pharmacy/chat/chatzoomable_image.dart';
+import 'package:healthcare_pharmacy/pages/index.dart';
+import 'package:healthcare_pharmacy/settings.dart';
+import 'package:image_picker/image_picker.dart';
+import 'chat_controller.dart';
+import 'chatmessage.dart';
+import 'package:photo_view/photo_view.dart';
+
+class ChatPage extends StatefulWidget {
+ var pharmacyName;
+ var profilePictureUrl;
+
+
+ ChatPage({
+ this.pharmacyName,this.profilePictureUrl
+ });
+
+ @override
+ State createState() => _ChatPageState();
+}
+
+class _ChatPageState extends State {
+ final ChatController chatController = Get.put(ChatController());
+ final TextEditingController content = TextEditingController();
+ final ImagePicker _picker = ImagePicker();
+ XFile? _image;
+ var id="2";
+ bool _sending = false;
+ final ScrollController _scrollController = ScrollController();
+
+ @override
+ void initState() {
+ super.initState();
+ _scrollToBottom();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor:Colors.green,
+ elevation: 0,
+ automaticallyImplyLeading: false,
+ flexibleSpace: SafeArea(
+ child: Container(
+ padding: EdgeInsets.only(right: 16),
+ child: Row(
+ children: [
+ IconButton(
+ onPressed: (){
+ Navigator.pop(context);
+ },
+ icon: Icon(Icons.arrow_back,color: Colors.black,),
+ ),
+ SizedBox(width: 2,),
+ CircleAvatar(
+ backgroundImage: NetworkImage(AppSettings.profilePictureUrl),
+ maxRadius: 20,
+ ),
+ SizedBox(width: 12,),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(widget.pharmacyName,style: TextStyle( fontSize: 16 ,fontWeight: FontWeight.w600),),
+ // SizedBox(height: 6,),
+ // Text("Online",style: TextStyle(color: Colors.grey.shade600, fontSize: 13),),
+ ],
+ ),
+ ),
+ /*IconButton(
+ onPressed: () {
+ UrlLauncher.launch("tel://8328206298");
+ },
+ icon: Icon(Icons.call, color: Colors.black),
+ ),*/
+ IconButton(
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => IndexPage()),
+ );
+ },
+ icon: Icon(Icons.videocam, color: Colors.black),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ body: Stack(
+ children: [
+ Obx(() => ListView.builder(
+ itemCount: chatController.messages.length,
+ shrinkWrap: true,
+ padding: EdgeInsets.only(top: 10, bottom: 80), // Adjust bottom padding to accommodate the input field
+ physics: ScrollPhysics(),
+ controller: _scrollController,
+ itemBuilder: (context, index) {
+ final data = chatController.messages[index];
+ return Container(
+ padding: EdgeInsets.only(
+ left: 14, right: 14, top: 10, bottom: 10),
+ child: Align(
+ alignment: (data.messageType != id ? Alignment.topLeft : Alignment.topRight),
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => ChatZoomableImage(data.messageContent),
+ ),
+ );
+ },
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(20),
+ color: (data.messageType != id
+ ? Colors.grey.shade200
+ : Colors.blue[200]),
+ ),
+ padding: EdgeInsets.all(16),
+ child: data.isText
+ ? Text(data.messageContent, style: TextStyle(fontSize: 15))
+ : Image.network(
+ data.messageContent,
+ scale: 3,
+ width: 100,
+ height: 100,
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+
+ ),
+ );
+ },
+ )),
+ Align(alignment: Alignment.bottomCenter,child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: Container(
+ height: 60,
+ width: double.infinity,
+ color: Colors.white,
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: getImage,
+ child: Container(
+ height: 30,
+ width: 30,
+ decoration: BoxDecoration(
+ color: Colors.lightBlue,
+ borderRadius: BorderRadius.circular(30),
+ ),
+ child: Icon(Icons.add, color: Colors.white, size: 20),
+ ),
+ ),
+ SizedBox(width: 15),
+ Expanded(
+ child: TextField(
+ controller: content,
+ decoration: InputDecoration(
+ hintText: "Write message...",
+ hintStyle: TextStyle(color: Colors.black54),
+ border: InputBorder.none,
+ ),
+ ),
+ ),
+ SizedBox(width: 15),
+ FloatingActionButton(
+ onPressed: () {
+ sendMessage();
+ },
+ child: Icon(Icons.send, color: Colors.white, size: 18),
+ backgroundColor: Colors.blue,
+ elevation: 0,
+ ),
+ ],
+ ),
+ ),
+ ),)
+ ],
+ ),
+ );
+ }
+
+ void _scrollToBottom() {
+ Future.delayed(Duration(milliseconds: 300), () {
+ if (_scrollController.hasClients) {
+ _scrollController.animateTo(
+ _scrollController.position.maxScrollExtent,
+ duration: Duration(milliseconds: 300),
+ curve: Curves.easeInOut,
+ );
+ }
+ });
+ }
+
+ Future getImage() async {
+ final XFile? image =
+ await _picker.pickImage(source: ImageSource.gallery);
+ if (image != null) {
+ setState(() {
+ _image = image;
+ });
+ sendMessage(); // Call sendMessage function to send the selected image immediately
+ }
+ }
+
+ void sendMessage() async {
+ String messageContent = content.text.trim();
+ if (messageContent.isNotEmpty || _image != null) {
+ setState(() {
+ _sending = true;
+ });
+ try {
+ if (_image != null) {
+ String imageUrl =
+ await chatController.uploadImage(File(_image!.path),'$id');
+ chatController.sendMessage(imageUrl, '$id', false);
+ _image = null; // Clear the selected image after sending
+ }
+ if (messageContent.isNotEmpty) {
+ chatController.sendMessage(messageContent, '$id', true);
+ content.clear();
+ }
+ } finally {
+ setState(() {
+ _sending = false;
+ });
+ }
+ _scrollToBottom(); // Scroll to the bottom after sending message
+ }
+ }
+}
diff --git a/lib/chat/chatzoomable_image.dart b/lib/chat/chatzoomable_image.dart
new file mode 100644
index 0000000..7696d77
--- /dev/null
+++ b/lib/chat/chatzoomable_image.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+import 'package:healthcare_pharmacy/settings.dart';
+import 'package:photo_view/photo_view.dart';
+
+class ChatZoomableImage extends StatelessWidget {
+ final String imageUrl;
+
+ ChatZoomableImage(this.imageUrl);
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: primaryColor, // Set the background color
+ title: Text('Preview Image'), // Set the title text
+ actions: [
+ IconButton(
+ icon: Icon(Icons.close),
+ onPressed: () {
+ Navigator.pop(context);
+ },
+ ),
+ ],
+ ),
+ body: Center(
+ child: imageUrl.isNotEmpty
+ ? PhotoView(
+ imageProvider: NetworkImage(imageUrl),
+ minScale: PhotoViewComputedScale.contained,
+ maxScale: PhotoViewComputedScale.contained * 3.0,
+ )
+ : Image.asset(
+ 'images/mobilebg.png', // Path to your default image
+ fit: BoxFit.cover,
+ ),
+ ),
+ );
+ }
+}
+
diff --git a/lib/chatview.dart b/lib/chatview.dart
new file mode 100644
index 0000000..e932dd8
--- /dev/null
+++ b/lib/chatview.dart
@@ -0,0 +1,201 @@
+import 'dart:convert';
+
+import 'package:flutter/material.dart';
+import 'package:healthcare_pharmacy/models/chatconversation_model.dart';
+import 'package:healthcare_pharmacy/settings.dart';
+import 'ChatMessage.dart';
+
+class ChatUIconvoid extends StatefulWidget {
+ const ChatUIconvoid({super.key});
+
+ @override
+ State createState() => _ChatUIconvoidState();
+}
+
+class _ChatUIconvoidState extends State {
+
+ TextEditingController _messageController = TextEditingController();
+ bool isLoading=false;
+ List chatCoversatitonIdList = [];
+ List messages = [
+ ChatMessage(message: "Hello", type: "receiver"),
+ ChatMessage(message: "How have you?", type: "receiver"),
+ ChatMessage(
+ message: "I am doing fine.How have you?",
+ type: "sender"),
+
+ ];
+
+ @override
+ void initState() {
+ // TODO: implement initState
+ isLoading=true;
+ getConversasionId();
+ super.initState();
+ }
+ Future getConversasionId() async {
+ isLoading = true;
+ try {
+ var response = await AppSettings.getChatId();
+ setState(() {
+ chatCoversatitonIdList =
+ ((jsonDecode(response)['newConversation']) as List).map((dynamic model) {
+ return GetCoversatitonIdModel.fromJson(model);
+ }).toList();
+
+ // Extracting the conversation_id from the response
+ String conversationId =
+ jsonDecode(response)['newConversation']['conversation_id'];
+
+ // Use the conversationId as needed in your code
+ print('Conversation ID: $conversationId');
+
+ isLoading = false;
+ isLoading = false;
+ });
+
+
+ } catch (e) {
+ setState(() {
+ isLoading = false;
+ });
+ }
+ }
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ elevation: 0,
+ automaticallyImplyLeading: false,
+ backgroundColor: Colors.white,
+ flexibleSpace: SafeArea(
+ child: Container(
+ padding: EdgeInsets.only(right: 16),
+ child: Row(
+ children: [
+ IconButton(
+ onPressed: (){
+ Navigator.pop(context);
+ },
+ icon: Icon(Icons.arrow_back,color: Colors.black,),
+ ),
+ SizedBox(width: 2,),
+ CircleAvatar(
+ backgroundImage: NetworkImage("https://www.shutterstock.com/image-photo/pharmacist-holding-medicine-box-capsule-260nw-717437125.jpg"),
+ maxRadius: 20,
+ ),
+ SizedBox(width: 12,),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text("Arminta pharma",style: TextStyle( fontSize: 16 ,fontWeight: FontWeight.w600),),
+ // SizedBox(height: 6,),
+ // Text("Online",style: TextStyle(color: Colors.grey.shade600, fontSize: 13),),
+ ],
+ ),
+ ),
+ Icon(Icons.settings,color: Colors.black54,),
+ ],
+ ),
+ ),
+ ),
+ ),
+ body: Stack(
+ children: [
+ ListView.builder(
+ itemCount: messages.length,
+ shrinkWrap: true,
+ padding: EdgeInsets.only(top: 10,bottom: 60),
+ itemBuilder: (context, index){
+ return Container(
+ padding: EdgeInsets.only(left: 14,right: 14,top: 10,bottom: 10),
+ child: Align(
+ alignment: (messages[index].type == "receiver"?Alignment.topLeft:Alignment.topRight),
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(20),
+ color: (messages[index].type == "receiver"?Colors.grey.shade200:Colors.blue[200]),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 16,vertical: 10),
+ child: Text(messages[index].message, style: TextStyle(fontSize: 15),),
+ ),
+ ),
+ );
+ },
+ ),
+ Align(
+ alignment: Alignment.bottomLeft,
+ child: Container(
+ padding: EdgeInsets.only(left: 10, bottom: 10, top: 10),
+ height: 60,
+ width: double.infinity,
+ color: Colors.white,
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: () {},
+ child: Container(
+ height: 30,
+ width: 30,
+ decoration: BoxDecoration(
+ color: Colors.lightBlue,
+ borderRadius: BorderRadius.circular(30),
+ ),
+ child: Icon(
+ Icons.add,
+ color: Colors.white,
+ size: 20,
+ ),
+ ),
+ ),
+ SizedBox(
+ width: 15,
+ ),
+ Expanded(
+ child: TextField(
+ controller: _messageController,
+ decoration: InputDecoration(
+ hintText: "Write message...",
+ hintStyle: TextStyle(color: Colors.black54),
+ border: InputBorder.none),
+ ),
+ ),
+ SizedBox(
+ width: 15,
+ ),
+ FloatingActionButton(
+ onPressed: () {
+ String newMessage = _messageController.text;
+ if (newMessage.isNotEmpty) {
+ // Add the new message to the list
+ setState(() {
+ messages.add(
+ ChatMessage(
+ message: newMessage,
+ type: "sender",
+ ),
+ );
+ });
+
+ // Clear the text field
+ _messageController.clear();
+ }
+ },
+ child: Icon(
+ Icons.send,
+ color: Colors.white,
+ size: 18,
+ ),
+ backgroundColor: Colors.blue,
+ elevation: 0,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ));
+ }
+}
diff --git a/lib/conver.dart b/lib/conver.dart
new file mode 100644
index 0000000..de7cf75
--- /dev/null
+++ b/lib/conver.dart
@@ -0,0 +1,395 @@
+import 'dart:convert';
+import 'dart:io';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:healthcare_pharmacy/pages/index.dart';
+import 'package:healthcare_pharmacy/settings.dart';
+import 'package:url_launcher/url_launcher.dart' as UrlLauncher;
+import 'package:web_socket_channel/io.dart';
+import 'package:web_socket_channel/web_socket_channel.dart';
+import 'models/ChatMessage.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:flutter_callkeep/flutter_callkeep.dart';
+
+
+class ChatUI extends StatefulWidget {
+
+ const ChatUI({Key? key}) : super(key: key);
+
+ @override
+ State createState() => _ChatUIState();
+}
+
+class _ChatUIState extends State {
+ WebSocketChannel channel=IOWebSocketChannel.connect(
+ "wss://socketsbay.com/wss/v2/1/demo/",
+ );
+ // WebSocket channel for call signaling
+ late WebSocketChannel callChannel;
+
+ WebSocketConnectionState _connectionState = WebSocketConnectionState.connecting;
+ late ScrollController _scrollController;
+ final TextEditingController _controller = TextEditingController();
+ // Store messages
+ final List _messages = [];
+ String myUserId = 'user456';
+ String otherUserId = 'user123';
+ final ImagePicker _picker = ImagePicker();
+
+ Future pickImageFromGallery() async {
+ try {
+ final image = await _picker.pickImage(source: ImageSource.gallery);
+ if (image == null) return;
+ final imageTemp = File(image.path);
+ setState(() {
+ AppSettings.updatedImage = imageTemp;
+ });
+ // uploadProfileApi(AppSettings.updatedImage);
+ AppSettings.saveProfile(image.path);
+
+
+ } on PlatformException catch (e) {
+ print('Failed to pick image: $e');
+ }
+ }
+
+ Future takeImageFromCamera() async {
+ try {
+ final image = await _picker.pickImage(source: ImageSource.camera);
+ if (image == null) return;
+ final imageTemp = File(image.path);
+ setState(() {
+ AppSettings.updatedImage = imageTemp;
+ });
+
+ //uploadProfileApi(AppSettings.updatedImage);
+ AppSettings.saveProfile(image.path);
+
+ } on PlatformException catch (e) {
+ print('Failed to pick image: $e');
+ }
+ }
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: _connectionState == WebSocketConnectionState.error ? Colors.red : _connectionState == WebSocketConnectionState.closed ? Colors.red : Colors.green,
+ elevation: 0,
+ automaticallyImplyLeading: false,
+ flexibleSpace: SafeArea(
+ child: Container(
+ padding: EdgeInsets.only(right: 16),
+ child: Row(
+ children: [
+ IconButton(
+ onPressed: (){
+ Navigator.pop(context);
+ },
+ icon: Icon(Icons.arrow_back,color: Colors.black,),
+ ),
+ SizedBox(width: 2,),
+ CircleAvatar(
+ backgroundImage: NetworkImage("https://ehealth.eletsonline.com/wp-content/uploads/2020/12/pharma-industry-in-2021.jpg"),
+ maxRadius: 20,
+ ),
+ SizedBox(width: 12,),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text("Suresh",style: TextStyle( fontSize: 16 ,fontWeight: FontWeight.w600),),
+ // SizedBox(height: 6,),
+ // Text("Online",style: TextStyle(color: Colors.grey.shade600, fontSize: 13),),
+ ],
+ ),
+ ),
+ IconButton(
+ onPressed: () {
+ UrlLauncher.launch("tel://8328206298");
+ },
+ icon: Icon(Icons.call, color: Colors.black),
+ ),
+ IconButton(
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => IndexPage()),
+ );
+ },
+ icon: Icon(Icons.videocam, color: Colors.black),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ body: Stack(
+ children: [
+ ListView.builder(
+ controller: _scrollController,
+ itemCount: _messages.length,
+ shrinkWrap: true,
+ padding: EdgeInsets.only(top: 10,bottom: 60),
+ itemBuilder: (context, index){
+ bool isSentByMe = _messages[index].senderId == myUserId;
+ return Container(
+ padding: EdgeInsets.only(left: 14,right: 14,top: 10,bottom: 10),
+ child: Align(
+ alignment: (isSentByMe?Alignment.topRight:Alignment.topLeft),
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(20),
+ color: (isSentByMe?Colors.blue[200]:Colors.grey[200]),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 16,vertical: 10),
+ child: Text(_messages[index].messageContent, style: TextStyle(fontSize: 15),),
+ ),
+ ),
+ );
+ },
+ ),
+ Align(
+ alignment: Alignment.bottomLeft,
+ child: Container(
+ padding: EdgeInsets.only(left: 10, bottom: 10, top: 10),
+ height: 60,
+ width: double.infinity,
+ color: Colors.white,
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: () {
+ showModalBottomSheet(
+ context: context,
+ builder: (BuildContext context) {
+ return SizedBox(
+ height: 200,
+ child: Center(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ GestureDetector(
+ child: Icon(
+ Icons.camera_alt_outlined,
+ size: 100,
+ color: greyColor,
+ ),
+ onTap: () async {
+ await takeImageFromCamera();
+ Navigator.pop(context);
+ },
+ ),
+ SizedBox(
+ width:
+ MediaQuery.of(context).size.width * .20,
+ ),
+ GestureDetector(
+ child: Icon(
+ Icons.photo,
+ size: 100,
+ color: greyColor,
+ ),
+ onTap: () async {
+ await pickImageFromGallery();
+ Navigator.pop(context);
+ },
+ ),
+ ],
+ ),
+ ),
+ );
+ });
+ },
+ child: Container(
+ height: 30,
+ width: 30,
+ decoration: BoxDecoration(
+ color: Colors.lightBlue,
+ borderRadius: BorderRadius.circular(30),
+ ),
+ child: Icon(
+ Icons.add,
+ color: Colors.white,
+ size: 20,
+ ),
+ ),
+ ),
+ SizedBox(
+ width: 15,
+ ),
+ Expanded(
+ child: TextField(
+ controller: _controller,
+ decoration: InputDecoration(
+ hintText: "Write message...",
+ hintStyle: TextStyle(color: Colors.black54),
+ border: InputBorder.none),
+ ),
+ ),
+ SizedBox(
+ width: 15,
+ ),
+ FloatingActionButton(
+ onPressed: () {
+ String newMessage = _controller.text;
+ if (newMessage.isNotEmpty) {
+ // Add the new message to the list
+ setState(() {
+ _sendMessage();
+ });
+
+ // Clear the text field
+ _controller.clear();
+ }
+ },
+ child: Icon(
+ Icons.send,
+ color: Colors.white,
+ size: 18,
+ ),
+ backgroundColor: Colors.blue,
+ elevation: 0,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ));
+
+ }
+
+
+
+ void _sendMessage() {
+ if (_controller.text.isNotEmpty) {
+ var message = ChatMessage(
+ senderId: myUserId,
+ receiverId: otherUserId,
+ messageType: 'text',
+ messageContent: _controller.text,
+ );
+ channel.sink.add(chatMessageToJson(message));
+ _messages.add(message);
+ _controller.clear();
+ }
+ }
+
+
+ @override
+ void initState() {
+ super.initState();
+ // Initialize the WebSocket channel for call signaling
+ callChannel = IOWebSocketChannel.connect(
+ "wss://socketsbay.com/wss/v2/1/demo/call", // adjust the URL accordingly
+ );
+ _scrollController = ScrollController();
+ channel.stream.listen((message) {
+ if (message is String) {
+ var receivedMessage = chatMessageFromJson(message);
+ setState(() {
+ _messages.add(receivedMessage);
+ });
+ _scrollToBottom();
+ }
+ }, onError: (error) {
+ setState(() {
+ _connectionState = WebSocketConnectionState.error;
+ });
+ },onDone: (){
+ setState(() {
+ _connectionState = WebSocketConnectionState.closed;
+ });
+ },);
+ }
+
+
+ // ... existing code ...
+
+ void startCall(String callId) {
+ // Send a call initiation message to the other user
+ var callMessage = {
+ 'type': 'call',
+ 'callId': callId,
+ 'senderId': myUserId,
+ 'receiverId': otherUserId,
+ };
+ callChannel.sink.add(jsonEncode(callMessage));
+
+ // Update UI or perform other actions as needed
+ // ...
+
+ // For simplicity, let's assume the call is accepted after a short delay
+ Future.delayed(Duration(seconds: 2), () {
+ // Handle call accepted
+ onCallAccepted(callId);
+ });
+ }
+
+ void onCallAccepted(String callId) {
+ // Update UI or perform other actions as needed
+ // ...
+
+ // Send a call accepted message to the other user
+ var acceptedMessage = {
+ 'type': 'call_accepted',
+ 'callId': callId,
+ 'senderId': myUserId,
+ 'receiverId': otherUserId,
+ };
+ callChannel.sink.add(jsonEncode(acceptedMessage));
+
+ // Start the actual call
+ // ...
+ }
+
+ void endCall(String callId) {
+ // Send a call end message to the other user
+ var endMessage = {
+ 'type': 'call_end',
+ 'callId': callId,
+ 'senderId': myUserId,
+ 'receiverId': otherUserId,
+ };
+ callChannel.sink.add(jsonEncode(endMessage));
+
+ // Update UI or perform other actions as needed
+ // ...
+
+ // For simplicity, let's assume the call is ended immediately
+ onCallEnded(callId);
+ }
+
+ void onCallEnded(String callId) {
+ // Update UI or perform other actions as needed
+ // ...
+
+ // Close the call WebSocket channel
+ callChannel.sink.close();
+
+ // For simplicity, let's assume the call ended immediately
+ // ...
+ }
+
+
+
+ void _scrollToBottom() {
+ // Scroll to the bottom of the list
+ _scrollController.animateTo(
+ _scrollController.position.maxScrollExtent,
+ duration: Duration(milliseconds: 200),
+ curve: Curves.easeOut,
+ );
+ }
+
+
+ @override
+ void dispose() {
+ channel.sink.close();
+ super.dispose();
+ }
+}
+
+enum WebSocketConnectionState { connecting, open, closing, closed, error }
\ No newline at end of file
diff --git a/lib/createoffers.dart b/lib/createoffers.dart
index f58d486..e8ce80b 100644
--- a/lib/createoffers.dart
+++ b/lib/createoffers.dart
@@ -10,7 +10,7 @@ import 'package:intl/intl.dart';
import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image/image.dart' as Img;
-
+import 'package:gallery_saver/gallery_saver.dart';
class offers extends StatefulWidget {
@@ -74,8 +74,7 @@ class _offersState extends State {
}
}
-
- Future takeImageFromCamera() async {
+ /* Future takeImageFromCamera() async {
try {
final image = await _picker.pickImage(source: ImageSource.camera);
if (image == null) return;
@@ -89,6 +88,11 @@ class _offersState extends State {
// Compress the image
List compressedImage = Img.encodeJpg(decodedImage!, quality: 45);
+ // Save the original and compressed images to the gallery
+ await GallerySaver.saveImage(image.path, albumName: 'MedicinesAlbum');
+ //await GallerySaver.saveImage(image.path, albumName: null);
+ //await GallerySaver.saveImage(imageFile.path, albumName: 'YourAlbumName');
+
// Save the compressed image back to file
await imageFile.writeAsBytes(compressedImage);
@@ -106,6 +110,32 @@ class _offersState extends State {
print('Failed to pick image: $e');
}
}
+*/
+ Future takeImageFromCamera() async {
+ try {
+ final image = await _picker.pickImage(source: ImageSource.camera);
+ if (image == null) return;
+
+ final File imageFile = File(image.path);
+
+ // Read the image from file
+ List imageBytes = await imageFile.readAsBytes();
+ Img.Image? decodedImage = Img.decodeImage(imageBytes);
+ // Compress the image
+ List compressedImage = Img.encodeJpg(decodedImage!, quality: 45);
+ await imageFile.writeAsBytes(compressedImage);
+ AppSettings.preLoaderDialog(context);
+ var res = await AppSettings.offeruploadImageHTTPNew(imageFile);
+ print(jsonDecode(res));
+ setState(() {
+ offerUrl = jsonDecode(res)['picture'][0]['url'];
+ print(offerUrl);
+ });
+ Navigator.of(context, rootNavigator: true).pop();
+ } on PlatformException catch (e) {
+ print('Failed to pick image: $e');
+ }
+ }
@override
Widget build(BuildContext context) {
diff --git a/lib/dashboard.dart b/lib/dashboard.dart
index 74dd953..f96f245 100644
--- a/lib/dashboard.dart
+++ b/lib/dashboard.dart
@@ -4,7 +4,10 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:healthcare_pharmacy/adddeliveryboy.dart';
+import 'package:healthcare_pharmacy/chat/chatpage.dart';
+import 'package:healthcare_pharmacy/chatview.dart';
import 'package:healthcare_pharmacy/companyoffrers.dart';
+import 'package:healthcare_pharmacy/conver.dart';
import 'package:healthcare_pharmacy/getallpharmacies.dart';
import 'package:healthcare_pharmacy/getdeliveryboydata.dart';
import 'package:healthcare_pharmacy/getmedicines.dart';
@@ -421,7 +424,7 @@ class _DashboardState extends State {
width: 10,
),
- Container(
+ /*Container(
child: AppSettings.qrCode==''?TextButton(
child: Text(
@@ -473,7 +476,7 @@ class _DashboardState extends State {
child: Image.memory(Uint8List.fromList(base64.decode(AppSettings.qrCode))),
),
),
- )
+ )*/
],
),),
SizedBox(
@@ -820,6 +823,31 @@ class _DashboardState extends State {
);
},
),
+ Divider(
+ color: Colors.grey,
+ ),
+ ListTile(
+ title: Row(
+ children: const [
+ Image(
+ image: const AssetImage('images/inactive.png'),
+ height: 25,
+ width: 25,
+ fit: BoxFit.fill),
+ const SizedBox(
+ width: 10,
+ ),
+ Text('Chat', style: TextStyle(color: Colors.black)),
+ ],
+ ),
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => ChatPage(pharmacyName: AppSettings.pharmacyName,profilePictureUrl: AppSettings.profilePictureUrl)),
+ );
+ },
+ ),
Divider(
color: Colors.grey,
diff --git a/lib/getdeliveryboydata.dart b/lib/getdeliveryboydata.dart
index 369f407..be547ce 100644
--- a/lib/getdeliveryboydata.dart
+++ b/lib/getdeliveryboydata.dart
@@ -183,8 +183,8 @@ class _GetDeliveryboyDataState extends State {
} else {
Navigator.of(context, rootNavigator: true).pop();
- AppSettings.longFailedStyledToast(
- "Deliveryboy upadtion failed", context);
+ AppSettings.longFailedToast(
+ "Deliveryboy upadtion failed");
Navigator.of(context).pop();
}
} catch (exception) {
@@ -192,7 +192,7 @@ class _GetDeliveryboyDataState extends State {
print(exception);
}
} else {
- AppSettings.longFailedStyledToast("enter details", context);
+ AppSettings.longFailedToast("enter details");
}
},
),
diff --git a/lib/getmedicines.dart b/lib/getmedicines.dart
index fd40517..3cda81f 100644
--- a/lib/getmedicines.dart
+++ b/lib/getmedicines.dart
@@ -127,74 +127,84 @@ class _GetMedicinesState extends State with TickerProviderStateMix
);
}
- Widget _bindMedicines() {
- if (medicine_name!='') {
- return Padding(padding: EdgeInsets.all(10),
- child: Container(
- width: double.infinity,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- GestureDetector(
- child: Container(
- width: MediaQuery.of(context).size.width * .18,
- height:
- MediaQuery.of(context).size.height * .10,
- decoration: BoxDecoration(
+ Widget _bindMedicines() {
+ if (medicine_name != '') {
+ return Padding(
+ padding: EdgeInsets.all(10),
+ child: Container(
+ width: double.infinity,
+ decoration: BoxDecoration(
+ color: Colors.white, // Set background color to white
+ borderRadius: BorderRadius.circular(5.0), // Set border radius to 5
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.5),
+ spreadRadius: 2,
+ blurRadius: 5,
+ offset: Offset(0, 3), // changes position of shadow
+ ),
+ ],
+ ),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GestureDetector(
+ child: Container(
+ width: MediaQuery.of(context).size.width * .18,
+ height: MediaQuery.of(context).size.height * .10,
+ decoration: BoxDecoration(
shape: BoxShape.rectangle,
image: DecorationImage(
- image: NetworkImage(medImages[0]) as ImageProvider, // picked file
- fit: BoxFit.contain)),
- ),
- onTap: () async {
- showPicDialog(medImages[0]);
- },
- ),
- GestureDetector(
- child: Column(
- children: [
- Text(("Name :"+ medicine_name),
- style: TextStyle(fontWeight: FontWeight.bold),
- ),
- Text(("Manufacturers :"+ medicine_manufacturers),
- style: TextStyle(fontWeight: FontWeight.bold),
- ),
- Text(
- medicine_salt_composition,
- style: TextStyle(fontWeight: FontWeight.bold),
- ),
- Text(("Estimate Price :"+ medicine_mrp),
- style: TextStyle(fontWeight: FontWeight.bold),
+ image: NetworkImage(medImages[0]) as ImageProvider,
+ fit: BoxFit.contain,
+ ),
+ borderRadius: BorderRadius.circular(5.0), // Set border radius to 5
),
- Text(("Medicine_Use :"+ medicine_primary_use),
- style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ onTap: () async {
+ showPicDialog(medImages[0]);
+ },
+ ),
+ SizedBox(width: 10),
+ Expanded(
+ child: GestureDetector(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: 30),
+ Text(
+ "Name: " + medicine_name,
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ Text(
+ "Estimate Price: " + medicine_mrp,
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ Text(
+ "Medicine Use: " + medicine_primary_use,
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ ],
),
- ],
+ onTap: () {
+ Navigator.push(
+ context,
+ new MaterialPageRoute(
+ builder: (__) => new MedicineDetails(
+ name: medicine_name,
+ price: medicine_mrp,
+ bookid: medbookingid,
+ ),
+ ),
+ );
+ },
+ ),
),
- onTap: () {
- /* Navigator.push(
- context,
- new MaterialPageRoute(
- builder: (__) => new MedicineDetailsCount()));*/
- Navigator.push(
- context,
- new MaterialPageRoute(
- builder: (__) => new MedicineDetails(name: medicine_name,price: medicine_mrp,bookid:medbookingid)));
- },
-
-
-
- ),
-
-
- ],
+ ],
+ ),
),
-
-
- ),
- );
- }
+ );
+ }
else {
return Center(
child: Padding(
diff --git a/lib/main.dart b/lib/main.dart
index 1c665c5..189e54a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,4 +1,10 @@
+import 'dart:io';
+
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
+import 'package:healthcare_pharmacy/PushNotificationService.dart';
+import 'package:healthcare_pharmacy/chat/chatpage.dart';
import 'package:sizer/sizer.dart';
import 'package:flutter/services.dart';
import 'splash_screen.dart';
@@ -7,6 +13,16 @@ void main () async {
// Set default home.
Widget _defaultHome = Splash();
WidgetsFlutterBinding.ensureInitialized();
+ FirebaseOptions firebaseOptions = FirebaseOptions(
+ apiKey: 'AIzaSyC89L-Xg53Bd_mdCPvKOu7BcC9Ya6UZeds',
+ appId: '1:60196905754:android:05ea9ecef5280e578a42a3',
+ messagingSenderId: '60196905754 ',
+ projectId: 'health-pharma-67443',
+ storageBucket: "health-pharma-67443.appspot.com"// Firebase Realtime Database URL
+ );
+ Platform.isAndroid? await Firebase.initializeApp(options: firebaseOptions):await Firebase.initializeApp();
+ PushNotificationService().initialize();
+ FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(alert: true,badge: true,sound: true);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(Sizer(
diff --git a/lib/medicinecart.dart b/lib/medicinecart.dart
index 3dba8f1..ebcd7a7 100644
--- a/lib/medicinecart.dart
+++ b/lib/medicinecart.dart
@@ -37,7 +37,10 @@ class _MedicineCartListState extends State with TickerProvider
String bookingidstring='';
bool isLoading=false;
-
+ double finalGrandTotal=0.0;
+ double gstPercentage=0.0;
+ double discountedTotalAmount=0.0;
+ double additionalDiscount=0.0;
@@ -244,31 +247,116 @@ class _MedicineCartListState extends State with TickerProvider
onPrimary: Colors.white, // foreground
),
onPressed: () async{
- // Calculate final amount
- double gst = 0.00; // Replace with your actual GST value
- double additionalDiscount = 10.00; // Replace with your actual additional discount value
- double finalAmount = double.parse(totalPrice) + gst - additionalDiscount;
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
- // Update controllers with values
- medicine_priceController.text = totalPrice.toString();
- medicine_gstPriceController.text = gst.toString();
+
+ double totalAmount = double.parse(totalPrice);
+ double additionalDiscountPercentage = 5;
+ double specialDiscountPercentage = 5;
+ gstPercentage = 18;
+
+ // Calculate additional discount
+ additionalDiscount = (totalAmount * additionalDiscountPercentage) / 100;
+ discountedTotalAmount = totalAmount - additionalDiscount;
+
+ // Calculate special discount
+ double specialDiscount = (discountedTotalAmount * specialDiscountPercentage) / 100;
+ double grandTotal = discountedTotalAmount - specialDiscount;
+
+
+ // Calculate GST on the grand total
+ double gstOnGrandTotal = (grandTotal * gstPercentage) / 100;
+ finalGrandTotal = grandTotal + gstOnGrandTotal;
+ medicine_priceController.text = finalGrandTotal.toString();
+ medicine_gstPriceController.text = gstPercentage.toString();
medicine_additionalPriceController.text = additionalDiscount.toString();
return AlertDialog(
- title: Text('Payment Receipt'),
+ title: Text(
+ 'Payment Receipt',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.red,
+ fontSize: 20
+ ),
+ ),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Text('Total Price: $totalPrice'),
- Text('GST: $gst'),
- Text('Additional Discount: $additionalDiscount'),
- Divider(), // Add a divider line
- Text('Final Amount: $finalAmount'), // Show final amount
+ Text(
+ 'Medicines Total Amount: ${totalAmount.toStringAsFixed(2)}',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ fontSize: 16
+ ),
+ ),
+
+ Text(
+ 'Additional Discount (-5%): ${additionalDiscount.toStringAsFixed(2)} ',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ fontSize: 16
+ ),
+ ),
+ Divider(
+ thickness: 2, // Adjust the thickness as needed
+ color: Colors.grey, // Adjust the color as needed
+ ),
+ Text(
+ 'Discounted Total Ammount: ${discountedTotalAmount.toStringAsFixed(2)}',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ fontSize: 16
+ ),
+ ),
+ Text(
+ 'Special Discount (-5%): ${specialDiscount.toStringAsFixed(2)}',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ fontSize: 16
+ ),
+ ),
+ Divider(
+ thickness: 2, // Adjust the thickness as needed
+ color: Colors.grey, // Adjust the color as needed
+ ),
+ Text(
+ 'Special Discounted Total Ammount: ${grandTotal.toStringAsFixed(2)}',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ fontSize: 16
+ ),
+ ),
+ Text(
+ 'GST (+18%): ${gstOnGrandTotal.toStringAsFixed(2)}',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ fontSize: 16
+ ),
+ ),
+ Divider(
+ thickness: 2, // Adjust the thickness as needed
+ color: Colors.black, // Adjust the color as needed
+ ),
+
+ Text(
+ 'Grand Total: ${finalGrandTotal.toStringAsFixed(2)}',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.redAccent,
+ fontSize: 20
+ ),
+ ),
],
),
actions: [
@@ -298,7 +386,7 @@ class _MedicineCartListState extends State with TickerProvider
AppSettings.longSuccessToast(
"Medicines Final Price Sent Successfully");
- await Navigator.push(
+ await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Dashboard()),
@@ -324,8 +412,53 @@ class _MedicineCartListState extends State with TickerProvider
child: Text('Submit'),
),
),
+ SizedBox(height: 10), // Add some spacing between buttons
+ /* Center(
+ child: ElevatedButton(
+ style: ElevatedButton.styleFrom(
+ primary: primaryColor, // background
+ onPrimary: Colors.white, // fores
+ ),
+ onPressed: () async{
+ var payload = new Map();
+ payload["pharmacyname"] =
+ "Arminta Pharma PVT LTD";
+ payload["pharmacyId"] =
+ "AWSSSUR1";
+ payload["customerId"] =
+ "AWSSSUR1";
+ payload["address"] =
+ "kphb";
+ payload["dateOfOrder"] =
+ "15/02/2024";
+ payload["action"] = "accept";
+ payload["price"] =
+ "1000";
+ payload["delivery_agent"] = "Arminta";
+ payload["agent_mobile"] = "8328206299";
+ payload["expectedDateOfDelivery"] ="20/02/2024";
+
+ bool requestStatus =
+ await AppSettings.assignDeliveryboyBookingRequests(
+ widget.bookidID,
+ payload);
+
+ if (requestStatus) {
+ Navigator.of(context).pop();
+ AppSettings.longSuccessToast(
+ "Booking Accepted");
+ // await getBookingRequestsData();
+
+
+ } else {}
+ },
+ child: Text('Assign Deliver Boy'),
+ ),
+ ),*/
],
+
);
+
},
);
@@ -336,6 +469,7 @@ class _MedicineCartListState extends State with TickerProvider
+
]);
} else {
return Center(
diff --git a/lib/models/ChatMessage.dart b/lib/models/ChatMessage.dart
new file mode 100644
index 0000000..f11c129
--- /dev/null
+++ b/lib/models/ChatMessage.dart
@@ -0,0 +1,37 @@
+import 'package:meta/meta.dart';
+import 'dart:convert';
+
+// Define chatMessageFromJson and chatMessageToJson at the top level
+ChatMessage chatMessageFromJson(String str) => ChatMessage.fromJson(json.decode(str));
+
+String chatMessageToJson(ChatMessage data) => json.encode(data.toJson());
+
+class ChatMessage {
+ String senderId;
+ String receiverId;
+ String messageType;
+ String messageContent;
+
+ ChatMessage({
+ required this.senderId,
+ required this.receiverId,
+ required this.messageType,
+ required this.messageContent,
+ });
+
+ factory ChatMessage.fromJson(Map json) => ChatMessage(
+ senderId: json["senderId"],
+ receiverId: json["receiverId"],
+ messageType: json["messageType"],
+ messageContent: json["messageContent"],
+ );
+
+ Map toJson() => {
+ "senderId": senderId,
+ "receiverId": receiverId,
+ "messageType": messageType,
+ "messageContent": messageContent,
+ };
+}
+
+
diff --git a/lib/models/biddingrequest_model.dart b/lib/models/biddingrequest_model.dart
index e0aa5e6..368495a 100644
--- a/lib/models/biddingrequest_model.dart
+++ b/lib/models/biddingrequest_model.dart
@@ -1,56 +1,67 @@
import 'package:flutter/material.dart';
import 'package:healthcare_pharmacy/settings.dart';
-class BiddingRequestsModel {
- String? custumerid_bidding = '';
- String? pharmacyid_bidding='';
- String? amount_bidding='';
- String? bidding_bookingid='';
- String? bidding_firstName='';
- String? bidding_contactNumber='';
- String? bidding_address='';
- String orderStatus='';
- String status='';
-
-
- Color cardColor=Colors.white;
- Color textColor=Colors.black;
-
+class PrescriptionPicture {
+ late String id;
+ late String url;
+ PrescriptionPicture({
+ required this.id,
+ required this.url,
+ });
- BiddingRequestsModel();
-
- factory BiddingRequestsModel.fromJson(Map json){
- BiddingRequestsModel rtvm = new BiddingRequestsModel();
+ factory PrescriptionPicture.fromJson(Map json) {
+ return PrescriptionPicture(
+ id: json['_id'],
+ url: json['url'],
+ );
+ }
+}
- rtvm.custumerid_bidding = json['customerId'].toString() ??'';
- rtvm.pharmacyid_bidding = json['pharmacyId'].toString() ?? '';
- rtvm.amount_bidding = json['biddingAmount'].toString() ?? '';
- rtvm.bidding_bookingid = json['bookingId'].toString() ?? '';
- rtvm.bidding_firstName = json['customerDetails']["firstName"].toString() ?? '';
- rtvm.bidding_firstName = json['customerDetails']["address1"].toString() ?? '';
- rtvm.bidding_firstName = json['customerDetails']["firstName"].toString() ?? '';
+class BiddingRequestsModel {
+ String? customerId = '';
+ String? pharmacyId = '';
+ String? amount = '';
+ String? bookingId = '';
+ String? profilePicture = '';
+ String? firstName = '';
+ String? address = '';
+ String orderStatus = '';
+ String status = '';
- rtvm.status = json['status'] ;
+ List PrescriptionPictures = [];
+ Color cardColor = Colors.white;
+ Color textColor = Colors.black;
- // rtvm.bidding_contactNumber = json['customerDetails']['profile']["contactNumber"].toString() ?? '';
+ BiddingRequestsModel();
- // rtvm.bidding_contactNumber = json['contactNumber'].toString() ?? '';
- // rtvm.bidding_address1 = json['address1'].toString() ?? '';
+ factory BiddingRequestsModel.fromJson(Map json) {
+ BiddingRequestsModel rtvm = BiddingRequestsModel();
+ rtvm.customerId = json['customerId'].toString() ?? '';
+ rtvm.pharmacyId = json['pharmacyId'].toString() ?? '';
+ rtvm.amount = json['biddingAmount'].toString() ?? '';
+ rtvm.bookingId = json['bookingId'].toString() ?? '';
+ rtvm.profilePicture = json['profilePicture'] ?? '';
+ rtvm.firstName = json['customerDetails']["firstName"].toString() ?? '';
+ rtvm.address = json['customerDetails']["address1"].toString() ?? '';
+ rtvm.status = json['status'];
- // rtvm.prescription_url = json['pictureUrl'][0] ?? '';
- if(rtvm.status.toString().toLowerCase()=='accepted'){
- rtvm.textColor=Colors.green;
- }
- else if(rtvm.status.toString().toLowerCase()=='rejected'){
- rtvm.textColor=Colors.red;
+ if (json['PrescriptionPictures'] != null) {
+ var pictures = json['PrescriptionPictures'] as List;
+ rtvm.PrescriptionPictures =
+ pictures.map((picture) => PrescriptionPicture.fromJson(picture)).toList();
}
- else{
- rtvm.textColor=primaryColor;
+
+ if (rtvm.status.toString().toLowerCase() == 'accepted') {
+ rtvm.textColor = Colors.green;
+ } else if (rtvm.status.toString().toLowerCase() == 'rejected') {
+ rtvm.textColor = Colors.red;
+ } else {
+ rtvm.textColor = primaryColor;
}
+
return rtvm;
}
-
-}
\ No newline at end of file
+}
diff --git a/lib/models/chatconversation_model.dart b/lib/models/chatconversation_model.dart
new file mode 100644
index 0000000..11cc606
--- /dev/null
+++ b/lib/models/chatconversation_model.dart
@@ -0,0 +1,22 @@
+import 'dart:convert';
+
+List listdadFromJson(String str) => List.from(json.decode(str).map((x) => GetCoversatitonIdModel .fromJson(x)));
+
+String listdadToJson(List data) => json.encode(List.from(data.map((x) => x.toJson())));
+
+class GetCoversatitonIdModel {
+ String ? conversation_id;
+
+ GetCoversatitonIdModel ({
+ required this.conversation_id,
+
+ });
+
+ factory GetCoversatitonIdModel .fromJson(Map json) => GetCoversatitonIdModel (
+ conversation_id: json["conversation_id"],
+ );
+
+ Map toJson() => {
+ "conversation_id": conversation_id,
+ };
+}
\ No newline at end of file
diff --git a/lib/offerstabdata.dart b/lib/offerstabdata.dart
index 025c3fc..6363f64 100644
--- a/lib/offerstabdata.dart
+++ b/lib/offerstabdata.dart
@@ -607,8 +607,8 @@ class _OffersDataState extends State with TickerProviderStateMixin,
);
} else {
Navigator.of(context, rootNavigator: true).pop();
- AppSettings.longFailedStyledToast(
- "Offer upadtion failed", context);
+ AppSettings.longFailedToast(
+ "Offer upadtion failed");
Navigator.of(context).pop();
}
} catch (exception) {
@@ -616,7 +616,7 @@ class _OffersDataState extends State with TickerProviderStateMixin,
print(exception);
}
} else {
- AppSettings.longFailedStyledToast("enter details", context);
+ AppSettings.longFailedToast("enter details");
}
},
),
diff --git a/lib/offersview.dart b/lib/offersview.dart
index 4dffce8..e696d04 100644
--- a/lib/offersview.dart
+++ b/lib/offersview.dart
@@ -384,8 +384,8 @@ class _OffersViewState extends State with TickerProviderStateMixin {
await getOffersViewData();
} else {
Navigator.of(context, rootNavigator: true).pop();
- AppSettings.longFailedStyledToast(
- "Offer upadtion failed", context);
+ AppSettings.longFailedToast(
+ "Offer upadtion failed");
Navigator.of(context).pop();
}
} catch (exception) {
@@ -393,7 +393,7 @@ class _OffersViewState extends State with TickerProviderStateMixin {
print(exception);
}
} else {
- AppSettings.longFailedStyledToast("enter details", context);
+ AppSettings.longFailedToast("enter details");
}
},
),
diff --git a/lib/pages/call.dart b/lib/pages/call.dart
new file mode 100644
index 0000000..59eaaa1
--- /dev/null
+++ b/lib/pages/call.dart
@@ -0,0 +1,271 @@
+
+import 'package:flutter/material.dart';
+import 'package:healthcare_pharmacy/settings.dart';
+import 'dart:async';
+import 'package:permission_handler/permission_handler.dart';
+
+import 'package:agora_rtc_engine/rtc_engine.dart';
+import 'package:agora_rtc_engine/rtc_engine.dart' as rtc_engine;
+import 'package:agora_rtc_engine/rtc_local_view.dart' as rtc_local_view;
+import 'package:agora_rtc_engine/rtc_remote_view.dart' as rtc_remote_view;
+
+class CallPage extends StatefulWidget {
+ final String? channelName;
+ final ClientRole? role;
+ const CallPage({Key? key, this.channelName, this.role}) : super(key: key);
+
+ @override
+ State createState() => _CallPageState();
+}
+
+class _CallPageState extends State {
+ final _users = [];
+ final _infoString = [];
+ late RtcEngine _engine;
+ bool muted = false; // Define the muted variable
+ bool viewPanel = true;
+ @override
+ void initState() {
+ super.initState();
+ initialize();
+ }
+
+ @override
+ void dispose() {
+ _users.clear();
+ _engine.leaveChannel();
+ _engine.destroy();
+ super.dispose();
+ }
+
+ Future initialize() async {
+ if (appId.isEmpty) {
+ setState(() {
+ _infoString.add('AppId is missing please provide AppId');
+ _infoString.add('Agora Engine is not starting');
+ });
+ return;
+ }
+ _engine = await rtc_engine.RtcEngine.create(appId);
+ await _engine.enableVideo();
+ await _engine.setChannelProfile(ChannelProfile.LiveBroadcasting);
+ await _engine.setClientRole(widget.role!);
+ _addAgoraEventHandler();
+ VideoEncoderConfiguration configuration = VideoEncoderConfiguration(
+ dimensions: VideoDimensions(width: 1920, height: 1080),
+ );
+ await _engine.setVideoEncoderConfiguration(configuration);
+ await _engine.joinChannel(token, widget.channelName!, null, 0);
+ }
+
+ void _addAgoraEventHandler() {
+ _engine.setEventHandler(
+ rtc_engine.RtcEngineEventHandler(
+ error: (code) {
+ setState(() {
+ final info = 'Error: $code';
+ _infoString.add(info);
+ });
+ },
+ joinChannelSuccess: (channel, uid, elapsed) {
+ setState(() {
+ final info = 'Join Channel: $channel, uid:$uid';
+ _infoString.add(info);
+ });
+ },
+ leaveChannel: (stats) {
+ setState(() {
+ _infoString.add('Leave Channel');
+ _users.clear();
+ });
+ },
+ userJoined: (uid, elapsed) {
+ setState(() {
+ final info = 'User joined: $uid';
+ _infoString.add(info);
+ _users.add(uid);
+ });
+ },
+ userOffline: (uid, elapsed) {
+ setState(() {
+ final info = 'User Offline: $uid';
+ _infoString.add(info);
+ _users.remove(uid);
+ });
+ },
+ firstRemoteVideoFrame: (uid, width, height, elapsed) {
+ setState(() {
+ final info = 'First Remote Video: $uid $width*$height';
+ _infoString.add(info);
+ _users.remove(uid);
+ });
+ },
+ ),
+ );
+ }
+
+
+
+
+
+ Widget _viewRows() {
+ final List list = [];
+ if (widget.role == ClientRole.Broadcaster) {
+ list.add(const rtc_local_view.SurfaceView());
+ }
+ for (var uid in _users) {
+ list.add(rtc_remote_view.SurfaceView(
+ uid: uid,
+ channelId: widget.channelName!,
+ ));
+ }
+ final views=list;
+ return Column(
+ children: List.generate(
+ views.length,
+ (index) => Expanded(
+ child: views[index],
+ ),
+ ),
+ );
+ }
+
+
+ Widget _toolbar() {
+ if (widget.role == ClientRole.Audience) return SizedBox();
+
+ return Container(
+ alignment: Alignment.bottomCenter,
+ padding: const EdgeInsets.symmetric(vertical: 48),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ RawMaterialButton(
+ onPressed: () {
+ setState(() {
+ muted = !muted;
+ });
+ _engine.muteLocalAudioStream(muted);
+ },
+ child: Icon(
+ muted ? Icons.mic_off : Icons.mic,
+ color: muted ? Colors.white : Colors.blueAccent,
+ size: 20.0,
+ ),
+ shape: CircleBorder(),
+ elevation: 2.0,
+ fillColor: muted ? Colors.blueAccent : Colors.white,
+ padding: EdgeInsets.all(12.0),
+ ),
+ RawMaterialButton(
+ onPressed: () => Navigator.pop(context),
+ child: Icon(
+ Icons.call_end,
+ color: Colors.white,
+ size: 35.0,
+ ),
+ shape: CircleBorder(),
+ elevation: 2.0,
+ fillColor: Colors.redAccent,
+ padding: EdgeInsets.all(15.0),
+ ),
+ RawMaterialButton(
+ onPressed: () {
+ _engine.switchCamera();
+ },
+ child: Icon(
+ Icons.switch_camera,
+ color: Colors.blueAccent,
+ size: 20.0,
+ ),
+ shape: CircleBorder(),
+ elevation: 2.0,
+ fillColor: Colors.white,
+ padding: EdgeInsets.all(12.0),
+ ),
+ ],
+ ),
+ );
+ }
+
+
+ Widget _panel()
+ {
+ return Visibility(
+ visible: viewPanel,
+ child: Container(
+ padding: const EdgeInsets.symmetric(vertical: 48),
+ alignment: Alignment.bottomCenter,
+ child: FractionallySizedBox(
+ heightFactor: 0.5,
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 48),
+ child: ListView.builder(
+ reverse: true,
+ itemCount: _infoString.length,
+ itemBuilder:(BuildContext context,int index)
+ {
+ if(_infoString.isEmpty)
+ {
+ return const Text("null");
+ }
+ return Padding(
+ padding: const EdgeInsets.symmetric(vertical: 3,horizontal: 10),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Flexible(
+ child: Container(
+ padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 5),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(5)
+ ),
+ child: Text(
+ _infoString[index],
+ style: const TextStyle(color:Colors.blueGrey),
+ ),
+ ),
+
+ )
+ ],
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text("VideoCall"),
+ centerTitle: true,
+ actions: [
+ IconButton(onPressed:()
+ {
+ setState(() {
+ viewPanel=!viewPanel;
+ });
+ }, icon: const Icon(Icons.ice_skating))
+ ],
+ ),
+ backgroundColor: Colors.black,
+ body: Center(
+ child: Stack(
+ children: [
+ _viewRows(),
+ _panel(),
+ _toolbar(),
+ ]
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/pages/index.dart b/lib/pages/index.dart
new file mode 100644
index 0000000..de048ea
--- /dev/null
+++ b/lib/pages/index.dart
@@ -0,0 +1,120 @@
+import 'package:agora_rtc_engine/rtc_engine.dart';
+import 'package:flutter/material.dart';
+import 'package:async/async.dart';
+import 'dart:developer';
+import 'package:permission_handler/permission_handler.dart';
+import './call.dart';
+import 'package:flutter/material.dart' hide Size;
+import 'dart:ui' as ui;
+
+class IndexPage extends StatefulWidget {
+ const IndexPage({Key? key}) : super(key: key);
+
+ @override
+ State createState() => _IndexPageState();
+}
+
+class _IndexPageState extends State {
+
+ TextEditingController _channelController = TextEditingController(text: 'call');
+
+ bool _validateError=false;
+ ClientRole? _role= ClientRole.Broadcaster;
+
+
+ @override
+ void dispose() {
+ _channelController.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text("VideoCall"),
+ centerTitle: true,
+ ),
+ body: SingleChildScrollView(
+ child: Container(
+ padding: const EdgeInsets.symmetric(horizontal: 20),
+ child: Column(
+ children: [
+ const SizedBox(height: 20),
+ const SizedBox(height: 20),
+ TextField(
+ controller: _channelController,
+ decoration: InputDecoration(
+ errorText: _validateError ? 'Chanel Name is Mondatory' : null,
+ border: UnderlineInputBorder(borderSide: BorderSide(width: 1),),
+ hintText: 'channel name',
+ ),
+ ),
+ RadioListTile(
+ title: const Text('Broadcaster'),
+ onChanged: (ClientRole? value)
+ {
+ setState(() {
+ _role=value;
+ });
+ },
+ value: ClientRole.Broadcaster,
+ groupValue: _role,
+ ),
+ RadioListTile(
+ title: const Text('Audience'),
+ onChanged: (ClientRole? value)
+ {
+ setState(() {
+ _role=value;
+ });
+ },
+ value: ClientRole.Audience,
+ groupValue: _role,
+ ),
+ ElevatedButton(
+ onPressed: onjoin,
+ child: const Text('Join'),
+ style: ElevatedButton.styleFrom(
+ minimumSize: const ui.Size(double.infinity, 40),
+ ),
+ )
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+
+ Future onjoin() async {
+ setState(() {
+ _channelController.text.isEmpty
+ ? _validateError=true:
+ _validateError=false; // This line doesn't actually update any state
+ });
+
+ if(_channelController.text.isNotEmpty)
+ {
+ await _handlecameraAndMic(Permission.camera);
+ await _handlecameraAndMic(Permission.microphone);
+ await Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (__) => CallPage(
+ channelName: _channelController.text, // Passes the text from _channelController as channelName
+ role: _role, // Passes the value of _role as role
+ ),
+ ),
+ );
+
+
+
+ }
+ }
+
+ Future _handlecameraAndMic(Permission permission) async
+ {
+ final status=await permission.request();
+ log(status.toString());
+ }
+}
diff --git a/lib/settings.dart b/lib/settings.dart
index e7aaba6..2f63e65 100644
--- a/lib/settings.dart
+++ b/lib/settings.dart
@@ -9,7 +9,6 @@ import 'package:healthcare_pharmacy/preloader.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart';
-import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'dart:async';
import 'package:geolocator/geolocator.dart';
import 'package:dio/dio.dart';
@@ -29,6 +28,9 @@ const Color dashboardbackground = Color(0XFFF5F5F5);
Color AppBarGradient_1 = Color(0XFF1258F6);
+const appId="e5b593d506884e32856b5d6b1d72860f";
+const token="007eJxTYDibv+bcAy2rY7+OVHIEfQj1+/0y//Sai9e3BXUrfzsU+G65AkOqaZKppXGKqYGZhYVJqrGRhalZkmmKWZJhirmRhZlBmt9i4bSGQEaG63HbWBkZIBDEZ2FITszJYWAAAHfyIs8=";
+
TextStyle PreloaderText() {
return TextStyle(color: Colors.blueAccent);
}
@@ -147,6 +149,8 @@ class AppSettings {
static double userLatitude = 0;
static double userLongitude = 0;
static String healthpharmaIdsign = '';
+ static String customerId = 'AHSUSNE1';
+
static String healthpharmastaticid = '123456789';
static String profileImage = '';
static List storedPreferenceValidKeys = ['pharmacyname', 'access_token'];
@@ -183,6 +187,7 @@ class AppSettings {
static String createOffersUrl = host + 'addoffer';
static String createCompanyOffersUrl = host + 'addcompanyoffer';
static String getOffersActiveDataUrl = host + 'getActivePharmacyOfferdata';
+
static String getApprovedOffersDataUrl = host + 'getapprovedPharmacyOfferdata';
static String getOffersinActiveDataUrl = host + 'getInActivePharmacyOfferdata';
static String updateOffersDataUrl = host + 'updateOffer';
@@ -205,6 +210,10 @@ class AppSettings {
static String deleteDeliveryboyUrl = host + 'deletedeliveryboy';
static String getPharmacyAccountsUrl = host + 'pharmacyAccounts';
static String generateQRCodeUrl = host + 'generate-qrcode-pharmacy';
+ static String getIdDataUrl = host + 'startConversation';
+ static String acceptBookingRequestsUrl = host + 'assignDeliveryBoy';
+
+
static File? updatedImage;
@@ -370,7 +379,36 @@ class AppSettings {
}
}
+ static Future assignDeliveryboyBookingRequests(var bookingId,payload) async {
+ var response = await http.post(Uri.parse(acceptBookingRequestsUrl + '/' + bookingId),
+ body: json.encode(payload), headers: await buildRequestHeaders());
+ if (response.statusCode == 200) {
+ try {
+ var _response = json.decode(response.body);
+ print(_response);
+ return true;
+ } catch (e) {
+ // display error toast
+ return false;
+ }
+ } else if (response.statusCode == 401) {
+ bool status = await AppSettings.resetToken();
+ if (status) {
+ response = await http.post(Uri.parse(acceptBookingRequestsUrl + '/' + bookingId),
+ body: json.encode(payload), headers: await buildRequestHeaders());
+ if (response.statusCode == 200) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
static Future generateQRCode() async {
var uri = Uri.parse(generateQRCodeUrl + '/' + healthpharmaIdsign);
@@ -590,6 +628,33 @@ class AppSettings {
return '';
}
}
+
+ static Future getChatId() async {
+ //path parameter
+ var uri = Uri.parse(getIdDataUrl + '/' +healthpharmaIdsign );
+ uri = uri.replace(query: 'customerId=$customerId');
+ var response = await http.get(uri, headers: await buildRequestHeaders());
+ var responcedatatemp=jsonDecode(response.body);
+ print("responcedata$responcedatatemp");
+ print("responcedata$customerId");
+ if (response.statusCode == 200) {
+ return response.body;
+ } else if (response.statusCode == 401) {
+ bool status = await AppSettings.resetToken();
+ if (status) {
+ response = await http.get(uri, headers: await buildRequestHeaders());
+ if (response.statusCode == 200) {
+ return response.body;
+ } else {
+ return '';
+ }
+ } else {
+ return '';
+ }
+ } else {
+ return '';
+ }
+ }
static Future getApprovedOffers() async {
//path parameter
var uri = Uri.parse(getApprovedOffersDataUrl + '/' + healthpharmaIdsign);
@@ -615,8 +680,8 @@ class AppSettings {
static Future getCartDetails(bookingId) async {
//path parameter
- var uri = Uri.parse(getCartDataUrl + '/' + bookingId);
- // uri = uri.replace(query: 'pharmacyId=$healthpharmaIdsign');
+ var uri = Uri.parse(getCartDataUrl + '/' +healthpharmaIdsign );
+ uri = uri.replace(query: 'bookingId=$bookingId');
var response = await http.get(uri, headers: await buildRequestHeaders());
var responcedatatemp=jsonDecode(response.body);
print("responcedata$responcedatatemp");
@@ -659,8 +724,8 @@ class AppSettings {
]
});
print("Timintgs"+body.toString());
- var uri = Uri.parse(addToCartDataUrl);
- uri = uri.replace(query: 'pharmacyId=$healthpharmaIdsign');
+ var uri = Uri.parse(addToCartDataUrl+ '/' + healthpharmaIdsign);
+ // uri = uri.replace(query: 'pharmacyId=$healthpharmaIdsign');
var response = await http.post(
uri,
headers: headers,
@@ -680,7 +745,8 @@ class AppSettings {
"additional_discount": additionalDiscont
});
print("cartResponce"+body.toString());
- var uri = Uri.parse(getCartFinalAmmountUrl+ '/' + bookingId);
+ var uri = Uri.parse(getCartFinalAmmountUrl + '/' +healthpharmaIdsign );
+ uri = uri.replace(query: 'bookingId=$bookingId');
var response = await http.post(
uri,
headers: headers,
@@ -690,10 +756,6 @@ class AppSettings {
return response;
}
-
-
-
-
static Future getPharmacyData() async {
var uri = Uri.parse(getPharmacyDataUrl);
var response = await http.get(uri, headers: await buildRequestHeaders());
@@ -1263,20 +1325,7 @@ class AppSettings {
fontSize: 16.0);
}*/
- static void longFailedStyledToast(String message, context) {
- showToast(
- message,
- context: context,
- animation: StyledToastAnimation.scale,
- reverseAnimation: StyledToastAnimation.fade,
- position: StyledToastPosition.bottom,
- animDuration: Duration(seconds: 1),
- duration: Duration(seconds: 6),
- curve: Curves.elasticOut,
- reverseCurve: Curves.linear,
- backgroundColor: Colors.red,
- );
- }
+
static void longFailedToast(String message) {
Fluttertoast.showToast(
msg: message,
diff --git a/lib/viewpager.dart b/lib/viewpager.dart
index 42fb436..c031e8d 100644
--- a/lib/viewpager.dart
+++ b/lib/viewpager.dart
@@ -549,8 +549,8 @@ class _ViewpagerState extends State {
);
} else {
Navigator.of(context, rootNavigator: true).pop();
- AppSettings.longFailedStyledToast(
- "Offer upadtion failed", context);
+ AppSettings.longFailedToast(
+ "Offer upadtion failed");
Navigator.of(context).pop();
}
} catch (exception) {
@@ -558,7 +558,7 @@ class _ViewpagerState extends State {
print(exception);
}
} else {
- AppSettings.longFailedStyledToast("enter details", context);
+ AppSettings.longFailedToast("enter details");
}
},
),
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc
index f6f23bf..7299b5c 100644
--- a/linux/flutter/generated_plugin_registrant.cc
+++ b/linux/flutter/generated_plugin_registrant.cc
@@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h"
+#include
#include
void fl_register_plugins(FlPluginRegistry* registry) {
+ g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
+ fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
+ file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
index f16b4c3..786ff5c 100644
--- a/linux/flutter/generated_plugins.cmake
+++ b/linux/flutter/generated_plugins.cmake
@@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
+ file_selector_linux
url_launcher_linux
)
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index a6de6bf..ca8b907 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -5,10 +5,13 @@
import FlutterMacOS
import Foundation
+import agora_rtc_engine
import cloud_firestore
import device_info_plus_macos
+import file_selector_macos
import firebase_core
import firebase_messaging
+import firebase_storage
import flutter_local_notifications
import geolocator_apple
import location
@@ -18,10 +21,13 @@ import shared_preferences_foundation
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
+ AgoraRtcEnginePlugin.register(with: registry.registrar(forPlugin: "AgoraRtcEnginePlugin"))
FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
+ FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
+ FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
diff --git a/pubspec.lock b/pubspec.lock
index f41f934..6004046 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -7,14 +7,21 @@ packages:
name: _flutterfire_internals
url: "https://pub.dartlang.org"
source: hosted
- version: "1.3.2"
+ version: "1.3.16"
+ agora_rtc_engine:
+ dependency: "direct main"
+ description:
+ name: agora_rtc_engine
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "5.3.1"
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
- version: "3.3.7"
+ version: "3.4.2"
args:
dependency: transitive
description:
@@ -79,26 +86,26 @@ packages:
source: hosted
version: "1.1.1"
cloud_firestore:
- dependency: "direct dev"
+ dependency: "direct main"
description:
name: cloud_firestore
url: "https://pub.dartlang.org"
source: hosted
- version: "4.8.0"
+ version: "4.14.0"
cloud_firestore_platform_interface:
dependency: transitive
description:
name: cloud_firestore_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "5.15.0"
+ version: "6.1.0"
cloud_firestore_web:
dependency: transitive
description:
name: cloud_firestore_web
url: "https://pub.dartlang.org"
source: hosted
- version: "3.6.0"
+ version: "3.9.0"
cloudinary_public:
dependency: "direct dev"
description:
@@ -161,7 +168,7 @@ packages:
name: dbus
url: "https://pub.dartlang.org"
source: hosted
- version: "0.7.3"
+ version: "0.7.4"
device_info_plus:
dependency: "direct dev"
description:
@@ -217,7 +224,7 @@ packages:
name: dio
url: "https://pub.dartlang.org"
source: hosted
- version: "5.2.0+1"
+ version: "5.4.0"
fake_async:
dependency: transitive
description:
@@ -239,48 +246,97 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
- firebase_core:
+ file_selector_linux:
+ dependency: transitive
+ description:
+ name: file_selector_linux
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.9.2"
+ file_selector_macos:
+ dependency: transitive
+ description:
+ name: file_selector_macos
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.9.3+1"
+ file_selector_platform_interface:
+ dependency: transitive
+ description:
+ name: file_selector_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.6.0"
+ file_selector_windows:
dependency: transitive
+ description:
+ name: file_selector_windows
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.9.3"
+ firebase_core:
+ dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
- version: "2.13.1"
+ version: "2.24.2"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "4.8.0"
+ version: "5.0.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
- version: "2.5.0"
+ version: "2.10.0"
firebase_messaging:
- dependency: "direct dev"
+ dependency: "direct main"
description:
name: firebase_messaging
url: "https://pub.dartlang.org"
source: hosted
- version: "14.6.2"
+ version: "14.7.10"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "4.5.2"
+ version: "4.5.18"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
url: "https://pub.dartlang.org"
source: hosted
- version: "3.5.2"
+ version: "3.5.18"
+ firebase_storage:
+ dependency: "direct main"
+ description:
+ name: firebase_storage
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "11.6.0"
+ firebase_storage_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_storage_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "5.1.3"
+ firebase_storage_web:
+ dependency: transitive
+ description:
+ name: firebase_storage_web
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.6.17"
flutter:
dependency: "direct main"
description: flutter
@@ -293,6 +349,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
+ flutter_callkeep:
+ dependency: "direct main"
+ description:
+ name: flutter_callkeep
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.3.2"
flutter_cupertino_datetime_picker:
dependency: "direct dev"
description:
@@ -327,9 +390,9 @@ packages:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.1"
+ version: "2.0.2"
flutter_local_notifications:
- dependency: "direct dev"
+ dependency: "direct main"
description:
name: flutter_local_notifications
url: "https://pub.dartlang.org"
@@ -349,18 +412,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
- flutter_localizations:
- dependency: transitive
- description: flutter
- source: sdk
- version: "0.0.0"
flutter_native_contact_picker:
dependency: "direct dev"
description:
name: flutter_native_contact_picker
url: "https://pub.dartlang.org"
source: hosted
- version: "0.0.4"
+ version: "0.0.6"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
@@ -382,20 +440,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
- flutter_styled_toast:
- dependency: "direct dev"
- description:
- name: flutter_styled_toast
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.3"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
url: "https://pub.dartlang.org"
source: hosted
- version: "1.0.3"
+ version: "1.1.6"
flutter_svg_provider:
dependency: "direct main"
description:
@@ -419,28 +470,35 @@ packages:
name: fluttertoast
url: "https://pub.dartlang.org"
source: hosted
- version: "8.2.2"
+ version: "8.2.4"
+ gallery_saver:
+ dependency: "direct dev"
+ description:
+ name: gallery_saver
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.3.2"
geocoding:
dependency: "direct dev"
description:
name: geocoding
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
geocoding_android:
dependency: transitive
description:
name: geocoding_android
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0"
+ version: "2.1.2"
geocoding_ios:
dependency: transitive
description:
name: geocoding_ios
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
geocoding_platform_interface:
dependency: transitive
description:
@@ -461,35 +519,35 @@ packages:
name: geolocator_android
url: "https://pub.dartlang.org"
source: hosted
- version: "4.1.8"
+ version: "4.3.1"
geolocator_apple:
dependency: transitive
description:
name: geolocator_apple
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.6"
+ version: "2.3.5"
geolocator_platform_interface:
dependency: transitive
description:
name: geolocator_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "4.0.7"
+ version: "4.1.0"
geolocator_web:
dependency: transitive
description:
name: geolocator_web
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.6"
+ version: "2.2.1"
geolocator_windows:
dependency: transitive
description:
name: geolocator_windows
url: "https://pub.dartlang.org"
source: hosted
- version: "0.1.1"
+ version: "0.1.3"
get:
dependency: "direct dev"
description:
@@ -524,7 +582,7 @@ packages:
name: google_maps_flutter_android
url: "https://pub.dartlang.org"
source: hosted
- version: "2.4.15"
+ version: "2.4.16"
google_maps_flutter_ios:
dependency: transitive
description:
@@ -538,14 +596,14 @@ packages:
name: google_maps_flutter_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.7"
+ version: "2.4.0"
google_maps_flutter_web:
dependency: transitive
description:
name: google_maps_flutter_web
url: "https://pub.dartlang.org"
source: hosted
- version: "0.5.0+1"
+ version: "0.5.3"
google_maps_place_picker_mb:
dependency: "direct dev"
description:
@@ -587,49 +645,63 @@ packages:
name: image
url: "https://pub.dartlang.org"
source: hosted
- version: "3.1.3"
+ version: "3.3.0"
image_picker:
dependency: "direct dev"
description:
name: image_picker
url: "https://pub.dartlang.org"
source: hosted
- version: "0.8.7+5"
+ version: "0.8.9"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
url: "https://pub.dartlang.org"
source: hosted
- version: "0.8.6+19"
+ version: "0.8.7+4"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.12"
+ version: "2.2.0"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
url: "https://pub.dartlang.org"
source: hosted
- version: "0.8.7+4"
+ version: "0.8.8"
+ image_picker_linux:
+ dependency: transitive
+ description:
+ name: image_picker_linux
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.1"
+ image_picker_macos:
+ dependency: transitive
+ description:
+ name: image_picker_macos
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.1"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "2.6.4"
- imei_plugin:
- dependency: "direct dev"
+ version: "2.9.0"
+ image_picker_windows:
+ dependency: transitive
description:
- name: imei_plugin
+ name: image_picker_windows
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.0"
+ version: "0.2.1"
intl:
dependency: "direct dev"
description:
@@ -804,28 +876,28 @@ packages:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.27"
+ version: "2.1.0"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.4"
+ version: "2.3.0"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.11"
+ version: "2.2.0"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.6"
+ version: "2.1.0"
path_provider_windows:
dependency: transitive
description:
@@ -834,40 +906,40 @@ packages:
source: hosted
version: "2.0.7"
permission_handler:
- dependency: "direct dev"
+ dependency: "direct main"
description:
name: permission_handler
url: "https://pub.dartlang.org"
source: hosted
- version: "10.3.0"
+ version: "10.4.5"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
url: "https://pub.dartlang.org"
source: hosted
- version: "10.2.3"
+ version: "10.3.6"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
url: "https://pub.dartlang.org"
source: hosted
- version: "9.1.0"
+ version: "9.1.4"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "3.10.0"
+ version: "3.12.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
url: "https://pub.dartlang.org"
source: hosted
- version: "0.1.2"
+ version: "0.1.3"
petitparser:
dependency: transitive
description:
@@ -888,14 +960,14 @@ packages:
name: platform
url: "https://pub.dartlang.org"
source: hosted
- version: "3.1.0"
+ version: "3.1.1"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.4"
+ version: "2.1.5"
pointycastle:
dependency: transitive
description:
@@ -916,7 +988,7 @@ packages:
name: provider
url: "https://pub.dartlang.org"
source: hosted
- version: "6.0.5"
+ version: "6.1.1"
pull_to_refresh:
dependency: "direct dev"
description:
@@ -958,7 +1030,7 @@ packages:
name: sanitize_html
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.0"
+ version: "2.1.0"
share:
dependency: "direct dev"
description:
@@ -972,49 +1044,49 @@ packages:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.2"
+ version: "2.2.0"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.4"
+ version: "2.2.0"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.2"
+ version: "2.3.3"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.0"
+ version: "2.3.0"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.0"
+ version: "2.3.0"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0"
+ version: "2.2.0"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.0"
+ version: "2.3.0"
sizer:
dependency: "direct dev"
description:
@@ -1089,7 +1161,7 @@ packages:
name: tuple
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.1"
+ version: "2.0.2"
typed_data:
dependency: transitive
description:
@@ -1105,7 +1177,7 @@ packages:
source: hosted
version: "2.2.0"
url_launcher:
- dependency: "direct dev"
+ dependency: "direct main"
description:
name: url_launcher
url: "https://pub.dartlang.org"
@@ -1117,7 +1189,7 @@ packages:
name: url_launcher_android
url: "https://pub.dartlang.org"
source: hosted
- version: "6.0.35"
+ version: "6.0.38"
url_launcher_ios:
dependency: transitive
description:
@@ -1138,28 +1210,28 @@ packages:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
- version: "3.0.5"
+ version: "3.0.6"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.2"
+ version: "2.1.3"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.17"
+ version: "2.0.18"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
url: "https://pub.dartlang.org"
source: hosted
- version: "3.0.6"
+ version: "3.0.7"
uuid:
dependency: "direct main"
description:
@@ -1181,6 +1253,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.0+2"
+ web_socket_channel:
+ dependency: "direct main"
+ description:
+ name: web_socket_channel
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
win32:
dependency: transitive
description:
@@ -1201,7 +1280,7 @@ packages:
name: xml
url: "https://pub.dartlang.org"
source: hosted
- version: "5.4.1"
+ version: "6.1.0"
yaml:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index efa1442..2a09e0e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -10,7 +10,12 @@ dependencies:
flutter:
sdk: flutter
-
+ firebase_core: ^2.24.2
+ web_socket_channel:
+ flutter_callkeep:
+ url_launcher: ^6.0.10
+ firebase_messaging: ^14.4.1
+ flutter_local_notifications: ^9.0.2
cupertino_icons: ^1.0.2
location: ^4.4.0
geolocator: ^9.0.2
@@ -24,22 +29,28 @@ dependencies:
uuid: ^3.0.7
flutter_svg_provider: ^1.0.3
flutter_svg: ^1.0.1
+ agora_rtc_engine: ^5.3.1
+ permission_handler:
+ cloud_firestore:
+ firebase_storage:
+
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
http: ^0.13.5
+ quantity_input: ^1.0.2
shared_preferences: ^2.0.15
sizer: ^2.0.11
geolocator: ^9.0.2
geocoding: ^2.0.4
image_picker: ^0.8.6+1
+ gallery_saver: ^2.0.3
flutter_launcher_icons: ^0.11.0
url_launcher: ^6.1.9
intl: ^0.17.0
flutter_svg: ^1.0.1
- flutter_styled_toast: ^2.1.3
google_maps_place_picker_mb: ^2.0.0-mb.22
flutter_datetime_picker: ^1.5.1
date_time_picker: ^2.1.0
@@ -49,7 +60,6 @@ dev_dependencies:
flutter_local_notifications: ^9.0.2
cloud_firestore: ^4.5.2
flutter_device_type: ^0.4.0
- imei_plugin: ^1.2.0
device_information: ^0.0.4
device_info_plus: ^3.2.4
overlay_support: ^2.1.0
@@ -63,7 +73,6 @@ dev_dependencies:
cloudinary_public: ^0.21.0
carousel_slider: ^4.2.1
photo_view: ^0.14.0
- quantity_input: ^1.0.2
flutter_native_contact_picker: ^0.0.4
path: ^1.8.0
path_provider: ^2.0.11
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 2cd4f25..9e818bf 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -6,14 +6,26 @@
#include "generated_plugin_registrant.h"
+#include
+#include
+#include
#include
+#include
#include
#include
#include
void RegisterPlugins(flutter::PluginRegistry* registry) {
+ AgoraRtcEnginePluginRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("AgoraRtcEnginePlugin"));
+ CloudFirestorePluginCApiRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("CloudFirestorePluginCApi"));
+ FileSelectorWindowsRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("FileSelectorWindows"));
FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
+ FirebaseStoragePluginCApiRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("FirebaseStoragePluginCApi"));
GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index 8ae151b..6f1c63a 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -3,7 +3,11 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
+ agora_rtc_engine
+ cloud_firestore
+ file_selector_windows
firebase_core
+ firebase_storage
geolocator_windows
permission_handler_windows
url_launcher_windows