1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-25 22:39:22 +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/lists/users_list.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/network_image_widget.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/ui_utils.dart';
import 'package:flutter/material.dart';
/// Single posts tile
@ -19,7 +23,7 @@ const TextStyle _userNameStyle = TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0);
class PostTile extends StatelessWidget {
class PostTile extends StatefulWidget {
final Post post;
final UsersList usersInfo;
final void Function(Post) onTapLike;
@ -34,7 +38,20 @@ class PostTile extends StatelessWidget {
assert(onTapLike != null),
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() {
// Header row
@ -55,7 +72,7 @@ class PostTile extends StatelessWidget {
_user.displayName,
style: _userNameStyle,
),
Text(diffTimeFromNowToStr(post.timeSent)),
Text(diffTimeFromNowToStr(widget.post.timeSent)),
],
),
),
@ -69,7 +86,7 @@ class PostTile extends StatelessWidget {
Widget _buildContentRow() {
Widget postContent;
switch (post.kind) {
switch (widget.post.kind) {
case PostKind.IMAGE:
postContent = _buildPostImage();
break;
@ -83,7 +100,8 @@ class PostTile extends StatelessWidget {
Container(child: postContent),
// 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
Center(
child: InkWell(
onTap: () => onTapLike(post),
onTap: () => widget.onTapLike(widget.post),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
@ -106,12 +124,14 @@ class PostTile extends StatelessWidget {
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Icon(
Icons.thumb_up,
color: post.userLikes ? Colors.blue : null,
color: widget.post.userLikes ? Colors.blue : null,
),
),
Text(post.likes < 2
? tr("%num% like", args: {"num": post.likes.toString()})
: tr("%num% likes", args: {"num": post.likes.toString()}))
Text(widget.post.likes < 2
? tr("%num% like",
args: {"num": widget.post.likes.toString()})
: tr("%num% likes",
args: {"num": widget.post.likes.toString()}))
],
),
),
@ -137,9 +157,8 @@ class PostTile extends StatelessWidget {
],
),
),
Container(
child: post.hasComments ? _buildComments() : null,
child: widget.post.hasComments ? _buildComments() : null,
),
],
),
@ -148,7 +167,7 @@ class PostTile extends StatelessWidget {
Widget _buildPostImage() {
return NetworkImageWidget(
url: post.fileURL,
url: widget.post.fileURL,
allowFullScreen: true,
roundedEdges: false,
);
@ -156,16 +175,19 @@ class PostTile extends StatelessWidget {
/// Build the list of comments
Widget _buildComments() {
assert(post.hasComments);
assert(widget.post.hasComments);
final comments = List.generate(
post.comments.length,
final comments = List<Widget>.generate(
widget.post.comments.length,
(num) => CommentTile(
comment: post.comments[num],
user: usersInfo.getUser(post.comments[num].userID),
comment: widget.post.comments[num],
user: widget.usersInfo.getUser(widget.post.comments[num].userID),
),
);
// Add comments form
comments.add(_buildCommentsForm());
return Container(
color: Colors.grey[300],
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;
}
/// 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;
}