Implement file picker web

This commit is contained in:
Christian Pauly 2020-06-20 09:32:49 +00:00
parent bcda0bbd5f
commit 2d83df34c0
9 changed files with 90 additions and 68 deletions

View File

@ -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

View File

@ -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),

View File

@ -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,
),
),

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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,
),
);

View File

@ -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:

View File

@ -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