I have 2 web specific flutter packages, dart:html and dart:js for web and path_provider for other platforms. My problem is that this project will compile for web but crashes when I try to build for linux with the following errors. How can I build a multiplatform app to download files? flutter clean and flutter pub get changed nothing.
ERROR: lib/ui/views/file_download_view.dart:15:8: Error: Not found: 'dart:html'
ERROR: import 'dart:html' as html;
ERROR: ^
ERROR: lib/ui/views/file_download_view.dart:16:8: Error: Not found: 'dart:js'
ERROR: import 'dart:js' as js;
ERROR: ^
ERROR: lib/ui/views/file_download_view.dart:118:12: Error: Method not found: 'Blob'.
ERROR: html.Blob(<Object>[bytes]),
ERROR: ^^^^
ERROR: lib/ui/views/file_download_view.dart:117:8: Error: Undefined name 'context'.
ERROR: js.context.callMethod("saveAs", <Object>[
ERROR: ^^^^^^^
ERROR: Unhandled exception:
Building Linux application...
Build process failed
I thought kIsWeb is supposed to separate them but the compiler crashes anyway. My code to separate them looks like this.
ElevatedButton.icon(
onPressed: () {
kIsWeb ? downloadWebFile(user) : downloadMobileFile(user);
},
My web specific code is
import 'dart:html' as html;
import 'dart:js' as js;
....
js: ^0.6.4
html: ^0.15.0
These show a linter warning "avoid using web-only libraries outside Flutter web plugin packages. How can I avoid that?
Future<void> downloadWebFile(User user) async {
final navigator = Navigator.of(context);
final storage = FlutterSecureStorage();
String? token = await storage.read(key: 'jwt');
Response<List<int>> rs;
rs = await Dio().get<List<int>>(
user.fileUrl,
options: Options(
headers: {HttpHeaders.authorizationHeader: 'Bearer $token'},
responseType: ResponseType.bytes),
onReceiveProgress: (rcv, total) {
received =
'received: ${rcv.toStringAsFixed(0)} out of total: ${total.toStringAsFixed(0)}';
setState(
() {
progress = ((rcv / total) * 100).toStringAsFixed(0);
},
);
if (progress == '100') {
setState(
() {
isDownloaded = true;
},
);
} else if (double.parse(progress) < 100) {}
},
);
if (progress == '100') {
downloading = false;
isDownloaded = true;
save(json.encode(rs.data), user.downloadFileName);
user.snackBarType = SnackBarType.success;
user.snackBarMessage = 'File downloaded successfully ';
navigator.pushNamedAndRemoveUntil(RoutePaths.matter, (route) => false);
} else {
downloading = false;
user.snackBarType = SnackBarType.failure;
user.snackBarMessage = 'File download failed';
navigator.pushNamedAndRemoveUntil(RoutePaths.matter, (route) => false);
}
}
Non web specific code:
Future<void> downloadMobileFile(User user) async {
setState(
() {
downloading = true;
filename = user.downloadFileName;
},
);
final navigator = Navigator.of(context);
bool hasPermission = await _requestWritePermission();
if (!hasPermission) return;
String savePath = await getFilePath(user.downloadFileName);
final storage = FlutterSecureStorage();
String? token = await storage.read(key: 'jwt');
Dio dio = Dio();
dio.download(
user.fileUrl,
savePath,
options: Options(
headers: {HttpHeaders.authorizationHeader: 'Bearer $token'},
),
onReceiveProgress: (rcv, total) {
received =
'received: ${rcv.toStringAsFixed(0)} out of total: ${total.toStringAsFixed(0)}';
setState(
() {
progress = ((rcv / total) * 100).toStringAsFixed(0);
},
);
if (progress == '100') {
setState(
() {
isDownloaded = true;
},
);
} else if (double.parse(progress) < 100) {}
},
deleteOnError: true,
).then(
(_) {
setState(
() {
if (progress == '100') {
downloading = false;
isDownloaded = true;
user.snackBarType = SnackBarType.success;
user.snackBarMessage = 'File downloaded successfully';
navigator.pushNamedAndRemoveUntil(
RoutePaths.matter, (route) => false);
} else {
downloading = false;
user.snackBarType = SnackBarType.failure;
user.snackBarMessage = 'File download failed';
}
},
);
},
);
Future<bool> _requestWritePermission() async {
await Permission.storage.request();
return await Permission.storage.request().isGranted;
}
Future<String> getFilePath(uniqueFileName) async {
String path = '';
Directory dir = await getApplicationDocumentsDirectory();
path = '${dir.path}/$uniqueFileName';
print("file download path");
print(path);
return path;
}
}