Skip to content

Commit 0aaf7a0

Browse files
Merge branch 'v6.2.0-beta.3'
2 parents 1e7091c + 1ba712b commit 0aaf7a0

27 files changed

+860
-61
lines changed

flutter_inappwebview/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
#### Platform Interface
1313
- Added `saveState`, `restoreState` methods to `PlatformInAppWebViewController` class
14-
- Added `useOnAjaxReadyStateChange`, `useOnAjaxProgress` properties to `InAppWebViewSettings`
14+
- Added `useOnAjaxReadyStateChange`, `useOnAjaxProgress`, `useOnShowFileChooser` properties to `InAppWebViewSettings`
15+
- Added `onShowFileChooser` WebView events
1516

1617
#### Android Platform
1718
- Implemented `saveState`, `restoreState` InAppWebViewController methods
19+
- Implemented `onShowFileChooser` WebView event
1820
- Merged "Android: implemented PlatformPrintJobController.onComplete" [#2216](https://github.com/pichillilorenzo/flutter_inappwebview/pull/2216) (thanks to [Doflatango](https://github.com/Doflatango))
1921

2022
#### macOS and iOS Platforms

flutter_inappwebview/lib/src/in_app_browser/in_app_browser.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,4 +609,9 @@ class InAppBrowser implements PlatformInAppBrowserEvents {
609609

610610
@override
611611
void onAcceleratorKeyPressed(AcceleratorKeyPressedDetail detail) {}
612+
613+
@override
614+
FutureOr<ShowFileChooserResponse?> onShowFileChooser(ShowFileChooserRequest request) {
615+
return null;
616+
}
612617
}

flutter_inappwebview/lib/src/in_app_webview/headless_in_app_webview.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ class HeadlessInAppWebView {
167167
)? onMicrophoneCaptureStateChanged,
168168
void Function(InAppWebViewController controller, Size oldContentSize, Size newContentSize)? onContentSizeChanged,
169169
void Function(InAppWebViewController controller, ProcessFailedDetail detail)? onProcessFailed,
170-
void Function(InAppWebViewController controller, AcceleratorKeyPressedDetail detail)? onAcceleratorKeyPressed})
170+
void Function(InAppWebViewController controller, AcceleratorKeyPressedDetail detail)? onAcceleratorKeyPressed,
171+
FutureOr<ShowFileChooserResponse?> Function(InAppWebViewController controller, ShowFileChooserRequest request)? onShowFileChooser})
171172
: this.fromPlatformCreationParams(
172173
params: PlatformHeadlessInAppWebViewCreationParams(
173174
controllerFromPlatform: (PlatformInAppWebViewController controller) =>
@@ -521,6 +522,10 @@ class HeadlessInAppWebView {
521522
? (controller, detail) =>
522523
onAcceleratorKeyPressed.call(controller, detail)
523524
: null,
525+
onShowFileChooser: onShowFileChooser != null
526+
? (controller, request) =>
527+
onShowFileChooser.call(controller, request)
528+
: null,
524529
));
525530

526531
///{@macro flutter_inappwebview_platform_interface.PlatformHeadlessInAppWebView.run}

flutter_inappwebview/lib/src/in_app_webview/in_app_webview.dart

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import 'dart:async';
22
import 'dart:collection';
3-
import 'dart:typed_data';
43

54
import 'package:flutter/foundation.dart';
5+
import 'package:flutter/gestures.dart';
66
import 'package:flutter/material.dart';
7-
import 'package:flutter/rendering.dart';
87
import 'package:flutter/services.dart';
98
import 'package:flutter/widgets.dart';
10-
import 'package:flutter/gestures.dart';
119
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
12-
import '../webview_environment/webview_environment.dart';
13-
import 'headless_in_app_webview.dart';
14-
import 'in_app_webview_controller.dart';
10+
1511
import '../find_interaction/find_interaction_controller.dart';
1612
import '../pull_to_refresh/main.dart';
1713
import '../pull_to_refresh/pull_to_refresh_controller.dart';
14+
import '../webview_environment/webview_environment.dart';
15+
import 'headless_in_app_webview.dart';
16+
import 'in_app_webview_controller.dart';
1817

1918
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewWidget}
2019
class InAppWebView extends StatefulWidget {
@@ -167,7 +166,8 @@ class InAppWebView extends StatefulWidget {
167166
)? onMicrophoneCaptureStateChanged,
168167
void Function(InAppWebViewController controller, Size oldContentSize, Size newContentSize)? onContentSizeChanged,
169168
void Function(InAppWebViewController controller, ProcessFailedDetail detail)? onProcessFailed,
170-
void Function(InAppWebViewController controller, AcceleratorKeyPressedDetail detail)? onAcceleratorKeyPressed})
169+
void Function(InAppWebViewController controller, AcceleratorKeyPressedDetail detail)? onAcceleratorKeyPressed,
170+
FutureOr<ShowFileChooserResponse?> Function(InAppWebViewController controller, ShowFileChooserRequest request)? onShowFileChooser})
171171
: this.fromPlatformCreationParams(
172172
key: key,
173173
params: PlatformInAppWebViewWidgetCreationParams(
@@ -542,6 +542,10 @@ class InAppWebView extends StatefulWidget {
542542
? (controller, detail) =>
543543
onAcceleratorKeyPressed.call(controller, detail)
544544
: null,
545+
onShowFileChooser: onShowFileChooser != null
546+
? (controller, request) =>
547+
onShowFileChooser.call(controller, request)
548+
: null,
545549
gestureRecognizers: gestureRecognizers,
546550
headlessWebView: headlessWebView?.platform,
547551
preventGestureDelay: preventGestureDelay,

flutter_inappwebview_android/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Updated flutter_inappwebview_platform_interface version to ^1.4.0-beta.3
44
- Implemented `saveState`, `restoreState` InAppWebViewController methods
5+
- Implemented `onShowFileChooser` WebView event
56
- Merged "Android: implemented PlatformPrintJobController.onComplete" [#2216](https://github.com/pichillilorenzo/flutter_inappwebview/pull/2216) (thanks to [Doflatango](https://github.com/Doflatango))
67
- Fixed "When useShouldInterceptAjaxRequest is true, some ajax requests doesn't work" [#2197](https://github.com/pichillilorenzo/flutter_inappwebview/issues/2197)
78

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package com.pichillilorenzo.flutter_inappwebview_android.types;
2+
3+
import android.annotation.TargetApi;
4+
import android.os.Build;
5+
import android.webkit.WebChromeClient;
6+
7+
import androidx.annotation.NonNull;
8+
import androidx.annotation.Nullable;
9+
10+
import java.util.Arrays;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.Objects;
15+
16+
public class ShowFileChooserRequest {
17+
private int mode;
18+
@NonNull
19+
private List<String> acceptTypes;
20+
private boolean isCaptureEnabled;
21+
@Nullable
22+
private String title;
23+
@Nullable
24+
private String filenameHint;
25+
26+
public ShowFileChooserRequest(int mode, @NonNull List<String> acceptTypes, boolean isCaptureEnabled, @Nullable String title, @Nullable String filenameHint) {
27+
this.mode = mode;
28+
this.acceptTypes = acceptTypes;
29+
this.isCaptureEnabled = isCaptureEnabled;
30+
this.title = title;
31+
this.filenameHint = filenameHint;
32+
}
33+
34+
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
35+
public static ShowFileChooserRequest fromFileChooserParams(WebChromeClient.FileChooserParams fileChooserParams) {
36+
int mode = fileChooserParams.getMode();
37+
List<String> acceptTypes = Arrays.asList(fileChooserParams.getAcceptTypes());
38+
boolean isCaptureEnabled = fileChooserParams.isCaptureEnabled();
39+
String title = fileChooserParams.getTitle() != null ? fileChooserParams.getTitle().toString() : null;
40+
String filenameHint = fileChooserParams.getFilenameHint();
41+
return new ShowFileChooserRequest(mode, acceptTypes, isCaptureEnabled, title, filenameHint);
42+
}
43+
44+
@Nullable
45+
public static ShowFileChooserRequest fromMap(@Nullable Map<String, Object> map) {
46+
if (map == null) {
47+
return null;
48+
}
49+
int mode = (int) map.get("mode");
50+
List<String> acceptTypes = (List<String>) map.get("acceptTypes");
51+
boolean isCaptureEnabled = (boolean) map.get("isCaptureEnabled");
52+
String title = (String) map.get("title");
53+
String filenameHint = (String) map.get("filenameHint");
54+
return new ShowFileChooserRequest(mode, acceptTypes, isCaptureEnabled, title, filenameHint);
55+
}
56+
57+
public Map<String, Object> toMap() {
58+
Map<String, Object> showFileChooserRequestMap = new HashMap<>();
59+
showFileChooserRequestMap.put("mode", mode);
60+
showFileChooserRequestMap.put("acceptTypes", acceptTypes);
61+
showFileChooserRequestMap.put("isCaptureEnabled", isCaptureEnabled);
62+
showFileChooserRequestMap.put("title", title);
63+
showFileChooserRequestMap.put("filenameHint", filenameHint);
64+
return showFileChooserRequestMap;
65+
}
66+
67+
68+
public int getMode() {
69+
return mode;
70+
}
71+
72+
public void setMode(int mode) {
73+
this.mode = mode;
74+
}
75+
76+
public @NonNull List<String> getAcceptTypes() {
77+
return acceptTypes;
78+
}
79+
80+
public void setAcceptTypes(@NonNull List<String> acceptTypes) {
81+
this.acceptTypes = acceptTypes;
82+
}
83+
84+
public boolean isCaptureEnabled() {
85+
return isCaptureEnabled;
86+
}
87+
88+
public void setCaptureEnabled(boolean captureEnabled) {
89+
isCaptureEnabled = captureEnabled;
90+
}
91+
92+
@Nullable
93+
public String getTitle() {
94+
return title;
95+
}
96+
97+
public void setTitle(@Nullable String title) {
98+
this.title = title;
99+
}
100+
101+
@Nullable
102+
public String getFilenameHint() {
103+
return filenameHint;
104+
}
105+
106+
public void setFilenameHint(@Nullable String filenameHint) {
107+
this.filenameHint = filenameHint;
108+
}
109+
110+
@Override
111+
public boolean equals(Object o) {
112+
if (this == o) return true;
113+
if (o == null || getClass() != o.getClass()) return false;
114+
115+
ShowFileChooserRequest that = (ShowFileChooserRequest) o;
116+
return mode == that.mode && isCaptureEnabled == that.isCaptureEnabled && acceptTypes.equals(that.acceptTypes) && Objects.equals(title, that.title) && Objects.equals(filenameHint, that.filenameHint);
117+
}
118+
119+
@Override
120+
public int hashCode() {
121+
int result = mode;
122+
result = 31 * result + acceptTypes.hashCode();
123+
result = 31 * result + Boolean.hashCode(isCaptureEnabled);
124+
result = 31 * result + Objects.hashCode(title);
125+
result = 31 * result + Objects.hashCode(filenameHint);
126+
return result;
127+
}
128+
129+
@NonNull
130+
@Override
131+
public String toString() {
132+
return "ShowFileChooserRequest{" +
133+
"mode=" + mode +
134+
", acceptTypes=" + acceptTypes +
135+
", isCaptureEnabled=" + isCaptureEnabled +
136+
", title='" + title + '\'' +
137+
", filenameHint='" + filenameHint + '\'' +
138+
'}';
139+
}
140+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.pichillilorenzo.flutter_inappwebview_android.types;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Objects;
9+
10+
public class ShowFileChooserResponse {
11+
private boolean handledByClient;
12+
@Nullable
13+
private List<String> filePaths;
14+
15+
public ShowFileChooserResponse(boolean handledByClient, @Nullable List<String> filePaths) {
16+
this.handledByClient = handledByClient;
17+
this.filePaths = filePaths;
18+
}
19+
20+
@Nullable
21+
public static ShowFileChooserResponse fromMap(@Nullable Map<String, Object> map) {
22+
if (map == null) {
23+
return null;
24+
}
25+
boolean handledByClient = (boolean) map.get("handledByClient");
26+
List<String> filePaths = (List<String>) map.get("filePaths");
27+
return new ShowFileChooserResponse(handledByClient, filePaths);
28+
}
29+
30+
public boolean isHandledByClient() {
31+
return handledByClient;
32+
}
33+
34+
public void setHandledByClient(boolean handledByClient) {
35+
this.handledByClient = handledByClient;
36+
}
37+
38+
@Nullable
39+
public List<String> getFilePaths() {
40+
return filePaths;
41+
}
42+
43+
public void setFilePaths(@Nullable List<String> filePaths) {
44+
this.filePaths = filePaths;
45+
}
46+
47+
@Override
48+
public boolean equals(Object o) {
49+
if (this == o) return true;
50+
if (o == null || getClass() != o.getClass()) return false;
51+
52+
ShowFileChooserResponse that = (ShowFileChooserResponse) o;
53+
return handledByClient == that.handledByClient && Objects.equals(filePaths, that.filePaths);
54+
}
55+
56+
@Override
57+
public int hashCode() {
58+
int result = Boolean.hashCode(handledByClient);
59+
result = 31 * result + Objects.hashCode(filePaths);
60+
return result;
61+
}
62+
63+
@NonNull
64+
@Override
65+
public String toString() {
66+
return "ShowFileChooserResponse{" +
67+
"handledByClient=" + handledByClient +
68+
", filePaths=" + filePaths +
69+
'}';
70+
}
71+
}

flutter_inappwebview_android/android/src/main/java/com/pichillilorenzo/flutter_inappwebview_android/webview/WebViewChannelDelegate.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import com.pichillilorenzo.flutter_inappwebview_android.types.SafeBrowsingResponse;
4242
import com.pichillilorenzo.flutter_inappwebview_android.types.ServerTrustAuthResponse;
4343
import com.pichillilorenzo.flutter_inappwebview_android.types.ServerTrustChallenge;
44+
import com.pichillilorenzo.flutter_inappwebview_android.types.ShowFileChooserRequest;
45+
import com.pichillilorenzo.flutter_inappwebview_android.types.ShowFileChooserResponse;
4446
import com.pichillilorenzo.flutter_inappwebview_android.types.SslCertificateExt;
4547
import com.pichillilorenzo.flutter_inappwebview_android.types.SyncBaseCallbackResultImpl;
4648
import com.pichillilorenzo.flutter_inappwebview_android.types.URLRequest;
@@ -1360,6 +1362,23 @@ public void onRequestFocus() {
13601362
channel.invokeMethod("onRequestFocus", obj);
13611363
}
13621364

1365+
public static class ShowFileChooserCallback extends BaseCallbackResultImpl<ShowFileChooserResponse> {
1366+
@Nullable
1367+
@Override
1368+
public ShowFileChooserResponse decodeResult(@Nullable Object obj) {
1369+
return ShowFileChooserResponse.fromMap((Map<String, Object>) obj);
1370+
}
1371+
}
1372+
1373+
public void onShowFileChooser(ShowFileChooserRequest request, @NonNull ShowFileChooserCallback callback) {
1374+
MethodChannel channel = getChannel();
1375+
if (channel == null) {
1376+
callback.defaultBehaviour(null);
1377+
return;
1378+
}
1379+
channel.invokeMethod("onShowFileChooser", request.toMap(), callback);
1380+
}
1381+
13631382
@Override
13641383
public void dispose() {
13651384
super.dispose();

0 commit comments

Comments
 (0)