Merge pull request #42 from krawieck/selectable-comments

This commit is contained in:
Marcin Wojnarowski 2020-09-16 22:12:19 +02:00 committed by GitHub
commit c99e8370fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 132 additions and 84 deletions

View File

@ -1,6 +1,8 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:lemmy_api_client/lemmy_api_client.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart';
import 'package:timeago/timeago.dart' as timeago; import 'package:timeago/timeago.dart' as timeago;
@ -13,7 +15,7 @@ import '../util/text_color.dart';
import 'bottom_modal.dart'; import 'bottom_modal.dart';
import 'markdown_text.dart'; import 'markdown_text.dart';
class Comment extends StatelessWidget { class Comment extends HookWidget {
final int indent; final int indent;
final int postCreatorId; final int postCreatorId;
final CommentTree commentTree; final CommentTree commentTree;
@ -32,57 +34,6 @@ class Comment extends StatelessWidget {
@required this.postCreatorId, @required this.postCreatorId,
}); });
void _openMoreMenu(BuildContext context) {
final com = commentTree.comment;
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (context) => BottomModal(
child: Column(
children: [
ListTile(
leading: Icon(Icons.open_in_browser),
title: Text('Open in browser'),
onTap: () async => await ul.canLaunch(com.apId)
? ul.launch(com.apId)
: Scaffold.of(context).showSnackBar(
SnackBar(content: Text("can't open in browser"))),
),
ListTile(
leading: Icon(Icons.share),
title: Text('Share url'),
onTap: () =>
Share.text('Share comment url', com.apId, 'text/plain'),
),
ListTile(
leading: Icon(Icons.share),
title: Text('Share text'),
onTap: () =>
Share.text('Share comment text', com.content, 'text/plain'),
),
ListTile(
leading: Icon(Icons.info_outline),
title: Text('Nerd stuff'),
onTap: () => _showCommentInfo(context),
),
],
),
),
);
}
void _save(bool save) {
print('SAVE COMMENT, $save');
}
void _reply() {
print('OPEN REPLY BOX');
}
void _vote(VoteType vote) {
print('COMMENT VOTE: ${vote.toString()}');
}
_showCommentInfo(BuildContext context) { _showCommentInfo(BuildContext context) {
final com = commentTree.comment; final com = commentTree.comment;
showDialog( showDialog(
@ -141,10 +92,83 @@ class Comment extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final comment = commentTree.comment; final selectable = useState(false);
final showRaw = useState(false);
final comment = commentTree.comment;
final saved = comment.saved ?? false; final saved = comment.saved ?? false;
void _openMoreMenu(BuildContext context) {
pop() => Navigator.of(context).pop();
final com = commentTree.comment;
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (context) => BottomModal(
child: Column(
children: [
ListTile(
leading: Icon(Icons.open_in_browser),
title: Text('Open in browser'),
onTap: () async => await ul.canLaunch(com.apId)
? ul.launch(com.apId)
: Scaffold.of(context).showSnackBar(
SnackBar(content: Text("can't open in browser"))),
),
ListTile(
leading: Icon(Icons.share),
title: Text('Share url'),
onTap: () =>
Share.text('Share comment url', com.apId, 'text/plain'),
),
ListTile(
leading: Icon(Icons.share),
title: Text('Share text'),
onTap: () =>
Share.text('Share comment text', com.content, 'text/plain'),
),
ListTile(
leading: Icon(
selectable.value ? Icons.assignment : Icons.content_cut),
title:
Text('Make text ${selectable.value ? 'un' : ''}selectable'),
onTap: () {
selectable.value = !selectable.value;
pop();
},
),
ListTile(
leading: Icon(showRaw.value ? Icons.brush : Icons.build),
title: Text('Show ${showRaw.value ? 'fancy' : 'raw'} text'),
onTap: () {
showRaw.value = !showRaw.value;
pop();
},
),
ListTile(
leading: Icon(Icons.info_outline),
title: Text('Nerd stuff'),
onTap: () => _showCommentInfo(context),
),
],
),
),
);
}
void _save(bool save) {
print('SAVE COMMENT, $save');
}
void _reply() {
print('OPEN REPLY BOX');
}
void _vote(VoteType vote) {
print('COMMENT VOTE: ${vote.toString()}');
}
// decide which username to use // decide which username to use
final username = () { final username = () {
if (comment.creatorPreferredUsername != null && if (comment.creatorPreferredUsername != null &&
@ -170,11 +194,57 @@ class Comment extends StatelessWidget {
)); ));
} else { } else {
return Flexible( return Flexible(
child: MarkdownText(commentTree.comment.content, child: showRaw.value
instanceUrl: commentTree.comment.instanceUrl)); ? selectable.value
? SelectableText(commentTree.comment.content)
: Text(commentTree.comment.content)
: MarkdownText(
commentTree.comment.content,
instanceUrl: commentTree.comment.instanceUrl,
selectable: selectable.value,
));
} }
}(); }();
final actions = Row(children: [
if (selectable.value)
_CommentAction(
icon: Icons.content_copy,
tooltip: 'copy',
onPressed: () {
Clipboard.setData(
ClipboardData(text: commentTree.comment.content))
.then((_) => Scaffold.of(context).showSnackBar(
SnackBar(content: Text('comment copied to clipboard'))));
}),
Spacer(),
_CommentAction(
icon: Icons.more_horiz,
onPressed: () => _openMoreMenu(context),
tooltip: 'more',
),
_CommentAction(
icon: saved ? Icons.bookmark : Icons.bookmark_border,
onPressed: () => _save(!saved),
tooltip: '${saved ? 'unsave' : 'save'} comment',
),
_CommentAction(
icon: Icons.reply,
onPressed: _reply,
tooltip: 'reply',
),
_CommentAction(
icon: Icons.arrow_upward,
onPressed: () => _vote(VoteType.up),
tooltip: 'upvote',
),
_CommentAction(
icon: Icons.arrow_downward,
onPressed: () => _vote(VoteType.down),
tooltip: 'downvote',
),
]);
return Column( return Column(
children: [ children: [
Container( Container(
@ -228,35 +298,10 @@ class Comment extends StatelessWidget {
), ),
) )
]), ]),
SizedBox(height: 10),
Row(children: [body]), Row(children: [body]),
Row(children: [ SizedBox(height: 5),
Spacer(), actions,
_CommentAction(
icon: Icons.more_horiz,
onPressed: () => _openMoreMenu(context),
tooltip: 'more',
),
_CommentAction(
icon: saved ? Icons.bookmark : Icons.bookmark_border,
onPressed: () => _save(!saved),
tooltip: '${saved ? 'unsave' : 'save'} comment',
),
_CommentAction(
icon: Icons.reply,
onPressed: _reply,
tooltip: 'reply',
),
_CommentAction(
icon: Icons.arrow_upward,
onPressed: () => _vote(VoteType.up),
tooltip: 'upvote',
),
_CommentAction(
icon: Icons.arrow_downward,
onPressed: () => _vote(VoteType.down),
tooltip: 'downvote',
),
])
], ],
), ),
padding: EdgeInsets.all(10), padding: EdgeInsets.all(10),

View File

@ -9,11 +9,14 @@ import 'fullscreenable_image.dart';
class MarkdownText extends StatelessWidget { class MarkdownText extends StatelessWidget {
final String instanceUrl; final String instanceUrl;
final String text; final String text;
MarkdownText(this.text, {@required this.instanceUrl}) final bool selectable;
MarkdownText(this.text, {@required this.instanceUrl, this.selectable = false})
: assert(instanceUrl != null); : assert(instanceUrl != null);
@override @override
Widget build(BuildContext context) => MarkdownBody( Widget build(BuildContext context) => MarkdownBody(
selectable: selectable,
data: text, data: text,
extensionSet: md.ExtensionSet.gitHubWeb, extensionSet: md.ExtensionSet.gitHubWeb,
onTapLink: (href) { onTapLink: (href) {