Merge pull request #1383 from krille-chan/krille/use-file-selector-on-linux

refactor: Use file selector on linux
This commit is contained in:
Krille-chan 2024-10-03 21:37:40 +02:00 committed by GitHub
commit 44bd4db774
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 144 additions and 89 deletions

View file

@ -10,7 +10,6 @@ import 'package:collection/collection.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/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:go_router/go_router.dart';
@ -29,11 +28,11 @@ import 'package:fluffychat/pages/chat/event_info_dialog.dart';
import 'package:fluffychat/pages/chat/recording_dialog.dart';
import 'package:fluffychat/pages/chat_details/chat_details.dart';
import 'package:fluffychat/utils/error_reporter.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../utils/account_bundles.dart';
import '../../utils/localized_exception_extension.dart';
@ -481,17 +480,12 @@ class ChatController extends State<ChatPageWithRoom>
}
void sendFileAction() async {
final result = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
compressionQuality: 0,
allowMultiple: true,
),
);
if (result == null || result.files.isEmpty) return;
final files = await selectFiles(context, allowMultiple: true);
if (files.isEmpty) return;
await showAdaptiveDialog(
context: context,
builder: (c) => SendFileDialog(
files: result.xFiles,
files: files,
room: room,
outerContext: context,
),
@ -511,19 +505,17 @@ class ChatController extends State<ChatPageWithRoom>
}
void sendImageAction() async {
final result = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
compressionQuality: 0,
type: FileType.image,
allowMultiple: true,
),
final files = await selectFiles(
context,
allowMultiple: true,
extensions: imageExtensions,
);
if (result == null || result.files.isEmpty) return;
if (files.isEmpty) return;
await showAdaptiveDialog(
context: context,
builder: (c) => SendFileDialog(
files: result.xFiles,
files: files,
room: room,
outerContext: context,
),

View file

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.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:go_router/go_router.dart';
@ -11,9 +10,9 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/chat_details/chat_details_view.dart';
import 'package:fluffychat/pages/settings/settings.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import 'package:fluffychat/widgets/matrix.dart';
enum AliasActions { copy, delete, setCanonical }
@ -165,16 +164,15 @@ class ChatDetailsController extends State<ChatDetails> {
name: result.path,
);
} else {
final picked = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
),
final picked = await selectFiles(
context,
allowMultiple: false,
extensions: imageExtensions,
);
final pickedFile = picked?.files.firstOrNull;
final pickedFile = picked.firstOrNull;
if (pickedFile == null) return;
file = MatrixFile(
bytes: pickedFile.bytes!,
bytes: await pickedFile.readAsBytes(),
name: pickedFile.name,
);
}

View file

@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'package:go_router/go_router.dart';
@ -15,8 +14,8 @@ import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../utils/localized_exception_extension.dart';
@ -201,10 +200,8 @@ class HomeserverPickerController extends State<HomeserverPicker> {
Widget build(BuildContext context) => HomeserverPickerView(this);
Future<void> restoreBackup() async {
final picked = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(withData: true),
);
final file = picked?.files.firstOrNull;
final picked = await selectFiles(context);
final file = picked.firstOrNull;
if (file == null) return;
setState(() {
error = null;
@ -212,7 +209,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
});
try {
final client = Matrix.of(context).getLoginClient();
await client.importDump(String.fromCharCodes(file.bytes!));
await client.importDump(String.fromCharCodes(await file.readAsBytes()));
Matrix.of(context).initMatrix();
} catch (e) {
setState(() {

View file

@ -2,11 +2,11 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:fluffychat/pages/new_group/new_group_view.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/widgets/matrix.dart';
class NewGroup extends StatefulWidget {
@ -35,15 +35,16 @@ class NewGroupController extends State<NewGroup> {
void setGroupCanBeFound(bool b) => setState(() => groupCanBeFound = b);
void selectPhoto() async {
final photo = await FilePicker.platform.pickFiles(
type: FileType.image,
final photo = await selectFiles(
context,
extensions: imageExtensions,
allowMultiple: false,
withData: true,
);
final bytes = await photo.singleOrNull?.readAsBytes();
setState(() {
avatarUrl = null;
avatar = photo?.files.singleOrNull?.bytes;
avatar = bytes;
});
}

View file

@ -2,13 +2,13 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/new_space/new_space_view.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -32,15 +32,14 @@ class NewSpaceController extends State<NewSpace> {
Uri? avatarUrl;
void selectPhoto() async {
final photo = await FilePicker.platform.pickFiles(
type: FileType.image,
allowMultiple: false,
withData: true,
final photo = await selectFiles(
context,
extensions: imageExtensions,
);
final bytes = await photo.firstOrNull?.readAsBytes();
setState(() {
avatarUrl = null;
avatar = photo?.files.singleOrNull?.bytes;
avatar = bytes;
});
}

View file

@ -4,14 +4,13 @@ import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.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';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import '../../widgets/matrix.dart';
import '../bootstrap/bootstrap_dialog.dart';
import 'settings_view.dart';
@ -136,16 +135,11 @@ class SettingsController extends State<Settings> {
name: result.path,
);
} else {
final result = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
),
);
final pickedFile = result?.files.firstOrNull;
final result = await selectFiles(context, extensions: imageExtensions);
final pickedFile = result.firstOrNull;
if (pickedFile == null) return;
file = MatrixFile(
bytes: pickedFile.bytes!,
bytes: await pickedFile.readAsBytes(),
name: pickedFile.name,
);
}

View file

@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.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:go_router/go_router.dart';
@ -13,8 +12,8 @@ import 'package:http/http.dart' hide Client;
import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import '../../widgets/matrix.dart';
import 'import_archive_dialog.dart';
import 'settings_emotes_view.dart';
@ -222,16 +221,11 @@ class EmotesSettingsController extends State<EmotesSettings> {
void imagePickerAction(
ValueNotifier<ImagePackImageContent?> controller,
) async {
final result = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
),
);
final pickedFile = result?.files.firstOrNull;
final result = await selectFiles(context, extensions: imageExtensions);
final pickedFile = result.firstOrNull;
if (pickedFile == null) return;
var file = MatrixImageFile(
bytes: pickedFile.bytes!,
bytes: await pickedFile.readAsBytes(),
name: pickedFile.name,
);
try {
@ -282,21 +276,17 @@ class EmotesSettingsController extends State<EmotesSettings> {
final result = await showFutureLoadingDialog<Archive?>(
context: context,
future: () async {
final result = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
'zip',
// TODO: add further encoders
],
// TODO: migrate to stream, currently brrrr because of `archive_io`.
withData: true,
),
final result = await selectFiles(
context,
extensions: [
'zip',
// TODO: add further encoders
],
);
if (result == null) return null;
if (result.isEmpty) return null;
final buffer = InputStream(result.files.single.bytes);
final buffer = InputStream(await result.first.readAsBytes());
final archive = ZipDecoder().decodeBuffer(buffer);

View file

@ -1,12 +1,11 @@
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/account_config.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/widgets/theme_builder.dart';
import '../../widgets/matrix.dart';
import 'settings_style_view.dart';
@ -26,20 +25,15 @@ class SettingsStyleController extends State<SettingsStyle> {
void setWallpaper() async {
final client = Matrix.of(context).client;
final picked = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
type: FileType.image,
withData: true,
),
);
final pickedFile = picked?.files.firstOrNull;
final picked = await selectFiles(context, extensions: imageExtensions);
final pickedFile = picked.firstOrNull;
if (pickedFile == null) return;
await showFutureLoadingDialog(
context: context,
future: () async {
final url = await client.uploadContent(
pickedFile.bytes!,
await pickedFile.readAsBytes(),
filename: pickedFile.name,
);
await client.updateApplicationAccountConfig(

View file

@ -0,0 +1,57 @@
import 'package:flutter/widgets.dart';
import 'package:file_picker/file_picker.dart';
import 'package:file_selector/file_selector.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_lock.dart';
Future<List<XFile>> selectFiles(
BuildContext context, {
String? title,
List<String>? extensions,
bool allowMultiple = false,
}) async {
if (!PlatformInfos.isLinux) {
final result = await AppLock.of(context).pauseWhile(
FilePicker.platform.pickFiles(
compressionQuality: 0,
allowMultiple: allowMultiple,
allowedExtensions: extensions,
),
);
return result?.xFiles ?? [];
}
if (allowMultiple) {
return await AppLock.of(context).pauseWhile(
openFiles(
confirmButtonText: title,
acceptedTypeGroups: [
if (extensions != null) XTypeGroup(extensions: extensions),
],
),
);
}
final file = await AppLock.of(context).pauseWhile(
openFile(
confirmButtonText: title,
acceptedTypeGroups: [
if (extensions != null) XTypeGroup(extensions: extensions),
],
),
);
if (file == null) return [];
return [file];
}
const imageExtensions = [
'png',
'PNG',
'jpg',
'JPG',
'jpeg',
'JPEG',
'webp',
'WebP',
];

View file

@ -382,6 +382,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.1.2"
file_selector:
dependency: "direct main"
description:
name: file_selector
sha256: "5019692b593455127794d5718304ff1ae15447dea286cdda9f0db2a796a1b828"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
file_selector_android:
dependency: transitive
description:
name: file_selector_android
sha256: b8c9717a0177ca6fa035554b82cd6c83b838ddc66b7704eb6df0f77f027ecc90
url: "https://pub.dev"
source: hosted
version: "0.5.1+7"
file_selector_ios:
dependency: transitive
description:
name: file_selector_ios
sha256: "38ebf91ecbcfa89a9639a0854ccaed8ab370c75678938eebca7d34184296f0bb"
url: "https://pub.dev"
source: hosted
version: "0.5.3"
file_selector_linux:
dependency: transitive
description:
@ -406,6 +430,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.6.2"
file_selector_web:
dependency: transitive
description:
name: file_selector_web
sha256: c4c0ea4224d97a60a7067eca0c8fd419e708ff830e0c83b11a48faf566cec3e7
url: "https://pub.dev"
source: hosted
version: "0.9.4+2"
file_selector_windows:
dependency: transitive
description:

View file

@ -27,6 +27,7 @@ dependencies:
emojis: ^0.9.9
#fcm_shared_isolate: ^0.1.0
file_picker: ^8.1.2
file_selector: ^1.0.3
flutter:
sdk: flutter
flutter_app_badger: ^1.5.0

View file

@ -132,5 +132,5 @@ index 69c80d6e..efd32d89 100644
- #fcm_shared_isolate: ^0.1.0
+ fcm_shared_isolate: ^0.1.0
file_picker: ^8.1.2
file_selector: ^1.0.3
flutter:
sdk: flutter