mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 12:59:21 +00:00
Created comments form
This commit is contained in:
parent
28de22f427
commit
c267940ce6
@ -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 {}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user