mirror of
				https://gitlab.com/famedly/fluffychat.git
				synced 2025-10-31 12:07:24 +01:00 
			
		
		
		
	Implement file picker web
This commit is contained in:
		
							parent
							
								
									bcda0bbd5f
								
							
						
					
					
						commit
						2d83df34c0
					
				| @ -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 | ||||
|  | ||||
| @ -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(), | ||||
|                               ] | ||||
|                             : <Widget>[ | ||||
|                                 if (!kIsWeb && inputText.isEmpty) | ||||
|                                 if (inputText.isEmpty) | ||||
|                                   PopupMenuButton<String>( | ||||
|                                     icon: Icon(Icons.add), | ||||
|                                     onSelected: (String choice) async { | ||||
| @ -694,32 +681,34 @@ class _ChatState extends State<_Chat> { | ||||
|                                           contentPadding: EdgeInsets.all(0), | ||||
|                                         ), | ||||
|                                       ), | ||||
|                                       PopupMenuItem<String>( | ||||
|                                         value: 'camera', | ||||
|                                         child: ListTile( | ||||
|                                           leading: CircleAvatar( | ||||
|                                             backgroundColor: Colors.purple, | ||||
|                                             foregroundColor: Colors.white, | ||||
|                                             child: Icon(Icons.camera_alt), | ||||
|                                       if (!kIsWeb) | ||||
|                                         PopupMenuItem<String>( | ||||
|                                           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<String>( | ||||
|                                         value: 'voice', | ||||
|                                         child: ListTile( | ||||
|                                           leading: CircleAvatar( | ||||
|                                             backgroundColor: Colors.red, | ||||
|                                             foregroundColor: Colors.white, | ||||
|                                             child: Icon(Icons.mic), | ||||
|                                       if (!kIsWeb) | ||||
|                                         PopupMenuItem<String>( | ||||
|                                           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), | ||||
|  | ||||
| @ -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<ChatDetails> { | ||||
|   } | ||||
| 
 | ||||
|   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<ChatDetails> { | ||||
|     final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( | ||||
|       widget.room.setAvatar( | ||||
|         MatrixFile( | ||||
|           bytes: await tempFile.readAsBytes(), | ||||
|           bytes: tempFile.bytes, | ||||
|           path: tempFile.path, | ||||
|         ), | ||||
|       ), | ||||
|  | ||||
| @ -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<Settings> { | ||||
|   } | ||||
| 
 | ||||
|   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<Settings> { | ||||
|     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<Settings> { | ||||
|   } | ||||
| 
 | ||||
|   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); | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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<SignUp> { | ||||
|   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<SignUp> { | ||||
|             ), | ||||
|             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) | ||||
|  | ||||
| @ -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<SignUpPassword> { | ||||
|       try { | ||||
|         await matrix.client.setAvatar( | ||||
|           MatrixFile( | ||||
|             bytes: await widget.avatar.readAsBytes(), | ||||
|             bytes: widget.avatar.bytes, | ||||
|             path: widget.avatar.path, | ||||
|           ), | ||||
|         ); | ||||
|  | ||||
							
								
								
									
										40
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								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: | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Christian Pauly
						Christian Pauly