1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 21:09:21 +00:00

Can post PDFs

This commit is contained in:
Pierre HUBERT 2020-04-24 13:35:05 +02:00
parent 2cf017ad2d
commit 3a9bb3d13e
7 changed files with 89 additions and 13 deletions

View File

@ -56,8 +56,11 @@ class APIHelper {
var v = request.bytesFiles[key]; var v = request.bytesFiles[key];
data.files.add(MapEntry( data.files.add(MapEntry(
key, key,
MultipartFile.fromBytes(v.bytes, MultipartFile.fromBytes(
filename: v.filename.split("/").last))); v.bytes,
filename: v.filename.split("/").last,
contentType: v.type,
)));
} }
} }

View File

@ -11,6 +11,7 @@ import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/displayed_content.dart'; import 'package:comunic/models/displayed_content.dart';
import 'package:comunic/models/new_post.dart'; import 'package:comunic/models/new_post.dart';
import 'package:comunic/models/post.dart'; import 'package:comunic/models/post.dart';
import 'package:http_parser/http_parser.dart';
/// Posts helper /// Posts helper
/// ///
@ -57,7 +58,7 @@ class PostsHelper {
/// failure /// failure
Future<PostsList> getLatest({int from = 0}) async { Future<PostsList> getLatest({int from = 0}) async {
final response = final response =
await APIRequest(uri: "posts/get_latest", needLogin: true, args: { await APIRequest(uri: "posts/get_latest", needLogin: true, args: {
"include_groups": true.toString(), "include_groups": true.toString(),
"startFrom": from.toString(), "startFrom": from.toString(),
}).exec(); }).exec();
@ -76,7 +77,8 @@ class PostsHelper {
/// Get the list of posts of a user /// Get the list of posts of a user
Future<PostsList> getUserPosts(int userID, {int from = 0}) async { Future<PostsList> getUserPosts(int userID, {int from = 0}) async {
final response = await (APIRequest(uri: "posts/get_user", needLogin: true) final response = await (APIRequest(uri: "posts/get_user", needLogin: true)
..addInt("userID", userID)..addInt("startFrom", from == 0 ? 0 : from - 1)) ..addInt("userID", userID)
..addInt("startFrom", from == 0 ? 0 : from - 1))
.exec(); .exec();
if (response.code != 200) return null; if (response.code != 200) return null;
@ -93,7 +95,8 @@ class PostsHelper {
/// Get the list of posts of a group /// Get the list of posts of a group
Future<PostsList> getGroupPosts(int groupID, {int from = 0}) async { Future<PostsList> getGroupPosts(int groupID, {int from = 0}) async {
final response = await (APIRequest(uri: "posts/get_group", needLogin: true) final response = await (APIRequest(uri: "posts/get_group", needLogin: true)
..addInt("groupID", groupID)..addInt("startFrom", from == 0 ? 0 : from - 1)) ..addInt("groupID", groupID)
..addInt("startFrom", from == 0 ? 0 : from - 1))
.exec(); .exec();
if (response.code != 200) return null; if (response.code != 200) return null;
@ -126,11 +129,11 @@ class PostsHelper {
/// This function crash in case of error /// This function crash in case of error
Future<void> createPost(NewPost post) async { Future<void> createPost(NewPost post) async {
APIRequest request = APIRequest request =
APIRequest(uri: "posts/create", needLogin: true, args: { APIRequest(uri: "posts/create", needLogin: true, args: {
"kind-page": _APIPostsTargetKindsMap[post.target], "kind-page": _APIPostsTargetKindsMap[post.target],
"kind-id": post.targetID.toString(), "kind-id": post.targetID.toString(),
"visibility": _APIPostsVisibilityLevelMap.map( "visibility": _APIPostsVisibilityLevelMap.map(
(s, v) => MapEntry(v, s))[post.visibility], (s, v) => MapEntry(v, s))[post.visibility],
"kind": _APIPostsKindsMap.map((s, k) => MapEntry(k, s))[post.kind], "kind": _APIPostsKindsMap.map((s, k) => MapEntry(k, s))[post.kind],
"content": post.content "content": post.content
}); });
@ -143,6 +146,13 @@ class PostsHelper {
request.addFile("image", post.image); request.addFile("image", post.image);
break; break;
case PostKind.PDF:
request.addBytesFile(
"pdf",
BytesFile("file.pdf", post.pdf,
type: MediaType.parse("application/pdf")));
break;
default: default:
throw Exception("Unsupported post type :" + post.kind.toString()); throw Exception("Unsupported post type :" + post.kind.toString());
break; break;
@ -174,7 +184,7 @@ class PostsHelper {
args: { args: {
"postID": id.toString(), "postID": id.toString(),
"new_level": "new_level":
_APIPostsVisibilityLevelMap.map((k, v) => MapEntry(v, k))[level] _APIPostsVisibilityLevelMap.map((k, v) => MapEntry(v, k))[level]
}, },
).exec()) ).exec())
.isOK; .isOK;

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:comunic/helpers/api_helper.dart'; import 'package:comunic/helpers/api_helper.dart';
import 'package:comunic/models/api_response.dart'; import 'package:comunic/models/api_response.dart';
import 'package:http_parser/http_parser.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
/// API Request model /// API Request model
@ -13,8 +14,13 @@ import 'package:meta/meta.dart';
class BytesFile { class BytesFile {
final String filename; final String filename;
final List<int> bytes; final List<int> bytes;
final MediaType type;
BytesFile(this.filename, this.bytes); const BytesFile(
this.filename,
this.bytes, {
this.type,
});
} }
class APIRequest { class APIRequest {

View File

@ -15,19 +15,22 @@ class NewPost {
final PostVisibilityLevel visibility; final PostVisibilityLevel visibility;
final String content; final String content;
final File image; final File image;
final List<int> pdf;
final PostKind kind; final PostKind kind;
NewPost({ const NewPost({
@required this.target, @required this.target,
@required this.targetID, @required this.targetID,
@required this.visibility, @required this.visibility,
@required this.content, @required this.content,
@required this.kind, @required this.kind,
@required this.image, @required this.image,
@required this.pdf,
}) : assert(target != null), }) : assert(target != null),
assert(targetID != null), assert(targetID != null),
assert(visibility != null), assert(visibility != null),
assert(content != null), assert(content != null),
assert(kind != PostKind.TEXT || content.length > 3), assert(kind != PostKind.TEXT || content.length > 3),
assert(kind != PostKind.IMAGE || image != null); assert(kind != PostKind.IMAGE || image != null),
assert(kind != PostKind.PDF || pdf != null);
} }

View File

@ -9,6 +9,7 @@ import 'package:comunic/utils/files_utils.dart';
import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/post_utils.dart'; import 'package:comunic/utils/post_utils.dart';
import 'package:comunic/utils/ui_utils.dart'; import 'package:comunic/utils/ui_utils.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// Widget that allows to create posts /// Widget that allows to create posts
@ -47,15 +48,20 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
final TextEditingController _postTextController = TextEditingController(); final TextEditingController _postTextController = TextEditingController();
PostVisibilityLevel _postVisibilityLevel; PostVisibilityLevel _postVisibilityLevel;
File _postImage; File _postImage;
List<int> _postPDF;
bool get hasImage => _postImage != null; bool get hasImage => _postImage != null;
bool get hasPDF => _postPDF != null;
bool get canSubmitForm => bool get canSubmitForm =>
!_isCreating && _postTextController.text.length > 5 || hasImage; !_isCreating && _postTextController.text.length > 5 || hasImage || hasPDF;
PostKind get postKind { PostKind get postKind {
if (hasImage) if (hasImage)
return PostKind.IMAGE; return PostKind.IMAGE;
else if (hasPDF)
return PostKind.PDF;
else else
return PostKind.TEXT; return PostKind.TEXT;
} }
@ -102,6 +108,13 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
onTap: _pickImageForPost, onTap: _pickImageForPost,
), ),
// Include PDF button
_PostOptionWidget(
icon: Icons.picture_as_pdf,
selected: postKind == PostKind.PDF,
onTap: _pickPDFForPost,
),
Expanded( Expanded(
child: Container(), child: Container(),
), ),
@ -159,6 +172,7 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
void _resetPostSelection() { void _resetPostSelection() {
setState(() { setState(() {
_postImage = null; _postImage = null;
_postPDF = null;
}); });
} }
@ -175,6 +189,27 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
}); });
} }
/// Pick a PDF for the new post
Future<void> _pickPDFForPost() async {
try {
final picker = FilePickerCross(
type: FileTypeCross.custom,
fileExtension: "pdf",
);
if (!await picker.pick()) return;
_resetPostSelection();
setState(() {
this._postPDF = picker.toUint8List();
});
} catch (e, stack) {
print("Pick PDF error: $e\n$stack");
showSimpleSnack(context, tr("Could not pick a PDF!"));
}
}
/// Submit new post /// Submit new post
Future<void> _submitForm() async { Future<void> _submitForm() async {
if (!canSubmitForm) if (!canSubmitForm)
@ -190,6 +225,7 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
content: _postTextController.text, content: _postTextController.text,
kind: postKind, kind: postKind,
image: _postImage, image: _postImage,
pdf: _postPDF,
)); ));
setState(() => _isCreating = false); setState(() => _isCreating = false);

View File

@ -113,6 +113,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
file_picker:
dependency: transitive
description:
name: file_picker
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.3+2"
file_picker_cross:
dependency: "direct main"
description:
name: file_picker_cross
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -171,7 +185,7 @@ packages:
source: hosted source: hosted
version: "0.12.0+4" version: "0.12.0+4"
http_parser: http_parser:
dependency: transitive dependency: "direct main"
description: description:
name: http_parser name: http_parser
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"

View File

@ -35,6 +35,7 @@ dependencies:
# The HTTP client is used to make requests on the Comunic API # The HTTP client is used to make requests on the Comunic API
dio: ^3.0.9 dio: ^3.0.9
http_parser: ^3.1.3
# This plugins allows to load remote images # This plugins allows to load remote images
cached_network_image: ^2.0.0 cached_network_image: ^2.0.0
@ -81,6 +82,9 @@ dependencies:
# Prevent phone from auto-locking during calls # Prevent phone from auto-locking during calls
wakelock: ^0.1.4+1 wakelock: ^0.1.4+1
# Pick any kind of file
file_picker_cross: ^1.2.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter