2019-07-05 09:40:43 +00:00
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:comunic/enums/post_kind.dart';
|
|
|
|
import 'package:comunic/enums/post_target.dart';
|
|
|
|
import 'package:comunic/enums/post_visibility_level.dart';
|
|
|
|
import 'package:comunic/helpers/posts_helper.dart';
|
|
|
|
import 'package:comunic/models/new_post.dart';
|
|
|
|
import 'package:comunic/utils/files_utils.dart';
|
|
|
|
import 'package:comunic/utils/intl_utils.dart';
|
|
|
|
import 'package:comunic/utils/post_utils.dart';
|
|
|
|
import 'package:comunic/utils/ui_utils.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
/// Widget that allows to create posts
|
|
|
|
///
|
|
|
|
/// @author Pierre HUBERT
|
|
|
|
|
|
|
|
const _ActiveButtonsColor = Colors.blue;
|
|
|
|
const _ActiveButtonsTextColor = Colors.white;
|
|
|
|
const _InactiveButtonsColor = Colors.grey;
|
|
|
|
const _InactiveButtonsTextColor = Colors.black;
|
|
|
|
|
|
|
|
class PostCreateFormWidget extends StatefulWidget {
|
|
|
|
final PostTarget postTarget;
|
|
|
|
final int targetID;
|
|
|
|
final void Function() onCreated;
|
|
|
|
|
|
|
|
const PostCreateFormWidget({
|
|
|
|
Key key,
|
|
|
|
@required this.postTarget,
|
|
|
|
@required this.targetID,
|
|
|
|
@required this.onCreated,
|
|
|
|
}) : assert(postTarget != null),
|
|
|
|
assert(targetID != null),
|
|
|
|
super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
_PostCreateFormWidgetState createState() => _PostCreateFormWidgetState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|
|
|
// Helpers
|
|
|
|
final PostsHelper _postHelper = PostsHelper();
|
|
|
|
|
|
|
|
// Class members
|
|
|
|
bool _isCreating = false;
|
|
|
|
final TextEditingController _postTextController = TextEditingController();
|
|
|
|
PostVisibilityLevel _postVisibilityLevel;
|
|
|
|
File _postImage;
|
|
|
|
|
|
|
|
bool get hasImage => _postImage != null;
|
|
|
|
|
|
|
|
bool get canSubmitForm =>
|
|
|
|
!_isCreating && _postTextController.text.length > 5 || hasImage;
|
|
|
|
|
|
|
|
PostKind get postKind {
|
|
|
|
if (hasImage)
|
|
|
|
return PostKind.IMAGE;
|
|
|
|
else
|
|
|
|
return PostKind.TEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
|
2020-04-17 08:41:10 +00:00
|
|
|
_resetForm();
|
2019-07-05 09:40:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Column(
|
|
|
|
children: <Widget>[
|
|
|
|
// Post text content
|
2019-07-05 09:50:37 +00:00
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
|
|
|
|
child: TextField(
|
|
|
|
controller: _postTextController,
|
|
|
|
minLines: 3,
|
|
|
|
maxLines: 10,
|
|
|
|
decoration: InputDecoration(hintText: tr("Create a new post...")),
|
|
|
|
onChanged: (s) => setState(() {}),
|
|
|
|
),
|
2019-07-05 09:40:43 +00:00
|
|
|
),
|
|
|
|
|
|
|
|
// Post options
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.only(right: 16.0),
|
|
|
|
child: Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
children: <Widget>[
|
2019-07-05 09:50:37 +00:00
|
|
|
// Text post button
|
|
|
|
_PostOptionWidget(
|
|
|
|
icon: Icons.text_format,
|
|
|
|
selected: postKind == PostKind.TEXT,
|
|
|
|
onTap: _resetPostSelection),
|
|
|
|
|
2019-07-05 09:40:43 +00:00
|
|
|
// Include image button
|
|
|
|
_PostOptionWidget(
|
|
|
|
icon: Icons.image,
|
2019-07-05 09:50:37 +00:00
|
|
|
selected: postKind == PostKind.IMAGE,
|
2019-07-05 09:40:43 +00:00
|
|
|
onTap: _pickImageForPost,
|
|
|
|
),
|
|
|
|
|
2019-07-05 09:50:37 +00:00
|
|
|
Expanded(
|
|
|
|
child: Container(),
|
|
|
|
),
|
|
|
|
|
2019-07-05 09:40:43 +00:00
|
|
|
// Post visibility level
|
|
|
|
_PostOptionWidget(
|
|
|
|
icon: PostVisibilityLevelsMapIcons[_postVisibilityLevel],
|
|
|
|
selected: false,
|
|
|
|
customColor: Colors.black,
|
|
|
|
onTap: _changeVisibilityLevel,
|
|
|
|
),
|
|
|
|
|
|
|
|
// Submit post button
|
|
|
|
_isCreating
|
|
|
|
? Container()
|
|
|
|
: FlatButton(
|
|
|
|
child: Text(tr("Send").toUpperCase()),
|
|
|
|
onPressed: canSubmitForm ? _submitForm : null,
|
|
|
|
color: _ActiveButtonsColor,
|
|
|
|
textColor: _ActiveButtonsTextColor,
|
|
|
|
disabledColor: _InactiveButtonsColor,
|
|
|
|
disabledTextColor: _InactiveButtonsTextColor,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-04-17 08:41:10 +00:00
|
|
|
/// Reset the form
|
|
|
|
void _resetForm() {
|
|
|
|
setState(() {
|
|
|
|
_postVisibilityLevel = widget.postTarget == PostTarget.GROUP_PAGE
|
|
|
|
? PostVisibilityLevel.GROUP_MEMBERS
|
|
|
|
: PostVisibilityLevel.FRIENDS;
|
|
|
|
|
|
|
|
_postTextController.text = "";
|
|
|
|
_resetPostSelection();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-05 09:40:43 +00:00
|
|
|
/// Change post visibility level
|
|
|
|
Future<void> _changeVisibilityLevel() async {
|
|
|
|
final newLevel = await showPostVisibilityPicker(
|
|
|
|
context: context,
|
|
|
|
initialLevel: _postVisibilityLevel,
|
|
|
|
isGroup: widget.postTarget == PostTarget.GROUP_PAGE,
|
|
|
|
);
|
|
|
|
|
|
|
|
setState(() => _postVisibilityLevel = newLevel);
|
|
|
|
}
|
|
|
|
|
2019-07-05 09:50:37 +00:00
|
|
|
/// Remove all data attached to the post (image, etc...)
|
|
|
|
void _resetPostSelection() {
|
|
|
|
setState(() {
|
|
|
|
_postImage = null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-05 09:40:43 +00:00
|
|
|
/// Pick an image for the new post
|
|
|
|
Future<void> _pickImageForPost() async {
|
|
|
|
final image = await pickImage(context);
|
|
|
|
|
|
|
|
if (image == null) return;
|
|
|
|
|
2019-07-05 09:50:37 +00:00
|
|
|
_resetPostSelection();
|
|
|
|
|
2019-07-05 09:40:43 +00:00
|
|
|
setState(() {
|
|
|
|
this._postImage = image;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Submit new post
|
|
|
|
Future<void> _submitForm() async {
|
|
|
|
if (!canSubmitForm)
|
|
|
|
showSimpleSnack(context, tr("Form can not be submitted at this point!"));
|
|
|
|
|
|
|
|
setState(() => _isCreating = true);
|
|
|
|
|
|
|
|
try {
|
|
|
|
await _postHelper.createPost(NewPost(
|
|
|
|
target: widget.postTarget,
|
|
|
|
targetID: widget.targetID,
|
|
|
|
visibility: _postVisibilityLevel,
|
|
|
|
content: _postTextController.text,
|
|
|
|
kind: postKind,
|
|
|
|
image: _postImage,
|
|
|
|
));
|
|
|
|
setState(() => _isCreating = false);
|
|
|
|
|
|
|
|
showSimpleSnack(context, tr("The post has been successfully created!"));
|
|
|
|
|
2020-04-17 08:41:10 +00:00
|
|
|
this._resetForm();
|
2019-07-05 09:40:43 +00:00
|
|
|
widget.onCreated();
|
|
|
|
} catch (e) {
|
|
|
|
setState(() => _isCreating = false);
|
|
|
|
print("Error while creating post : " + e.toString());
|
|
|
|
showSimpleSnack(context, tr("Could not create post !"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Widget for a single post option
|
|
|
|
class _PostOptionWidget extends StatelessWidget {
|
|
|
|
final IconData icon;
|
|
|
|
final bool selected;
|
|
|
|
final Color customColor;
|
|
|
|
final void Function() onTap;
|
|
|
|
|
|
|
|
const _PostOptionWidget(
|
|
|
|
{Key key,
|
|
|
|
@required this.icon,
|
|
|
|
@required this.selected,
|
|
|
|
@required this.onTap,
|
|
|
|
this.customColor})
|
|
|
|
: assert(icon != null),
|
|
|
|
assert(selected != null),
|
|
|
|
assert(onTap != null),
|
|
|
|
super(key: key);
|
|
|
|
|
|
|
|
bool get hasCustomColor => customColor != null;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return IconButton(
|
|
|
|
icon: Icon(icon),
|
|
|
|
onPressed: onTap,
|
|
|
|
color: hasCustomColor
|
|
|
|
? customColor
|
|
|
|
: selected ? _ActiveButtonsColor : _InactiveButtonsColor,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|