mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-12-26 12:58:51 +00:00
Simplify image picking code
This commit is contained in:
parent
ea45bf828c
commit
e70aaabbc9
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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(
|
||||
uri: "settings/upload_custom_emoji",
|
||||
needLogin: true,
|
||||
args: {"shortcut": newEmoji.shortcut})
|
||||
.addPickedFile("image", newEmoji.image)
|
||||
.execWithFiles())
|
||||
.assertOk();
|
||||
await APIRequest(
|
||||
uri: "settings/upload_custom_emoji",
|
||||
needLogin: true,
|
||||
args: {"shortcut": newEmoji.shortcut})
|
||||
.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)
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
final image = await pickImage(context);
|
||||
try {
|
||||
final image = await pickImage(context);
|
||||
|
||||
if (image == null) return;
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
// Pick a new image
|
||||
final newImage = await pickImage(context);
|
||||
setState(() {
|
||||
_commentImage = newImage;
|
||||
});
|
||||
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
|
||||
|
@ -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,15 +242,20 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
||||
|
||||
/// Pick an image for the new post
|
||||
Future<void> _pickImageForPost() async {
|
||||
final image = await pickImage(context);
|
||||
try {
|
||||
final image = await pickImage(context);
|
||||
|
||||
if (image == null) return;
|
||||
if (image == null) return;
|
||||
|
||||
_resetPostSelection();
|
||||
_resetPostSelection();
|
||||
|
||||
setState(() {
|
||||
this._postImage = image;
|
||||
});
|
||||
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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user