mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 21:09:21 +00:00
Can post PDFs
This commit is contained in:
parent
2cf017ad2d
commit
3a9bb3d13e
@ -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,
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
16
pubspec.lock
16
pubspec.lock
@ -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"
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user