Add comment sorting with temporary dropdown

This commit is contained in:
krawieck 2020-09-02 13:49:07 +02:00
parent 9e85fd5a2d
commit fcf622dcfe
3 changed files with 142 additions and 12 deletions

View File

@ -1,5 +1,16 @@
import 'package:lemmy_api_client/lemmy_api_client.dart';
import 'util/hot_rank.dart';
enum CommentSortType {
hot,
top,
// ignore: constant_identifier_names
new_,
old,
chat,
}
class CommentTree {
CommentView comment;
List<CommentTree> children;
@ -30,4 +41,63 @@ class CommentTree {
var result = parents.map(gatherChildren).toList();
return result;
}
void sort(CommentSortType sortType) {
switch (sortType) {
case CommentSortType.chat:
throw Exception('i dont do this kinda stuff kido');
case CommentSortType.hot:
return _sort((b, a) =>
a.comment.computedHotRank.compareTo(b.comment.computedHotRank));
case CommentSortType.new_:
return _sort(
(b, a) => a.comment.published.compareTo(b.comment.published));
case CommentSortType.old:
return _sort(
(b, a) => b.comment.published.compareTo(a.comment.published));
case CommentSortType.top:
return _sort((b, a) => a.comment.score.compareTo(b.comment.score));
}
}
void _sort(int compare(CommentTree a, CommentTree b)) {
children.sort(compare);
for (var el in children) {
el._sort(compare);
}
}
static void sortList(CommentSortType sortType, List<CommentTree> comms) {
switch (sortType) {
case CommentSortType.chat:
throw Exception('i dont do this kinda stuff kido');
case CommentSortType.hot:
comms.sort((b, a) =>
a.comment.computedHotRank.compareTo(b.comment.computedHotRank));
for (var i = 0; i < comms.length; i++) {
comms[i].sort(sortType);
}
break;
case CommentSortType.new_:
comms
.sort((b, a) => a.comment.published.compareTo(b.comment.published));
for (var i = 0; i < comms.length; i++) {
comms[i].sort(sortType);
}
break;
case CommentSortType.old:
comms
.sort((b, a) => b.comment.published.compareTo(a.comment.published));
for (var i = 0; i < comms.length; i++) {
comms[i].sort(sortType);
}
break;
case CommentSortType.top:
comms.sort((b, a) => a.comment.score.compareTo(b.comment.score));
for (var i = 0; i < comms.length; i++) {
comms[i].sort(sortType);
}
break;
}
}
}

View File

@ -1,7 +1,9 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:timeago/timeago.dart' as timeago;
import '../comment_tree.dart';
import '../util/text_color.dart';
import 'markdown_text.dart';
class Comment extends StatelessWidget {
@ -22,7 +24,7 @@ class Comment extends StatelessWidget {
@override
Widget build(BuildContext context) {
var comment = commentTree.comment;
final comment = commentTree.comment;
// decide which username to use
final username = () {
@ -91,6 +93,8 @@ class Comment extends StatelessWidget {
if (comment.bannedFromCommunity)
CommentTag('BANNED FROM COMMUNITY', Colors.red),
Spacer(),
Text(timeago.format(comment.published, locale: 'en_short')),
Text(' · '),
Text(comment.score.toString()),
]),
Row(children: [body]),
@ -137,7 +141,7 @@ class CommentTag extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2),
child: Text(text,
style: TextStyle(
color: Colors.white,
color: textColorBasedOnBackground(bgColor),
fontSize: Theme.of(context).textTheme.bodyText1.fontSize - 5,
fontWeight: FontWeight.w800,
)),

View File

@ -16,16 +16,72 @@ class CommentSection extends HookWidget {
assert(postCreatorId != null);
@override
Widget build(BuildContext context) => Column(children: [
// sorting menu goes here
if (comments.isEmpty)
Padding(
padding: EdgeInsets.symmetric(vertical: 50),
child: Text(
'no comments yet',
style: TextStyle(fontStyle: FontStyle.italic),
Widget build(BuildContext context) {
var rawComms = useState(rawComments);
var comms = useState(comments);
var sorting = useState(CommentSortType.hot);
return Column(children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
decoration: BoxDecoration(
border: Border.all(color: Colors.black45),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: DropdownButton(
// TODO: change it to universal BottomModal
underline: Container(),
isDense: true,
// ignore: avoid_types_on_closure_parameters
onChanged: (CommentSortType val) {
if (val != sorting.value && val != CommentSortType.chat) {
CommentTree.sortList(val, comms.value);
} else {
rawComms.value
.sort((a, b) => a.published.compareTo(b.published));
}
sorting.value = val;
},
value: sorting.value,
items: [
DropdownMenuItem(
child: Text('Hot'), value: CommentSortType.hot),
DropdownMenuItem(
child: Text('Top'), value: CommentSortType.top),
DropdownMenuItem(
child: Text('New'), value: CommentSortType.new_),
DropdownMenuItem(
child: Text('Old'), value: CommentSortType.old),
DropdownMenuItem(
child: Text('Chat'), value: CommentSortType.chat),
],
),
),
Spacer(),
],
),
),
// sorting menu goes here
if (comments.isEmpty)
Padding(
padding: EdgeInsets.symmetric(vertical: 50),
child: Text(
'no comments yet',
style: TextStyle(fontStyle: FontStyle.italic),
),
for (var com in comments) Comment(com, postCreatorId: postCreatorId),
]);
)
else if (sorting.value == CommentSortType.chat)
for (final com in rawComms.value)
Comment(
CommentTree(com),
postCreatorId: postCreatorId,
)
else
for (var com in comms.value) Comment(com, postCreatorId: postCreatorId),
]);
}
}