added onCameraCaptureStateChanged and onMicrophoneCaptureStateChanged webview events
This commit is contained in:
parent
71c2093283
commit
17ed6c881a
|
@ -5,6 +5,7 @@
|
|||
- Added `ProxyController` for Android
|
||||
- Added `pauseAllMediaPlayback`, `setAllMediaPlaybackSuspended`, `closeAllMediaPresentations`, `requestMediaPlaybackState`, `isInFullscreen`, `getCameraCaptureState`, `setCameraCaptureState`, `getMicrophoneCaptureState`, `setMicrophoneCaptureState` WebView controller methods
|
||||
- Added `underPageBackgroundColor`, `isTextInteractionEnabled`, `isSiteSpecificQuirksModeEnabled`, `upgradeKnownHostsToHTTPS`, `forceDarkStrategy` WebView settings
|
||||
- Added `onCameraCaptureStateChanged`, `onMicrophoneCaptureStateChanged` WebView events
|
||||
- Added support for `onPermissionRequest` event on iOS 15.0+
|
||||
- Updated `getMetaThemeColor` on iOS 15.0+
|
||||
- Deprecated `onLoadError` for `onReceivedError`. `onReceivedError` will be called also for subframes.
|
||||
|
|
|
@ -177,6 +177,7 @@
|
|||
CreatedOnToolsVersion = 7.3.1;
|
||||
DevelopmentTeam = PFP8UV45Y6;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.BackgroundModes = {
|
||||
enabled = 1;
|
||||
|
@ -443,6 +444,8 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = PFP8UV45Y6;
|
||||
ENABLE_BITCODE = NO;
|
||||
|
@ -456,8 +459,9 @@
|
|||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-Example";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.pichillilorenzo.flutterinappwebviewExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -471,6 +475,8 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = PFP8UV45Y6;
|
||||
ENABLE_BITCODE = NO;
|
||||
|
@ -484,8 +490,9 @@
|
|||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-Example";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.pichillilorenzo.flutterinappwebviewExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
|
@ -309,6 +309,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
|||
options: [.new, .old],
|
||||
context: nil)
|
||||
|
||||
if #available(iOS 15.0, *) {
|
||||
addObserver(self,
|
||||
forKeyPath: #keyPath(WKWebView.cameraCaptureState),
|
||||
options: [.new, .old],
|
||||
context: nil)
|
||||
|
||||
addObserver(self,
|
||||
forKeyPath: #keyPath(WKWebView.microphoneCaptureState),
|
||||
options: [.new, .old],
|
||||
context: nil)
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(onCreateContextMenu),
|
||||
|
@ -628,18 +640,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
|||
let progress = Int(estimatedProgress * 100)
|
||||
onProgressChanged(progress: progress)
|
||||
inAppBrowserDelegate?.didChangeProgress(progress: estimatedProgress)
|
||||
} else if keyPath == #keyPath(WKWebView.url) && change?[NSKeyValueChangeKey.newKey] is URL {
|
||||
} else if keyPath == #keyPath(WKWebView.url) && change?[.newKey] is URL {
|
||||
initializeWindowIdJS()
|
||||
let newUrl = change?[NSKeyValueChangeKey.newKey] as? URL
|
||||
onUpdateVisitedHistory(url: newUrl?.absoluteString)
|
||||
inAppBrowserDelegate?.didUpdateVisitedHistory(url: newUrl)
|
||||
} else if keyPath == #keyPath(WKWebView.title) && change?[NSKeyValueChangeKey.newKey] is String {
|
||||
let newTitle = change?[NSKeyValueChangeKey.newKey] as? String
|
||||
} else if keyPath == #keyPath(WKWebView.title) && change?[.newKey] is String {
|
||||
let newTitle = change?[.newKey] as? String
|
||||
onTitleChanged(title: newTitle)
|
||||
inAppBrowserDelegate?.didChangeTitle(title: newTitle)
|
||||
} else if keyPath == #keyPath(UIScrollView.contentOffset) {
|
||||
let newContentOffset = change?[NSKeyValueChangeKey.newKey] as? CGPoint
|
||||
let oldContentOffset = change?[NSKeyValueChangeKey.oldKey] as? CGPoint
|
||||
let newContentOffset = change?[.newKey] as? CGPoint
|
||||
let oldContentOffset = change?[.oldKey] as? CGPoint
|
||||
let startedByUser = scrollView.isDragging || scrollView.isDecelerating
|
||||
if newContentOffset != oldContentOffset {
|
||||
DispatchQueue.main.async {
|
||||
|
@ -647,15 +659,30 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
|||
}
|
||||
}
|
||||
}
|
||||
// else if #available(iOS 15.0, *) {
|
||||
// if keyPath == #keyPath(WKWebView.fullscreenState) {
|
||||
else if #available(iOS 15.0, *) {
|
||||
if keyPath == #keyPath(WKWebView.cameraCaptureState) || keyPath == #keyPath(WKWebView.microphoneCaptureState) {
|
||||
var oldState: WKMediaCaptureState? = nil
|
||||
if let oldValue = change?[.oldKey] as? Int {
|
||||
oldState = WKMediaCaptureState.init(rawValue: oldValue)
|
||||
}
|
||||
var newState: WKMediaCaptureState? = nil
|
||||
if let newValue = change?[.newKey] as? Int {
|
||||
newState = WKMediaCaptureState.init(rawValue: newValue)
|
||||
}
|
||||
if keyPath == #keyPath(WKWebView.cameraCaptureState) {
|
||||
onCameraCaptureStateChanged(oldState: oldState, newState: newState)
|
||||
} else {
|
||||
onMicrophoneCaptureStateChanged(oldState: oldState, newState: newState)
|
||||
}
|
||||
}
|
||||
// else if keyPath == #keyPath(WKWebView.fullscreenState) {
|
||||
// if fullscreenState == .enteringFullscreen {
|
||||
// onEnterFullscreen()
|
||||
// } else if fullscreenState == .exitingFullscreen {
|
||||
// onExitFullscreen()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
replaceGestureHandlerIfNeeded()
|
||||
}
|
||||
|
||||
|
@ -2756,6 +2783,18 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
|||
channel?.invokeMethod("onExitFullscreen", arguments: [])
|
||||
}
|
||||
|
||||
@available(iOS 15.0, *)
|
||||
public func onCameraCaptureStateChanged(oldState: WKMediaCaptureState?, newState: WKMediaCaptureState?) {
|
||||
let arguments = ["oldState": oldState?.rawValue, "newState": newState?.rawValue]
|
||||
channel?.invokeMethod("onCameraCaptureStateChanged", arguments: arguments)
|
||||
}
|
||||
|
||||
@available(iOS 15.0, *)
|
||||
public func onMicrophoneCaptureStateChanged(oldState: WKMediaCaptureState?, newState: WKMediaCaptureState?) {
|
||||
let arguments = ["oldState": oldState?.rawValue, "newState": newState?.rawValue]
|
||||
channel?.invokeMethod("onMicrophoneCaptureStateChanged", arguments: arguments)
|
||||
}
|
||||
|
||||
// public func onContextMenuConfigurationForElement(linkURL: String?, result: FlutterResult?) {
|
||||
// let arguments: [String: Any?] = ["linkURL": linkURL]
|
||||
// channel?.invokeMethod("onContextMenuConfigurationForElement", arguments: arguments, result: result)
|
||||
|
@ -3130,9 +3169,11 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
|||
removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.url))
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.title))
|
||||
// if #available(iOS 15.0, *) {
|
||||
if #available(iOS 15.0, *) {
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.cameraCaptureState))
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.microphoneCaptureState))
|
||||
// removeObserver(self, forKeyPath: #keyPath(WKWebView.fullscreenState))
|
||||
// }
|
||||
}
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale))
|
||||
resumeTimers()
|
||||
|
|
|
@ -1047,6 +1047,28 @@ class InAppBrowser {
|
|||
Future<ShouldAllowDeprecatedTLSAction?>? shouldAllowDeprecatedTLS(
|
||||
URLAuthenticationChallenge challenge) {}
|
||||
|
||||
///Event fired when a change in the camera capture state occurred.
|
||||
///
|
||||
///**NOTE**: available only on iOS 15.0+.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
void onCameraCaptureStateChanged(
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
) {}
|
||||
|
||||
///Event fired when a change in the microphone capture state occurred.
|
||||
///
|
||||
///**NOTE**: available only on iOS 15.0+.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
void onMicrophoneCaptureStateChanged(
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
) {}
|
||||
|
||||
void throwIfAlreadyOpened({String message = ''}) {
|
||||
if (this.isOpened()) {
|
||||
throw InAppBrowserAlreadyOpenedException([
|
||||
|
|
|
@ -147,6 +147,8 @@ class HeadlessInAppWebView implements WebView {
|
|||
@Deprecated('Use shouldAllowDeprecatedTLS instead')
|
||||
this.iosShouldAllowDeprecatedTLS,
|
||||
this.shouldAllowDeprecatedTLS,
|
||||
this.onCameraCaptureStateChanged,
|
||||
this.onMicrophoneCaptureStateChanged,
|
||||
}) {
|
||||
id = IdGenerator.generate();
|
||||
webViewController = new InAppWebViewController(id, this);
|
||||
|
@ -401,11 +403,10 @@ class HeadlessInAppWebView implements WebView {
|
|||
///Use [onDownloadStartRequest] instead
|
||||
@Deprecated('Use onDownloadStartRequest instead')
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri url)?
|
||||
onDownloadStart;
|
||||
void Function(InAppWebViewController controller, Uri url)? onDownloadStart;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller,
|
||||
void Function(InAppWebViewController controller,
|
||||
DownloadStartRequest downloadStartRequest)? onDownloadStartRequest;
|
||||
|
||||
@override
|
||||
|
@ -430,12 +431,12 @@ class HeadlessInAppWebView implements WebView {
|
|||
///Use [onReceivedError] instead.
|
||||
@Deprecated("Use onReceivedError instead")
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri? url, int code,
|
||||
void Function(InAppWebViewController controller, Uri? url, int code,
|
||||
String message)? onLoadError;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller,
|
||||
WebResourceRequest request, WebResourceError error)? onReceivedError;
|
||||
void Function(InAppWebViewController controller, WebResourceRequest request,
|
||||
WebResourceError error)? onReceivedError;
|
||||
|
||||
///Use [onReceivedHttpError] instead.
|
||||
@Deprecated("Use onReceivedHttpError instead")
|
||||
|
@ -443,9 +444,7 @@ class HeadlessInAppWebView implements WebView {
|
|||
void Function(InAppWebViewController controller, Uri? url, int statusCode,
|
||||
String description)? onLoadHttpError;
|
||||
|
||||
final void Function(
|
||||
InAppWebViewController controller,
|
||||
WebResourceRequest request,
|
||||
void Function(InAppWebViewController controller, WebResourceRequest request,
|
||||
WebResourceResponse errorResponse)? onReceivedHttpError;
|
||||
|
||||
@override
|
||||
|
@ -662,4 +661,18 @@ class HeadlessInAppWebView implements WebView {
|
|||
Future<WebResourceResponse?> Function(
|
||||
InAppWebViewController controller, WebResourceRequest request)?
|
||||
shouldInterceptRequest;
|
||||
|
||||
@override
|
||||
Future<void> Function(
|
||||
InAppWebViewController controller,
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
)? onCameraCaptureStateChanged;
|
||||
|
||||
@override
|
||||
Future<void> Function(
|
||||
InAppWebViewController controller,
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
)? onMicrophoneCaptureStateChanged;
|
||||
}
|
||||
|
|
|
@ -139,6 +139,8 @@ class InAppWebView extends StatefulWidget implements WebView {
|
|||
@Deprecated('Use shouldAllowDeprecatedTLS instead')
|
||||
this.iosShouldAllowDeprecatedTLS,
|
||||
this.shouldAllowDeprecatedTLS,
|
||||
this.onCameraCaptureStateChanged,
|
||||
this.onMicrophoneCaptureStateChanged,
|
||||
this.gestureRecognizers,
|
||||
}) : super(key: key);
|
||||
|
||||
|
@ -542,6 +544,20 @@ class InAppWebView extends StatefulWidget implements WebView {
|
|||
final Future<WebResourceResponse?> Function(
|
||||
InAppWebViewController controller, WebResourceRequest request)?
|
||||
shouldInterceptRequest;
|
||||
|
||||
@override
|
||||
final Future<void> Function(
|
||||
InAppWebViewController controller,
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
)? onCameraCaptureStateChanged;
|
||||
|
||||
@override
|
||||
final Future<void> Function(
|
||||
InAppWebViewController controller,
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
)? onMicrophoneCaptureStateChanged;
|
||||
}
|
||||
|
||||
class _InAppWebViewState extends State<InAppWebView> {
|
||||
|
@ -680,7 +696,9 @@ class _InAppWebViewState extends State<InAppWebView> {
|
|||
@override
|
||||
void dispose() {
|
||||
dynamic viewId = _controller?.getViewId();
|
||||
if (viewId != null && kIsWeb && WebPlatformManager.webViews.containsKey(viewId)) {
|
||||
if (viewId != null &&
|
||||
kIsWeb &&
|
||||
WebPlatformManager.webViews.containsKey(viewId)) {
|
||||
WebPlatformManager.webViews.remove(viewId);
|
||||
}
|
||||
super.dispose();
|
||||
|
|
|
@ -1081,7 +1081,7 @@ class InAppWebViewController {
|
|||
onLoadCallback != null) {
|
||||
onLoadCallback();
|
||||
}
|
||||
return null;
|
||||
break;
|
||||
case "onInjectedScriptError":
|
||||
String id = call.arguments[0];
|
||||
var onErrorCallback = _injectedScriptsFromURL[id]?.onError;
|
||||
|
@ -1089,7 +1089,31 @@ class InAppWebViewController {
|
|||
onErrorCallback != null) {
|
||||
onErrorCallback();
|
||||
}
|
||||
return null;
|
||||
break;
|
||||
case "onCameraCaptureStateChanged":
|
||||
if ((_webview != null && _webview!.onCameraCaptureStateChanged != null) ||
|
||||
_inAppBrowser != null) {
|
||||
var oldState = MediaCaptureState.fromValue(call.arguments["oldState"]);
|
||||
var newState = MediaCaptureState.fromValue(call.arguments["newState"]);
|
||||
|
||||
if (_webview != null && _webview!.onCameraCaptureStateChanged != null)
|
||||
_webview!.onCameraCaptureStateChanged!(this, oldState, newState);
|
||||
else
|
||||
_inAppBrowser!.onCameraCaptureStateChanged(oldState, newState);
|
||||
}
|
||||
break;
|
||||
case "onMicrophoneCaptureStateChanged":
|
||||
if ((_webview != null && _webview!.onMicrophoneCaptureStateChanged != null) ||
|
||||
_inAppBrowser != null) {
|
||||
var oldState = MediaCaptureState.fromValue(call.arguments["oldState"]);
|
||||
var newState = MediaCaptureState.fromValue(call.arguments["newState"]);
|
||||
|
||||
if (_webview != null && _webview!.onMicrophoneCaptureStateChanged != null)
|
||||
_webview!.onMicrophoneCaptureStateChanged!(this, oldState, newState);
|
||||
else
|
||||
_inAppBrowser!.onMicrophoneCaptureStateChanged(oldState, newState);
|
||||
}
|
||||
break;
|
||||
case "onCallJsHandler":
|
||||
String handlerName = call.arguments["handlerName"];
|
||||
// decode args to json
|
||||
|
|
|
@ -848,6 +848,30 @@ abstract class WebView {
|
|||
InAppWebViewController controller,
|
||||
URLAuthenticationChallenge challenge)? shouldAllowDeprecatedTLS;
|
||||
|
||||
///Event fired when a change in the camera capture state occurred.
|
||||
///
|
||||
///**NOTE**: available only on iOS 15.0+.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
final Future<void> Function(
|
||||
InAppWebViewController controller,
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
)? onCameraCaptureStateChanged;
|
||||
|
||||
///Event fired when a change in the microphone capture state occurred.
|
||||
///
|
||||
///**NOTE**: available only on iOS 15.0+.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
final Future<void> Function(
|
||||
InAppWebViewController controller,
|
||||
MediaCaptureState? oldState,
|
||||
MediaCaptureState? newState,
|
||||
)? onMicrophoneCaptureStateChanged;
|
||||
|
||||
///Initial url request that will be loaded.
|
||||
///
|
||||
///**NOTE for Android**: when loading an URL Request using "POST" method, headers are ignored.
|
||||
|
@ -927,7 +951,8 @@ abstract class WebView {
|
|||
@Deprecated('Use onReceivedError instead')
|
||||
this.onLoadError,
|
||||
this.onReceivedError,
|
||||
@Deprecated("Use onReceivedHttpError instead") this.onLoadHttpError,
|
||||
@Deprecated("Use onReceivedHttpError instead")
|
||||
this.onLoadHttpError,
|
||||
this.onReceivedHttpError,
|
||||
this.onProgressChanged,
|
||||
this.onConsoleMessage,
|
||||
|
@ -1015,6 +1040,8 @@ abstract class WebView {
|
|||
@Deprecated('Use shouldAllowDeprecatedTLS instead')
|
||||
this.iosShouldAllowDeprecatedTLS,
|
||||
this.shouldAllowDeprecatedTLS,
|
||||
this.onCameraCaptureStateChanged,
|
||||
this.onMicrophoneCaptureStateChanged,
|
||||
this.initialUrlRequest,
|
||||
this.initialFile,
|
||||
this.initialData,
|
||||
|
|
Loading…
Reference in New Issue