From e07ba2a6759b817f683898d1395551ad06eaf7be Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Mon, 25 Apr 2022 17:39:04 +0200 Subject: [PATCH] fix #1152 --- CHANGELOG.md | 4 + .../ActionBroadcastReceiver.java | 2 +- .../ChromeCustomTabsActivity.java | 53 ++++++--- .../ChromeSafariBrowserManager.java | 15 ++- .../TrustedWebActivity.java | 4 +- .../types/CustomTabsActionButton.java | 104 ++++++++++++++++++ .../types/CustomTabsMenuItem.java | 72 ++++++++++++ .../webview_flutter_test.dart | 52 ++++++++- .../chrome_safari_browser_example.screen.dart | 17 ++- example/lib/in_app_webiew_example.screen.dart | 14 +++ .../chrome_safari_browser.dart | 68 +++++++++++- lib/src/types.dart | 1 - 12 files changed, 376 insertions(+), 30 deletions(-) create mode 100644 android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsActionButton.java create mode 100644 android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsMenuItem.java diff --git a/CHANGELOG.md b/CHANGELOG.md index ce0db971..624ee67c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.4.2 + +- Added `setActionButton` method to `ChromeSafariBrowser` class + ## 5.4.1+2 - Fixed "Android ServiceWorkerControllerCompat.setServiceWorkerClient(null) makes Webivew Plugin Crashes" [#1151](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1151) diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java index f51d857c..1d3bb700 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java @@ -34,7 +34,7 @@ public class ActionBroadcastReceiver extends BroadcastReceiver { obj.put("url", url); obj.put("title", title); obj.put("id", id); - channel.invokeMethod("onChromeSafariBrowserMenuItemActionPerform", obj); + channel.invokeMethod("onChromeSafariBrowserItemActionPerform", obj); } } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java index 1bfe3105..e62072b7 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java @@ -3,12 +3,14 @@ package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs; import android.app.Activity; import android.app.PendingIntent; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.util.Log; +import androidx.annotation.Nullable; import androidx.browser.customtabs.CustomTabColorSchemeParams; import androidx.browser.customtabs.CustomTabsCallback; import androidx.browser.customtabs.CustomTabsIntent; @@ -16,7 +18,10 @@ import androidx.browser.customtabs.CustomTabsService; import androidx.browser.customtabs.CustomTabsSession; import com.pichillilorenzo.flutter_inappwebview.R; +import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsActionButton; +import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsMenuItem; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +42,10 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. protected boolean onChromeSafariBrowserOpened = false; protected boolean onChromeSafariBrowserCompletedInitialLoad = false; public ChromeSafariBrowserManager manager; + public String initialUrl; + public List menuItems = new ArrayList<>(); + @Nullable + public CustomTabsActionButton actionButton; @Override protected void onCreate(Bundle savedInstanceState) { @@ -55,20 +64,23 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. channel = new MethodChannel(manager.plugin.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + id); channel.setMethodCallHandler(this); - final String url = b.getString("url"); + initialUrl = b.getString("url"); options = new ChromeCustomTabsOptions(); - options.parse((HashMap) b.getSerializable("options")); - - final List> menuItemList = (List>) b.getSerializable("menuItemList"); - + options.parse((Map) b.getSerializable("options")); + actionButton = CustomTabsActionButton.fromMap((Map) b.getSerializable("actionButton")); + List> menuItemList = (List>) b.getSerializable("menuItemList"); + for (Map menuItem : menuItemList) { + menuItems.add(CustomTabsMenuItem.fromMap(menuItem)); + } + final ChromeCustomTabsActivity chromeCustomTabsActivity = this; customTabActivityHelper = new CustomTabActivityHelper(); customTabActivityHelper.setConnectionCallback(new CustomTabActivityHelper.ConnectionCallback() { @Override public void onCustomTabsConnected() { - customTabsConnected(url, menuItemList); + customTabsConnected(); } @Override @@ -140,13 +152,13 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. } } - public void customTabsConnected (String url, List> menuItemList) { + public void customTabsConnected() { customTabsSession = customTabActivityHelper.getSession(); - Uri uri = Uri.parse(url); + Uri uri = Uri.parse(initialUrl); customTabActivityHelper.mayLaunchUrl(uri, null, null); builder = new CustomTabsIntent.Builder(customTabsSession); - prepareCustomTabs(menuItemList); + prepareCustomTabs(); CustomTabsIntent customTabsIntent = builder.build(); prepareCustomTabsIntent(customTabsIntent); @@ -154,7 +166,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. CustomTabActivityHelper.openCustomTab(this, customTabsIntent, uri, CHROME_CUSTOM_TAB_REQUEST_CODE); } - private void prepareCustomTabs(List> menuItemList) { + private void prepareCustomTabs() { if (options.addDefaultShareMenuItem != null) { builder.setShareState(options.addDefaultShareMenuItem ? CustomTabsIntent.SHARE_STATE_ON : CustomTabsIntent.SHARE_STATE_OFF); @@ -173,10 +185,21 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel. builder.setUrlBarHidingEnabled(options.enableUrlBarHiding); builder.setInstantAppsEnabled(options.instantAppsEnabled); - for (HashMap menuItem : menuItemList) { - int id = (int) menuItem.get("id"); - String label = (String) menuItem.get("label"); - builder.addMenuItem(label, createPendingIntent(id)); + for (CustomTabsMenuItem menuItem : menuItems) { + builder.addMenuItem(menuItem.getLabel(), + createPendingIntent(menuItem.getId())); + } + + if (actionButton != null) { + byte[] data = actionButton.getIcon(); + BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); + bitmapOptions.inMutable = true; + Bitmap bmp = BitmapFactory.decodeByteArray( + data, 0, data.length, bitmapOptions + ); + builder.setActionButton(bmp, actionButton.getDescription(), + createPendingIntent(actionButton.getId()), + actionButton.isShouldTint()); } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java index ec06f5e9..0516e86c 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java @@ -41,15 +41,22 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl switch (call.method) { case "open": - { + if (plugin != null) { String url = (String) call.argument("url"); HashMap options = (HashMap) call.argument("options"); + HashMap actionButton = (HashMap) call.argument("actionButton"); List> menuItemList = (List>) call.argument("menuItemList"); - open(plugin.activity, id, url, options, menuItemList, result); + open(plugin.activity, id, url, options, actionButton, menuItemList, result); + } else { + result.success(false); } break; case "isAvailable": - result.success(CustomTabActivityHelper.isAvailable(plugin.activity)); + if (plugin != null) { + result.success(CustomTabActivityHelper.isAvailable(plugin.activity)); + } else { + result.success(false); + } break; default: result.notImplemented(); @@ -57,6 +64,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl } public void open(Activity activity, String id, String url, HashMap options, + HashMap actionButton, List> menuItemList, MethodChannel.Result result) { Intent intent = null; @@ -66,6 +74,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl extras.putString("id", id); extras.putString("managerId", this.id); extras.putSerializable("options", options); + extras.putSerializable("actionButton", (Serializable) actionButton); extras.putSerializable("menuItemList", (Serializable) menuItemList); Boolean isSingleInstance = (Boolean) Util.getOrDefault(options, "isSingleInstance", false); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/TrustedWebActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/TrustedWebActivity.java index 16c656f6..113b6d92 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/TrustedWebActivity.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/TrustedWebActivity.java @@ -18,9 +18,9 @@ public class TrustedWebActivity extends ChromeCustomTabsActivity { public TrustedWebActivityIntentBuilder builder; @Override - public void customTabsConnected (String url, List> menuItemList) { + public void customTabsConnected() { customTabsSession = customTabActivityHelper.getSession(); - Uri uri = Uri.parse(url); + Uri uri = Uri.parse(initialUrl); customTabActivityHelper.mayLaunchUrl(uri, null, null); builder = new TrustedWebActivityIntentBuilder(uri); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsActionButton.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsActionButton.java new file mode 100644 index 00000000..b95b764c --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsActionButton.java @@ -0,0 +1,104 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Arrays; +import java.util.Map; + +public class CustomTabsActionButton { + private int id; + + @NonNull + private byte[] icon; + + @NonNull + private String description; + + private boolean shouldTint; + + public CustomTabsActionButton(int id, @NonNull byte[] icon, @NonNull String description, boolean shouldTint) { + this.id = id; + this.icon = icon; + this.description = description; + this.shouldTint = shouldTint; + } + + @Nullable + public static CustomTabsActionButton fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + int id = (int) map.get("id"); + byte[] icon = (byte[]) map.get("icon"); + String description = (String) map.get("description"); + boolean shouldTint = (boolean) map.get("shouldTint"); + return new CustomTabsActionButton(id, icon, description, shouldTint); + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @NonNull + public byte[] getIcon() { + return icon; + } + + public void setIcon(@NonNull byte[] icon) { + this.icon = icon; + } + + @NonNull + public String getDescription() { + return description; + } + + public void setDescription(@NonNull String description) { + this.description = description; + } + + public boolean isShouldTint() { + return shouldTint; + } + + public void setShouldTint(boolean shouldTint) { + this.shouldTint = shouldTint; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CustomTabsActionButton that = (CustomTabsActionButton) o; + + if (id != that.id) return false; + if (shouldTint != that.shouldTint) return false; + if (!Arrays.equals(icon, that.icon)) return false; + return description.equals(that.description); + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + Arrays.hashCode(icon); + result = 31 * result + description.hashCode(); + result = 31 * result + (shouldTint ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "CustomTabsActionButton{" + + "id=" + id + + ", icon=" + Arrays.toString(icon) + + ", description='" + description + '\'' + + ", shouldTint=" + shouldTint + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsMenuItem.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsMenuItem.java new file mode 100644 index 00000000..c00b4da0 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomTabsMenuItem.java @@ -0,0 +1,72 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Arrays; +import java.util.Map; + +public class CustomTabsMenuItem { + private int id; + + @NonNull + private String label; + + public CustomTabsMenuItem(int id, @NonNull String label) { + this.id = id; + this.label = label; + } + + @Nullable + public static CustomTabsMenuItem fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + int id = (int) map.get("id"); + String label = (String) map.get("label"); + return new CustomTabsMenuItem(id, label); + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @NonNull + public String getLabel() { + return label; + } + + public void setLabel(@NonNull String label) { + this.label = label; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CustomTabsMenuItem that = (CustomTabsMenuItem) o; + + if (id != that.id) return false; + return label.equals(that.label); + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + label.hashCode(); + return result; + } + + @Override + public String toString() { + return "CustomTabsMenuItem{" + + "id=" + id + + ", label='" + label + '\'' + + '}'; + } +} diff --git a/example/integration_test/webview_flutter_test.dart b/example/integration_test/webview_flutter_test.dart index 67a24e49..31b6e369 100644 --- a/example/integration_test/webview_flutter_test.dart +++ b/example/integration_test/webview_flutter_test.dart @@ -4148,7 +4148,7 @@ setTimeout(function() { if (Platform.isAndroid) { await pageLoaded.future; expect(await controller.evaluateJavascript(source: "document.body"), - isNull); + isEmpty); } else if (Platform.isIOS) { expect(pageLoaded.future, doesNotComplete); } @@ -5847,7 +5847,57 @@ setTimeout(function() { expect(chromeSafariBrowser.isOpened(), false); }); + test('add custom menu item', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + chromeSafariBrowser.addMenuItem(ChromeSafariBrowserMenuItem( + id: 2, + label: 'Custom item menu 1', + action: (url, title) { + print('Custom item menu 1 clicked!'); + })); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: Uri.parse("https://github.com/flutter")); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); + }, throwsA(isInstanceOf())); + + await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }); + group('Android Custom Tabs', () { + test('add custom action button', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + var actionButtonIcon = await rootBundle.load('test_assets/images/flutter-logo.png'); + chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton( + id: 1, + description: 'Action Button description', + icon: actionButtonIcon.buffer.asUint8List(), + action: (url, title) { + print('Action Button 1 clicked!'); + })); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: Uri.parse("https://github.com/flutter")); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); + }, throwsA(isInstanceOf())); + + await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }); + test('Custom Tabs single instance', () async { var chromeSafariBrowser = new MyChromeSafariBrowser(); expect(chromeSafariBrowser.isOpened(), false); diff --git a/example/lib/chrome_safari_browser_example.screen.dart b/example/lib/chrome_safari_browser_example.screen.dart index c2fb9a3c..0fe67854 100755 --- a/example/lib/chrome_safari_browser_example.screen.dart +++ b/example/lib/chrome_safari_browser_example.screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'main.dart'; @@ -32,8 +33,20 @@ class _ChromeSafariBrowserExampleScreenState extends State { @override void initState() { + rootBundle.load('assets/images/flutter-logo.png').then((actionButtonIcon) { + widget.browser.setActionButton(ChromeSafariBrowserActionButton( + id: 1, + description: 'Action Button description', + icon: actionButtonIcon.buffer.asUint8List(), + action: (url, title) { + print('Action Button 1 clicked!'); + print(url); + print(title); + })); + }); + widget.browser.addMenuItem(ChromeSafariBrowserMenuItem( - id: 1, + id: 2, label: 'Custom item menu 1', action: (url, title) { print('Custom item menu 1 clicked!'); @@ -41,7 +54,7 @@ class _ChromeSafariBrowserExampleScreenState print(title); })); widget.browser.addMenuItem(ChromeSafariBrowserMenuItem( - id: 2, + id: 3, label: 'Custom item menu 2', action: (url, title) { print('Custom item menu 2 clicked!'); diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index b656d6fe..a92baa96 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -169,6 +169,20 @@ class _InAppWebViewExampleScreenState extends State { this.url = url.toString(); urlController.text = this.url; }); + if (url?.host == 'github.com') { + await controller.loadUrl( + urlRequest: URLRequest( + url: Uri.parse('https://flutter-header-echo.herokuapp.com/'), + headers: { + 'test_header': 'flutter_test_header' + })); + final String? currentUrl = (await controller.getUrl())?.toString(); + print(currentUrl); + await Future.delayed(Duration(seconds: 2)); + final String? content = await controller.evaluateJavascript( + source: 'document.documentElement.innerText'); + print(content); + } }, onLoadError: (controller, url, code, message) { pullToRefreshController.endRefreshing(); diff --git a/lib/src/chrome_safari_browser/chrome_safari_browser.dart b/lib/src/chrome_safari_browser/chrome_safari_browser.dart index 2f476d1d..625112c6 100755 --- a/lib/src/chrome_safari_browser/chrome_safari_browser.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:collection'; +import 'dart:typed_data'; import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/src/util.dart'; @@ -40,6 +41,7 @@ class ChromeSafariBrowser { ///View ID used internally. late final String id; + ChromeSafariBrowserActionButton? _actionButton; Map _menuItems = new HashMap(); bool _isOpened = false; late MethodChannel _channel; @@ -66,12 +68,14 @@ class ChromeSafariBrowser { onClosed(); this._isOpened = false; break; - case "onChromeSafariBrowserMenuItemActionPerform": + case "onChromeSafariBrowserItemActionPerform": String url = call.arguments["url"]; String title = call.arguments["title"]; int id = call.arguments["id"].toInt(); - if (this._menuItems[id] != null) { - this._menuItems[id]!.action(url, title); + if (this._actionButton?.id == id) { + this._actionButton?.action(url, title); + } else if (this._menuItems[id] != null) { + this._menuItems[id]?.action(url, title); } break; default: @@ -91,13 +95,14 @@ class ChromeSafariBrowser { List> menuItemList = []; _menuItems.forEach((key, value) { - menuItemList.add({"id": value.id, "label": value.label}); + menuItemList.add(value.toMap()); }); Map args = {}; args.putIfAbsent('id', () => id); args.putIfAbsent('url', () => url.toString()); args.putIfAbsent('options', () => options?.toMap() ?? {}); + args.putIfAbsent('actionButton', () => _actionButton?.toMap()); args.putIfAbsent('menuItemList', () => menuItemList); await _sharedChannel.invokeMethod('open', args); this._isOpened = true; @@ -109,6 +114,16 @@ class ChromeSafariBrowser { await _channel.invokeMethod("close", args); } + ///Set a custom action button. + /// + ///**NOTE**: Not available in a Trusted Web Activity. + /// + ///**Supported Platforms/Implementations**: + ///- Android ([Official API - CustomTabsIntent.Builder.setActionButton ](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent.Builder#setActionButton(android.graphics.Bitmap,%20java.lang.String,%20android.app.PendingIntent,%20boolean))) + void setActionButton(ChromeSafariBrowserActionButton actionButton) { + this._actionButton = actionButton; + } + ///Adds a [ChromeSafariBrowserMenuItem] to the menu. /// ///**NOTE**: Not available in an Android Trusted Web Activity. @@ -164,11 +179,54 @@ class ChromeSafariBrowser { } } +///Class that represents a custom action button for a [ChromeSafariBrowser] instance. +/// +///**NOTE**: Not available in an Android Trusted Web Activity. +class ChromeSafariBrowserActionButton { + ///The action button id. It should be different from the [ChromeSafariBrowserMenuItem.id]. + int id; + + ///The icon byte data. + Uint8List icon; + + ///The description for the button. To be used for accessibility. + String description; + + ///Whether the action button should be tinted. + bool shouldTint; + + ///Callback function to be invoked when the menu item is clicked + final void Function(String url, String title) action; + + ChromeSafariBrowserActionButton( + {required this.id, required this.icon, + required this.description, required this.action, + this.shouldTint = false}); + + Map toMap() { + return { + "id": id, + "icon": icon, + "description": description, + "shouldTint": shouldTint + }; + } + + Map toJson() { + return this.toMap(); + } + + @override + String toString() { + return toMap().toString(); + } +} + ///Class that represents a custom menu item for a [ChromeSafariBrowser] instance. /// ///**NOTE**: Not available in an Android Trusted Web Activity. class ChromeSafariBrowserMenuItem { - ///The menu item id + ///The menu item id. It should be different from [ChromeSafariBrowserActionButton.id]. int id; ///The label of the menu item diff --git a/lib/src/types.dart b/lib/src/types.dart index 18676438..d0dfef75 100755 --- a/lib/src/types.dart +++ b/lib/src/types.dart @@ -1,5 +1,4 @@ import 'dart:collection'; -import 'dart:io'; import 'dart:typed_data'; import 'dart:convert'; import 'dart:ui';