Code committed

This commit is contained in:
2025-08-08 22:21:49 +05:30
parent f572983146
commit 9abcd609bf
22 changed files with 992 additions and 417 deletions

View File

@@ -1,59 +1,68 @@
plugins { plugins {
id "com.android.application" id "com.android.application"
id "kotlin-android" id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin" id "dev.flutter.flutter-gradle-plugin"
} }
def localProperties = new Properties() // Load key.properties for signing release builds
def localPropertiesFile = rootProject.file("local.properties") def keystoreProperties = new Properties()
if (localPropertiesFile.exists()) { def keystorePropertiesFile = rootProject.file("key.properties")
localPropertiesFile.withReader("UTF-8") { reader -> if (keystorePropertiesFile.exists()) {
localProperties.load(reader) keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
} }
def flutterVersionCode = localProperties.getProperty("flutter.versionCode") // Flutter versioning
if (flutterVersionCode == null) { def flutterVersionCode = 12
flutterVersionCode = "1" def flutterVersionName = "1.0.4"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
flutterVersionName = "1.0"
}
android { android {
namespace = "com.frontshop.userapp" namespace = "com.frontshop.userapp"
compileSdk = flutter.compileSdkVersion compileSdk = 35
ndkVersion = flutter.ndkVersion ndkVersion = "26.1.10909125" // Optional; only if you use native code
compileOptions { defaultConfig {
sourceCompatibility = JavaVersion.VERSION_1_8 applicationId = "com.frontshop.userapp"
targetCompatibility = JavaVersion.VERSION_1_8 minSdk = 23
targetSdk = 35
versionCode = flutterVersionCode
versionName = flutterVersionName
} }
defaultConfig signingConfigs {
{ release {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). storeFile file(keystoreProperties['storeFile'])
applicationId = "com.frontshop.userapp" storePassword keystoreProperties['storePassword']
// You can update the following values to match your application needs. keyAlias keystoreProperties['keyAlias']
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. keyPassword keystoreProperties['keyPassword']
minSdk = flutter.minSdkVersion }
targetSdk = flutter.targetSdkVersion
versionCode = flutterVersionCode.toInteger()
versionName = flutterVersionName
} }
buildTypes { buildTypes {
release { release {
// TODO: Add your own signing config for the release build. signingConfig = signingConfigs.release
// Signing with the debug keys for now, so `flutter run --release` works. minifyEnabled false
signingConfig = signingConfigs.debug shrinkResources false
} }
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
}
kotlinOptions {
jvmTarget = '1.8'
}
} }
flutter { flutter {
source = "../.." source = "../.."
} }
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
// ✅ PhonePe SDK - ensure this matches your maven URL from root `build.gradle`
}

View File

@@ -1,35 +1,35 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.frontshop.userapp"> package="com.frontshop.userapp">
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/> android:requestLegacyExternalStorage="true"
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:requestLegacyExternalStorage="true"
android:enableOnBackInvokedCallback="true" android:enableOnBackInvokedCallback="true"
android:label="Frontshop" android:label="Frontshop"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<meta-data <!-- Firebase notification channel -->
android:name="com.google.firebase.messaging.default_notification_channel_id" <meta-data
android:value="high_importance_channel"/> android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel"/>
<!-- Main activity -->
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@@ -39,69 +39,76 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user <!-- Flutter splash theme -->
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme"/>
/>
<!-- PhonePe / Deeplink support -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="frontshop"
android:host="payment-response"
android:pathPrefix="/" />
</intent-filter>
<!-- Main launcher -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Razorpay Tokenizer -->
<activity
android:name="com.razorpay.RzpTokeniserSdkFlutter.TokeniserSdkActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:exported="false" />
<!-- Firebase Messaging -->
<service
android:name="io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService"
android:exported="true"
tools:replace="android:exported">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<!-- Firebase Maps API Key -->
<meta-data android:name="com.google.android.geo.API_KEY" <meta-data android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyAi3_Dls63iGs7Nccgdm-4FkS0rhT03-4U"/> android:value="AIzaSyAi3_Dls63iGs7Nccgdm-4FkS0rhT03-4U"/>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <!-- Flutter embedding -->
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
<service
android:name="io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService"
android:exported="true"
tools:replace="android:exported">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application> </application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. --> <!-- Queries for package visibility -->
<queries> <queries>
<intent> <intent>
<action android:name="android.intent.action.PROCESS_TEXT"/> <action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/> <data android:mimeType="text/plain"/>
</intent> </intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries> </queries>
<!-- Provide required visibility configuration for API level 30 and above -->
<queries>
<!-- If your app checks for SMS support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
</intent>
<!-- If your app checks for call support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<!-- If your application checks for inAppBrowserView launch mode support -->
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
</manifest> </manifest>

View File

@@ -1,5 +1,3 @@
package com.frontshop.userapp package com.frontshop.userapp
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.android.FlutterActivity class MainActivity : FlutterFragmentActivity()
class MainActivity: FlutterActivity()

View File

@@ -2,14 +2,18 @@ allprojects {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
// ✅ Required for PhonePe SDK
maven {
url "https://phonepe.mycloudrepo.io/public/repositories/phonepe-intentsdk-android"
}
} }
} }
rootProject.buildDir = "../build" rootProject.buildDir = "../build"
subprojects { subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}" project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(":app") project.evaluationDependsOn(":app")
} }

View File

@@ -2,4 +2,5 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip

View File

@@ -18,7 +18,7 @@ pluginManagement {
plugins { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false id "com.android.application" version "8.6.0" apply false
id "org.jetbrains.kotlin.android" version "1.9.10" apply false id "org.jetbrains.kotlin.android" version "1.9.10" apply false
} }

View File

@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
# platform :ios, '12.0' # platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@@ -45,5 +45,21 @@
<true/> <true/>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true/>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tez</string>
<string>phonepe</string>
<string>paytmmp</string>
<string>bhim</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>frontshop</string> <!-- 👈 must match `appSchema` -->
</array>
</dict>
</array>
</dict> </dict>
</plist> </plist>

View File

@@ -1,11 +1,11 @@
class APIURL { class APIURL {
static const BASE_URL = "http://210.89.44.183:3333/xam/"; static const BASE_URL = "https://www.mv.frontshopemporium.in/xam/";
static const String sendOtp = "${BASE_URL}auth/send-otp/customer"; static const String sendOtp = "${BASE_URL}auth/send-otp/customer";
static const String verifyOtp = "${BASE_URL}auth/verify-otp/customer"; static const String verifyOtp = "${BASE_URL}auth/verify-otp/customer";
static const String loginOtp = "${BASE_URL}auth/login/customer"; static const String loginOtp = "${BASE_URL}auth/login/customer";
static const String login = "${BASE_URL}auth/login/vendor"; static const String login = "${BASE_URL}auth/login/vendor";
static const String customerRegister = "${BASE_URL}auth/register/customer"; static const String customerRegister = "${BASE_URL}auth/register/customer";
static const String getAllProduct = "${BASE_URL}products"; static const String getAllProduct = "${BASE_URL}products?order=home";
static const String getProductDetails = "${BASE_URL}products/"; static const String getProductDetails = "${BASE_URL}products/";
static const String getBanners = "${BASE_URL}banners"; static const String getBanners = "${BASE_URL}banners";
static const String customerLogOut = "${BASE_URL}auth/logout/customer"; static const String customerLogOut = "${BASE_URL}auth/logout/customer";
@@ -39,6 +39,8 @@ class APIURL {
static const String getProduct = "${BASE_URL}products"; static const String getProduct = "${BASE_URL}products";
static const String getCategoryByLevel = "${BASE_URL}categories/by-level/1"; static const String getCategoryByLevel = "${BASE_URL}categories/by-level/1";
static const String getMe = "${BASE_URL}auth/me"; static const String getMe = "${BASE_URL}auth/me";
static const String distanctByProduct = "${BASE_URL}distance/delivery-charges-by-distance";
static const String createProduct = "${BASE_URL}products"; static const String createProduct = "${BASE_URL}products";
@@ -50,6 +52,7 @@ class APIURL {
static const String updateStatus = "${BASE_URL}orders/items/"; static const String updateStatus = "${BASE_URL}orders/items/";
static const String checkAddress = "${BASE_URL}distance/by-address/"; static const String checkAddress = "${BASE_URL}distance/by-address/";
static const String productReview = "${BASE_URL}products/"; static const String productReview = "${BASE_URL}products/";
static const String upDateDeviceToken = "${BASE_URL}devices/register"; static const String upDateDeviceToken = "${BASE_URL}devices/register";

View File

@@ -377,75 +377,66 @@ class AddtocartProvider extends ChangeNotifier {
////////////////////////////COD //////////// ////////////////////////////COD ////////////
Future<void> paymentCODOrder( Future<bool> paymentCODOrder(
BuildContext context, BuildContext context,
double subtotal, double subtotal,
int deliverCharge, int deliverCharge,
String couponId, String couponId,
String addressId, String addressId,
) async { ) async {
ispaymentLoader = true; ispaymentLoader = true;
notifyListeners(); notifyListeners();
var data;
if (couponId.isNotEmpty) {
data = {
"addressId": addressId,
"paymentMethod": "COD",
"paymentStatus": "PENDING",
"orderStatus": "PENDING",
"subtotal": subtotal,
"deliveryCharge": deliverCharge,
"transactionId": "phonepe_transaction_123",
"couponId": couponId
};
} else {
data = {
"addressId": addressId,
"paymentMethod": "COD",
"paymentStatus": "PENDING",
"orderStatus": "PENDING",
"subtotal": subtotal,
"deliveryCharge": deliverCharge,
};
}
print("kjfhxgkljfhg ${data}"); var data = {
"addressId": addressId,
"paymentMethod": "COD",
"paymentStatus": "PENDING",
"orderStatus": "PENDING",
"subtotal": subtotal,
"deliveryCharge": deliverCharge,
};
if (couponId.isNotEmpty) {
data["couponId"] = couponId;
data["transactionId"] = "phonepe_transaction_123";
}
try { try {
var result = await _homeRepo.paymentCODOrder(data); var result = await _homeRepo.paymentCODOrder(data);
return result.fold( return result.fold(
(error) { (error) {
Fluttertoast.showToast( Fluttertoast.showToast(
msg: "${error.message}", msg: "${error.message}",
toastLength: Toast.LENGTH_SHORT, toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM, gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.green, backgroundColor: Colors.red,
textColor: Colors.white, textColor: Colors.white,
fontSize: 14.0, fontSize: 14.0,
); );
ispaymentLoader = false; ispaymentLoader = false;
notifyListeners(); notifyListeners();
return false;
}, },
(response) { (response) {
context.clearAndPush(routePath: MyRoutes.SUCCESSPAYMENT);
ispaymentLoader = false; ispaymentLoader = false;
notifyListeners(); notifyListeners();
return true;
}, },
); );
} catch (e) { } catch (e) {
ispaymentLoader = false; ispaymentLoader = false;
notifyListeners();
Fluttertoast.showToast( Fluttertoast.showToast(
msg: "${e}", msg: "${e}",
toastLength: Toast.LENGTH_SHORT, toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM, gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.green, backgroundColor: Colors.red,
textColor: Colors.white, textColor: Colors.white,
fontSize: 14.0, fontSize: 14.0,
); );
notifyListeners(); return false;
} }
} }

View File

@@ -1,13 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:grocery_app/src/common_widget/name_text_field.dart'; import 'package:grocery_app/src/common_widget/name_text_field.dart';
import 'package:grocery_app/src/common_widget/network_image.dart'; import 'package:grocery_app/src/common_widget/network_image.dart';
import 'package:grocery_app/src/logic/provider/addTocart_provider.dart'; import 'package:grocery_app/src/logic/provider/addTocart_provider.dart';
import 'package:grocery_app/src/ui/payment/phonepe_payment.dart';
import 'package:grocery_app/utils/constants/assets_constant.dart'; import 'package:grocery_app/utils/constants/assets_constant.dart';
import 'package:grocery_app/utils/constants/color_constant.dart'; import 'package:grocery_app/utils/constants/color_constant.dart';
import 'package:grocery_app/utils/extensions/uicontext.dart'; import 'package:grocery_app/utils/extensions/uicontext.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../payment/razorpay_payment.dart';
class CardCheckoutScreen extends StatefulWidget { class CardCheckoutScreen extends StatefulWidget {
int deliveryCharge; int deliveryCharge;
// String currency; // String currency;
@@ -15,7 +19,7 @@ class CardCheckoutScreen extends StatefulWidget {
// String name; // String name;
// String phone; // String phone;
// String email; // String email;
// String userId; String userId;
String cartId; String cartId;
String addressId; String addressId;
// String remarks; // String remarks;
@@ -30,7 +34,7 @@ class CardCheckoutScreen extends StatefulWidget {
// required this.name, // required this.name,
// required this.phone, // required this.phone,
// required this.email, // required this.email,
// required this.userId, required this.userId,
required this.cartId, required this.cartId,
required this.addressId, required this.addressId,
// required this.remarks, // required this.remarks,
@@ -84,7 +88,7 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
), ),
Expanded( Expanded(
child: InkWell( child: InkWell(
onTap: () { /* onTap: () {
if (paymentProvider.selectedPaymentMethod == "Online") { if (paymentProvider.selectedPaymentMethod == "Online") {
print("dsjfkhkdfhgdkfghdfg"); print("dsjfkhkdfhgdkfghdfg");
paymentProvider.orderPaymnet( paymentProvider.orderPaymnet(
@@ -93,7 +97,8 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
widget.cartId, widget.cartId,
widget.addressId, widget.addressId,
widget.couponId!); widget.couponId!);
} else { }
else {
paymentProvider.paymentCODOrder( paymentProvider.paymentCODOrder(
context, context,
widget.originalAmount, widget.originalAmount,
@@ -102,6 +107,68 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
widget.addressId, widget.addressId,
); );
} }
},*/
onTap: (){
if(paymentProvider.selectedPaymentMethod!=null) {
if (paymentProvider.selectedPaymentMethod ==
"razorpay") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RazorpayPaymentScreen(
amount: widget.originalAmount +
widget.deliveryCharge,
cartId: widget.cartId,
addressId: widget.addressId,
couponId: widget.couponId,
userId: widget.userId,
),
),
);
} else if (paymentProvider.selectedPaymentMethod ==
"phonepe") {
// Navigate to PhonePe screen (optional for now)
// Replace this when you implement PhonePe
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PhonePePaymentScreen(
amount: widget.originalAmount +
widget.deliveryCharge,
cartId: widget.cartId,
addressId: widget.addressId,
//couponId: widget.couponId,
userId: widget.userId,
),
),
);
/* ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("PhonePe integration coming soon")),
);*/
} /*
else {
paymentProvider.paymentCODOrder(
context,
widget.originalAmount,
widget.deliveryCharge,
widget.couponId ?? "",
widget.addressId,
);
}*/
}else
{
Fluttertoast.showToast(
msg: "Select Payment method",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.green,
textColor: Colors.white,
fontSize: 14.0,
);
}
}, },
child: Container( child: Container(
height: 50, height: 50,
@@ -173,16 +240,34 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
), ),
SizedBox(height: 0), SizedBox(height: 0),
ListTile( /* ListTile(
leading: Icon(Icons.payment, color: Colors.blue), leading: Icon(Icons.payment, color: Colors.blue),
title: Text("Online Payment"), title: Text("Online Payment"),
trailing: paymentProvider.selectedPaymentMethod == "Online" trailing: paymentProvider.selectedPaymentMethod == "Online"
? Icon(Icons.check_circle, color: Colors.green) ? Icon(Icons.check_circle, color: Colors.green)
: null, : null,
onTap: () { onTap: () {
paymentProvider.selectPaymentMethod("Online"); // paymentProvider.selectPaymentMethod("Online");
// Navigator.pop(context); // Navigator.pop(context);
}, },
),*/
RadioListTile<String>(
value: "razorpay",
groupValue: paymentProvider.selectedPaymentMethod,
title: const Text("Razorpay Online Payment"),
onChanged: (value) {
paymentProvider.selectPaymentMethod(value!);
},
),
RadioListTile<String>(
value: "phonepe",
groupValue: paymentProvider.selectedPaymentMethod,
title: const Text("PhonePe Online Payment"),
onChanged: (value) {
paymentProvider.selectPaymentMethod(value!);
},
), ),
// Cash on Delivery (COD) Option // Cash on Delivery (COD) Option
@@ -404,3 +489,4 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
); );
} }
} }

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:carousel_slider/carousel_slider.dart'; import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
@@ -15,6 +17,7 @@ import 'package:grocery_app/src/ui/widgets/elevated_button.dart';
import 'package:grocery_app/utils/constants/color_constant.dart'; import 'package:grocery_app/utils/constants/color_constant.dart';
import 'package:grocery_app/utils/constants/shared_pref_utils.dart'; import 'package:grocery_app/utils/constants/shared_pref_utils.dart';
import 'package:grocery_app/utils/extensions/uicontext.dart'; import 'package:grocery_app/utils/extensions/uicontext.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:skeletonizer/skeletonizer.dart'; import 'package:skeletonizer/skeletonizer.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@@ -1006,6 +1009,8 @@ class _MycartState extends State<Mycart> {
); );
} }
void _showAddressBottomSheet(BuildContext context) { void _showAddressBottomSheet(BuildContext context) {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
@@ -1140,6 +1145,67 @@ class AddressBottomSheet extends StatefulWidget {
} }
class _AddressBottomSheetState extends State<AddressBottomSheet> { class _AddressBottomSheetState extends State<AddressBottomSheet> {
Future<String?> fetchDeliveryMessage() async {
const String url = 'https://www.mv.frontshopemporium.in/xam/distance/delivery-charges-by-distance';
try {
final response = await http.get(Uri.parse(url), headers: {
"Content-Type": "application/json",
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
});
print('continue response');
print(response.statusCode);
print(response.body);
if (response.statusCode == 200) {
final Map<String, dynamic> data = json.decode(response.body);
print(data);
final List<dynamic> nonDeliverableProducts = data['nonDeliverableProducts'] ?? [];
if (nonDeliverableProducts.isNotEmpty) {
final String reason = nonDeliverableProducts[0]['reason'];
print(reason);
return reason;
} else {
return '';
}
} else {
return 'Failed with status: ${response.statusCode}';
}
} catch (e) {
return 'Error: $e';
}
}
Future<String?> setDefaultAddress(String addressId) async {
String url = 'https://www.mv.frontshopemporium.in/xam/user/addresses/${addressId}/set-default';
try {
final response = await http.put(Uri.parse(url), headers: {
"Content-Type": "application/json",
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
});
print('address response');
print(response.statusCode);
print(response.body);
if (response.statusCode == 200) {
/* final Map<String, dynamic> data = json.decode(response.body);
print(data);
final List<dynamic> nonDeliverableProducts = data['nonDeliverableProducts'] ?? [];
if (nonDeliverableProducts.isNotEmpty) {
final String reason = nonDeliverableProducts[0]['reason'];
return reason;
} else {
return 'No non-deliverable products found';
}*/
} else {
return 'Failed with status: ${response.statusCode}';
}
} catch (e) {
return 'Error: $e';
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
@@ -1186,8 +1252,8 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
Consumer<AddtocartProvider>( Consumer<AddtocartProvider>(
builder: (context, paymentProvider, child) { builder: (context, paymentProvider, child) {
return ElevatedButton.icon( return ElevatedButton.icon(
onPressed: () { onPressed: () async{
if (paymentProvider.selectedAddress.isNotEmpty) { /* if (paymentProvider.selectedAddress.isNotEmpty) {
if (paymentProvider.isDeliverable) { if (paymentProvider.isDeliverable) {
Navigator.pop(context); Navigator.pop(context);
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(
@@ -1200,7 +1266,7 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
// name: paymentProvider.selecteUserName, // name: paymentProvider.selecteUserName,
// phone: paymentProvider.selecteUserPhone, // phone: paymentProvider.selecteUserPhone,
// email: paymentProvider.selecteEmail, // email: paymentProvider.selecteEmail,
// userId: paymentProvider.allitem.userId!, userId: paymentProvider.allitem.userId!,
cartId: paymentProvider.allitem.id!, cartId: paymentProvider.allitem.id!,
addressId: paymentProvider.selectedAddress, addressId: paymentProvider.selectedAddress,
// remarks: paymentProvider.selecteUserName, // remarks: paymentProvider.selecteUserName,
@@ -1229,17 +1295,97 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
textColor: Colors.white, textColor: Colors.white,
fontSize: 14.0, fontSize: 14.0,
); );
}*/
// Call your API and get the message
String? message = await fetchDeliveryMessage(); // Use the function from earlier
if (message != null && message.isNotEmpty) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Alert"),
content: Text(message),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(); // Close the dialog
},
child: Text("OK"),
),
],
);
},
);
} else {
Navigator.pop(context);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return CardCheckoutScreen(
deliveryCharge: paymentProvider.getdeliverycharge,
originalAmount: paymentProvider.grandPrice,
userId: paymentProvider.allitem.userId!,
cartId: paymentProvider.allitem.id!,
addressId: paymentProvider.selectedAddress,
couponId: paymentProvider.couponId,
);
},
));
} }
}, },
/*
// Call your API and get the message
await paymentProvider.paymentCODOrder(
context,
paymentProvider.grandPrice,
paymentProvider.getdeliverycharge,
paymentProvider.couponId ?? "",
paymentProvider.selectedAddress,
);
*/
/* if (message != null && message.isNotEmpty) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 14.0,
);
} else {*/
/*
Navigator.pop(context);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return CardCheckoutScreen(
deliveryCharge: paymentProvider.getdeliverycharge,
originalAmount: paymentProvider.grandPrice,
userId: paymentProvider.allitem.userId!,
cartId: paymentProvider.allitem.id!,
addressId: paymentProvider.selectedAddress,
couponId: paymentProvider.couponId,
);
},
));
// }
},*/
label: Text( label: Text(
"Continue", "Continue",
style: TextStyle(color: Colors.white, fontSize: 16), style: TextStyle(color: Colors.white, fontSize: 16),
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: paymentProvider.isDeliverable backgroundColor:Colors.green,
/*backgroundColor: paymentProvider.isDeliverable
? Colors.green ? Colors.green
: Colors.grey, : Colors.grey,
minimumSize: Size(double.infinity, 50), */minimumSize: Size(double.infinity, 50),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)), borderRadius: BorderRadius.circular(10)),
), ),
@@ -1278,12 +1424,13 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
activeColor: Colors.green, activeColor: Colors.green,
onChanged: (value) { onChanged: (value) {
addressProvider.checkAddress(context, value); addressProvider.checkAddress(context, value);
setDefaultAddress(address.id);
addressProvider.selectAddress( addressProvider.selectAddress(
value.toString(), value.toString(),
address.phoneNumber, address.phoneNumber,
address.name, address.name,
address.user!.email); address.user!.email);
}, },
), ),
title: Text( title: Text(

View File

@@ -59,7 +59,7 @@ class _MyOrderScreenState extends State<MyOrderScreen> {
width: 20, width: 20,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
context.clearAndPush(routePath: MyRoutes.BOTTOMNAV); context.clearAndPush(routePath: MyRoutes.HOME);
}, },
child: SvgPicture.asset( child: SvgPicture.asset(
APPASSETS.back, APPASSETS.back,

View File

@@ -0,0 +1,271 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
import 'package:phonepe_payment_sdk/phonepe_payment_sdk.dart';
import 'package:uuid/uuid.dart';
import 'dart:convert';
import 'dart:async';
import 'package:app_links/app_links.dart';
import '../../../utils/constants/shared_pref_utils.dart';
import '../../core/routes/routes.dart';
import '../myOrder/my_order.dart';
class PhonePePaymentScreen extends StatefulWidget {
final double amount;
final String cartId;
final String addressId;
final String userId;
const PhonePePaymentScreen({
required this.amount,
required this.cartId,
required this.addressId,
required this.userId,
super.key,
});
@override
State<PhonePePaymentScreen> createState() => _PhonePePaymentScreenState();
}
class _PhonePePaymentScreenState extends State<PhonePePaymentScreen> {
String _statusMessage = "Initiating payment...";
bool _isLoading = true;
final AppLinks _appLinks = AppLinks();
StreamSubscription<Uri>? _linkSub;
@override
void initState() {
super.initState();
_listenForRedirect();
_initiateAndStartPayment();
}
@override
void dispose() {
_linkSub?.cancel();
super.dispose();
}
void _listenForRedirect() {
print("Listening for redirect...");
_linkSub = _appLinks.uriLinkStream.listen((Uri uri) {
print("Deep link received: $uri");
final transactionId = uri.queryParameters['transactionId'];
final status = uri.queryParameters['status'];
if (transactionId != null && status == "SUCCESS") {
//_verifyPayment(transactionId);
} else if (status == "CANCEL") {
setState(() {
_statusMessage = "Payment cancelled by user.";
_isLoading = false;
});
Navigator.pop(context, false); // 👈 Return failure
} else {
setState(() {
_statusMessage = "Payment failed or unknown status.";
_isLoading = false;
});
Navigator.pop(context, false); // 👈 Return failure
}
}, onError: (err) {
print("Deep link error: $err");
setState(() {
_statusMessage = "Error handling redirect: $err";
_isLoading = false;
});
Navigator.pop(context, false); // 👈 Return failure
});
}
Future<void> _initiateAndStartPayment() async {
try {
final uri = Uri.parse("https://www.mv.frontshopemporium.in/xam/payment/phonepe/sdk/initiate");
print("Calling backend initiate API...");
final response = await http.post(
uri,
headers: {
"Content-Type": "application/json",
"authorization": "Bearer ${await SharedPrefUtils.getToken()}",
},
body: jsonEncode({
"amount": widget.amount,
"cartId": widget.cartId,
"addressId": widget.addressId,
}),
);
print("Response code: ${response.statusCode}");
print("Response body: ${response.body}");
if (response.statusCode != 200 && response.statusCode != 201) {
setState(() {
_statusMessage = "Failed to initiate payment.";
_isLoading = false;
});
return;
}
final data = jsonDecode(response.body);
final String? orderId = data['orderId'];
final String? merchantId = data['merchantId'];
final String? token = data['token'];
const String environment = "PRODUCTION";
const String appSchema = "frontshop";
final String flowId = 'FLWID_${Uuid().v4()}';
if (orderId == null || merchantId == null || token == null) {
print("Invalid response from backend. Missing fields.");
setState(() {
_statusMessage = "Invalid response from backend.";
_isLoading = false;
});
return;
}
print("Initializing SDK...");
PhonePePaymentSdk.init(environment, merchantId, flowId, true);
final payload = {
"orderId": orderId,
"merchantId": merchantId,
"token": token,
"paymentMode": {"type": "PAY_PAGE"},
};
String request = jsonEncode(payload);
print("Starting transaction with payload: $request");
final result = await PhonePePaymentSdk.startTransaction(request, appSchema);
print("Transaction result: $result");
if (result != null) {
final status = result['status']?.toString() ?? '';
final error = result['error']?.toString() ?? '';
if (status == 'SUCCESS') {
final txnId = data['merchantOrderId']?? '';
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Payment Successful!")),
);
_verifyPayment(txnId);
context.push(MyRoutes.MYORDER);
} else if (status == 'CANCELLED') {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Payment Cancelled by User")),
);
setState(() {
_statusMessage = "Payment cancelled.";
_isLoading = false;
});
Navigator.pop(context, false);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Payment Failed: $error")),
);
setState(() {
_statusMessage = "Payment failed.";
_isLoading = false;
});
Navigator.pop(context, false);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("No response from PhonePe")),
);
setState(() {
_statusMessage = "No response.";
_isLoading = false;
});
Navigator.pop(context, false);
}
} catch (e) {
print("Error during payment: $e");
setState(() {
_statusMessage = "Error: ${e.toString()}";
_isLoading = false;
});
Navigator.pop(context, false); // 👈 Exit with failure
}
}
Future<void> _verifyPayment(String transactionId) async {
try {
final verifyUri = Uri.parse(
"https://mv.frontshopemporium.in/xam/payment/phonepe/sdk/status/$transactionId",
);
final response = await http.get(
verifyUri,
headers: {
"Content-Type": "application/json",
"authorization": "Bearer ${await SharedPrefUtils.getToken()}",
},
);
print("Status check response: ${response.body}");
if (response.statusCode == 200) {
final statusData = jsonDecode(response.body);
final paymentStatus = statusData['status'];
if (paymentStatus == "SUCCESS") {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Order Placed Successfully")),
);
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (_) => MyOrderScreen()),
(route) => false,
);
}
else {
setState(() {
_statusMessage = "Payment verification failed: $paymentStatus";
_isLoading = false;
});
Navigator.pop(context, false); // ❌ Return failure
}
} else {
setState(() {
_statusMessage = "Failed to verify payment.";
_isLoading = false;
});
Navigator.pop(context, false);
}
} catch (e) {
print("Verification error: $e");
setState(() {
_statusMessage = "Verification error: ${e.toString()}";
_isLoading = false;
});
Navigator.pop(context, false); // ❌ Return failure
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("PhonePe Payment")),
body: Center(
child: _isLoading
? const CircularProgressIndicator()
: Text(
_statusMessage,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 16),
),
),
);
}
}

View File

@@ -7,12 +7,16 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <gtk/gtk_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar); file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) gtk_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
gtk_plugin_register_with_registrar(gtk_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux file_selector_linux
gtk
url_launcher_linux url_launcher_linux
) )

View File

@@ -5,6 +5,7 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import app_links
import connectivity_plus import connectivity_plus
import file_selector_macos import file_selector_macos
import firebase_core import firebase_core
@@ -15,10 +16,11 @@ import geolocator_apple
import package_info_plus import package_info_plus
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import sqflite import sqflite_darwin
import url_launcher_macos import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@ name: grocery_app
description: "CustomerApp" description: "CustomerApp"
publish_to: 'none' publish_to: 'none'
version: 1.0.0+1 version: 1.0.3+25
environment: environment:
sdk: '>=3.4.0 <4.0.0' sdk: '>=3.4.0 <4.0.0'
@@ -24,20 +24,25 @@ dependencies:
flutter_toggle_tab: ^1.4.1 flutter_toggle_tab: ^1.4.1
dotted_border: ^2.1.0 dotted_border: ^2.1.0
go_router: ^14.2.0 go_router: ^14.2.0
uuid: ^4.0.0
phonepe_payment_sdk: ^3.0.0
google_maps_flutter: google_maps_flutter:
geolocator: geolocator:
geocoding: geocoding:
flutter_google_places: app_links: ^3.0.0
google_api_headers: google_places_flutter: ^2.1.0
google_api_headers: ^4.4.1
fluttertoast: fluttertoast:
flutter_rating_stars: ^1.1.0 flutter_rating_stars: ^1.1.0
url_launcher: ^6.3.1 url_launcher: ^6.3.1
skeletonizer: ^1.4.3 skeletonizer: ^1.4.3
art_sweetalert: ^0.0.5 art_sweetalert: ^0.0.5
blur: blur:
flutter_rating_bar: flutter_rating_bar:
change_app_package_name: ^1.5.0 change_app_package_name: ^1.5.0
permission_handler: ^11.3.1 permission_handler: ^11.3.1
flutter_local_notifications: ^18.0.1 flutter_local_notifications: ^18.0.1
firebase_core: firebase_core:
firebase_messaging: firebase_messaging:
@@ -75,6 +80,10 @@ dependencies:
image_picker: any image_picker: any
shimmer: ^3.0.0 shimmer: ^3.0.0
flutter_inappwebview: ^6.0.0 flutter_inappwebview: ^6.0.0
razorpay_flutter: ^1.3.7
http: ^1.1.0
dev_dependencies: dev_dependencies:

View File

@@ -1,30 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:grocery_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApplication());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}

View File

@@ -6,20 +6,26 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <app_links/app_links_plugin_c_api.h>
#include <connectivity_plus/connectivity_plus_windows_plugin.h> #include <connectivity_plus/connectivity_plus_windows_plugin.h>
#include <file_selector_windows/file_selector_windows.h> #include <file_selector_windows/file_selector_windows.h>
#include <firebase_core/firebase_core_plugin_c_api.h> #include <firebase_core/firebase_core_plugin_c_api.h>
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
#include <geolocator_windows/geolocator_windows.h> #include <geolocator_windows/geolocator_windows.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
AppLinksPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
ConnectivityPlusWindowsPluginRegisterWithRegistrar( ConnectivityPlusWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
FileSelectorWindowsRegisterWithRegistrar( FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows")); registry->GetRegistrarForPlugin("FileSelectorWindows"));
FirebaseCorePluginCApiRegisterWithRegistrar( FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
GeolocatorWindowsRegisterWithRegistrar( GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows")); registry->GetRegistrarForPlugin("GeolocatorWindows"));
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(

View File

@@ -3,9 +3,11 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
app_links
connectivity_plus connectivity_plus
file_selector_windows file_selector_windows
firebase_core firebase_core
flutter_inappwebview_windows
geolocator_windows geolocator_windows
permission_handler_windows permission_handler_windows
url_launcher_windows url_launcher_windows