diff --git a/CHANGELOG.md b/CHANGELOG.md index 31f5033..928bcf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features: - New room list app bar design - Chat app bar transparent +- Implement web file picker ### Changes: - Show presences of users sharing a direct chat - Big refactoring diff --git a/lib/views/chat.dart b/lib/views/chat.dart index 8d24351..8c74540 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -3,7 +3,6 @@ import 'dart:io'; import 'dart:math'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:file_picker/file_picker.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/avatar.dart'; import 'package:fluffychat/components/chat_settings_popup_menu.dart'; @@ -20,9 +19,9 @@ import 'package:fluffychat/utils/room_status_extension.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:bot_toast/bot_toast.dart'; -import 'package:image_picker/image_picker.dart'; +import 'package:memoryfilepicker/memoryfilepicker.dart'; import 'package:pedantic/pedantic.dart'; +import 'package:image_picker/image_picker.dart'; import 'chat_details.dart'; import 'chat_list.dart'; @@ -187,25 +186,17 @@ class _ChatState extends State<_Chat> { } void sendFileAction(BuildContext context) async { - if (kIsWeb) { - BotToast.showText(text: L10n.of(context).notSupportedInWeb); - return; - } - var file = await FilePicker.getFile(); + var file = await MemoryFilePicker.getFile(); if (file == null) return; await SimpleDialogs(context).tryRequestWithLoadingDialog( room.sendFileEvent( - MatrixFile(bytes: await file.readAsBytes(), path: file.path), + MatrixFile(bytes: file.bytes, path: file.path), ), ); } void sendImageAction(BuildContext context) async { - if (kIsWeb) { - BotToast.showText(text: L10n.of(context).notSupportedInWeb); - return; - } - var file = await ImagePicker.pickImage( + var file = await MemoryFilePicker.getImage( source: ImageSource.gallery, imageQuality: 50, maxWidth: 1600, @@ -213,17 +204,13 @@ class _ChatState extends State<_Chat> { if (file == null) return; await SimpleDialogs(context).tryRequestWithLoadingDialog( room.sendImageEvent( - MatrixFile(bytes: await file.readAsBytes(), path: file.path), + MatrixFile(bytes: await file.bytes, path: file.path), ), ); } void openCameraAction(BuildContext context) async { - if (kIsWeb) { - BotToast.showText(text: L10n.of(context).notSupportedInWeb); - return; - } - var file = await ImagePicker.pickImage( + var file = await MemoryFilePicker.getImage( source: ImageSource.camera, imageQuality: 50, maxWidth: 1600, @@ -231,7 +218,7 @@ class _ChatState extends State<_Chat> { if (file == null) return; await SimpleDialogs(context).tryRequestWithLoadingDialog( room.sendImageEvent( - MatrixFile(bytes: await file.readAsBytes(), path: file.path), + MatrixFile(bytes: file.bytes, path: file.path), ), ); } @@ -650,7 +637,7 @@ class _ChatState extends State<_Chat> { : Container(), ] : [ - if (!kIsWeb && inputText.isEmpty) + if (inputText.isEmpty) PopupMenuButton( icon: Icon(Icons.add), onSelected: (String choice) async { @@ -694,32 +681,34 @@ class _ChatState extends State<_Chat> { contentPadding: EdgeInsets.all(0), ), ), - PopupMenuItem( - value: 'camera', - child: ListTile( - leading: CircleAvatar( - backgroundColor: Colors.purple, - foregroundColor: Colors.white, - child: Icon(Icons.camera_alt), + if (!kIsWeb) + PopupMenuItem( + value: 'camera', + child: ListTile( + leading: CircleAvatar( + backgroundColor: Colors.purple, + foregroundColor: Colors.white, + child: Icon(Icons.camera_alt), + ), + title: Text( + L10n.of(context).openCamera), + contentPadding: EdgeInsets.all(0), ), - title: - Text(L10n.of(context).openCamera), - contentPadding: EdgeInsets.all(0), ), - ), - PopupMenuItem( - value: 'voice', - child: ListTile( - leading: CircleAvatar( - backgroundColor: Colors.red, - foregroundColor: Colors.white, - child: Icon(Icons.mic), + if (!kIsWeb) + PopupMenuItem( + value: 'voice', + child: ListTile( + leading: CircleAvatar( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + child: Icon(Icons.mic), + ), + title: Text( + L10n.of(context).voiceMessage), + contentPadding: EdgeInsets.all(0), ), - title: Text( - L10n.of(context).voiceMessage), - contentPadding: EdgeInsets.all(0), ), - ), ], ), EncryptionButton(room), diff --git a/lib/views/chat_details.dart b/lib/views/chat_details.dart index 71e6d50..fb184bb 100644 --- a/lib/views/chat_details.dart +++ b/lib/views/chat_details.dart @@ -15,6 +15,7 @@ import 'package:flutter/services.dart'; import 'package:bot_toast/bot_toast.dart'; import 'package:image_picker/image_picker.dart'; import 'package:link_text/link_text.dart'; +import 'package:memoryfilepicker/memoryfilepicker.dart'; import './settings_emotes.dart'; class ChatDetails extends StatefulWidget { @@ -100,7 +101,7 @@ class _ChatDetailsState extends State { } void setAvatarAction(BuildContext context) async { - final tempFile = await ImagePicker.pickImage( + final tempFile = await MemoryFilePicker.getImage( source: ImageSource.gallery, imageQuality: 50, maxWidth: 1600, @@ -109,7 +110,7 @@ class _ChatDetailsState extends State { final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( widget.room.setAvatar( MatrixFile( - bytes: await tempFile.readAsBytes(), + bytes: tempFile.bytes, path: tempFile.path, ), ), diff --git a/lib/views/settings.dart b/lib/views/settings.dart index 4ba98ad..4a043dc 100644 --- a/lib/views/settings.dart +++ b/lib/views/settings.dart @@ -1,9 +1,12 @@ +import 'dart:io'; + import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/settings_themes.dart'; import 'package:fluffychat/views/settings_devices.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:memoryfilepicker/memoryfilepicker.dart'; import 'package:url_launcher/url_launcher.dart'; import 'app_info.dart'; @@ -81,7 +84,7 @@ class _SettingsState extends State { } void setAvatarAction(BuildContext context) async { - final tempFile = await ImagePicker.pickImage( + final tempFile = await MemoryFilePicker.getImage( source: ImageSource.gallery, imageQuality: 50, maxWidth: 1600, @@ -91,7 +94,7 @@ class _SettingsState extends State { final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( matrix.client.setAvatar( MatrixFile( - bytes: await tempFile.readAsBytes(), + bytes: tempFile.bytes, path: tempFile.path, ), ), @@ -105,9 +108,9 @@ class _SettingsState extends State { } void setWallpaperAction(BuildContext context) async { - final wallpaper = await ImagePicker.pickImage(source: ImageSource.gallery); + final wallpaper = await ImagePicker().getImage(source: ImageSource.gallery); if (wallpaper == null) return; - Matrix.of(context).wallpaper = wallpaper; + Matrix.of(context).wallpaper = File(wallpaper.path); await Matrix.of(context) .store .setItem('chat.fluffy.wallpaper', wallpaper.path); diff --git a/lib/views/settings_emotes.dart b/lib/views/settings_emotes.dart index 834f716..e7c0482 100644 --- a/lib/views/settings_emotes.dart +++ b/lib/views/settings_emotes.dart @@ -4,6 +4,7 @@ import 'package:flutter_advanced_networkimage/provider.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:image_picker/image_picker.dart'; import 'package:bot_toast/bot_toast.dart'; +import 'package:memoryfilepicker/memoryfilepicker.dart'; import 'chat_list.dart'; import '../components/adaptive_page_layout.dart'; @@ -367,14 +368,13 @@ class _EmoteImagePickerState extends State<_EmoteImagePicker> { BotToast.showText(text: L10n.of(context).notSupportedInWeb); return; } - var file = await ImagePicker.pickImage( + var file = await MemoryFilePicker.getImage( source: ImageSource.gallery, imageQuality: 50, maxWidth: 128, maxHeight: 128); if (file == null) return; - final matrixFile = - MatrixFile(bytes: await file.readAsBytes(), path: file.path); + final matrixFile = MatrixFile(bytes: file.bytes, path: file.path); final uploadResp = await SimpleDialogs(context).tryRequestWithLoadingDialog( Matrix.of(context) diff --git a/lib/views/sign_up.dart b/lib/views/sign_up.dart index 9be825e..5cb2cd2 100644 --- a/lib/views/sign_up.dart +++ b/lib/views/sign_up.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'dart:math'; import 'package:famedlysdk/famedlysdk.dart'; @@ -10,6 +9,7 @@ import 'package:fluffychat/views/sign_up_password.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:memoryfilepicker/memoryfilepicker.dart'; class SignUp extends StatefulWidget { @override @@ -20,10 +20,10 @@ class _SignUpState extends State { final TextEditingController usernameController = TextEditingController(); String usernameError; bool loading = false; - File avatar; + MemoryFile avatar; void setAvatarAction() async { - var file = await ImagePicker.pickImage( + var file = await MemoryFilePicker.getImage( source: ImageSource.gallery, maxHeight: 512, maxWidth: 512, @@ -92,7 +92,8 @@ class _SignUpState extends State { ), ListTile( leading: CircleAvatar( - backgroundImage: avatar == null ? null : FileImage(avatar), + backgroundImage: + avatar == null ? null : MemoryImage(avatar.bytes), backgroundColor: avatar == null ? Theme.of(context).brightness == Brightness.dark ? Color(0xff121212) diff --git a/lib/views/sign_up_password.dart b/lib/views/sign_up_password.dart index 16fc5c8..6990734 100644 --- a/lib/views/sign_up_password.dart +++ b/lib/views/sign_up_password.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'dart:math'; import 'package:famedlysdk/famedlysdk.dart'; @@ -8,11 +7,12 @@ import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/views/auth_web_view.dart'; import 'package:flutter/material.dart'; import 'package:bot_toast/bot_toast.dart'; +import 'package:memoryfilepicker/memoryfilepicker.dart'; import 'chat_list.dart'; class SignUpPassword extends StatefulWidget { - final File avatar; + final MemoryFile avatar; final String username; final String displayname; const SignUpPassword(this.username, {this.avatar, this.displayname}); @@ -100,7 +100,7 @@ class _SignUpPasswordState extends State { try { await matrix.client.setAvatar( MatrixFile( - bytes: await widget.avatar.readAsBytes(), + bytes: widget.avatar.bytes, path: widget.avatar.path, ), ); diff --git a/pubspec.lock b/pubspec.lock index 788c4c4..d0e06a3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -160,12 +160,19 @@ packages: source: hosted version: "0.1.3" file_picker: - dependency: "direct main" + dependency: transitive description: name: file_picker url: "https://pub.dartlang.org" source: hosted - version: "1.4.3+2" + version: "1.12.0" + file_picker_platform_interface: + dependency: transitive + description: + name: file_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" firebase_messaging: dependency: "direct main" description: @@ -225,6 +232,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.8" flutter_secure_storage: dependency: "direct main" description: @@ -327,12 +341,19 @@ packages: source: hosted version: "2.1.12" image_picker: - dependency: "direct main" + dependency: transitive description: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.6.2+3" + version: "0.6.7+2" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" intl: dependency: "direct main" description: @@ -405,6 +426,13 @@ packages: url: "https://gitlab.com/famedly/libraries/matrix_file_e2ee.git" source: git version: "1.0.3" + memoryfilepicker: + dependency: "direct main" + description: + name: memoryfilepicker + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1" meta: dependency: transitive description: @@ -553,7 +581,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" pointycastle: dependency: transitive description: @@ -740,7 +768,7 @@ packages: name: universal_html url: "https://pub.dartlang.org" source: hosted - version: "1.1.12" + version: "1.2.3" universal_io: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 563b878..982bae7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,8 +31,7 @@ dependencies: localstorage: ^3.0.1+4 bubble: ^1.1.9+1 - file_picker: ^1.4.3+2 - image_picker: ^0.6.2+3 + memoryfilepicker: ^0.1.1 flutter_speed_dial: ^1.2.5 url_launcher: ^5.4.1 url_launcher_web: ^0.1.0