Code committed
This commit is contained in:
@@ -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`
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,34 +2,34 @@
|
|||||||
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>
|
||||||
|
|||||||
@@ -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()
|
|
||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
271
lib/src/ui/payment/phonepe_payment.dart
Normal file
271
lib/src/ui/payment/phonepe_payment.dart
Normal 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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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"))
|
||||||
|
|||||||
494
pubspec.lock
494
pubspec.lock
File diff suppressed because it is too large
Load Diff
15
pubspec.yaml
15
pubspec.yaml
@@ -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,16 +24,21 @@ 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
|
||||||
@@ -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:
|
||||||
|
|||||||
@@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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(
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user