fix: Desktop file picker

This commit is contained in:
Christian Pauly 2020-10-04 17:01:54 +02:00 committed by Inex Code
parent d56b25b190
commit 1e5f7de794
12 changed files with 188 additions and 89 deletions

View File

@ -3,7 +3,8 @@ import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_platform_interface/file_picker_platform_interface.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart';
import 'package:fluffychat/components/avatar.dart'; import 'package:fluffychat/components/avatar.dart';
import 'package:fluffychat/components/chat_settings_popup_menu.dart'; import 'package:fluffychat/components/chat_settings_popup_menu.dart';
@ -17,6 +18,7 @@ import 'package:fluffychat/components/reply_content.dart';
import 'package:fluffychat/config/app_emojis.dart'; import 'package:fluffychat/config/app_emojis.dart';
import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/utils/matrix_locals.dart'; import 'package:fluffychat/utils/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/room_status_extension.dart'; import 'package:fluffychat/utils/room_status_extension.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -24,7 +26,6 @@ import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:memoryfilepicker/memoryfilepicker.dart';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:scroll_to_index/scroll_to_index.dart';
@ -211,38 +212,66 @@ class _ChatState extends State<_Chat> {
} }
void sendFileAction(BuildContext context) async { void sendFileAction(BuildContext context) async {
var file = await MemoryFilePicker.getFile(); final result =
if (file == null) return; await FilePickerCross.importFromStorage(type: FileTypeCross.any);
if (result == null) return;
await showDialog( await showDialog(
context: context, context: context,
builder: (context) => SendFileDialog( builder: (context) => SendFileDialog(
file: file: MatrixFile(
MatrixFile(bytes: file.bytes, name: file.path).detectFileType, bytes: result.toUint8List(),
room: room, name: result.fileName,
)); ).detectFileType,
room: room,
),
);
} }
void sendImageAction(BuildContext context) async { void sendImageAction(BuildContext context) async {
var file = await MemoryFilePicker.getFile(type: FileType.image); MatrixFile file;
if (file == null) return; if (PlatformInfos.isMobile) {
final bytes = await file.bytes; final result = await ImagePicker().getImage(
source: ImageSource.gallery,
imageQuality: 50,
maxWidth: 1600,
maxHeight: 1600);
if (result == null) return;
file = MatrixFile(
bytes: await result.readAsBytes(),
name: result.path,
);
} else {
final result =
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
if (result == null) return;
file = MatrixFile(
bytes: result.toUint8List(),
name: result.fileName,
);
}
await showDialog( await showDialog(
context: context, context: context,
builder: (context) => SendFileDialog( builder: (context) => SendFileDialog(
file: MatrixImageFile(bytes: bytes, name: file.path), file: file,
room: room, room: room,
)); ),
);
} }
void openCameraAction(BuildContext context) async { void openCameraAction(BuildContext context) async {
var file = await MemoryFilePicker.getImage(source: ImageSource.camera); var file = await ImagePicker().getImage(source: ImageSource.camera);
if (file == null) return; if (file == null) return;
final bytes = await file.readAsBytes();
await showDialog( await showDialog(
context: context, context: context,
builder: (context) => SendFileDialog( builder: (context) => SendFileDialog(
file: MatrixImageFile(bytes: file.bytes, name: file.path), file: MatrixImageFile(
room: room, bytes: bytes,
)); name: file.path,
),
room: room,
),
);
} }
void voiceMessageAction(BuildContext context) async { void voiceMessageAction(BuildContext context) async {
@ -888,7 +917,7 @@ class _ChatState extends State<_Chat> {
contentPadding: EdgeInsets.all(0), contentPadding: EdgeInsets.all(0),
), ),
), ),
if (!kIsWeb) if (PlatformInfos.isMobile)
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'camera', value: 'camera',
child: ListTile( child: ListTile(
@ -902,7 +931,7 @@ class _ChatState extends State<_Chat> {
contentPadding: EdgeInsets.all(0), contentPadding: EdgeInsets.all(0),
), ),
), ),
if (!kIsWeb) if (PlatformInfos.isMobile)
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'voice', value: 'voice',
child: ListTile( child: ListTile(
@ -972,7 +1001,7 @@ class _ChatState extends State<_Chat> {
), ),
), ),
), ),
if (!kIsWeb && inputText.isEmpty) if (PlatformInfos.isMobile && inputText.isEmpty)
Container( Container(
height: 56, height: 56,
alignment: Alignment.center, alignment: Alignment.center,

View File

@ -1,6 +1,8 @@
import 'package:bot_toast/bot_toast.dart'; import 'package:bot_toast/bot_toast.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart';
import 'package:fluffychat/components/chat_settings_popup_menu.dart'; import 'package:fluffychat/components/chat_settings_popup_menu.dart';
import 'package:fluffychat/components/content_banner.dart'; import 'package:fluffychat/components/content_banner.dart';
@ -8,6 +10,7 @@ import 'package:fluffychat/components/dialogs/simple_dialogs.dart';
import 'package:fluffychat/components/list_items/participant_list_item.dart'; import 'package:fluffychat/components/list_items/participant_list_item.dart';
import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/utils/matrix_locals.dart'; import 'package:fluffychat/utils/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/views/chat_list.dart'; import 'package:fluffychat/views/chat_list.dart';
import 'package:fluffychat/views/invitation_selection.dart'; import 'package:fluffychat/views/invitation_selection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -16,7 +19,6 @@ import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:matrix_link_text/link_text.dart'; import 'package:matrix_link_text/link_text.dart';
import 'package:memoryfilepicker/memoryfilepicker.dart';
import './settings_emotes.dart'; import './settings_emotes.dart';
import './settings_multiple_emotes.dart'; import './settings_multiple_emotes.dart';
@ -104,19 +106,31 @@ class _ChatDetailsState extends State<ChatDetails> {
} }
void setAvatarAction(BuildContext context) async { void setAvatarAction(BuildContext context) async {
final tempFile = await MemoryFilePicker.getImage( MatrixFile file;
source: ImageSource.gallery, if (PlatformInfos.isMobile) {
imageQuality: 50, final result = await ImagePicker().getImage(
maxWidth: 1600, source: ImageSource.gallery,
maxHeight: 1600); imageQuality: 50,
if (tempFile == null) return; maxWidth: 1600,
maxHeight: 1600);
if (result == null) return;
file = MatrixFile(
bytes: await result.readAsBytes(),
name: result.path,
);
} else {
final result = await FilePickerCross.importFromStorage(
type: FileTypeCross.image,
);
if (result == null) return;
file = MatrixFile(
bytes: result.toUint8List(),
name: result.fileName,
);
}
final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( final success = await SimpleDialogs(context).tryRequestWithLoadingDialog(
widget.room.setAvatar( widget.room.setAvatar(file),
MatrixFile(
bytes: tempFile.bytes,
name: tempFile.path,
),
),
); );
if (success != false) { if (success != false) {
BotToast.showText(text: L10n.of(context).avatarHasBeenChanged); BotToast.showText(text: L10n.of(context).avatarHasBeenChanged);

View File

@ -2,15 +2,17 @@ import 'dart:io';
import 'package:bot_toast/bot_toast.dart'; import 'package:bot_toast/bot_toast.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/components/settings_themes.dart'; import 'package:fluffychat/components/settings_themes.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/views/settings_devices.dart'; import 'package:fluffychat/views/settings_devices.dart';
import 'package:fluffychat/views/settings_ignore_list.dart'; import 'package:fluffychat/views/settings_ignore_list.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:memoryfilepicker/memoryfilepicker.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../components/adaptive_page_layout.dart'; import '../components/adaptive_page_layout.dart';
@ -137,20 +139,30 @@ class _SettingsState extends State<Settings> {
} }
void setAvatarAction(BuildContext context) async { void setAvatarAction(BuildContext context) async {
final tempFile = await MemoryFilePicker.getImage( MatrixFile file;
source: ImageSource.gallery, if (PlatformInfos.isMobile) {
imageQuality: 50, final result = await ImagePicker().getImage(
maxWidth: 1600, source: ImageSource.gallery,
maxHeight: 1600); imageQuality: 50,
if (tempFile == null) return; maxWidth: 1600,
maxHeight: 1600);
if (result == null) return;
file = MatrixFile(
bytes: await result.readAsBytes(),
name: result.path,
);
} else {
final result =
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
if (result == null) return;
file = MatrixFile(
bytes: result.toUint8List(),
name: result.fileName,
);
}
final matrix = Matrix.of(context); final matrix = Matrix.of(context);
final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( final success = await SimpleDialogs(context).tryRequestWithLoadingDialog(
matrix.client.setAvatar( matrix.client.setAvatar(file),
MatrixFile(
bytes: tempFile.bytes,
name: tempFile.path,
),
),
); );
if (success != false) { if (success != false) {
setState(() { setState(() {

View File

@ -1,12 +1,13 @@
import 'package:bot_toast/bot_toast.dart'; import 'package:bot_toast/bot_toast.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:memoryfilepicker/memoryfilepicker.dart';
import '../components/adaptive_page_layout.dart'; import '../components/adaptive_page_layout.dart';
import '../components/dialogs/simple_dialogs.dart'; import '../components/dialogs/simple_dialogs.dart';
@ -458,16 +459,30 @@ class _EmoteImagePickerState extends State<_EmoteImagePicker> {
BotToast.showText(text: L10n.of(context).notSupportedInWeb); BotToast.showText(text: L10n.of(context).notSupportedInWeb);
return; return;
} }
var file = await MemoryFilePicker.getImage( MatrixFile file;
source: ImageSource.gallery, if (PlatformInfos.isMobile) {
imageQuality: 50, final result = await ImagePicker().getImage(
maxWidth: 128, source: ImageSource.gallery,
maxHeight: 128); imageQuality: 50,
if (file == null) return; maxWidth: 1600,
final matrixFile = MatrixFile(bytes: file.bytes, name: file.path); maxHeight: 1600);
if (result == null) return;
file = MatrixFile(
bytes: await result.readAsBytes(),
name: result.path,
);
} else {
final result = await FilePickerCross.importFromStorage(
type: FileTypeCross.image);
if (result == null) return;
file = MatrixFile(
bytes: result.toUint8List(),
name: result.fileName,
);
}
final uploadResp = final uploadResp =
await SimpleDialogs(context).tryRequestWithLoadingDialog( await SimpleDialogs(context).tryRequestWithLoadingDialog(
Matrix.of(context).client.upload(matrixFile.bytes, matrixFile.name), Matrix.of(context).client.upload(file.bytes, file.name),
); );
setState(() { setState(() {
widget.controller.text = uploadResp; widget.controller.text = uploadResp;

View File

@ -1,6 +1,8 @@
import 'dart:math'; import 'dart:math';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/components/matrix.dart';
import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/views/login.dart'; import 'package:fluffychat/views/login.dart';
@ -8,8 +10,6 @@ import 'package:fluffychat/views/sign_up_password.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart';
import 'package:memoryfilepicker/memoryfilepicker.dart';
class SignUp extends StatefulWidget { class SignUp extends StatefulWidget {
SignUp({Key key, WellKnownInformations this.wellknown: null}) SignUp({Key key, WellKnownInformations this.wellknown: null})
@ -25,16 +25,19 @@ class _SignUpState extends State<SignUp> {
final TextEditingController usernameController = TextEditingController(); final TextEditingController usernameController = TextEditingController();
String usernameError; String usernameError;
bool loading = false; bool loading = false;
MemoryFile avatar; MatrixFile avatar;
void setAvatarAction() async { void setAvatarAction() async {
var file = await MemoryFilePicker.getImage( var file =
source: ImageSource.gallery, await FilePickerCross.importFromStorage(type: FileTypeCross.image);
maxHeight: 512, if (file != null) {
maxWidth: 512, setState(
imageQuality: 50, () => avatar = MatrixFile(
); bytes: file.toUint8List(),
if (file != null) setState(() => avatar = file); name: file.fileName,
),
);
}
} }
void signUpAction(BuildContext context) async { void signUpAction(BuildContext context) async {

View File

@ -2,17 +2,17 @@ import 'dart:math';
import 'package:bot_toast/bot_toast.dart'; import 'package:bot_toast/bot_toast.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/components/matrix.dart';
import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/views/auth_web_view.dart'; import 'package:fluffychat/views/auth_web_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:memoryfilepicker/memoryfilepicker.dart';
import 'chat_list.dart'; import 'chat_list.dart';
class SignUpPassword extends StatefulWidget { class SignUpPassword extends StatefulWidget {
final MemoryFile avatar; final MatrixFile avatar;
final String username; final String username;
final String displayname; final String displayname;
final WellKnownInformations wellknown; final WellKnownInformations wellknown;
@ -101,12 +101,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
} }
if (widget.avatar != null) { if (widget.avatar != null) {
try { try {
await matrix.client.setAvatar( await matrix.client.setAvatar(widget.avatar);
MatrixFile(
bytes: widget.avatar.bytes,
name: widget.avatar.path,
),
);
} catch (exception) { } catch (exception) {
BotToast.showText(text: L10n.of(context).couldNotSetAvatar); BotToast.showText(text: L10n.of(context).couldNotSetAvatar);
} }

View File

@ -4,9 +4,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_chooser/file_chooser_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_chooser_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileChooserPlugin");
file_chooser_plugin_register_with_registrar(file_chooser_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_chooser
url_launcher_linux url_launcher_linux
) )

View File

@ -162,6 +162,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.6" version: "1.3.6"
disk_space:
dependency: transitive
description:
name: disk_space
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.3"
encrypt: encrypt:
dependency: transitive dependency: transitive
description: description:
@ -197,6 +204,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.2.1" version: "5.2.1"
file_chooser:
dependency: transitive
description:
name: file_chooser
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
file_picker: file_picker:
dependency: transitive dependency: transitive
description: description:
@ -204,6 +218,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.13.3" version: "1.13.3"
file_picker_cross:
dependency: "direct main"
description:
name: file_picker_cross
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.2"
file_picker_platform_interface: file_picker_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -407,7 +428,7 @@ packages:
source: hosted source: hosted
version: "2.1.18" version: "2.1.18"
image_picker: image_picker:
dependency: transitive dependency: "direct main"
description: description:
name: image_picker name: image_picker
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
@ -497,13 +518,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.5" version: "0.1.5"
memoryfilepicker:
dependency: "direct main"
description:
name: memoryfilepicker
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -590,6 +604,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.3" version: "1.9.3"
package_info:
dependency: transitive
description:
name: package_info
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.3"
password_hash: password_hash:
dependency: transitive dependency: transitive
description: description:

View File

@ -28,7 +28,8 @@ dependencies:
path: ../famedlysdk path: ../famedlysdk
localstorage: ^3.0.1+4 localstorage: ^3.0.1+4
memoryfilepicker: ^0.1.3 file_picker_cross: ^4.2.2
image_picker: ^0.6.7+11
url_launcher: ^5.4.1 url_launcher: ^5.4.1
url_launcher_web: ^0.1.0 url_launcher_web: ^0.1.0
cached_network_image: ^2.3.2+1 cached_network_image: ^2.3.2+1

View File

@ -4,9 +4,12 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_chooser/file_chooser_plugin.h>
#include <url_launcher_windows/url_launcher_plugin.h> #include <url_launcher_windows/url_launcher_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
FileChooserPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileChooserPlugin"));
UrlLauncherPluginRegisterWithRegistrar( UrlLauncherPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherPlugin")); registry->GetRegistrarForPlugin("UrlLauncherPlugin"));
} }

View File

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_chooser
url_launcher_windows url_launcher_windows
) )