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 { // 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(); _postVisibilityLevel = widget.postTarget == PostTarget.GROUP_PAGE ? PostVisibilityLevel.GROUP_MEMBERS : PostVisibilityLevel.FRIENDS; } @override Widget build(BuildContext context) { return Column( children: [ // 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: [ // 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, ), ], ), ) ], ); } /// Change post visibility level Future _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 _pickImageForPost() async { final image = await pickImage(context); if (image == null) return; _resetPostSelection(); setState(() { this._postImage = image; }); } /// Submit new post Future _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!")); 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, ); } }