1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-26 23:09:21 +00:00
comunicmobile/lib/ui/widgets/post_create_form_widget.dart

239 lines
6.4 KiB
Dart

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();
_resetForm();
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
// Post text content
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(() {}),
),
),
// Post options
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// Text post button
_PostOptionWidget(
icon: Icons.text_format,
selected: postKind == PostKind.TEXT,
onTap: _resetPostSelection),
// Include image button
_PostOptionWidget(
icon: Icons.image,
selected: postKind == PostKind.IMAGE,
onTap: _pickImageForPost,
),
Expanded(
child: Container(),
),
// 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,
),
],
),
)
],
);
}
/// Reset the form
void _resetForm() {
setState(() {
_postVisibilityLevel = widget.postTarget == PostTarget.GROUP_PAGE
? PostVisibilityLevel.GROUP_MEMBERS
: PostVisibilityLevel.FRIENDS;
_postTextController.text = "";
_resetPostSelection();
});
}
/// 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);
}
/// Remove all data attached to the post (image, etc...)
void _resetPostSelection() {
setState(() {
_postImage = null;
});
}
/// Pick an image for the new post
Future<void> _pickImageForPost() async {
final image = await pickImage(context);
if (image == null) return;
_resetPostSelection();
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!"));
this._resetForm();
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,
);
}
}