refactor: Switch to file_picker package and get rid of some dependency overrides

This commit is contained in:
Krille 2023-03-18 17:02:12 +01:00
commit d9aa2f8e44
17 changed files with 175 additions and 212 deletions

View file

@ -3,7 +3,8 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart';
@ -68,14 +69,15 @@ class AddStoryController extends State<AddStoryPage> {
}
void importMedia() async {
final picked = await FilePickerCross.importFromStorage(
type: FileTypeCross.image,
final picked = await FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
);
final fileName = picked.fileName;
if (fileName == null) return;
final file = picked?.files.firstOrNull;
if (file == null) return;
final matrixFile = MatrixImageFile(
bytes: picked.toUint8List(),
name: fileName,
bytes: file.bytes!,
name: file.name,
);
setState(() {
image = matrixFile;

View file

@ -9,7 +9,7 @@ import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:image_picker/image_picker.dart';
@ -352,19 +352,20 @@ class ChatController extends State<Chat> {
}
void sendFileAction() async {
final result = await FilePickerCross.importMultipleFromStorage(
type: FileTypeCross.any,
final result = await FilePicker.platform.pickFiles(
allowMultiple: true,
withData: true,
);
if (result.isEmpty) return;
if (result == null || result.files.isEmpty) return;
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
files: result
files: result.files
.map(
(xfile) => MatrixFile(
bytes: xfile.toUint8List(),
name: xfile.fileName!,
bytes: xfile.bytes!,
name: xfile.name,
).detectFileType,
)
.toList(),
@ -374,20 +375,22 @@ class ChatController extends State<Chat> {
}
void sendImageAction() async {
final result = await FilePickerCross.importMultipleFromStorage(
type: FileTypeCross.image,
final result = await FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
allowMultiple: true,
);
if (result.isEmpty) return;
if (result == null || result.files.isEmpty) return;
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
files: result
files: result.files
.map(
(xfile) => MatrixFile(
bytes: xfile.toUint8List(),
name: xfile.fileName!,
bytes: xfile.bytes!,
name: xfile.name,
).detectFileType,
)
.toList(),

View file

@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:image_picker/image_picker.dart';
@ -312,12 +313,15 @@ class ChatDetailsController extends State<ChatDetails> {
name: result.path,
);
} else {
final result =
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
if (result.fileName == null) return;
final picked = await FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
);
final pickedFile = picked?.files.firstOrNull;
if (pickedFile == null) return;
file = MatrixFile(
bytes: result.toUint8List(),
name: result.fileName!,
bytes: pickedFile.bytes!,
name: pickedFile.name,
);
}
await showFutureLoadingDialog(

View file

@ -4,7 +4,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:hive_flutter/hive_flutter.dart';
@ -186,14 +187,15 @@ class HomeserverPickerController extends State<HomeserverPicker> {
}
Future<void> restoreBackup() async {
final file = await FilePickerCross.importFromStorage();
if (file.fileName == null) return;
final picked = await FilePicker.platform.pickFiles(withData: true);
final file = picked?.files.firstOrNull;
if (file == null) return;
await showFutureLoadingDialog(
context: context,
future: () async {
try {
final client = Matrix.of(context).getLoginClient();
await client.importDump(file.toString());
await client.importDump(String.fromCharCodes(file.bytes!));
Matrix.of(context).initMatrix();
} catch (e, s) {
Logs().e('Future error:', e, s);

View file

@ -3,7 +3,8 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:image_picker/image_picker.dart';
@ -134,12 +135,15 @@ class SettingsController extends State<Settings> {
name: result.path,
);
} else {
final result =
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
if (result.fileName == null) return;
final result = await FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
);
final pickedFile = result?.files.firstOrNull;
if (pickedFile == null) return;
file = MatrixFile(
bytes: result.toUint8List(),
name: result.fileName!,
bytes: pickedFile.bytes!,
name: pickedFile.name,
);
}
final success = await showFutureLoadingDialog(

View file

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:matrix/matrix.dart';
@ -209,12 +210,15 @@ class EmotesSettingsController extends State<EmotesSettings> {
void imagePickerAction(
ValueNotifier<ImagePackImageContent?> controller,
) async {
final result =
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
if (result.fileName == null) return;
final result = await FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
);
final pickedFile = result?.files.firstOrNull;
if (pickedFile == null) return;
var file = MatrixImageFile(
bytes: result.toUint8List(),
name: result.fileName!,
bytes: pickedFile.bytes!,
name: pickedFile.name,
);
try {
file = (await file.generateThumbnail(

View file

@ -4,7 +4,6 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:flutter_app_lock/flutter_app_lock.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
@ -13,6 +12,7 @@ import 'package:intl/intl.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../bootstrap/bootstrap_dialog.dart';
import 'settings_security_view.dart';
@ -177,25 +177,23 @@ class SettingsSecurityController extends State<SettingsSecurity> {
if (response != OkCancelResult.ok) {
return;
}
await showFutureLoadingDialog(
final file = await showFutureLoadingDialog(
context: context,
future: () async {
try {
final export = await Matrix.of(context).client.exportDump();
final filePickerCross = FilePickerCross(
Uint8List.fromList(const Utf8Codec().encode(export!)),
path:
'/fluffychat-export-${DateFormat(DateFormat.YEAR_MONTH_DAY).format(DateTime.now())}.fluffybackup',
fileExtension: 'fluffybackup',
);
await filePickerCross.exportToStorage(
subject: L10n.of(context)!.dehydrateShare,
);
} catch (e, s) {
Logs().e('Export error', e, s);
}
final export = await Matrix.of(context).client.exportDump();
if (export == null) throw Exception('Export data is null.');
final exportBytes = Uint8List.fromList(
const Utf8Codec().encode(export),
);
final exportFileName =
'fluffychat-export-${DateFormat(DateFormat.YEAR_MONTH_DAY).format(DateTime.now())}.fluffybackup';
return MatrixFile(bytes: exportBytes, name: exportFileName);
},
);
file.result?.save(context);
}
@override

View file

@ -1,8 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
@ -19,14 +18,16 @@ class SettingsStyle extends StatefulWidget {
class SettingsStyleController extends State<SettingsStyle> {
void setWallpaperAction() async {
final wallpaper =
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
final path = wallpaper.path;
if (path == null) return;
Matrix.of(context).wallpaper = File(path);
final picked = await FilePicker.platform.pickFiles(
type: FileType.image,
withData: false,
);
final pickedFile = picked?.files.firstOrNull;
if (pickedFile == null) return;
await Matrix.of(context)
.store
.setItem(SettingKeys.wallpaper, wallpaper.path);
.setItem(SettingKeys.wallpaper, pickedFile.path);
setState(() {});
}

View file

@ -1,9 +1,14 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:image_picker/image_picker.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:matrix/matrix.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/size_string.dart';
@ -13,10 +18,65 @@ extension MatrixFileExtension on MatrixFile {
if (PlatformInfos.isIOS) {
return share(context);
}
final fileName = name.split('/').last;
final file = FilePickerCross(bytes);
await file.exportToStorage(fileName: fileName, share: false);
if (PlatformInfos.isWeb) {
_webDownload();
return;
}
final downloadPath = PlatformInfos.isAndroid
? await getDownloadPathAndroid()
: await FilePicker.platform.saveFile(
dialogTitle: L10n.of(context)!.saveFile,
fileName: name,
type: filePickerFileType,
);
if (downloadPath == null) return;
final result = await showFutureLoadingDialog(
context: context,
future: () => File(downloadPath).writeAsBytes(bytes),
);
if (result.error != null) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
L10n.of(context)!.fileHasBeenSavedAt(downloadPath),
),
),
);
}
Future<String> getDownloadPathAndroid() async {
final downloadDirectories = await getExternalStorageDirectories(
type: StorageDirectory.downloads,
);
if (downloadDirectories != null && downloadDirectories.isNotEmpty) {
return downloadDirectories.first.path;
}
final fallbackDirectory = await getApplicationDocumentsDirectory();
return fallbackDirectory.path;
}
FileType get filePickerFileType {
if (this is MatrixImageFile) return FileType.image;
if (this is MatrixAudioFile) return FileType.audio;
if (this is MatrixVideoFile) return FileType.video;
return FileType.any;
}
void _webDownload() {
html.AnchorElement(
href: html.Url.createObjectUrlFromBlob(
html.Blob(
[bytes],
'application/octet-stream',
),
),
)
..download = name
..click();
}
void share(BuildContext context) async {