Closed ManishKiranagi closed 2 years ago
Could you show some sample code that doesn't work? Also, some help about how to try it on Safari? I don't work on a Mac, although I do have a working virtual machine. Simply running flutter run
doesn't start Safari though, it starts Chrome even on a Mac. Maybe you could also check what the browser dev tools console window says?
@deakjahn
I used the example code on https://pub.dev/packages/flutter_dropzone/example and added a TextButton for the file picking
Expanded( child: Stack( children: [ buildZone2(context), Center(child: Text(message2)), TextButton( onPressed: () async { print('before'); var files = await controller1.pickFiles(); print('after'); print(files); }, child: const Text('Add'), ) ], ), )
flutter run --release and then open that link in Safari.. you should be able to see the log in the Safari Console which only prints 'before' Chrome prints 'before', 'after' and the file object
After some investigation - using https://github.com/flutter/flutter/issues/74644 and https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only it appears that input elements need to be part of the dom to have effect. I tested this by changing flutter_dropzone_web.dart to add document.body!.append(picker) and it seems to work consistently on Safari and Chrome
Future<List<dynamic>> pickFiles(bool multiple) { final completer = Completer<List<dynamic>>(); final picker = FileUploadInputElement(); document.body!.append(picker); picker.multiple = multiple; picker.onChange.listen((_) => completer.complete(picker.files)); picker.click(); return completer.future; }
Do you use CanvasKit or DomCanvas?
Running the same URL while Chrome is running it? Interesting idea, never occurred to me. Yes, it works.
Oops, I get both before and after. Now what? :-) I'll try to include a screenshot but first I have to find out how.
Catalina, Safari 14.0.
Shall we try to put that append()
with a condition if we can actually test for Safari? What's your opinion? I have a code somewhere else that determines the browser, I'll dig it up but will it be reliable?
@deakjahn Yes adding append with a condition will be fantastic if possible. Just one thing - can that element be removed from the DOM in a dispose or something
I use CanvasKit, but same problem with html renderer as well.
The browser code is on the Dart side in another app of mine, I don't knwo where it came from, probably JS and transposed to Dart.
String _getBrowser() {
final userAgent = html.window.navigator.userAgent;
var browser = html.window.navigator.appName;
var version = html.window.navigator.appVersion;
int verOffset, nameOffset;
// Opera
if ((verOffset = userAgent.indexOf('Opera')) != -1) {
browser = 'Opera';
version = userAgent.substring(verOffset + 6);
if ((verOffset = userAgent.indexOf('Version')) != -1) {
version = userAgent.substring(verOffset + 8);
}
}
// Opera Next
if ((verOffset = userAgent.indexOf('OPR')) != -1) {
browser = 'Opera';
version = userAgent.substring(verOffset + 4);
}
// Edge
else if ((verOffset = userAgent.indexOf('Edge')) != -1) {
browser = 'Microsoft Edge';
version = userAgent.substring(verOffset + 5);
}
// MSIE
else if ((verOffset = userAgent.indexOf('MSIE')) != -1) {
browser = 'Microsoft Internet Explorer';
version = userAgent.substring(verOffset + 5);
}
// Chrome
else if ((verOffset = userAgent.indexOf('Chrome')) != -1) {
browser = 'Chrome';
version = userAgent.substring(verOffset + 7);
}
// Safari
else if ((verOffset = userAgent.indexOf('Safari')) != -1) {
browser = 'Safari';
version = userAgent.substring(verOffset + 7);
if ((verOffset = userAgent.indexOf('Version')) != -1) {
version = userAgent.substring(verOffset + 8);
}
}
// Firefox
else if ((verOffset = userAgent.indexOf('Firefox')) != -1) {
browser = 'Firefox';
version = userAgent.substring(verOffset + 8);
}
// MSIE 11+
else if (userAgent.contains('Trident/')) {
browser = 'Microsoft Internet Explorer';
version = userAgent.substring(userAgent.indexOf('rv:') + 3);
}
// Other browsers
else if ((nameOffset = userAgent.lastIndexOf(' ') + 1) < (verOffset = userAgent.lastIndexOf('/'))) {
browser = userAgent.substring(nameOffset, verOffset);
version = userAgent.substring(verOffset + 1);
if (browser.toLowerCase() == browser.toUpperCase()) {
browser = html.window.navigator.appName;
}
}
return '$browser ($version)';
}
The Safari part specifically extracted?
That's just looking for "Safari" in the UA string, nothing else.
But why do I receive an "after" in my Safari? :-)
I have this but I can't really tell because it works for me both with and without:
Future<List<dynamic>> pickFiles(bool multiple) {
final completer = Completer<List<dynamic>>();
final picker = FileUploadInputElement();
final isSafari = window.navigator.userAgent.contains('Safari');
if (isSafari) document.body!.append(picker);
picker.multiple = multiple;
picker.onChange.listen((_) {
completer.complete(picker.files);
if (isSafari) picker.remove();
});
picker.click();
return completer.future;
}
Could you check if this works for you?
@deakjahn I have tested and it works perfectly. Could you do lowercase check for Safari instead window.navigator.userAgent.toLowerCase().contains('safari') I have tested that and it works as well
Could you tell me if you are going to publish a pre-release version?
If you say it works I can't see any reason why not to push it.
3.0.5 it is.
Thanks.. will try now
@deakjahn Getting this.. on flutter pub get depends on flutter_dropzone ^3.0.5 which doesn't match any versions, version solving failed.
Did you happen to change the version manually? You don't have to... The main plugin doesn't have 3.0.5 yet, only the web sub-plugin has. And you don't need to change anything anywhere, just update the current one and you'll get it automatically.
Leave
flutter_dropzone: ^3.0.3
in your pubspec, let the system sort out the rest.
OK. I had to delete flutter_dropzone: ^3.0.3 and flutter pub get, then add again flutter_dropzone: ^3.0.3 and flutter pub get and then in the pub cache I see dropzoneweb 3.0.5!
Yes. This is a so-called federated plugin, one that has a main one and two additional ones (could even have more than two, of course). You only need to bother with the main plugin, the rest is upgraded automatically. Unless there is a major, breaking change (eg. 3.1.0 or even 4.0.0), you always get the latest versions of both the main plugin and the dependent ones, even if, for instance, the main plugin still technically refers to web 3.0.4 and not 3.0.5 (I'll change that with the next coming push of the main plugin but there's no rush because it works as is, automatically).
I upgraded to Flutter 2.5.3 and am using Dropzone 3.0.3 I was previously on Flutter 1.25.0-8.3.pre and dropzone 1.0.9 After upgrade the controller.pickFiles has stopped working on Mac Safari - it doesnt return anything, no exceptions. This used to work on the previous version. I need urgent help on this as it is blocking my deployments.