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

Created comments form

This commit is contained in:
Pierre HUBERT 2019-05-18 09:45:15 +02:00
parent 28de22f427
commit c267940ce6
2 changed files with 167 additions and 18 deletions

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:comunic/enums/post_kind.dart'; import 'package:comunic/enums/post_kind.dart';
import 'package:comunic/lists/users_list.dart'; import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/post.dart'; import 'package:comunic/models/post.dart';
@ -6,7 +8,9 @@ import 'package:comunic/ui/tiles/comment_tile.dart';
import 'package:comunic/ui/widgets/account_image_widget.dart'; import 'package:comunic/ui/widgets/account_image_widget.dart';
import 'package:comunic/ui/widgets/network_image_widget.dart'; import 'package:comunic/ui/widgets/network_image_widget.dart';
import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/date_utils.dart';
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/ui_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// Single posts tile /// Single posts tile
@ -19,7 +23,7 @@ const TextStyle _userNameStyle = TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 16.0); fontSize: 16.0);
class PostTile extends StatelessWidget { class PostTile extends StatefulWidget {
final Post post; final Post post;
final UsersList usersInfo; final UsersList usersInfo;
final void Function(Post) onTapLike; final void Function(Post) onTapLike;
@ -34,7 +38,20 @@ class PostTile extends StatelessWidget {
assert(onTapLike != null), assert(onTapLike != null),
super(key: key); super(key: key);
User get _user => usersInfo.getUser(post.userID); @override
State<StatefulWidget> createState() => _PostTileState();
}
class _PostTileState extends State<PostTile> {
// Class members
TextEditingController _controller = TextEditingController();
File _commentImage;
User get _user => widget.usersInfo.getUser(widget.post.userID);
bool get _commentValid => _controller.text.toString().length > 3;
bool get _hasImage => _commentImage != null;
Widget _buildHeaderRow() { Widget _buildHeaderRow() {
// Header row // Header row
@ -55,7 +72,7 @@ class PostTile extends StatelessWidget {
_user.displayName, _user.displayName,
style: _userNameStyle, style: _userNameStyle,
), ),
Text(diffTimeFromNowToStr(post.timeSent)), Text(diffTimeFromNowToStr(widget.post.timeSent)),
], ],
), ),
), ),
@ -69,7 +86,7 @@ class PostTile extends StatelessWidget {
Widget _buildContentRow() { Widget _buildContentRow() {
Widget postContent; Widget postContent;
switch (post.kind) { switch (widget.post.kind) {
case PostKind.IMAGE: case PostKind.IMAGE:
postContent = _buildPostImage(); postContent = _buildPostImage();
break; break;
@ -83,7 +100,8 @@ class PostTile extends StatelessWidget {
Container(child: postContent), Container(child: postContent),
// Post text // Post text
Container(child: post.hasContent ? Text(post.content) : null), Container(
child: widget.post.hasContent ? Text(widget.post.content) : null),
], ],
); );
} }
@ -97,7 +115,7 @@ class PostTile extends StatelessWidget {
// Like button // Like button
Center( Center(
child: InkWell( child: InkWell(
onTap: () => onTapLike(post), onTap: () => widget.onTapLike(widget.post),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -106,12 +124,14 @@ class PostTile extends StatelessWidget {
padding: const EdgeInsets.only(left: 8.0, right: 8.0), padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Icon( child: Icon(
Icons.thumb_up, Icons.thumb_up,
color: post.userLikes ? Colors.blue : null, color: widget.post.userLikes ? Colors.blue : null,
), ),
), ),
Text(post.likes < 2 Text(widget.post.likes < 2
? tr("%num% like", args: {"num": post.likes.toString()}) ? tr("%num% like",
: tr("%num% likes", args: {"num": post.likes.toString()})) args: {"num": widget.post.likes.toString()})
: tr("%num% likes",
args: {"num": widget.post.likes.toString()}))
], ],
), ),
), ),
@ -137,9 +157,8 @@ class PostTile extends StatelessWidget {
], ],
), ),
), ),
Container( Container(
child: post.hasComments ? _buildComments() : null, child: widget.post.hasComments ? _buildComments() : null,
), ),
], ],
), ),
@ -148,7 +167,7 @@ class PostTile extends StatelessWidget {
Widget _buildPostImage() { Widget _buildPostImage() {
return NetworkImageWidget( return NetworkImageWidget(
url: post.fileURL, url: widget.post.fileURL,
allowFullScreen: true, allowFullScreen: true,
roundedEdges: false, roundedEdges: false,
); );
@ -156,16 +175,19 @@ class PostTile extends StatelessWidget {
/// Build the list of comments /// Build the list of comments
Widget _buildComments() { Widget _buildComments() {
assert(post.hasComments); assert(widget.post.hasComments);
final comments = List.generate( final comments = List<Widget>.generate(
post.comments.length, widget.post.comments.length,
(num) => CommentTile( (num) => CommentTile(
comment: post.comments[num], comment: widget.post.comments[num],
user: usersInfo.getUser(post.comments[num].userID), user: widget.usersInfo.getUser(widget.post.comments[num].userID),
), ),
); );
// Add comments form
comments.add(_buildCommentsForm());
return Container( return Container(
color: Colors.grey[300], color: Colors.grey[300],
child: Padding( child: Padding(
@ -176,4 +198,98 @@ class PostTile extends StatelessWidget {
), ),
); );
} }
/// Build comments form
Widget _buildCommentsForm() {
return Padding(
padding: EdgeInsets.only(
left: 8.0,
right: 8.0,
top: (widget.post.comments.length > 0 ? 8.0 : 0)),
child: Row(
children: <Widget>[
// Comment input
Expanded(
child: TextField(
controller: _controller,
onChanged: (s) => setState(() {}),
onSubmitted: _commentValid ? (s) => _submitComment() : null,
decoration: InputDecoration(
hintText: tr("New comment..."),
hintStyle: TextStyle(color: Colors.grey, fontSize: 12),
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide(width: 0.5, color: Colors.grey),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(3),
bottomLeft: Radius.circular(3),
),
gapPadding: 1),
contentPadding: EdgeInsets.only(
left: 10,
right: 10,
bottom: 5,
top: 5,
)),
),
),
// Image button
Container(
width: 30,
child: FlatButton(
padding: EdgeInsets.only(),
onPressed: _pickImage,
child: Icon(
Icons.image,
color: _hasImage ? Colors.blue : Colors.grey,
),
),
),
// Submit button
Container(
width: 40,
child: FlatButton(
padding: EdgeInsets.only(),
onPressed:
_commentValid || _hasImage ? () => _submitComment() : null,
child: Icon(
Icons.send,
color: _commentValid || _hasImage ? Colors.blue : Colors.grey,
),
),
),
],
),
);
}
/// Pick an image
Future<void> _pickImage() async {
// Ask the user to confirm image removal if there is already one selected
if (_hasImage) {
if (await askUserConfirmation(
context: context,
title: tr("Remove selected image"),
message: tr("Do you want to unselected currently selected image ?"),
)) {
setState(() {
_commentImage = null;
});
}
return;
}
// Pick a new image
final newImage = await pickImage(context);
setState(() {
_commentImage = newImage;
});
}
/// Submit comment entered by the user
Future<bool> _submitComment() async {}
} }

View File

@ -118,3 +118,36 @@ Future<String> askUserString({
return controller.text; return controller.text;
} }
/// Show an alert dialog to get user confirmation for something
///
/// Return value of this function is never null
Future<bool> askUserConfirmation({
@required BuildContext context,
String title,
@required String message,
}) async {
if (title == null) title = tr("Confirm operation");
final result = await showDialog<bool>(
context: context,
builder: (c) => AlertDialog(
title: Text(title),
content: Text(message),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context, false),
child: Text(tr("Cancel").toUpperCase()),
),
FlatButton(
onPressed: () => Navigator.pop(context, true),
child: Text(
tr("Confirm").toUpperCase(),
style: TextStyle(color: Colors.red),
),
),
],
));
return result != null && result;
}