1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-10-23 06:53:23 +00:00

Simplify image picking code

This commit is contained in:
Pierre HUBERT 2021-03-13 18:03:20 +01:00
parent ea45bf828c
commit e70aaabbc9
14 changed files with 85 additions and 105 deletions

View File

@ -60,17 +60,6 @@ class APIHelper {
contentType: v.type,
)));
}
// Process picked files
for (final key in request.pickedFiles.keys) {
var v = request.pickedFiles[key];
data.files.add(MapEntry(
key,
MultipartFile.fromBytes(
await v.readAsBytes(),
filename: v.path.split("/").last,
)));
}
}
// Execute the request

View File

@ -17,7 +17,7 @@ class CommentsHelper {
"content": comment.hasContent ? comment.content : "",
});
if (comment.hasImage) request.addPickedFile("image", comment.image);
if (comment.hasImage) request.addBytesFile("image", comment.image);
final response = await request.execWithFiles();

View File

@ -142,7 +142,7 @@ class PostsHelper {
break;
case PostKind.IMAGE:
request.addPickedFile("image", post.image);
request.addBytesFile("image", post.image);
break;
case PostKind.WEB_LINK:

View File

@ -5,7 +5,8 @@ import 'package:comunic/models/data_conservation_policy_settings.dart';
import 'package:comunic/models/general_settings.dart';
import 'package:comunic/models/new_emoji.dart';
import 'package:comunic/models/security_settings.dart';
import 'package:image_picker/image_picker.dart';
import '../models/api_request.dart';
/// Settings helper
///
@ -92,11 +93,10 @@ class SettingsHelper {
}
/// Upload a new account image
static Future<bool> uploadAccountImage(PickedFile newImage) async =>
(await APIRequest(uri: "settings/upload_account_image", needLogin: true)
.addPickedFile("picture", newImage)
.execWithFiles())
.isOK;
static Future<void> uploadAccountImage(BytesFile newImage) async =>
await APIRequest(uri: "settings/upload_account_image", needLogin: true)
.addBytesFile("picture", newImage)
.execWithFilesAndThrow();
/// Upload a new account image from memory
static Future<bool> uploadAccountImageFromMemory(List<int> bytes) async =>
@ -128,13 +128,12 @@ class SettingsHelper {
/// Upload a new custom emoji
static Future<void> uploadNewCustomEmoji(NewEmoji newEmoji) async =>
(await APIRequest(
await APIRequest(
uri: "settings/upload_custom_emoji",
needLogin: true,
args: {"shortcut": newEmoji.shortcut})
.addPickedFile("image", newEmoji.image)
.execWithFiles())
.assertOk();
.addBytesFile("image", newEmoji.image)
.execWithFilesAndThrow();
/// Delete a custom emoji
///
@ -220,7 +219,8 @@ class SettingsHelper {
/// Throws in case of failure
static Future<void> setDataConservationPolicy(
String password, DataConservationPolicySettings newSettings) async {
await APIRequest(uri: "settings/set_data_conservation_policy", needLogin: true)
await APIRequest(
uri: "settings/set_data_conservation_policy", needLogin: true)
.addString("password", password)
.addInt("inactive_account_lifetime",
newSettings.inactiveAccountLifeTime ?? 0)

View File

@ -4,7 +4,6 @@ import 'package:comunic/helpers/api_helper.dart';
import 'package:comunic/models/api_response.dart';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import 'package:image_picker/image_picker.dart';
import 'package:meta/meta.dart';
/// API Request model
@ -32,7 +31,6 @@ class APIRequest {
CancelToken cancelToken;
Map<String, String> args;
Map<String, File> files = Map();
Map<String, PickedFile> pickedFiles = Map();
Map<String, BytesFile> bytesFiles = Map();
APIRequest({@required this.uri, this.needLogin = false, this.args})
@ -73,11 +71,6 @@ class APIRequest {
return this;
}
APIRequest addPickedFile(String name, PickedFile file) {
pickedFiles[name] = file;
return this;
}
APIRequest addBytesFile(String name, BytesFile file) {
this.bytesFiles[name] = file;
return this;

View File

@ -1,6 +1,7 @@
import 'package:image_picker/image_picker.dart';
import 'package:meta/meta.dart';
import 'api_request.dart';
/// New comment information
///
/// @author Pierre HUBERT
@ -8,7 +9,7 @@ import 'package:meta/meta.dart';
class NewComment {
final int postID;
final String content;
final PickedFile image;
final BytesFile image;
const NewComment({
@required this.postID,

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'api_request.dart';
/// New emoji information
///
@ -7,7 +8,7 @@ import 'package:image_picker/image_picker.dart';
class NewEmoji {
final String shortcut;
final PickedFile image;
final BytesFile image;
const NewEmoji({
@required this.shortcut,

View File

@ -1,9 +1,10 @@
import 'package:comunic/enums/post_kind.dart';
import 'package:comunic/enums/post_target.dart';
import 'package:comunic/enums/post_visibility_level.dart';
import 'package:image_picker/image_picker.dart';
import 'package:meta/meta.dart';
import 'api_request.dart';
/// New post information
///
/// @author Pierre HUBERT
@ -27,7 +28,7 @@ class NewPost {
final int targetID;
final PostVisibilityLevel visibility;
final String content;
final PickedFile image;
final BytesFile image;
final String url;
final List<int> pdf;
final PostKind kind;

View File

@ -15,6 +15,9 @@ import 'package:identicon/identicon.dart';
import 'package:random_string/random_string.dart';
import 'package:settings_ui/settings_ui.dart';
import '../../../utils/log_utils.dart';
import '../../../utils/ui_utils.dart';
/// Account image settings section
///
/// @author Pierre Hubert
@ -156,15 +159,16 @@ class _AccountImageSettingsScreenState
/// Upload a new account image
void _uploadAccountImage() async {
try {
final image = await pickImage(context);
if (image == null) return;
if (!await SettingsHelper.uploadAccountImage(image)) {
showSimpleSnack(context, tr("Could not upload your account image!"));
return;
await SettingsHelper.uploadAccountImage(image);
} catch (e, s) {
logError(e, s);
snack(context, tr("Failed to upload new account image!"));
}
_key.currentState.refresh();
}

View File

@ -12,7 +12,9 @@ import 'package:comunic/utils/input_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../../models/api_request.dart';
import '../../../utils/ui_utils.dart';
/// Emojies account settings
///
@ -136,7 +138,7 @@ class _NewCustomEmojiDialog extends StatefulWidget {
class _NewCustomEmojiDialogState extends State<_NewCustomEmojiDialog> {
final _controller = TextEditingController();
PickedFile _file;
BytesFile _file;
bool get _hasImage => _file != null;
@ -209,6 +211,7 @@ class _NewCustomEmojiDialogState extends State<_NewCustomEmojiDialog> {
});
} catch (e, stack) {
print("Could not pick an image! $e\n$stack");
snack(context, tr("Failed to pick an image!"));
}
}
}

View File

@ -259,19 +259,19 @@ class _GroupSettingsScreenState extends SafeState<GroupSettingsScreen> {
// Upload a new logo
SettingsTile(
title: tr("Upload a new logo"),
onPressed: (_) => _uploadNewLogo,
onPressed: (_) => _uploadNewLogo(),
),
// Generate a new random logo
SettingsTile(
title: tr("Generate a new random logo"),
onPressed: (_) => _generateRandomLogo,
onPressed: (_) => _generateRandomLogo(),
),
// Delete current logo
SettingsTile(
title: tr("Delete logo"),
onPressed: (_) => _deleteLogo,
onPressed: (_) => _deleteLogo(),
),
],
);
@ -281,8 +281,8 @@ class _GroupSettingsScreenState extends SafeState<GroupSettingsScreen> {
void _uploadNewLogo() async {
try {
final logo = await pickImage(context);
final bytes = await logo.readAsBytes();
await _doUploadLogo(bytes);
if (logo == null) return;
await _doUploadLogo(logo.bytes);
} catch (e, stack) {
print("Could not upload new logo! $e\n$stack");
showSimpleSnack(context, tr("Could not upload new logo!"));
@ -328,7 +328,7 @@ class _GroupSettingsScreenState extends SafeState<GroupSettingsScreen> {
tiles: [
SettingsTile(
title: tr("Delete group"),
onPressed: (_) => _deleteGroup,
onPressed: (_) => _deleteGroup(),
),
],
);

View File

@ -26,9 +26,11 @@ import 'package:comunic/utils/post_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_picker/image_picker.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../models/api_request.dart';
import '../../utils/log_utils.dart';
/// Single posts tile
///
/// @author Pierre HUBERT
@ -77,7 +79,7 @@ class _PostTileState extends State<PostTile> {
// Class members
TextEditingController _commentController = TextEditingController();
PickedFile _commentImage;
BytesFile _commentImage;
bool _submitting = false;
int _maxNumberOfCommentToShow = 10;
@ -493,11 +495,16 @@ class _PostTileState extends State<PostTile> {
return;
}
try {
// Pick a new image
final newImage = await pickImage(context);
setState(() {
_commentImage = newImage;
});
} catch (e, s) {
logError(e, s);
snack(context, tr("Failed to choose an image!"));
}
}
/// Submit comment entered by the user

View File

@ -13,7 +13,10 @@ import 'package:comunic/utils/post_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../models/api_request.dart';
import '../../utils/log_utils.dart';
import '../../utils/ui_utils.dart';
/// Widget that allows to create posts
///
@ -48,7 +51,7 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
bool _isCreating = false;
final TextEditingController _postTextController = TextEditingController();
PostVisibilityLevel _postVisibilityLevel;
PickedFile _postImage;
BytesFile _postImage;
String _postURL;
List<int> _postPDF;
DateTime _timeEnd;
@ -239,6 +242,7 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
/// Pick an image for the new post
Future<void> _pickImageForPost() async {
try {
final image = await pickImage(context);
if (image == null) return;
@ -248,6 +252,10 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
setState(() {
this._postImage = image;
});
} catch (e, s) {
logError(e, s);
snack(context, tr("Failed to pick image for post!"));
}
}
/// Choose a new URL for the post

View File

@ -1,54 +1,27 @@
import 'dart:io';
import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:random_string/random_string.dart';
import '../models/api_request.dart';
import '../ui/dialogs/pick_file_dialog.dart';
/// Files utilities
///
/// @author Pierre HUBERT
enum _ChooseImageSource { GALLERY, CAMERA }
/// Ask the user to choose an image, either from the gallery or using the camera
///
/// Returns null in case of failure
Future<PickedFile> pickImage(BuildContext context) async {
/// First, we ask the user to choose between image picker and camera
final result = await showDialog<_ChooseImageSource>(
/// Throws an exception null in case of failure
Future<BytesFile> pickImage(BuildContext context) async {
return await showPickFileDialog(
context: context,
builder: (c) {
return AlertDialog(
title: Text(tr("Choose an image")),
actions: <Widget>[
//Gallery
TextButton(
onPressed: () => Navigator.pop(context, _ChooseImageSource.GALLERY),
child: Text(
tr("Image gallery").toUpperCase(),
),
),
// Camera
TextButton(
onPressed: () => Navigator.pop(context, _ChooseImageSource.CAMERA),
child: Text(
tr("Camera").toUpperCase(),
),
),
],
allowedMimeTypes: ["image/png", "image/jpeg", "image/gif"],
imageMaxHeight: 10000,
imageMaxWidth: 10000,
);
},
);
if (result == null) return null;
return await ImagePicker().getImage(
source: result == _ChooseImageSource.CAMERA
? ImageSource.camera
: ImageSource.gallery);
}
/// Generate a new temporary file