From 1a14b83301adc78018b7fff6efc5d52713da38b0 Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Wed, 25 Sep 2024 15:13:25 +0530 Subject: [PATCH 1/9] Added Method Channel - OpenMenuWidget , ShowDownloadButton --- .../plugins/GeneratedPluginRegistrant.java | 10 - example/android/local.properties | 4 +- example/ios/Flutter/AppFrameworkInfo.plist | 2 +- example/ios/Podfile | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 7 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- example/ios/Runner/Info.plist | 2 + example/lib/main.dart | 116 ++++++----- example/pubspec.lock | 193 +++++++++--------- example/pubspec.yaml | 4 +- .../SwiftVerloopFlutterSdkPlugin.swift | 13 +- ios/verloop_flutter_sdk.podspec | 4 +- lib/verloop_flutter_sdk.dart | 19 ++ lib/verloop_flutter_sdk_method_channel.dart | 21 ++ ...erloop_flutter_sdk_platform_interface.dart | 9 + 15 files changed, 242 insertions(+), 166 deletions(-) diff --git a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index a82bb02..60d9831 100644 --- a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -15,16 +15,6 @@ public final class GeneratedPluginRegistrant { private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { - try { - flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin()); - } catch (Exception e) { - Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e); - } - try { - flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin()); - } catch (Exception e) { - Log.e(TAG, "Error registering plugin firebase_messaging, io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin", e); - } try { flutterEngine.getPlugins().add(new io.verloop.verloop_flutter_sdk.VerloopFlutterSdkPlugin()); } catch (Exception e) { diff --git a/example/android/local.properties b/example/android/local.properties index 100b284..b37df45 100644 --- a/example/android/local.properties +++ b/example/android/local.properties @@ -1,3 +1,3 @@ -sdk.dir=C:/Users/ADYA H S/AppData/Local/Android/Sdk -flutter.sdk=C:\\flutter +sdk.dir=/Users/pankajpatel/Library/Android/sdk +flutter.sdk=/Users/pankajpatel/Development/flutter flutter.buildMode=debug \ No newline at end of file diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 8d4492f..7c56964 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 12.0 diff --git a/example/ios/Podfile b/example/ios/Podfile index 1e8c3c9..eb8b0f9 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' + platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index f367720..451d9b9 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -157,7 +157,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -223,10 +223,12 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -237,6 +239,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a..5e31d3d 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ UIViewControllerBasedStatusBarAppearance + UIApplicationSupportsIndirectInputEvents + diff --git a/example/lib/main.dart b/example/lib/main.dart index 715cf5c..37a1f8d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,22 +1,21 @@ import 'dart:developer'; -import 'dart:ffi'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; +//import 'package:firebase_core/firebase_core.dart'; +//import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:verloop_flutter_sdk/verloop_flutter_sdk.dart'; -import 'firebase_options.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + + // await Firebase.initializeApp( + // // options: DefaultFirebaseOptions.currentPlatform, + // ); runApp(const MyApp()); } class MyApp extends StatefulWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({super.key}); @override State createState() => _MyAppState(); @@ -173,44 +172,69 @@ class _MyAppState extends State { ), floatingActionButton: changed == true ? const SizedBox() - : FutureBuilder( - // Initialize FlutterFire - future: FirebaseMessaging.instance.getToken(), - builder: (context, snapshot) { - // Check for errors - if (snapshot.hasError) { - return const Text("Something went wrong"); - } - if (snapshot.hasData && snapshot.data != "") { - String token = snapshot.data ?? ""; - - return VerloopWidget( - clientId: clientId, - fcmToken: token, - recipeId: recipeId, - roomVariables: roomMap, - userVariables: userMap, - userId: userId, - userName: userName, - userEmail: userEmail, - userPhone: userPhone, - onButtonClicked: - (String? title, String? payload, String? type) { - log("button click title $title $payload"); - }, - onUrlClicked: (String? url) { - log("url clicked $url"); - }, - overrideUrlOnClick: true, - child: const FloatingActionButton( - onPressed: null, - child: Icon(Icons.chat), - ), - ); - } - return const Text("Loading..."); - }, - ), + : VerloopWidget( + clientId: clientId, + // fcmToken: token, + // recipeId: recipeId, + // roomVariables: roomMap, + // userVariables: userMap, + // userId: userId, + // userName: userName, + // userEmail: userEmail, + userPhone: userPhone, + openMenuWidget: true, + showDownloadButton: false, + onButtonClicked: + (String? title, String? payload, String? type) { + log("button click title $title $payload"); + }, + onUrlClicked: (String? url) { + log("url clicked $url"); + }, + overrideUrlOnClick: true, + child: const FloatingActionButton( + onPressed: null, + child: Icon(Icons.chat), + ), + ) + // : FutureBuilder( + // // Initialize FlutterFire + // future: FirebaseMessaging.instance.getToken(), + // builder: (context, snapshot) { + // // Check for errors + // if (snapshot.hasError) { + // return const Text("Something went wrong"); + // } + // if (snapshot.hasData && snapshot.data != "") { + // String token = snapshot.data ?? ""; + // + // return VerloopWidget( + // clientId: clientId, + // fcmToken: token, + // recipeId: recipeId, + // roomVariables: roomMap, + // userVariables: userMap, + // userId: userId, + // userName: userName, + // userEmail: userEmail, + // userPhone: userPhone, + // onButtonClicked: + // (String? title, String? payload, String? type) { + // log("button click title $title $payload"); + // }, + // onUrlClicked: (String? url) { + // log("url clicked $url"); + // }, + // overrideUrlOnClick: true, + // child: const FloatingActionButton( + // onPressed: null, + // child: Icon(Icons.chat), + // ), + // ); + // } + // return const Text("Loading..."); + // }, + // ), ), ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index fcb9523..5d03f0e 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,100 +5,58 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.8.2" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.3.0" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.18.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.8" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "1.18.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.4.1" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.5" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - url: "https://pub.dartlang.org" - source: hosted - version: "11.4.2" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.2" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -108,9 +66,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.2" flutter_test: dependency: "direct dev" description: flutter @@ -121,55 +80,78 @@ packages: description: flutter source: sdk version: "0.0.0" - js: + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.dev" + source: hosted + version: "10.0.5" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + leak_tracker_testing: dependency: transitive description: - name: js - url: "https://pub.dartlang.org" + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "3.0.1" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.0" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" source: hosted - version: "0.12.11" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" source: hosted - version: "0.1.4" + version: "0.11.1" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" source: hosted - version: "1.7.0" + version: "1.15.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" source: hosted - version: "1.8.1" + version: "1.9.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - url: "https://pub.dartlang.org" + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.8" sky_engine: dependency: transitive description: flutter @@ -179,58 +161,73 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.dev" source: hosted - version: "0.4.9" + version: "0.7.2" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" verloop_flutter_sdk: dependency: "direct main" description: path: ".." relative: true source: path - version: "0.0.4" + version: "0.0.9" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + url: "https://pub.dev" + source: hosted + version: "14.2.5" sdks: - dart: ">=2.17.3 <3.0.0" - flutter: ">=2.5.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index e02f05e..af321df 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -29,8 +29,8 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 - firebase_messaging: ^14.8.0 - firebase_core: ^2.28.0 + #firebase_messaging: ^14.8.0 + #firebase_core: ^2.28.0 dev_dependencies: flutter_test: diff --git a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift index 3ff1863..345d62d 100644 --- a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift +++ b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift @@ -111,7 +111,7 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg result(1) case "setUrlClickListener": if let args = call.arguments as? Dictionary { - var overrideUrl = args["OVERRIDE_URL"] as? Bool + let overrideUrl = args["OVERRIDE_URL"] as? Bool if overrideUrl != nil { config?.setUrlRedirectionFlag(canRedirect: !overrideUrl!) // if you wish to open the url in a browser, then keep it as false } @@ -121,6 +121,17 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg return; }) result(1) + case "showDownloadButton": + if let args = call.arguments as? Dictionary { + let isAllowFileDownload = args["isAllowFileDownload"] as? Bool + if isAllowFileDownload != nil { + config?.showDownloadButton(isAllowFileDownload ?? false) + } + } + result(1) + case "openMenuWidget": + config?.openMenuWidget() + result(1) case "buildVerloop": if config == nil { result(FlutterError.init(code: SwiftVerloopFlutterSdkPlugin.ERROR_101, diff --git a/ios/verloop_flutter_sdk.podspec b/ios/verloop_flutter_sdk.podspec index 492be0d..1fef8e7 100644 --- a/ios/verloop_flutter_sdk.podspec +++ b/ios/verloop_flutter_sdk.podspec @@ -15,8 +15,8 @@ This is a wrapper over native SDK for flutter app s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency "VerloopSDKiOS", "0.2.7" - s.platform = :ios, '11.0' + s.dependency "VerloopSDKiOS", "0.2.13" + s.platform = :ios, '12.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/lib/verloop_flutter_sdk.dart b/lib/verloop_flutter_sdk.dart index 3d5d0bc..4b613ea 100644 --- a/lib/verloop_flutter_sdk.dart +++ b/lib/verloop_flutter_sdk.dart @@ -16,6 +16,7 @@ class VerloopWidget extends StatefulWidget { final String? userEmail; final String? userPhone; final bool overrideUrlOnClick; + final bool showDownloadButton; final Widget? child; final Function(String? title, String? payload, String? type)? onButtonClicked; @@ -23,6 +24,7 @@ class VerloopWidget extends StatefulWidget { final Map? userVariables; final Map? roomVariables; + final bool? openMenuWidget; const VerloopWidget( {Key? key, @@ -38,6 +40,8 @@ class VerloopWidget extends StatefulWidget { this.roomVariables, this.onButtonClicked, this.onUrlClicked, + this.openMenuWidget, + this.showDownloadButton = false, this.overrideUrlOnClick = false}) : super(key: key); @@ -79,6 +83,7 @@ class _VerloopWidgetState extends State { ); sdk?.setButtonClickListener(); sdk?.setUrlClickListener(overrideUrlOnClick: widget.overrideUrlOnClick); + sdk?.showDownloadButton(isAllowFileDownload: widget.showDownloadButton); sdk?.buildVerloop(); sdk?.onButtonClicked.listen((event) { widget.onButtonClicked?.call(event.title, event.payload, event.type); @@ -86,6 +91,11 @@ class _VerloopWidgetState extends State { sdk?.onUrlClicked.listen((event) { widget.onUrlClicked?.call(event.url); }); + + if (widget.openMenuWidget == true) { + sdk?.openMenuWidget(); + } + setState(() { _ready = true; }); @@ -141,6 +151,15 @@ class VerloopSdk { return await VerloopFlutterSdkPlatform.instance.setButtonClickListener(); } + Future openMenuWidget() async { + return await VerloopFlutterSdkPlatform.instance.openMenuWidget(); + } + + Future showDownloadButton({bool isAllowFileDownload = false}) async { + return await VerloopFlutterSdkPlatform.instance + .showDownloadButton(isAllowFileDownload: isAllowFileDownload); + } + Future setUrlClickListener({bool overrideUrlOnClick = false}) async { return await VerloopFlutterSdkPlatform.instance .setUrlClickListener(overrideUrlOnClick: overrideUrlOnClick); diff --git a/lib/verloop_flutter_sdk_method_channel.dart b/lib/verloop_flutter_sdk_method_channel.dart index 848128b..7cc64b7 100644 --- a/lib/verloop_flutter_sdk_method_channel.dart +++ b/lib/verloop_flutter_sdk_method_channel.dart @@ -71,6 +71,27 @@ class MethodChannelVerloopFlutterSdk extends VerloopFlutterSdkPlatform { log("Failed to set url click listener: '${e.message}'."); } } + + @override + Future openMenuWidget() async { + try { + await verloopMethods.invokeMethod('openMenuWidget'); + } on PlatformException catch (e) { + log("Failed to load widget: '${e.message}'."); + } + } + + @override + Future showDownloadButton({bool isAllowFileDownload = false}) async { + try { + await verloopMethods + .invokeMethod('showDownloadButton', { + 'isAllowFileDownload': isAllowFileDownload, + }); + } on PlatformException catch (e) { + log("Failed to set url click listener: '${e.message}'."); + } + } @override Future buildVerloop() async { diff --git a/lib/verloop_flutter_sdk_platform_interface.dart b/lib/verloop_flutter_sdk_platform_interface.dart index 5467044..81d4ed6 100644 --- a/lib/verloop_flutter_sdk_platform_interface.dart +++ b/lib/verloop_flutter_sdk_platform_interface.dart @@ -45,8 +45,17 @@ abstract class VerloopFlutterSdkPlatform extends PlatformInterface { 'setButtonClickListener() has not been implemented.'); } + Future openMenuWidget() async { + throw UnimplementedError( + 'openMenuWidget() has not been implemented.'); + } + Future setUrlClickListener({bool overrideUrlOnClick = false}) async { throw UnimplementedError('setUrlClickListener() has not been implemented.'); + } + + Future showDownloadButton({bool isAllowFileDownload = false}) async { + throw UnimplementedError('showDownloadButton() has not been implemented.'); } Future buildVerloop() async { From aa9d855026429938400cc250a4d2902b2c6e6b48 Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Tue, 22 Oct 2024 15:31:46 +0530 Subject: [PATCH 2/9] - Flutter Method channel --- example/ios/Podfile.lock | 102 +------ example/ios/Runner/AppDelegate.swift | 2 +- example/lib/main.dart | 234 +--------------- example/lib/screens/home_screen.dart | 43 +++ .../screens/login-screen/login_screen.dart | 257 ++++++++++++++++++ .../SwiftVerloopFlutterSdkPlugin.swift | 68 ++++- 6 files changed, 373 insertions(+), 333 deletions(-) create mode 100644 example/lib/screens/home_screen.dart create mode 100644 example/lib/screens/login-screen/login_screen.dart diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index acefd34..80a3d53 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,117 +1,29 @@ PODS: - - Firebase/CoreOnly (8.15.0): - - FirebaseCore (= 8.15.0) - - Firebase/Messaging (8.15.0): - - Firebase/CoreOnly - - FirebaseMessaging (~> 8.15.0) - - firebase_core (1.18.0): - - Firebase/CoreOnly (= 8.15.0) - - Flutter - - firebase_messaging (11.4.2): - - Firebase/Messaging (= 8.15.0) - - firebase_core - - Flutter - - FirebaseCore (8.15.0): - - FirebaseCoreDiagnostics (~> 8.0) - - GoogleUtilities/Environment (~> 7.7) - - GoogleUtilities/Logger (~> 7.7) - - FirebaseCoreDiagnostics (8.15.0): - - GoogleDataTransport (~> 9.1) - - GoogleUtilities/Environment (~> 7.7) - - GoogleUtilities/Logger (~> 7.7) - - nanopb (~> 2.30908.0) - - FirebaseInstallations (8.15.0): - - FirebaseCore (~> 8.0) - - GoogleUtilities/Environment (~> 7.7) - - GoogleUtilities/UserDefaults (~> 7.7) - - PromisesObjC (< 3.0, >= 1.2) - - FirebaseMessaging (8.15.0): - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) - - GoogleDataTransport (~> 9.1) - - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - - GoogleUtilities/Environment (~> 7.7) - - GoogleUtilities/Reachability (~> 7.7) - - GoogleUtilities/UserDefaults (~> 7.7) - - nanopb (~> 2.30908.0) - Flutter (1.0.0) - - GoogleDataTransport (9.2.0): - - GoogleUtilities/Environment (~> 7.7) - - nanopb (< 2.30910.0, >= 2.30908.0) - - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/AppDelegateSwizzler (7.7.0): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (7.7.0): - - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/Logger (7.7.0): - - GoogleUtilities/Environment - - GoogleUtilities/Network (7.7.0): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (7.7.0)" - - GoogleUtilities/Reachability (7.7.0): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (7.7.0): - - GoogleUtilities/Logger - - nanopb (2.30908.0): - - nanopb/decode (= 2.30908.0) - - nanopb/encode (= 2.30908.0) - - nanopb/decode (2.30908.0) - - nanopb/encode (2.30908.0) - - PromisesObjC (2.1.1) - verloop_flutter_sdk (0.0.4): - Flutter - - VerloopSDKiOS (= 0.2.5) - - VerloopSDKiOS (0.2.5) + - VerloopSDKiOS (= 0.2.13) + - VerloopSDKiOS (0.2.13) DEPENDENCIES: - - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) - verloop_flutter_sdk (from `.symlinks/plugins/verloop_flutter_sdk/ios`) SPEC REPOS: trunk: - - Firebase - - FirebaseCore - - FirebaseCoreDiagnostics - - FirebaseInstallations - - FirebaseMessaging - - GoogleDataTransport - - GoogleUtilities - - nanopb - - PromisesObjC - VerloopSDKiOS EXTERNAL SOURCES: - firebase_core: - :path: ".symlinks/plugins/firebase_core/ios" - firebase_messaging: - :path: ".symlinks/plugins/firebase_messaging/ios" Flutter: :path: Flutter verloop_flutter_sdk: :path: ".symlinks/plugins/verloop_flutter_sdk/ios" SPEC CHECKSUMS: - Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d - firebase_core: b14c1cfa29b9eb316345f74d1489328283825d6d - firebase_messaging: 5374d57b2ca7a5efe1a150500b9a2451ca9ff5af - FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1 - FirebaseCoreDiagnostics: 92e07a649aeb66352b319d43bdd2ee3942af84cb - FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd - FirebaseMessaging: 5e5118a2383b3531e730d974680954c679ca0a13 - Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a - GoogleDataTransport: 1c8145da7117bd68bbbed00cf304edb6a24de00f - GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1 - nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 - PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb - verloop_flutter_sdk: e0461f415b265e2481a8bd251c8210a0711840fe - VerloopSDKiOS: bfd1532603c6c0cfbb8ceb47b05d155139152ff1 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + verloop_flutter_sdk: ff3eb6eac5a66f821da75fe6151d25e0006d2f19 + VerloopSDKiOS: 264442f5a14053eb354335debd536278d27762ac -PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c +PODFILE CHECKSUM: ce13d36744da294d67f8e460dbb7aed7c09bd7f4 -COCOAPODS: 1.11.3 +COCOAPODS: 1.15.2 diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift index 70693e4..b636303 100644 --- a/example/ios/Runner/AppDelegate.swift +++ b/example/ios/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import UIKit import Flutter -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/example/lib/main.dart b/example/lib/main.dart index 37a1f8d..8f63ca7 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,9 +1,5 @@ -import 'dart:developer'; - -//import 'package:firebase_core/firebase_core.dart'; -//import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; -import 'package:verloop_flutter_sdk/verloop_flutter_sdk.dart'; +import 'package:verloop_flutter_sdk_example/screens/login-screen/login_screen.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -14,235 +10,15 @@ void main() async { runApp(const MyApp()); } -class MyApp extends StatefulWidget { +class MyApp extends StatelessWidget { const MyApp({super.key}); - @override - State createState() => _MyAppState(); -} - -class _MyAppState extends State { - final Map roomMap = {"key1": "value1"}; - final Map userMap = {"key2": "value2"}; - String clientId = "hello"; - String? recipeId; - String? userId; - String? userName; - String? userEmail; - String? userPhone; - final clientIdController = TextEditingController(); - final recipeIdController = TextEditingController(); - final userIdController = TextEditingController(); - final userNameController = TextEditingController(); - final userEmailController = TextEditingController(); - final userPhoneController = TextEditingController(); - bool changed = true; - @override Widget build(BuildContext context) { return MaterialApp( - home: Scaffold( - appBar: AppBar( - backgroundColor: Colors.black, - title: const Text('Plugin example app'), - ), - body: SingleChildScrollView( - child: Stack( - children: [ - Flex( - direction: Axis.vertical, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: TextField( - controller: clientIdController, - onChanged: (String text) { - setState(() { - clientId = clientIdController.text; - changed = true; - }); - }, - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: - 'Enter the client id eg: hello or hello.stage', - ), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: TextField( - controller: recipeIdController, - onChanged: (String text) { - setState(() { - recipeId = recipeIdController.text; - changed = true; - }); - }, - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: 'Enter the recipe ID', - ), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: TextField( - controller: userIdController, - onChanged: (String text) { - setState(() { - userId = userIdController.text; - changed = true; - }); - }, - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: 'Enter the user Id', - ), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: TextField( - controller: userNameController, - onChanged: (String text) { - setState(() { - userName = userNameController.text; - changed = true; - }); - }, - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: 'Enter the user name', - ), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: TextField( - controller: userPhoneController, - onChanged: (String text) { - setState(() { - userPhone = userPhoneController.text; - changed = true; - }); - }, - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: 'Enter the user phone', - ), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: TextField( - controller: userEmailController, - onChanged: (String text) { - setState(() { - userEmail = userEmailController.text; - changed = true; - }); - }, - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: 'Enter the user email', - ), - ), - ), - Text('Running for client $clientId'), - changed == false - ? const SizedBox() - : TextButton( - onPressed: () { - setState(() { - changed = false; - }); - }, - child: const Text("Submit")), - ], - ), - ], - ), - ), - floatingActionButton: changed == true - ? const SizedBox() - : VerloopWidget( - clientId: clientId, - // fcmToken: token, - // recipeId: recipeId, - // roomVariables: roomMap, - // userVariables: userMap, - // userId: userId, - // userName: userName, - // userEmail: userEmail, - userPhone: userPhone, - openMenuWidget: true, - showDownloadButton: false, - onButtonClicked: - (String? title, String? payload, String? type) { - log("button click title $title $payload"); - }, - onUrlClicked: (String? url) { - log("url clicked $url"); - }, - overrideUrlOnClick: true, - child: const FloatingActionButton( - onPressed: null, - child: Icon(Icons.chat), - ), - ) - // : FutureBuilder( - // // Initialize FlutterFire - // future: FirebaseMessaging.instance.getToken(), - // builder: (context, snapshot) { - // // Check for errors - // if (snapshot.hasError) { - // return const Text("Something went wrong"); - // } - // if (snapshot.hasData && snapshot.data != "") { - // String token = snapshot.data ?? ""; - // - // return VerloopWidget( - // clientId: clientId, - // fcmToken: token, - // recipeId: recipeId, - // roomVariables: roomMap, - // userVariables: userMap, - // userId: userId, - // userName: userName, - // userEmail: userEmail, - // userPhone: userPhone, - // onButtonClicked: - // (String? title, String? payload, String? type) { - // log("button click title $title $payload"); - // }, - // onUrlClicked: (String? url) { - // log("url clicked $url"); - // }, - // overrideUrlOnClick: true, - // child: const FloatingActionButton( - // onPressed: null, - // child: Icon(Icons.chat), - // ), - // ); - // } - // return const Text("Loading..."); - // }, - // ), - ), + theme: ThemeData(useMaterial3: true), + debugShowCheckedModeBanner: true, + home: const LoginScreen(), ); } - - @override - void dispose() { - clientIdController.dispose(); - recipeIdController.dispose(); - super.dispose(); - } } diff --git a/example/lib/screens/home_screen.dart b/example/lib/screens/home_screen.dart new file mode 100644 index 0000000..bbd1eff --- /dev/null +++ b/example/lib/screens/home_screen.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; + +class HomeScreen extends StatefulWidget { + final String? title; + final String? payload; + final String? type; + + const HomeScreen({ + super.key, + this.title, + this.type, + this.payload, + }); + + @override + State createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State { + @override + Widget build(BuildContext context) { + final size = MediaQuery.sizeOf(context); + return Scaffold( + appBar: AppBar( + automaticallyImplyLeading: false, + title: const Text("Home-screen"), + ), + body: SizedBox( + width: size.width, + height: size.height, + child: Center( + child: Column( + children: [ + Text(widget.title ?? ""), + Text(widget.payload ?? ""), + Text(widget.type ?? ""), + ], + ), + ), + ), + ); + } +} diff --git a/example/lib/screens/login-screen/login_screen.dart b/example/lib/screens/login-screen/login_screen.dart new file mode 100644 index 0000000..9cc68f8 --- /dev/null +++ b/example/lib/screens/login-screen/login_screen.dart @@ -0,0 +1,257 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:verloop_flutter_sdk/verloop_flutter_sdk.dart'; +import 'package:verloop_flutter_sdk_example/screens/home_screen.dart'; + +class LoginScreen extends StatefulWidget { + const LoginScreen({super.key}); + + @override + State createState() => _LoginScreenState(); +} + +class _LoginScreenState extends State { + final Map roomMap = {"key1": "value1"}; + final Map userMap = {"key2": "value2"}; + String clientId = "hello"; + String? recipeId; + String? userId; + String? userName; + String? userEmail; + String? userPhone; + final clientIdController = TextEditingController(); + final recipeIdController = TextEditingController(); + final userIdController = TextEditingController(); + final userNameController = TextEditingController(); + final userEmailController = TextEditingController(); + final userPhoneController = TextEditingController(); + bool changed = true; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.black, + title: const Text('Plugin example app'), + ), + body: SingleChildScrollView( + child: Stack( + children: [ + Flex( + direction: Axis.vertical, + children: [ + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + child: TextField( + controller: clientIdController, + onChanged: (String text) { + setState(() { + clientId = clientIdController.text; + changed = true; + }); + }, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: + 'Enter the client id eg: hello or hello.stage', + ), + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + child: TextField( + controller: recipeIdController, + onChanged: (String text) { + setState(() { + recipeId = recipeIdController.text; + changed = true; + }); + }, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Enter the recipe ID', + ), + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + child: TextField( + controller: userIdController, + onChanged: (String text) { + setState(() { + userId = userIdController.text; + changed = true; + }); + }, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Enter the user Id', + ), + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + child: TextField( + controller: userNameController, + onChanged: (String text) { + setState(() { + userName = userNameController.text; + changed = true; + }); + }, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Enter the user name', + ), + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + child: TextField( + controller: userPhoneController, + onChanged: (String text) { + setState(() { + userPhone = userPhoneController.text; + changed = true; + }); + }, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Enter the user phone', + ), + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + child: TextField( + controller: userEmailController, + onChanged: (String text) { + setState(() { + userEmail = userEmailController.text; + changed = true; + }); + }, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Enter the user email', + ), + ), + ), + Text('Running for client $clientId'), + changed == false + ? const SizedBox() + : TextButton( + onPressed: () { + setState(() { + changed = false; + }); + }, + child: const Text("Submit")), + ], + ), + ], + ), + ), + floatingActionButton: changed == true + ? const SizedBox() + : VerloopWidget( + clientId: clientId, + // fcmToken: token, + // recipeId: recipeId, + // roomVariables: roomMap, + // userVariables: userMap, + // userId: userId, + // userName: userName, + // userEmail: userEmail, + // userPhone: userPhone, + onButtonClicked: + (String? title, String? payload, String? type) { + log("button click title $title $payload"); + if (payload != null) { + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute( + builder: (context) => HomeScreen( + title: title, + payload: payload, + type: type, + )), + (Route route) => route.isFirst); + } + + }, + onUrlClicked: (String? url) { + log("url clicked $url"); + if (url != null) { + // Pop Verloop and remove all routes until the initial route + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute( + builder: (context) => HomeScreen(title: url)), + (Route route) => route.isFirst); + } + }, + overrideUrlOnClick: true, + child: const FloatingActionButton( + onPressed: null, + child: Icon(Icons.chat), + ), + ) + // : FutureBuilder( + // // Initialize FlutterFire + // future: FirebaseMessaging.instance.getToken(), + // builder: (context, snapshot) { + // // Check for errors + // if (snapshot.hasError) { + // return const Text("Something went wrong"); + // } + // if (snapshot.hasData && snapshot.data != "") { + // String token = snapshot.data ?? ""; + // + // return VerloopWidget( + // clientId: clientId, + // fcmToken: token, + // recipeId: recipeId, + // roomVariables: roomMap, + // userVariables: userMap, + // userId: userId, + // userName: userName, + // userEmail: userEmail, + // userPhone: userPhone, + // onButtonClicked: + // (String? title, String? payload, String? type) { + // log("button click title $title $payload"); + // }, + // onUrlClicked: (String? url) { + // log("url clicked $url"); + // }, + // overrideUrlOnClick: true, + // child: const FloatingActionButton( + // onPressed: null, + // child: Icon(Icons.chat), + // ), + // ); + // } + // return const Text("Loading..."); + // }, + // ), + ); + } + + @override + void dispose() { + clientIdController.dispose(); + recipeIdController.dispose(); + super.dispose(); + } +} diff --git a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift index 345d62d..bf7214f 100644 --- a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift +++ b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift @@ -5,6 +5,8 @@ import VerloopSDKiOS public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDelegate { private var previousWindow: UIWindow? = nil private var window = UIWindow() + + private var viewController: UIViewController? private static var methodChannel = "verloop.flutter.dev/method-call" private static var buttonClickChannel = "verloop.flutter.dev/events/button-click" @@ -26,6 +28,7 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg let channel = FlutterMethodChannel(name: methodChannel, binaryMessenger: registrar.messenger()) let buttonChannel = FlutterEventChannel(name: buttonClickChannel, binaryMessenger: registrar.messenger()) let urlChannel = FlutterEventChannel(name: urlClickChannel, binaryMessenger: registrar.messenger()) + let instance = SwiftVerloopFlutterSdkPlugin() registrar.addMethodCallDelegate(instance, channel: channel) @@ -105,6 +108,9 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg } case "setButtonClickListener": config?.setButtonOnClickListener(onButtonClicked:{(title: String?, type: String?, payload: String?) in + self.viewController?.dismiss(animated: true, completion: { + self.viewController = nil // Clear the reference after dismissing + }) SwiftVerloopFlutterSdkPlugin.buttonHandler?.buttonClicked(title: title, type: type, payload: payload) return; }) @@ -117,6 +123,9 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg } } config?.setUrlClickListener(onUrlClicked:{(url: String?) in + self.viewController?.dismiss(animated: true, completion: { + self.viewController = nil // Clear the reference after dismissing + }) SwiftVerloopFlutterSdkPlugin.urlHandler?.urlClicked(url: url) return; }) @@ -148,14 +157,24 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg details: "call buildVerloop before calling showChat")) return } - previousWindow = UIApplication.shared.keyWindow - window.isOpaque = true -// window.backgroundColor = UIColor.white -// window.frame = UIScreen.main.bounds - - window.windowLevel = UIWindow.Level.normal + 1 - window.rootViewController = verloop!.getNavController() - window.makeKeyAndVisible() +// previousWindow = UIApplication.shared.keyWindow +// window.isOpaque = true +// window.windowLevel = UIWindow.Level.normal + 1 + //window.rootViewController = verloop!.getNavController() + //window.makeKeyAndVisible() +// if let topVC = UIApplication.shared.keyWindow?.rootViewController?.topMostViewController() { +// viewController = topVC +// viewController!.present(verloop!.getNavController(), animated: true, completion: nil) +// } + //viewController = UIApplication.shared.delegate!.window!!.rootViewController! + //viewController!.present(verloop!.getNavController(), animated: true, completion: nil) + //viewController(with: nil)?.present(verloop!.getNavController(), animated: true, completion: nil) + // Present the view controller + viewController = verloop!.getNavController() + if let rootVC = UIApplication.shared.delegate?.window??.rootViewController { + rootVC.present(viewController!, animated: true, completion: nil) + } + case "dispose": verloop = nil clientId = nil @@ -173,4 +192,37 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg previousWindow = nil window.windowLevel = UIWindow.Level.normal - 30 } + + func viewController(with window: UIWindow?) -> UIViewController? { + var windowToUse = window + if windowToUse == nil { + for window in UIApplication.shared.windows { + if window.isKeyWindow { + windowToUse = window + break + } + } + } + + var topController = windowToUse?.rootViewController + while ((topController?.presentedViewController) != nil) { + topController = topController?.presentedViewController + } + return topController + } + +} + +extension UIViewController { + func topMostViewController() -> UIViewController { + if let presentedVC = self.presentedViewController { + return presentedVC.topMostViewController() + } else if let navVC = self as? UINavigationController { + return navVC.visibleViewController?.topMostViewController() ?? self + } else if let tabVC = self as? UITabBarController { + return tabVC.selectedViewController?.topMostViewController() ?? self + } else { + return self + } + } } From dffad93d8164f294eabeecf5f568827a72919b33 Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Tue, 22 Oct 2024 17:45:40 +0530 Subject: [PATCH 3/9] Add DismissChat callback --- .../screens/login-screen/login_screen.dart | 21 ++++---- .../SwiftVerloopFlutterSdkPlugin.swift | 52 ++----------------- lib/verloop_flutter_sdk.dart | 5 ++ lib/verloop_flutter_sdk_method_channel.dart | 18 +++++-- ...erloop_flutter_sdk_platform_interface.dart | 5 ++ 5 files changed, 40 insertions(+), 61 deletions(-) diff --git a/example/lib/screens/login-screen/login_screen.dart b/example/lib/screens/login-screen/login_screen.dart index 9cc68f8..bfa8915 100644 --- a/example/lib/screens/login-screen/login_screen.dart +++ b/example/lib/screens/login-screen/login_screen.dart @@ -27,6 +27,8 @@ class _LoginScreenState extends State { final userEmailController = TextEditingController(); final userPhoneController = TextEditingController(); bool changed = true; + final VerloopSdk verloop = VerloopSdk(); + @override void initState() { @@ -179,21 +181,22 @@ class _LoginScreenState extends State { onButtonClicked: (String? title, String? payload, String? type) { log("button click title $title $payload"); + verloop.dismissChat(); if (payload != null) { - Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute( - builder: (context) => HomeScreen( - title: title, - payload: payload, - type: type, - )), - (Route route) => route.isFirst); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => HomeScreen( + title: title, + payload: payload, + type: type, + )), + ); } - }, onUrlClicked: (String? url) { log("url clicked $url"); if (url != null) { + verloop.dismissChat(); // Pop Verloop and remove all routes until the initial route Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( diff --git a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift index bf7214f..d264c77 100644 --- a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift +++ b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift @@ -108,9 +108,6 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg } case "setButtonClickListener": config?.setButtonOnClickListener(onButtonClicked:{(title: String?, type: String?, payload: String?) in - self.viewController?.dismiss(animated: true, completion: { - self.viewController = nil // Clear the reference after dismissing - }) SwiftVerloopFlutterSdkPlugin.buttonHandler?.buttonClicked(title: title, type: type, payload: payload) return; }) @@ -123,9 +120,6 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg } } config?.setUrlClickListener(onUrlClicked:{(url: String?) in - self.viewController?.dismiss(animated: true, completion: { - self.viewController = nil // Clear the reference after dismissing - }) SwiftVerloopFlutterSdkPlugin.urlHandler?.urlClicked(url: url) return; }) @@ -162,14 +156,6 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg // window.windowLevel = UIWindow.Level.normal + 1 //window.rootViewController = verloop!.getNavController() //window.makeKeyAndVisible() -// if let topVC = UIApplication.shared.keyWindow?.rootViewController?.topMostViewController() { -// viewController = topVC -// viewController!.present(verloop!.getNavController(), animated: true, completion: nil) -// } - //viewController = UIApplication.shared.delegate!.window!!.rootViewController! - //viewController!.present(verloop!.getNavController(), animated: true, completion: nil) - //viewController(with: nil)?.present(verloop!.getNavController(), animated: true, completion: nil) - // Present the view controller viewController = verloop!.getNavController() if let rootVC = UIApplication.shared.delegate?.window??.rootViewController { rootVC.present(viewController!, animated: true, completion: nil) @@ -182,6 +168,11 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg config?.setButtonOnClickListener(onButtonClicked: nil) config = nil return + + case "dismissChat": + self.viewController?.dismiss(animated: true, completion: { + self.viewController = nil // Clear the reference after dismissing + }) default: result(FlutterMethodNotImplemented) } @@ -192,37 +183,4 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg previousWindow = nil window.windowLevel = UIWindow.Level.normal - 30 } - - func viewController(with window: UIWindow?) -> UIViewController? { - var windowToUse = window - if windowToUse == nil { - for window in UIApplication.shared.windows { - if window.isKeyWindow { - windowToUse = window - break - } - } - } - - var topController = windowToUse?.rootViewController - while ((topController?.presentedViewController) != nil) { - topController = topController?.presentedViewController - } - return topController - } - -} - -extension UIViewController { - func topMostViewController() -> UIViewController { - if let presentedVC = self.presentedViewController { - return presentedVC.topMostViewController() - } else if let navVC = self as? UINavigationController { - return navVC.visibleViewController?.topMostViewController() ?? self - } else if let tabVC = self as? UITabBarController { - return tabVC.selectedViewController?.topMostViewController() ?? self - } else { - return self - } - } } diff --git a/lib/verloop_flutter_sdk.dart b/lib/verloop_flutter_sdk.dart index 4b613ea..5489de8 100644 --- a/lib/verloop_flutter_sdk.dart +++ b/lib/verloop_flutter_sdk.dart @@ -184,4 +184,9 @@ class VerloopSdk { Future dispose() async { return await VerloopFlutterSdkPlatform.instance.dispose(); } + + Future dismissChat() async { + return await VerloopFlutterSdkPlatform.instance.dismissChat(); + } + } diff --git a/lib/verloop_flutter_sdk_method_channel.dart b/lib/verloop_flutter_sdk_method_channel.dart index 7cc64b7..bd93a67 100644 --- a/lib/verloop_flutter_sdk_method_channel.dart +++ b/lib/verloop_flutter_sdk_method_channel.dart @@ -71,9 +71,9 @@ class MethodChannelVerloopFlutterSdk extends VerloopFlutterSdkPlatform { log("Failed to set url click listener: '${e.message}'."); } } - + @override - Future openMenuWidget() async { + Future openMenuWidget() async { try { await verloopMethods.invokeMethod('openMenuWidget'); } on PlatformException catch (e) { @@ -83,9 +83,8 @@ class MethodChannelVerloopFlutterSdk extends VerloopFlutterSdkPlatform { @override Future showDownloadButton({bool isAllowFileDownload = false}) async { - try { - await verloopMethods - .invokeMethod('showDownloadButton', { + try { + await verloopMethods.invokeMethod('showDownloadButton', { 'isAllowFileDownload': isAllowFileDownload, }); } on PlatformException catch (e) { @@ -141,4 +140,13 @@ class MethodChannelVerloopFlutterSdk extends VerloopFlutterSdkPlatform { log("Failed to dispose widget: '${e.message}'."); } } + + @override + Future dismissChat() async { + try { + await verloopMethods.invokeMethod('dismissChat'); + } on PlatformException catch (e) { + log("Failed to load widget: '${e.message}'."); + } + } } diff --git a/lib/verloop_flutter_sdk_platform_interface.dart b/lib/verloop_flutter_sdk_platform_interface.dart index 81d4ed6..d1da25f 100644 --- a/lib/verloop_flutter_sdk_platform_interface.dart +++ b/lib/verloop_flutter_sdk_platform_interface.dart @@ -77,4 +77,9 @@ abstract class VerloopFlutterSdkPlatform extends PlatformInterface { Future dispose() async { throw UnimplementedError('dispose() has not been implemented.'); } + + Future dismissChat() async { + throw UnimplementedError('dismissChat() has not been implemented.'); + } + } From 6911caad644a02151a967cfec9573f4c7bce755a Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Wed, 23 Oct 2024 09:50:19 +0530 Subject: [PATCH 4/9] - Updated Firebase --- .../plugins/GeneratedPluginRegistrant.java | 11 +++ example/lib/main.dart | 13 ++- .../screens/login-screen/login_screen.dart | 89 +++++++------------ 3 files changed, 54 insertions(+), 59 deletions(-) diff --git a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 60d9831..95bd2cc 100644 --- a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -15,6 +15,17 @@ public final class GeneratedPluginRegistrant { private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e); + } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin firebase_messaging, io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin", e); + } + try { flutterEngine.getPlugins().add(new io.verloop.verloop_flutter_sdk.VerloopFlutterSdkPlugin()); } catch (Exception e) { diff --git a/example/lib/main.dart b/example/lib/main.dart index 8f63ca7..c64b1c9 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,17 +1,22 @@ +import 'dart:developer'; +import 'dart:ffi'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:verloop_flutter_sdk_example/screens/login-screen/login_screen.dart'; +import 'firebase_options.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - // await Firebase.initializeApp( - // // options: DefaultFirebaseOptions.currentPlatform, - // ); + await Firebase.initializeApp( + // options: DefaultFirebaseOptions.currentPlatform, + ); runApp(const MyApp()); } class MyApp extends StatelessWidget { - const MyApp({super.key}); + const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/example/lib/screens/login-screen/login_screen.dart b/example/lib/screens/login-screen/login_screen.dart index bfa8915..bdd8108 100644 --- a/example/lib/screens/login-screen/login_screen.dart +++ b/example/lib/screens/login-screen/login_screen.dart @@ -3,6 +3,8 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:verloop_flutter_sdk/verloop_flutter_sdk.dart'; import 'package:verloop_flutter_sdk_example/screens/home_screen.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @@ -168,17 +170,28 @@ class _LoginScreenState extends State { ), floatingActionButton: changed == true ? const SizedBox() - : VerloopWidget( - clientId: clientId, - // fcmToken: token, - // recipeId: recipeId, - // roomVariables: roomMap, - // userVariables: userMap, - // userId: userId, - // userName: userName, - // userEmail: userEmail, - // userPhone: userPhone, - onButtonClicked: + : FutureBuilder( + // Initialize FlutterFire + future: FirebaseMessaging.instance.getToken(), + builder: (context, snapshot) { + // Check for errors + if (snapshot.hasError) { + return const Text("Something went wrong"); + } + if (snapshot.hasData && snapshot.data != "") { + String token = snapshot.data ?? ""; + + return VerloopWidget( + clientId: clientId, + fcmToken: token, + recipeId: recipeId, + roomVariables: roomMap, + userVariables: userMap, + userId: userId, + userName: userName, + userEmail: userEmail, + userPhone: userPhone, + onButtonClicked: (String? title, String? payload, String? type) { log("button click title $title $payload"); verloop.dismissChat(); @@ -204,50 +217,16 @@ class _LoginScreenState extends State { (Route route) => route.isFirst); } }, - overrideUrlOnClick: true, - child: const FloatingActionButton( - onPressed: null, - child: Icon(Icons.chat), - ), - ) - // : FutureBuilder( - // // Initialize FlutterFire - // future: FirebaseMessaging.instance.getToken(), - // builder: (context, snapshot) { - // // Check for errors - // if (snapshot.hasError) { - // return const Text("Something went wrong"); - // } - // if (snapshot.hasData && snapshot.data != "") { - // String token = snapshot.data ?? ""; - // - // return VerloopWidget( - // clientId: clientId, - // fcmToken: token, - // recipeId: recipeId, - // roomVariables: roomMap, - // userVariables: userMap, - // userId: userId, - // userName: userName, - // userEmail: userEmail, - // userPhone: userPhone, - // onButtonClicked: - // (String? title, String? payload, String? type) { - // log("button click title $title $payload"); - // }, - // onUrlClicked: (String? url) { - // log("url clicked $url"); - // }, - // overrideUrlOnClick: true, - // child: const FloatingActionButton( - // onPressed: null, - // child: Icon(Icons.chat), - // ), - // ); - // } - // return const Text("Loading..."); - // }, - // ), + overrideUrlOnClick: true, + child: const FloatingActionButton( + onPressed: null, + child: Icon(Icons.chat), + ), + ); + } + return const Text("Loading..."); + }, + ), ); } From e06bc7f2f3d80448a76bc2d3299047f11de6f8fd Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Wed, 23 Oct 2024 09:52:53 +0530 Subject: [PATCH 5/9] firebase files updated --- .../io/flutter/plugins/GeneratedPluginRegistrant.java | 11 ----------- example/lib/main.dart | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 95bd2cc..60d9831 100644 --- a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -15,17 +15,6 @@ public final class GeneratedPluginRegistrant { private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { - try { - flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin()); - } catch (Exception e) { - Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e); - } - try { - flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin()); - } catch (Exception e) { - Log.e(TAG, "Error registering plugin firebase_messaging, io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin", e); - } - try { flutterEngine.getPlugins().add(new io.verloop.verloop_flutter_sdk.VerloopFlutterSdkPlugin()); } catch (Exception e) { diff --git a/example/lib/main.dart b/example/lib/main.dart index c64b1c9..ab80b78 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -10,7 +10,7 @@ void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( - // options: DefaultFirebaseOptions.currentPlatform, + options: DefaultFirebaseOptions.currentPlatform, ); runApp(const MyApp()); } From 82be39f8278e4800708e978afc1d1ca675e7083d Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Wed, 23 Oct 2024 10:06:58 +0530 Subject: [PATCH 6/9] Firebase init --- .vscode/settings.json | 3 + .../plugins/GeneratedPluginRegistrant.java | 10 +++ example/firebase.json | 1 + example/ios/Runner.xcodeproj/project.pbxproj | 4 ++ example/ios/Runner/GoogleService-Info.plist | 30 ++++++++ example/lib/main.dart | 3 +- .../screens/login-screen/login_screen.dart | 4 +- example/pubspec.lock | 68 ++++++++++++++++++- example/pubspec.yaml | 2 + 9 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 example/firebase.json create mode 100644 example/ios/Runner/GoogleService-Info.plist diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..385f27a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} diff --git a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 60d9831..a82bb02 100644 --- a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -15,6 +15,16 @@ public final class GeneratedPluginRegistrant { private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e); + } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin firebase_messaging, io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin", e); + } try { flutterEngine.getPlugins().add(new io.verloop.verloop_flutter_sdk.VerloopFlutterSdkPlugin()); } catch (Exception e) { diff --git a/example/firebase.json b/example/firebase.json new file mode 100644 index 0000000..2eda079 --- /dev/null +++ b/example/firebase.json @@ -0,0 +1 @@ +{"flutter":{"platforms":{"android":{"default":{"projectId":"my-verloop-test","appId":"1:1049556476892:android:3ef483bef07eaa623fe519","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"my-verloop-test","appId":"1:1049556476892:ios:35c079ea09c2762c3fe519","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"my-verloop-test","configurations":{"android":"1:1049556476892:android:3ef483bef07eaa623fe519","ios":"1:1049556476892:ios:35c079ea09c2762c3fe519","web":"1:1049556476892:web:b256cbf7e31b45da3fe519"}}}}}} \ No newline at end of file diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 451d9b9..9ff7ae7 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + CFB86FA7F1E23C7400773CF2 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3C12750059E0DAF337671250 /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -34,6 +35,7 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 26E955E17FBB789930D87DCE /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3C12750059E0DAF337671250 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 5921071C758174D1AA451058 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -99,6 +101,7 @@ 97C146EF1CF9000F007C117D /* Products */, 01CB55533E4F801C6CE483D4 /* Pods */, 06A055ECF0156BD2FDCF837A /* Frameworks */, + 3C12750059E0DAF337671250 /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -193,6 +196,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + CFB86FA7F1E23C7400773CF2 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/example/ios/Runner/GoogleService-Info.plist b/example/ios/Runner/GoogleService-Info.plist new file mode 100644 index 0000000..c8f370a --- /dev/null +++ b/example/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyCV1IQbJP1K6VC2_w3NKNgB6FHGOo5sa28 + GCM_SENDER_ID + 1049556476892 + PLIST_VERSION + 1 + BUNDLE_ID + io.verloop.verloopFlutterSdkExample + PROJECT_ID + my-verloop-test + STORAGE_BUCKET + my-verloop-test.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:1049556476892:ios:35c079ea09c2762c3fe519 + + \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index ab80b78..6aff43d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,7 +1,7 @@ import 'dart:developer'; import 'dart:ffi'; import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; +//import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:verloop_flutter_sdk_example/screens/login-screen/login_screen.dart'; import 'firebase_options.dart'; @@ -22,6 +22,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(useMaterial3: true), + debugShowCheckedModeBanner: true, home: const LoginScreen(), ); diff --git a/example/lib/screens/login-screen/login_screen.dart b/example/lib/screens/login-screen/login_screen.dart index bdd8108..1392db3 100644 --- a/example/lib/screens/login-screen/login_screen.dart +++ b/example/lib/screens/login-screen/login_screen.dart @@ -3,8 +3,8 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:verloop_flutter_sdk/verloop_flutter_sdk.dart'; import 'package:verloop_flutter_sdk_example/screens/home_screen.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; +// ignore: depend_on_referenced_packages + import 'package:firebase_messaging/firebase_messaging.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); diff --git a/example/pubspec.lock b/example/pubspec.lock index 5d03f0e..5d2fbc3 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2" + url: "https://pub.dev" + source: hosted + version: "1.3.44" async: dependency: transitive description: @@ -57,6 +65,54 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96" + url: "https://pub.dev" + source: hosted + version: "3.6.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810 + url: "https://pub.dev" + source: hosted + version: "5.3.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 + url: "https://pub.dev" + source: hosted + version: "2.18.1" + firebase_messaging: + dependency: "direct main" + description: + name: firebase_messaging + sha256: eb6e28a3a35deda61fe8634967c84215efc19133ba58d8e0fc6c9a2af2cba05e + url: "https://pub.dev" + source: hosted + version: "15.1.3" + firebase_messaging_platform_interface: + dependency: transitive + description: + name: firebase_messaging_platform_interface + sha256: b316c4ee10d93d32c033644207afc282d9b2b4372f3cf9c6022f3558b3873d2d + url: "https://pub.dev" + source: hosted + version: "4.5.46" + firebase_messaging_web: + dependency: transitive + description: + name: firebase_messaging_web + sha256: d7f0147a1a9fe4313168e20154a01fd5cf332898de1527d3930ff77b8c7f5387 + url: "https://pub.dev" + source: hosted + version: "3.9.2" flutter: dependency: "direct main" description: flutter @@ -228,6 +284,14 @@ packages: url: "https://pub.dev" source: hosted version: "14.2.5" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.22.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index af321df..e67e1ca 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -29,6 +29,8 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + firebase_core: ^3.6.0 + firebase_messaging: ^15.1.3 #firebase_messaging: ^14.8.0 #firebase_core: ^2.28.0 From 650aa062a06484785e59c2fff06287edc57b4ccd Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Wed, 23 Oct 2024 18:15:54 +0530 Subject: [PATCH 7/9] Android method channel updated --- android/build.gradle | 2 +- .../VerloopFlutterSdkPlugin.kt | 28 ++++++ example/android/gradlew | 0 example/ios/Podfile | 2 +- example/ios/Podfile.lock | 93 ++++++++++++++++++- example/ios/Runner.xcodeproj/project.pbxproj | 18 ++++ example/lib/main.dart | 2 +- .../screens/login-screen/login_screen.dart | 37 ++++---- .../SwiftVerloopFlutterSdkPlugin.swift | 2 +- 9 files changed, 162 insertions(+), 22 deletions(-) mode change 100644 => 100755 example/android/gradlew diff --git a/android/build.gradle b/android/build.gradle index 102519a..0c1dd25 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -48,5 +48,5 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.github.verloop:android-sdk:1.1.14' + implementation 'com.github.verloop:android-sdk:1.1.15' } diff --git a/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt b/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt index b4ddd9b..b45beef 100644 --- a/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt +++ b/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt @@ -234,6 +234,28 @@ class VerloopFlutterSdkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware result.success(1) return } + "showDownloadButton" -> { + val args = call.arguments as? Map + if (args != null) { + val isAllowFileDownload = args["isAllowFileDownload"] as? Boolean + if (isAllowFileDownload != null) { + if (configBuilder != null) { + configBuilder = + configBuilder!!.allowFileDownload(isAllowFileDownload) + } + } + } + result.success(1) + return + } + "openMenuWidget" -> { + if (configBuilder != null) { + configBuilder = + configBuilder!!.openMenuWidgetOnStart(true) + } + result.success(1) + return + } "buildVerloop" -> { if (configBuilder == null) { configBuilder = VerloopConfig.Builder() @@ -276,6 +298,12 @@ class VerloopFlutterSdkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware return } verloop!!.showChat() + + result.success(1) + return + } + "dismissChat" -> { + activity.finish() // Dismiss the activity result.success(1) return } diff --git a/example/android/gradlew b/example/android/gradlew old mode 100644 new mode 100755 diff --git a/example/ios/Podfile b/example/ios/Podfile index eb8b0f9..728c145 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # 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. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 80a3d53..7e63457 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,29 +1,120 @@ PODS: + - Firebase/CoreOnly (11.2.0): + - FirebaseCore (= 11.2.0) + - Firebase/Messaging (11.2.0): + - Firebase/CoreOnly + - FirebaseMessaging (~> 11.2.0) + - firebase_core (3.6.0): + - Firebase/CoreOnly (= 11.2.0) + - Flutter + - firebase_messaging (15.1.3): + - Firebase/Messaging (= 11.2.0) + - firebase_core + - Flutter + - FirebaseCore (11.2.0): + - FirebaseCoreInternal (~> 11.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/Logger (~> 8.0) + - FirebaseCoreInternal (11.4.0): + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - FirebaseInstallations (11.4.0): + - FirebaseCore (~> 11.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - FirebaseMessaging (11.2.0): + - FirebaseCore (~> 11.0) + - FirebaseInstallations (~> 11.0) + - GoogleDataTransport (~> 10.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/Reachability (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - nanopb (~> 3.30910.0) - Flutter (1.0.0) + - GoogleDataTransport (10.1.0): + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - GoogleUtilities/AppDelegateSwizzler (8.0.2): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.0.2): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.0.2): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.0.2): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.0.2)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.0.2) + - GoogleUtilities/Reachability (8.0.2): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.0.2): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) - verloop_flutter_sdk (0.0.4): - Flutter - VerloopSDKiOS (= 0.2.13) - VerloopSDKiOS (0.2.13) DEPENDENCIES: + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) - verloop_flutter_sdk (from `.symlinks/plugins/verloop_flutter_sdk/ios`) SPEC REPOS: trunk: + - Firebase + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseMessaging + - GoogleDataTransport + - GoogleUtilities + - nanopb + - PromisesObjC - VerloopSDKiOS EXTERNAL SOURCES: + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" + firebase_messaging: + :path: ".symlinks/plugins/firebase_messaging/ios" Flutter: :path: Flutter verloop_flutter_sdk: :path: ".symlinks/plugins/verloop_flutter_sdk/ios" SPEC CHECKSUMS: + Firebase: 98e6bf5278170668a7983e12971a66b2cd57fc8c + firebase_core: 2bedc3136ec7c7b8561c6123ed0239387b53f2af + firebase_messaging: 15d114e1a41fc31e4fbabcd48d765a19eec94a38 + FirebaseCore: a282032ae9295c795714ded2ec9c522fc237f8da + FirebaseCoreInternal: 5c2b016f06a96fbf20d9b443459f80427a827d7b + FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414 + FirebaseMessaging: c9ec7b90c399c7a6100297e9d16f8a27fc7f7152 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 + GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 verloop_flutter_sdk: ff3eb6eac5a66f821da75fe6151d25e0006d2f19 VerloopSDKiOS: 264442f5a14053eb354335debd536278d27762ac -PODFILE CHECKSUM: ce13d36744da294d67f8e460dbb7aed7c09bd7f4 +PODFILE CHECKSUM: 30517025a2fecca2d72dac25f08abb5b9a8f1a56 COCOAPODS: 1.15.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 9ff7ae7..706b404 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -144,6 +144,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 9FCC63B39E4B04B6BD3E9AC5 /* [CP] Embed Pods Frameworks */, + 86DB66AE6B389BD5D0912729 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -241,6 +242,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 86DB66AE6B389BD5D0912729 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; diff --git a/example/lib/main.dart b/example/lib/main.dart index 6aff43d..94421a2 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,7 +16,7 @@ void main() async { } class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({super.key}); @override Widget build(BuildContext context) { diff --git a/example/lib/screens/login-screen/login_screen.dart b/example/lib/screens/login-screen/login_screen.dart index 1392db3..0635d5f 100644 --- a/example/lib/screens/login-screen/login_screen.dart +++ b/example/lib/screens/login-screen/login_screen.dart @@ -191,31 +191,34 @@ class _LoginScreenState extends State { userName: userName, userEmail: userEmail, userPhone: userPhone, - onButtonClicked: + showDownloadButton: true, + openMenuWidget:true, + onButtonClicked: (String? title, String? payload, String? type) { log("button click title $title $payload"); verloop.dismissChat(); if (payload != null) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => HomeScreen( - title: title, - payload: payload, - type: type, - )), - ); - } + // verloop.dismissChat(); + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute( + builder: (context) => HomeScreen( + title: title, + payload: payload, + type: type, + )), + (Route route) => route.isFirst); + } }, onUrlClicked: (String? url) { log("url clicked $url"); if (url != null) { - verloop.dismissChat(); - // Pop Verloop and remove all routes until the initial route - Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute( - builder: (context) => HomeScreen(title: url)), - (Route route) => route.isFirst); - } + //verloop.dismissChat(); + // Pop Verloop and remove all routes until the initial route + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute( + builder: (context) => HomeScreen(title: url)), + (Route route) => route.isFirst); + } }, overrideUrlOnClick: true, child: const FloatingActionButton( diff --git a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift index d264c77..d1760a1 100644 --- a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift +++ b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift @@ -133,7 +133,7 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg } result(1) case "openMenuWidget": - config?.openMenuWidget() + config?.openMenuWidget() result(1) case "buildVerloop": if config == nil { From 571e125f7abf24cb218e449d78cd0c398a67b8d8 Mon Sep 17 00:00:00 2001 From: Raghav Rawat Date: Sun, 27 Oct 2024 23:18:06 +0530 Subject: [PATCH 8/9] Updated the android functionality with broadcast emitters for closing the verloop widget --- android/build.gradle | 2 +- .../VerloopFlutterSdkPlugin.kt | 9 +-- .../screens/login-screen/login_screen.dart | 55 ++++++++++--------- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 0c1dd25..50d581e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -48,5 +48,5 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.github.verloop:android-sdk:1.1.15' + implementation 'com.github.verloop:android-sdk:1.1.16-rc.3' } diff --git a/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt b/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt index b45beef..252a520 100644 --- a/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt +++ b/android/src/main/kotlin/io/verloop/verloop_flutter_sdk/VerloopFlutterSdkPlugin.kt @@ -1,8 +1,7 @@ package io.verloop.verloop_flutter_sdk import android.app.Activity -import android.util.Log -import android.view.inputmethod.InputBinding +import android.content.Intent import androidx.annotation.NonNull import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware @@ -11,11 +10,12 @@ import io.flutter.plugin.common.EventChannel import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import io.flutter.plugin.common.MethodChannel.Result import io.verloop.sdk.LiveChatButtonClickListener import io.verloop.sdk.LiveChatUrlClickListener import io.verloop.sdk.Verloop import io.verloop.sdk.VerloopConfig +import io.verloop.sdk.ui.Constants + /** VerloopFlutterSdkPlugin */ class VerloopFlutterSdkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { @@ -303,7 +303,8 @@ class VerloopFlutterSdkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware return } "dismissChat" -> { - activity.finish() // Dismiss the activity + val intent = Intent(Constants.ACTION_CLOSE_VERLOOP_WIDGET) + activity.sendBroadcast(intent) result.success(1) return } diff --git a/example/lib/screens/login-screen/login_screen.dart b/example/lib/screens/login-screen/login_screen.dart index 0635d5f..d559349 100644 --- a/example/lib/screens/login-screen/login_screen.dart +++ b/example/lib/screens/login-screen/login_screen.dart @@ -193,33 +193,8 @@ class _LoginScreenState extends State { userPhone: userPhone, showDownloadButton: true, openMenuWidget:true, - onButtonClicked: - (String? title, String? payload, String? type) { - log("button click title $title $payload"); - verloop.dismissChat(); - if (payload != null) { - // verloop.dismissChat(); - Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute( - builder: (context) => HomeScreen( - title: title, - payload: payload, - type: type, - )), - (Route route) => route.isFirst); - } - }, - onUrlClicked: (String? url) { - log("url clicked $url"); - if (url != null) { - //verloop.dismissChat(); - // Pop Verloop and remove all routes until the initial route - Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute( - builder: (context) => HomeScreen(title: url)), - (Route route) => route.isFirst); - } - }, + onButtonClicked:_handleButtonClick, + onUrlClicked: _handleUrlClick, overrideUrlOnClick: true, child: const FloatingActionButton( onPressed: null, @@ -233,6 +208,32 @@ class _LoginScreenState extends State { ); } + void _handleButtonClick(String? title, String? payload, String? type) async { + log("button click title $title $payload"); + if (payload != null) { + verloop.dismissChat(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => HomeScreen( + title: title, + payload: payload, + type: type, + )), + ); + } + } + + void _handleUrlClick(String? url) { + log("url clicked $url"); + if (url != null) { + //verloop.dismissChat(); + // Pop Verloop and remove all routes until the initial route + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => HomeScreen(title: url)), + (Route route) => route.isFirst); + } + } + @override void dispose() { clientIdController.dispose(); From 44a77af204391bceb7a06812ad20b28604362196 Mon Sep 17 00:00:00 2001 From: Pankaj Patel Date: Mon, 28 Oct 2024 09:40:32 +0530 Subject: [PATCH 9/9] Firebase Init Enable --- example/ios/Runner.xcodeproj/project.pbxproj | 7 ++++-- example/lib/main.dart | 2 -- .../SwiftVerloopFlutterSdkPlugin.swift | 23 ++++++++++--------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 706b404..f872d17 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -516,7 +516,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = 4; - DEVELOPMENT_TEAM = 5423774D8G; + DEVELOPMENT_TEAM = R5ANF7UMFA; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -541,8 +541,10 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; - DEVELOPMENT_TEAM = 5423774D8G; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -552,6 +554,7 @@ MARKETING_VERSION = 1.0.3; PRODUCT_BUNDLE_IDENTIFIER = io.verloop.verloopFlutterSdkExample; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/example/lib/main.dart b/example/lib/main.dart index 94421a2..35ed30c 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; -import 'dart:ffi'; import 'package:firebase_core/firebase_core.dart'; //import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; diff --git a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift index d1760a1..46b7572 100644 --- a/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift +++ b/ios/Classes/SwiftVerloopFlutterSdkPlugin.swift @@ -42,7 +42,7 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg switch call.method { case "setConfig": if let args = call.arguments as? Dictionary { - var clientId = args["CLIENT_ID"] as? String + let clientId = args["CLIENT_ID"] as? String if clientId == nil || clientId == "" { result(FlutterError.init(code: SwiftVerloopFlutterSdkPlugin.ERROR_102, message: "CLIENT_ID missing", @@ -51,49 +51,49 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg } config = VLConfig(clientId: clientId!) - var userId = args["USER_ID"] as? String + let userId = args["USER_ID"] as? String if userId != nil && userId != "" { config?.setUserId(userId: userId!) } - var fcmToken = args["FCM_TOKEN"] as? String + let fcmToken = args["FCM_TOKEN"] as? String if fcmToken != nil && fcmToken != "" { config?.setNotificationToken(notificationToken: fcmToken!) // If you wish to get notifications, else, skip this } - var recipeId = args["RECIPE_ID"] as? String + let recipeId = args["RECIPE_ID"] as? String if recipeId != nil && recipeId != "" { config?.setRecipeId(recipeId: recipeId!) // In case you want to use default recipe, skip this } - var userName = args["USER_NAME"] as? String + let userName = args["USER_NAME"] as? String if userName != nil && userName != "" { config?.setUserName(userName: userName!) // If guest name variable is a part of the recipe, or the value is not required, skip this } - var userEmail = args["USER_EMAIL"] as? String + let userEmail = args["USER_EMAIL"] as? String if userEmail != nil && userEmail != "" { config?.setUserEmail(userEmail: userEmail!) // If email variable is a part of the recipe, or the value is not required, skip this } - var userPhone = args["USER_PHONE"] as? String + let userPhone = args["USER_PHONE"] as? String if userPhone != nil && userPhone != "" { config?.setUserPhone(userPhone: userPhone!) // If phone variable is a part of the recipe, or the value is not required, skip this } - var isStaging = args["IS_STAGING"] as? Bool + let isStaging = args["IS_STAGING"] as? Bool if isStaging != nil { config?.setStaging(isStaging: isStaging!) // Keep this as true if you want to access .stage.verloop.io account. If the account doesn't exist, keep it as false or skip it } - var customFields = args["ROOM_CUSTOM_FIELDS"] as? Dictionary // These are predefined variables added on room level + let customFields = args["ROOM_CUSTOM_FIELDS"] as? Dictionary // These are predefined variables added on room level if customFields != nil { for (key, value) in customFields! { config?.putCustomField(key: key, value: value, scope: VLConfig.SCOPE.ROOM) } } - var userCustomFields = args["USER_CUSTOM_FIELDS"] as? Dictionary // These are predefined variables added on user level + let userCustomFields = args["USER_CUSTOM_FIELDS"] as? Dictionary // These are predefined variables added on user level if userCustomFields != nil { for (key, value) in userCustomFields! { config?.putCustomField(key: key, value: value, scope: VLConfig.SCOPE.USER) @@ -160,7 +160,7 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg if let rootVC = UIApplication.shared.delegate?.window??.rootViewController { rootVC.present(viewController!, animated: true, completion: nil) } - + result(1) case "dispose": verloop = nil clientId = nil @@ -173,6 +173,7 @@ public class SwiftVerloopFlutterSdkPlugin: NSObject, FlutterPlugin, VLEventDeleg self.viewController?.dismiss(animated: true, completion: { self.viewController = nil // Clear the reference after dismissing }) + result(1) default: result(FlutterMethodNotImplemented) }