From 10cc96d23a3ea488588f2ad6739be322048bee91 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 28 Aug 2020 13:30:42 +0200 Subject: [PATCH 01/27] Move actions to separate functions. still not implemented --- lib/components/post.dart | 72 ++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/lib/components/post.dart b/lib/components/post.dart index 2001b26..9b3112a 100644 --- a/lib/components/post.dart +++ b/lib/components/post.dart @@ -13,14 +13,57 @@ class PostWidget extends StatelessWidget { final String linkPostDomain; ThemeData _theme; -//https://images-assets.nasa.gov/image/PIA04921/PIA04921~orig.jpg + PostWidget(this.post) : hostUrl = post.communityActorId.split('/')[2], linkPostDomain = post.url != null ? post.url.split('/')[2] : null; + // == ACTIONS == + + void _openLink() { + print('OPEN LINK'); + } + + void _goToUser() { + print('GO TO USER'); + } + + void _goToPost() { + print('GO OT POST'); + } + + void _goToCommunity() { + print('GO TO COMMUNITY'); + } + + void _goToInstance() { + print('GO TO INSTANCE'); + } + + // POST ACTIONS + + void _savePost() { + print('SAVE POST'); + } + + void _upvotePost() { + print('UPVOTE POST'); + } + + void _downvotePost() { + print('DOWNVOTE POST'); + } + + void _showMoreMenu() { + print('SHOW MORE MENU'); + } + + // == UI == + @override Widget build(BuildContext context) { _theme = Theme.of(context); + return Container( decoration: BoxDecoration( boxShadow: [BoxShadow(blurRadius: 10, color: Colors.black54)], @@ -28,9 +71,7 @@ class PostWidget extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(20)), ), child: InkWell( - onTap: () { - print('GO TO POST'); - }, + onTap: _openLink, child: Column( children: [ _info(), @@ -55,7 +96,7 @@ class PostWidget extends StatelessWidget { Padding( padding: const EdgeInsets.only(right: 10), child: InkWell( - onTap: () => print('GO TO COMMUNITY'), + onTap: _goToCommunity, child: SizedBox( height: 40, width: 40, @@ -94,7 +135,7 @@ class PostWidget extends StatelessWidget { text: post.communityName, style: TextStyle(fontWeight: FontWeight.w600), recognizer: TapGestureRecognizer() - ..onTap = () => print('GO TO COMMUNITY')), + ..onTap = _goToCommunity), TextSpan( text: '@', style: TextStyle(fontWeight: FontWeight.w300)), @@ -102,7 +143,7 @@ class PostWidget extends StatelessWidget { text: hostUrl, style: TextStyle(fontWeight: FontWeight.w600), recognizer: TapGestureRecognizer() - ..onTap = () => print('GO TO INSTANCE')), + ..onTap = _goToInstance), ], ), ) @@ -122,8 +163,7 @@ class PostWidget extends StatelessWidget { text: ''' ${post.creatorPreferredUsername ?? post.creatorName}''', style: TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => print('GO TO USER'), + recognizer: TapGestureRecognizer()..onTap = _goToUser, ), TextSpan( text: @@ -141,7 +181,7 @@ class PostWidget extends StatelessWidget { Column( children: [ IconButton( - onPressed: () => print('POPUP MENU'), + onPressed: _showMoreMenu, icon: Icon(Icons.more_vert), ) ], @@ -166,7 +206,7 @@ class PostWidget extends StatelessWidget { ), if (post.thumbnailUrl != null) InkWell( - onTap: () => print('OPEN LINK'), + onTap: _openLink, child: Stack(children: [ ClipRRect( borderRadius: BorderRadius.circular(20), @@ -221,7 +261,7 @@ class PostWidget extends StatelessWidget { return Padding( padding: const EdgeInsets.all(10), child: InkWell( - onTap: () => print('OPEN LINK'), + onTap: _openLink, child: Container( decoration: BoxDecoration( border: Border.all(width: 1), @@ -270,13 +310,11 @@ class PostWidget extends StatelessWidget { icon: post.saved == true ? Icon(Icons.bookmark) : Icon(Icons.bookmark_border), - onPressed: () => print('SAVE')), - IconButton( - icon: Icon(Icons.arrow_upward), onPressed: () => print('UPVOTE')), + onPressed: _savePost), + IconButton(icon: Icon(Icons.arrow_upward), onPressed: _upvotePost), Text(post.score.toString()), IconButton( - icon: Icon(Icons.arrow_downward), - onPressed: () => print('DOWNVOTE')), + icon: Icon(Icons.arrow_downward), onPressed: _downvotePost), ], ), ); From e107fb6cc63225bd78fe95c974e8db32860bf32e Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 28 Aug 2020 13:45:03 +0200 Subject: [PATCH 02/27] Rename `components` to `widgets` --- lib/{components => widgets}/post.dart | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{components => widgets}/post.dart (100%) diff --git a/lib/components/post.dart b/lib/widgets/post.dart similarity index 100% rename from lib/components/post.dart rename to lib/widgets/post.dart From 697bbf4e9cbd257ebad1b6587f16536c4d65d9b4 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 28 Aug 2020 13:47:52 +0200 Subject: [PATCH 03/27] Bump `lemmy_api_client` and revise imports --- lib/widgets/post.dart | 2 +- pubspec.lock | 2 +- pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 9b3112a..77fb676 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -2,7 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:lemmy_api_client/src/models/post.dart'; +import 'package:lemmy_api_client/lemmy_api_client.dart'; import 'package:timeago/timeago.dart' as timeago; class PostWidget extends StatelessWidget { diff --git a/pubspec.lock b/pubspec.lock index 5da9ea7..7086f81 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -325,7 +325,7 @@ packages: name: lemmy_api_client url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" logging: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 690eed9..c12dfbb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: flutter_hooks: ^0.13.2 cached_network_image: ^2.2.0+1 timeago: ^2.0.27 - lemmy_api_client: ^0.1.3 + lemmy_api_client: ^0.1.4 flutter: sdk: flutter From 9fabb75676277315ae55f47b45e08a2755d147c7 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sat, 29 Aug 2020 20:31:53 +0200 Subject: [PATCH 04/27] fix overflow for number of comments --- lib/widgets/post.dart | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 77fb676..c045132 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -298,9 +298,17 @@ class PostWidget extends StatelessWidget { child: Row( children: [ Icon(Icons.comment), - post.numberOfComments == 1 - ? Text(' 1 comment') - : Text(' ${post.numberOfComments} comments'), + if (post.numberOfComments == 1) + Text(' 1 comment') + else + Expanded( + flex: 999, + child: Text( + ''' ${NumberFormat.compact().format(post.numberOfComments)} comments''', + overflow: TextOverflow.fade, + softWrap: false, + ), + ), Spacer(), IconButton( icon: Icon(Icons.share), From 015a29435bf3cd1a720109c2d38c7528eb267a96 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sat, 29 Aug 2020 21:01:01 +0200 Subject: [PATCH 05/27] Restruture `post.dart` to be more sane --- lib/widgets/post.dart | 65 +++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index c045132..cc43b37 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -2,9 +2,27 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; import 'package:timeago/timeago.dart' as timeago; +enum MediaType { + image, + gallery, + video, + other, +} + +MediaType whatType(String url) { + if (url == null) return MediaType.other; + + // @TODO: make detection more nuanced + if (url.endsWith('.jpg') || url.endsWith('.png') || url.endsWith('.gif')) { + return MediaType.image; + } + return MediaType.other; +} + class PostWidget extends StatelessWidget { final PostView post; final String hostUrl; @@ -40,6 +58,10 @@ class PostWidget extends StatelessWidget { print('GO TO INSTANCE'); } + void _openFullImage() { + print('OPEN FULL IMAGE'); + } + // POST ACTIONS void _savePost() { @@ -71,12 +93,16 @@ class PostWidget extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(20)), ), child: InkWell( - onTap: _openLink, + onTap: _goToPost, child: Column( children: [ _info(), _title(), - _content(), + if (whatType(post.url) != MediaType.other) + _postImage() + else if (post.url != null) + _linkPreview(), + if (post.body != null) _textBody(), _actions(), ], ), @@ -204,7 +230,13 @@ class PostWidget extends StatelessWidget { style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), ), ), - if (post.thumbnailUrl != null) + if (post.url != null && + !(whatType(post.url) != MediaType.other) && + post.thumbnailUrl != null) + Spacer(), + if (post.url != null && + !(whatType(post.url) != MediaType.other) && + post.thumbnailUrl != null) InkWell( onTap: _openLink, child: Stack(children: [ @@ -233,21 +265,17 @@ class PostWidget extends StatelessWidget { ); } - Widget _content() { - if (post.url == null) return Container(); - // naive implementation for now but will have - // to add system for detecting type of media - if (post.url.endsWith('.jpg') || - post.url.endsWith('.png') || - post.url.endsWith('.gif')) { - return CachedNetworkImage( + Widget _postImage() { + assert(post.url != null); + + return InkWell( + onTap: _openFullImage, + child: CachedNetworkImage( imageUrl: post.url, progressIndicatorBuilder: (context, url, progress) => CircularProgressIndicator(value: progress.progress), - ); - } else { - return _linkPreview(); - } + ), + ); } Widget _linkPreview() { @@ -292,6 +320,13 @@ class PostWidget extends StatelessWidget { ); } + Widget _textBody() { + return Padding( + padding: const EdgeInsets.all(10), + child: Text(post.body), + ); + } + Widget _actions() { return Padding( padding: const EdgeInsets.fromLTRB(10, 5, 10, 5), From 8c68c17308acaffde20d3d3588e1f917d9918868 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sat, 29 Aug 2020 22:50:37 +0200 Subject: [PATCH 06/27] Add markdown support for post --- lib/widgets/post.dart | 10 +++++++++- pubspec.lock | 14 ++++++++++++++ pubspec.yaml | 2 ++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index cc43b37..b7900de 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -2,8 +2,10 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:intl/intl.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; +import 'package:markdown/markdown.dart' as md; import 'package:timeago/timeago.dart' as timeago; enum MediaType { @@ -323,7 +325,13 @@ class PostWidget extends StatelessWidget { Widget _textBody() { return Padding( padding: const EdgeInsets.all(10), - child: Text(post.body), + child: MarkdownBody( + data: post.body, + extensionSet: md.ExtensionSet.gitHubWeb, + onTapLink: (href) { + // + }, + ), ); } diff --git a/pubspec.lock b/pubspec.lock index 7086f81..5371b06 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -244,6 +244,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.13.2" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.3" flutter_test: dependency: "direct dev" description: flutter @@ -333,6 +340,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.11.4" + markdown: + dependency: "direct main" + description: + name: markdown + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.8" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c12dfbb..4ffece3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,8 @@ environment: sdk: '>=2.7.0 <3.0.0' dependencies: + markdown: ^2.1.8 + flutter_markdown: ^0.4.3 esys_flutter_share: ^1.0.2 flutter_hooks: ^0.13.2 cached_network_image: ^2.2.0+1 From 8275dd1086ad895a3ecefea0ed1ea8cc83c3ea24 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 30 Aug 2020 16:39:32 +0200 Subject: [PATCH 07/27] Bump `lemmy_api_client` version --- pubspec.lock | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 5371b06..9740f36 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -332,7 +332,7 @@ packages: name: lemmy_api_client url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.2.1" logging: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4ffece3..5e530d9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,7 +27,7 @@ dependencies: flutter_hooks: ^0.13.2 cached_network_image: ^2.2.0+1 timeago: ^2.0.27 - lemmy_api_client: ^0.1.4 + lemmy_api_client: ^0.2.1 flutter: sdk: flutter From e673eac152315972b9602c082e6e32fd3626d099 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 30 Aug 2020 16:49:59 +0200 Subject: [PATCH 08/27] Add handlink links in markdown and general link launcher --- lib/url_launcher.dart | 10 ++++++++++ lib/widgets/post.dart | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 lib/url_launcher.dart diff --git a/lib/url_launcher.dart b/lib/url_launcher.dart new file mode 100644 index 0000000..a0a719e --- /dev/null +++ b/lib/url_launcher.dart @@ -0,0 +1,10 @@ +import 'package:url_launcher/url_launcher.dart' as ul; + +Future urlLauncher(String url) async { + if (await ul.canLaunch(url)) { + await ul.launch(url); + } else { + throw Exception(); + // @TODO handle opening links to stuff in app + } +} diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index b7900de..9a337fc 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -8,6 +8,8 @@ import 'package:lemmy_api_client/lemmy_api_client.dart'; import 'package:markdown/markdown.dart' as md; import 'package:timeago/timeago.dart' as timeago; +import '../url_launcher.dart'; + enum MediaType { image, gallery, @@ -33,6 +35,7 @@ class PostWidget extends StatelessWidget { final String linkPostDomain; ThemeData _theme; + BuildContext _context; PostWidget(this.post) : hostUrl = post.communityActorId.split('/')[2], @@ -87,6 +90,7 @@ class PostWidget extends StatelessWidget { @override Widget build(BuildContext context) { _theme = Theme.of(context); + _context = context; return Container( decoration: BoxDecoration( @@ -329,7 +333,10 @@ class PostWidget extends StatelessWidget { data: post.body, extensionSet: md.ExtensionSet.gitHubWeb, onTapLink: (href) { - // + urlLauncher(href) + .catchError((e) => Scaffold.of(_context).showSnackBar(SnackBar( + content: Text('couldn\'t open link'), + ))); }, ), ); From c56c8e34f3610a69ee2b483f5817474497afda5a Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 30 Aug 2020 18:54:51 +0200 Subject: [PATCH 09/27] Update pubspec.yaml --- pubspec.lock | 47 +++++++++++++++++++++++++++++++++++++++++++++++ pubspec.yaml | 1 + 2 files changed, 48 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index 9740f36..12d700a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -256,6 +256,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" glob: dependency: transitive description: @@ -445,6 +450,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.1" + platform_detect: + dependency: transitive + description: + name: platform_detect + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" plugin_platform_interface: dependency: transitive description: @@ -604,6 +616,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + url: "https://pub.dartlang.org" + source: hosted + version: "5.5.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+7" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.8" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" uuid: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5e530d9..6360dfb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,7 @@ environment: sdk: '>=2.7.0 <3.0.0' dependencies: + url_launcher: ^5.5.1 markdown: ^2.1.8 flutter_markdown: ^0.4.3 esys_flutter_share: ^1.0.2 From 91aada67e9053ae2a06c83c249ef687bf82370d4 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 30 Aug 2020 19:29:12 +0200 Subject: [PATCH 10/27] Remove '@' from '@TODO:' --- lib/widgets/post.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 9a337fc..45225e2 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -20,7 +20,7 @@ enum MediaType { MediaType whatType(String url) { if (url == null) return MediaType.other; - // @TODO: make detection more nuanced + // TODO: make detection more nuanced if (url.endsWith('.jpg') || url.endsWith('.png') || url.endsWith('.gif')) { return MediaType.image; } @@ -155,7 +155,7 @@ class PostWidget extends StatelessWidget { children: [ Row(children: [ RichText( - overflow: TextOverflow.ellipsis, // @TODO: fix overflowing + overflow: TextOverflow.ellipsis, // TODO: fix overflowing text: TextSpan( style: TextStyle( fontSize: 15, color: _theme.textTheme.bodyText1.color), @@ -363,7 +363,7 @@ class PostWidget extends StatelessWidget { IconButton( icon: Icon(Icons.share), onPressed: () => Share.text('Share post url', post.apId, - 'text/plain')), // @TODO: find a way to mark it as url + 'text/plain')), // TODO: find a way to mark it as url IconButton( icon: post.saved == true ? Icon(Icons.bookmark) From fcafde2d0f4c21deac23ca226572a4782ea99f1f Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 30 Aug 2020 19:31:55 +0200 Subject: [PATCH 11/27] Change if with 2 `Text`s to 1 `Text` with ternary inside --- lib/widgets/post.dart | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 45225e2..d770633 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -348,17 +348,14 @@ class PostWidget extends StatelessWidget { child: Row( children: [ Icon(Icons.comment), - if (post.numberOfComments == 1) - Text(' 1 comment') - else - Expanded( - flex: 999, - child: Text( - ''' ${NumberFormat.compact().format(post.numberOfComments)} comments''', - overflow: TextOverflow.fade, - softWrap: false, - ), + Expanded( + flex: 999, + child: Text( + ''' ${NumberFormat.compact().format(post.numberOfComments)} comment${post.numberOfComments == 1 ? '' : 's'}''', + overflow: TextOverflow.fade, + softWrap: false, ), + ), Spacer(), IconButton( icon: Icon(Icons.share), @@ -370,7 +367,7 @@ class PostWidget extends StatelessWidget { : Icon(Icons.bookmark_border), onPressed: _savePost), IconButton(icon: Icon(Icons.arrow_upward), onPressed: _upvotePost), - Text(post.score.toString()), + Text(NumberFormat.compact().format(post.score)), IconButton( icon: Icon(Icons.arrow_downward), onPressed: _downvotePost), ], From 712ea2994d5797a1febac3303c4eb43c9a54de07 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 01:46:47 +0200 Subject: [PATCH 12/27] Add CommentTree #16 `CommentTree` transforms `List` of `CommentView`s into a tree-like structure --- lib/widgets/comment_tree.dart | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 lib/widgets/comment_tree.dart diff --git a/lib/widgets/comment_tree.dart b/lib/widgets/comment_tree.dart new file mode 100644 index 0000000..d0da0da --- /dev/null +++ b/lib/widgets/comment_tree.dart @@ -0,0 +1,33 @@ +import 'package:lemmy_api_client/lemmy_api_client.dart'; + +class CommentTree { + CommentView comment; + List children; + + CommentTree(this.comment, [this.children]) { + children ??= []; + } + + static List fromList(List comments) { + CommentTree gatherChildren(CommentTree parent) { + for (var el in comments) { + if (el.parentId == parent.comment.id) { + parent.children.add(gatherChildren(CommentTree(el))); + } + } + return parent; + } + + var parents = []; + + // first pass to get all the parents + for (var i = 0; i < comments.length; i++) { + if (comments[i].parentId == null) { + parents.add(CommentTree(comments[i])); + } + } + + var result = parents.map(gatherChildren).toList(); + return result; + } +} From 3bb56a71dd92ef0f7127b11c2c083985227a7456 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 01:47:08 +0200 Subject: [PATCH 13/27] Add 2 widgets for displaying comments #16 --- lib/widgets/comment.dart | 49 +++++++++++++++++++++++++++++++++++++++ lib/widgets/comments.dart | 23 ++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 lib/widgets/comment.dart create mode 100644 lib/widgets/comments.dart diff --git a/lib/widgets/comment.dart b/lib/widgets/comment.dart new file mode 100644 index 0000000..4ef138d --- /dev/null +++ b/lib/widgets/comment.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +import 'comment_tree.dart'; + +class CommentWidget extends StatelessWidget { + final int indent; + final CommentTree commentTree; + CommentWidget( + this.commentTree, { + this.indent = 0, + }); + + @override + Widget build(BuildContext context) { + var comment = commentTree.comment; + return Column( + children: [ + Container( + child: Column( + children: [ + Row(children: [ + Text(comment.creatorPreferredUsername ?? comment.creatorName), + Spacer(), + Text(comment.score.toString()), + ]), + Row(children: [ + Flexible(child: Text(commentTree.comment.content)), + ]), + Row(children: [ + Spacer(), + // actions go here + ]) + ], + ), + padding: EdgeInsets.all(10), + margin: EdgeInsets.only(left: indent > 1 ? (indent - 1) * 5.0 : 0), + decoration: BoxDecoration( + border: Border( + left: indent > 0 + ? BorderSide(color: Colors.red, width: 5) + : BorderSide.none, + top: BorderSide(width: 0.2))), + ), + for (var c in commentTree.children) + CommentWidget(c, indent: indent + 1), + ], + ); + } +} diff --git a/lib/widgets/comments.dart b/lib/widgets/comments.dart new file mode 100644 index 0000000..c0a85bd --- /dev/null +++ b/lib/widgets/comments.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:lemmy_api_client/lemmy_api_client.dart'; + +import 'comment.dart'; +import 'comment_tree.dart'; + +/// Manages comments section, sorts them +class CommentsWidget extends HookWidget { + final List rawComments; + final List comments; + + CommentsWidget(this.rawComments) + : comments = CommentTree.fromList(rawComments); + + @override + Widget build(BuildContext context) { + return Column(children: [ + // sorting menu goes here + for (var com in comments) CommentWidget(com), + ]); + } +} From 2ca3565bfcd809e9bc51257c4d6dde8f04745232 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 12:22:29 +0200 Subject: [PATCH 14/27] Moved displaying markdown to separate widget --- lib/widgets/markdown_text.dart | 23 +++++++++++++++++++++++ lib/widgets/post.dart | 15 ++------------- 2 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 lib/widgets/markdown_text.dart diff --git a/lib/widgets/markdown_text.dart b/lib/widgets/markdown_text.dart new file mode 100644 index 0000000..f6d90f2 --- /dev/null +++ b/lib/widgets/markdown_text.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:markdown/markdown.dart' as md; + +import '../url_launcher.dart'; + +Widget MarkdownText(String text, BuildContext context) { + return MarkdownBody( + data: text, + extensionSet: md.ExtensionSet.gitHubWeb, + onTapLink: (href) { + urlLauncher(href) + .catchError((e) => Scaffold.of(context).showSnackBar(SnackBar( + content: Row( + children: [ + Icon(Icons.warning), + Text('couldn\'t open link'), + ], + ), + ))); + }, + ); +} diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index d770633..3044634 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -2,13 +2,11 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:intl/intl.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; -import 'package:markdown/markdown.dart' as md; import 'package:timeago/timeago.dart' as timeago; -import '../url_launcher.dart'; +import 'markdown_text.dart'; enum MediaType { image, @@ -329,16 +327,7 @@ class PostWidget extends StatelessWidget { Widget _textBody() { return Padding( padding: const EdgeInsets.all(10), - child: MarkdownBody( - data: post.body, - extensionSet: md.ExtensionSet.gitHubWeb, - onTapLink: (href) { - urlLauncher(href) - .catchError((e) => Scaffold.of(_context).showSnackBar(SnackBar( - content: Text('couldn\'t open link'), - ))); - }, - ), + child: MarkdownText(post.body, _context), ); } From cf3862d2e2865d1268d66c167e2bf609c5787a4f Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 12:23:32 +0200 Subject: [PATCH 15/27] Add markdown rendering to comments --- lib/widgets/comment.dart | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/widgets/comment.dart b/lib/widgets/comment.dart index 4ef138d..09865aa 100644 --- a/lib/widgets/comment.dart +++ b/lib/widgets/comment.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'comment_tree.dart'; +import 'markdown_text.dart'; class CommentWidget extends StatelessWidget { final int indent; @@ -13,6 +14,23 @@ class CommentWidget extends StatelessWidget { @override Widget build(BuildContext context) { var comment = commentTree.comment; + var body; + if (comment.deleted) { + body = Flexible( + child: Text( + 'comment deleted by creator', + style: TextStyle(fontStyle: FontStyle.italic), + )); + } else if (comment.removed) { + body = Flexible( + child: Text( + 'comment deleted by moderator', + style: TextStyle(fontStyle: FontStyle.italic), + )); + } else { + body = + Flexible(child: MarkdownText(commentTree.comment.content, context)); + } return Column( children: [ Container( @@ -23,9 +41,7 @@ class CommentWidget extends StatelessWidget { Spacer(), Text(comment.score.toString()), ]), - Row(children: [ - Flexible(child: Text(commentTree.comment.content)), - ]), + Row(children: [body]), Row(children: [ Spacer(), // actions go here From 663d4bb913c66e3d194647bf6023d2cddc1732d3 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 13:39:27 +0200 Subject: [PATCH 16/27] Fix username displaying for comments --- lib/widgets/comment.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/widgets/comment.dart b/lib/widgets/comment.dart index 09865aa..310840e 100644 --- a/lib/widgets/comment.dart +++ b/lib/widgets/comment.dart @@ -14,6 +14,16 @@ class CommentWidget extends StatelessWidget { @override Widget build(BuildContext context) { var comment = commentTree.comment; + + // decide which username to use + var username; + if (comment.creatorPreferredUsername != null && + comment.creatorPreferredUsername != '') { + username = comment.creatorPreferredUsername; + } else { + username = '@${comment.creatorName}'; + } + var body; if (comment.deleted) { body = Flexible( From 6704fed4e5d747773ecee8568bd6025b29d2cee0 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 15:29:02 +0200 Subject: [PATCH 17/27] Add comment pfp, op, banned --- lib/widgets/comment.dart | 72 +++++++++++++++++++++++++++++++++++++-- lib/widgets/comments.dart | 15 ++++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/lib/widgets/comment.dart b/lib/widgets/comment.dart index 310840e..7fa5c1d 100644 --- a/lib/widgets/comment.dart +++ b/lib/widgets/comment.dart @@ -5,12 +5,20 @@ import 'markdown_text.dart'; class CommentWidget extends StatelessWidget { final int indent; + final int postCreatorId; final CommentTree commentTree; CommentWidget( this.commentTree, { this.indent = 0, + @required this.postCreatorId, }); + void _goToUser() { + print('GO TO USER'); + } + + bool get isOP => commentTree.comment.creatorId == postCreatorId; + @override Widget build(BuildContext context) { var comment = commentTree.comment; @@ -47,7 +55,38 @@ class CommentWidget extends StatelessWidget { child: Column( children: [ Row(children: [ - Text(comment.creatorPreferredUsername ?? comment.creatorName), + if (comment.creatorAvatar != null) + InkWell( + onTap: _goToUser, + child: Padding( + padding: const EdgeInsets.only(right: 5), + child: CachedNetworkImage( + imageUrl: comment.creatorAvatar, + height: 20, + width: 20, + imageBuilder: (context, imageProvider) => Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + fit: BoxFit.cover, + image: imageProvider, + ), + ), + ), + ), + ), + ), + InkWell( + child: Text(username, + style: TextStyle( + color: Theme.of(context).accentColor, + )), + onLongPress: _goToUser, + ), + if (isOP) CommentTag('OP', Theme.of(context).accentColor), + if (comment.banned) CommentTag('BANNED', Colors.red), + if (comment.bannedFromCommunity) + CommentTag('BANNED FROM COMMUNITY', Colors.red), Spacer(), Text(comment.score.toString()), ]), @@ -68,8 +107,37 @@ class CommentWidget extends StatelessWidget { top: BorderSide(width: 0.2))), ), for (var c in commentTree.children) - CommentWidget(c, indent: indent + 1), + CommentWidget( + c, + indent: indent + 1, + postCreatorId: postCreatorId, + ), ], ); } } + +class CommentTag extends StatelessWidget { + final String text; + final Color bgColor; + + const CommentTag(this.text, this.bgColor); + + @override + Widget build(BuildContext context) => Padding( + padding: const EdgeInsets.only(left: 5), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5)), + color: bgColor, + ), + padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2), + child: Text(text, + style: TextStyle( + color: Colors.white, + fontSize: Theme.of(context).textTheme.bodyText1.fontSize - 5, + fontWeight: FontWeight.w800, + )), + ), + ); +} diff --git a/lib/widgets/comments.dart b/lib/widgets/comments.dart index c0a85bd..be6039c 100644 --- a/lib/widgets/comments.dart +++ b/lib/widgets/comments.dart @@ -9,15 +9,26 @@ import 'comment_tree.dart'; class CommentsWidget extends HookWidget { final List rawComments; final List comments; + final int postCreatorId; - CommentsWidget(this.rawComments) + CommentsWidget(this.rawComments, this.postCreatorId) : comments = CommentTree.fromList(rawComments); @override Widget build(BuildContext context) { + var sorting = useState(SortType.active); return Column(children: [ // sorting menu goes here - for (var com in comments) CommentWidget(com), + if (comments.length == 0) + Padding( + padding: EdgeInsets.symmetric(vertical: 50), + child: Text( + 'no comments yet', + style: TextStyle(fontStyle: FontStyle.italic), + ), + ), + for (var com in comments) + CommentWidget(com, postCreatorId: postCreatorId), ]); } } From 16d490c0ad4327b607047de37aef4ab81c8304ad Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 18:26:57 +0200 Subject: [PATCH 18/27] Add missing import --- lib/widgets/comment.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/widgets/comment.dart b/lib/widgets/comment.dart index 7fa5c1d..043602b 100644 --- a/lib/widgets/comment.dart +++ b/lib/widgets/comment.dart @@ -1,3 +1,4 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'comment_tree.dart'; From e1608d9f32f871f1f3213fb8801e5005844d9632 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 19:04:23 +0200 Subject: [PATCH 19/27] Change `@TODO` to `TODO:` --- lib/url_launcher.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/url_launcher.dart b/lib/url_launcher.dart index a0a719e..210fc15 100644 --- a/lib/url_launcher.dart +++ b/lib/url_launcher.dart @@ -5,6 +5,6 @@ Future urlLauncher(String url) async { await ul.launch(url); } else { throw Exception(); - // @TODO handle opening links to stuff in app + // TODO: handle opening links to stuff in app } } From eee965fba1c0068ec5ab187c09881fc048854d8b Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 19:56:48 +0200 Subject: [PATCH 20/27] * move comment out of `widgets/` * remove `Widget` suffix from widgets * change `list.length != 0` to `list.isEmpty` * convert MarkdownText into stateless widget --- lib/{widgets => }/comment.dart | 13 +++++----- lib/widgets/comments.dart | 14 +++++------ lib/widgets/markdown_text.dart | 46 ++++++++++++++++++++++------------ lib/widgets/post.dart | 6 ++--- 4 files changed, 46 insertions(+), 33 deletions(-) rename lib/{widgets => }/comment.dart (94%) diff --git a/lib/widgets/comment.dart b/lib/comment.dart similarity index 94% rename from lib/widgets/comment.dart rename to lib/comment.dart index 043602b..0a5d21c 100644 --- a/lib/widgets/comment.dart +++ b/lib/comment.dart @@ -1,14 +1,14 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; -import 'comment_tree.dart'; -import 'markdown_text.dart'; +import 'widgets/comment_tree.dart'; +import 'widgets/markdown_text.dart'; -class CommentWidget extends StatelessWidget { +class Comment extends StatelessWidget { final int indent; final int postCreatorId; final CommentTree commentTree; - CommentWidget( + Comment( this.commentTree, { this.indent = 0, @required this.postCreatorId, @@ -47,8 +47,7 @@ class CommentWidget extends StatelessWidget { style: TextStyle(fontStyle: FontStyle.italic), )); } else { - body = - Flexible(child: MarkdownText(commentTree.comment.content, context)); + body = Flexible(child: MarkdownText(commentTree.comment.content)); } return Column( children: [ @@ -108,7 +107,7 @@ class CommentWidget extends StatelessWidget { top: BorderSide(width: 0.2))), ), for (var c in commentTree.children) - CommentWidget( + Comment( c, indent: indent + 1, postCreatorId: postCreatorId, diff --git a/lib/widgets/comments.dart b/lib/widgets/comments.dart index be6039c..7337471 100644 --- a/lib/widgets/comments.dart +++ b/lib/widgets/comments.dart @@ -2,24 +2,25 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; -import 'comment.dart'; +import '../comment.dart'; import 'comment_tree.dart'; /// Manages comments section, sorts them -class CommentsWidget extends HookWidget { +class Comments extends HookWidget { final List rawComments; final List comments; final int postCreatorId; - CommentsWidget(this.rawComments, this.postCreatorId) - : comments = CommentTree.fromList(rawComments); + Comments(this.rawComments, {@required this.postCreatorId}) + : comments = CommentTree.fromList(rawComments), + assert(postCreatorId != null); @override Widget build(BuildContext context) { var sorting = useState(SortType.active); return Column(children: [ // sorting menu goes here - if (comments.length == 0) + if (comments.isEmpty) Padding( padding: EdgeInsets.symmetric(vertical: 50), child: Text( @@ -27,8 +28,7 @@ class CommentsWidget extends HookWidget { style: TextStyle(fontStyle: FontStyle.italic), ), ), - for (var com in comments) - CommentWidget(com, postCreatorId: postCreatorId), + for (var com in comments) Comment(com, postCreatorId: postCreatorId), ]); } } diff --git a/lib/widgets/markdown_text.dart b/lib/widgets/markdown_text.dart index f6d90f2..a315f50 100644 --- a/lib/widgets/markdown_text.dart +++ b/lib/widgets/markdown_text.dart @@ -1,23 +1,37 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:markdown/markdown.dart' as md; import '../url_launcher.dart'; -Widget MarkdownText(String text, BuildContext context) { - return MarkdownBody( - data: text, - extensionSet: md.ExtensionSet.gitHubWeb, - onTapLink: (href) { - urlLauncher(href) - .catchError((e) => Scaffold.of(context).showSnackBar(SnackBar( - content: Row( - children: [ - Icon(Icons.warning), - Text('couldn\'t open link'), - ], - ), - ))); - }, - ); +class MarkdownText extends StatelessWidget { + final String text; + MarkdownText(this.text); + + @override + Widget build(BuildContext context) => MarkdownBody( + data: text, + extensionSet: md.ExtensionSet.gitHubWeb, + onTapLink: (href) { + urlLauncher(href) + .catchError((e) => Scaffold.of(context).showSnackBar(SnackBar( + content: Row( + children: [ + Icon(Icons.warning), + Text('couldn\'t open link'), + ], + ), + ))); + }, + imageBuilder: (uri, title, alt) => CachedNetworkImage( + imageUrl: uri.toString(), + errorWidget: (context, url, error) => Row( + children: [ + Icon(Icons.warning), + Text('couldn\'t load image, ${error.toString()}') + ], + ), + ), + ); } diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 3044634..27e2ec8 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -25,7 +25,7 @@ MediaType whatType(String url) { return MediaType.other; } -class PostWidget extends StatelessWidget { +class Post extends StatelessWidget { final PostView post; final String hostUrl; @@ -35,7 +35,7 @@ class PostWidget extends StatelessWidget { ThemeData _theme; BuildContext _context; - PostWidget(this.post) + Post(this.post) : hostUrl = post.communityActorId.split('/')[2], linkPostDomain = post.url != null ? post.url.split('/')[2] : null; @@ -327,7 +327,7 @@ class PostWidget extends StatelessWidget { Widget _textBody() { return Padding( padding: const EdgeInsets.all(10), - child: MarkdownText(post.body, _context), + child: MarkdownText(post.body), ); } From e22a3094e4db1b2bddb0139815a0ca944abb4c19 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 19:58:09 +0200 Subject: [PATCH 21/27] Convert string that include `'` in them to double quouted strings --- lib/widgets/markdown_text.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/widgets/markdown_text.dart b/lib/widgets/markdown_text.dart index a315f50..7ef6878 100644 --- a/lib/widgets/markdown_text.dart +++ b/lib/widgets/markdown_text.dart @@ -19,7 +19,7 @@ class MarkdownText extends StatelessWidget { content: Row( children: [ Icon(Icons.warning), - Text('couldn\'t open link'), + Text("couldn't open link"), ], ), ))); @@ -29,7 +29,7 @@ class MarkdownText extends StatelessWidget { errorWidget: (context, url, error) => Row( children: [ Icon(Icons.warning), - Text('couldn\'t load image, ${error.toString()}') + Text("couldn't load image, ${error.toString()}") ], ), ), From 8c7e7c283bd2e03defcc62374d982974fc6b1301 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 20:02:51 +0200 Subject: [PATCH 22/27] reformat expression to be more sane --- lib/widgets/post.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 27e2ec8..b933e7e 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -235,11 +235,11 @@ class Post extends StatelessWidget { ), ), if (post.url != null && - !(whatType(post.url) != MediaType.other) && + whatType(post.url) == MediaType.other && post.thumbnailUrl != null) Spacer(), if (post.url != null && - !(whatType(post.url) != MediaType.other) && + whatType(post.url) == MediaType.other && post.thumbnailUrl != null) InkWell( onTap: _openLink, From fdcb29fb1cc2d884da9207d8c190e7ecd49ea42e Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 20:10:05 +0200 Subject: [PATCH 23/27] oops, moved the wrong thing --- lib/{widgets => }/comment_tree.dart | 0 lib/{ => widgets}/comment.dart | 4 ++-- lib/widgets/comments.dart | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename lib/{widgets => }/comment_tree.dart (100%) rename lib/{ => widgets}/comment.dart (98%) diff --git a/lib/widgets/comment_tree.dart b/lib/comment_tree.dart similarity index 100% rename from lib/widgets/comment_tree.dart rename to lib/comment_tree.dart diff --git a/lib/comment.dart b/lib/widgets/comment.dart similarity index 98% rename from lib/comment.dart rename to lib/widgets/comment.dart index 0a5d21c..be479bc 100644 --- a/lib/comment.dart +++ b/lib/widgets/comment.dart @@ -1,8 +1,8 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; -import 'widgets/comment_tree.dart'; -import 'widgets/markdown_text.dart'; +import '../comment_tree.dart'; +import 'markdown_text.dart'; class Comment extends StatelessWidget { final int indent; diff --git a/lib/widgets/comments.dart b/lib/widgets/comments.dart index 7337471..0300eba 100644 --- a/lib/widgets/comments.dart +++ b/lib/widgets/comments.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; -import '../comment.dart'; -import 'comment_tree.dart'; +import '../comment_tree.dart'; +import 'comment.dart'; /// Manages comments section, sorts them class Comments extends HookWidget { From 3c47eb08869fac3694cbb7b958c87ff4818c9fd5 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 21:03:50 +0200 Subject: [PATCH 24/27] move ui building functions into the build method --- lib/widgets/post.dart | 537 +++++++++++++++++++++--------------------- 1 file changed, 268 insertions(+), 269 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index b933e7e..4f71346 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -27,17 +27,14 @@ MediaType whatType(String url) { class Post extends StatelessWidget { final PostView post; - final String hostUrl; + final String instanceUrl; /// nullable - final String linkPostDomain; - - ThemeData _theme; - BuildContext _context; + final String postUrlDomain; Post(this.post) - : hostUrl = post.communityActorId.split('/')[2], - linkPostDomain = post.url != null ? post.url.split('/')[2] : null; + : instanceUrl = post.communityActorId.split('/')[2], + postUrlDomain = post.url != null ? post.url.split('/')[2] : null; // == ACTIONS == @@ -49,8 +46,8 @@ class Post extends StatelessWidget { print('GO TO USER'); } - void _goToPost() { - print('GO OT POST'); + void _goToPost(BuildContext context) { + print('GO TO POST'); } void _goToCommunity() { @@ -87,280 +84,282 @@ class Post extends StatelessWidget { @override Widget build(BuildContext context) { - _theme = Theme.of(context); - _context = context; + final theme = Theme.of(context); + + /// assemble info section + Widget info() { + // TODO: add NSFW, locked, removed, deleted, stickied + return Column(children: [ + Padding( + padding: const EdgeInsets.all(10), + child: Row(children: [ + Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (post.communityIcon != null) + Padding( + padding: const EdgeInsets.only(right: 10), + child: InkWell( + onTap: _goToCommunity, + child: SizedBox( + height: 40, + width: 40, + child: CachedNetworkImage( + imageBuilder: (context, imageProvider) => Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + fit: BoxFit.cover, + image: imageProvider, + ), + ), + ), + imageUrl: post.communityIcon, + errorWidget: (context, url, error) => + Text(error.toString()), + ), + ), + ), + ), + ], + ), + Column( + children: [ + Row(children: [ + RichText( + overflow: TextOverflow.ellipsis, // TODO: fix overflowing + text: TextSpan( + style: TextStyle( + fontSize: 15, color: theme.textTheme.bodyText1.color), + children: [ + TextSpan( + text: '!', + style: TextStyle(fontWeight: FontWeight.w300)), + TextSpan( + text: post.communityName, + style: TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = _goToCommunity), + TextSpan( + text: '@', + style: TextStyle(fontWeight: FontWeight.w300)), + TextSpan( + text: instanceUrl, + style: TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = _goToInstance), + ], + ), + ) + ]), + Row(children: [ + RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: TextStyle( + fontSize: 13, + color: theme.textTheme.bodyText1.color), + children: [ + TextSpan( + text: 'by', + style: TextStyle(fontWeight: FontWeight.w300)), + TextSpan( + text: + ''' ${post.creatorPreferredUsername ?? post.creatorName}''', + style: TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = _goToUser, + ), + TextSpan( + text: + ''' 路 ${timeago.format(post.published, locale: 'en_short')}'''), + if (postUrlDomain != null) + TextSpan(text: ' 路 $postUrlDomain'), + if (post.locked) TextSpan(text: ' 路 馃敀'), + ], + )) + ]), + ], + crossAxisAlignment: CrossAxisAlignment.start, + ), + Spacer(), + Column( + children: [ + IconButton( + onPressed: _showMoreMenu, + icon: Icon(Icons.more_vert), + ) + ], + ) + ]), + ), + ]); + } + + /// assemble title section + Widget title() { + return Padding( + padding: const EdgeInsets.only(left: 10, right: 10, bottom: 10), + child: Row( + children: [ + Flexible( + child: Text( + '${post.name}', + textAlign: TextAlign.left, + softWrap: true, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), + ), + ), + if (post.url != null && + whatType(post.url) == MediaType.other && + post.thumbnailUrl != null) + Spacer(), + if (post.url != null && + whatType(post.url) == MediaType.other && + post.thumbnailUrl != null) + InkWell( + onTap: _openLink, + child: Stack(children: [ + ClipRRect( + borderRadius: BorderRadius.circular(20), + child: CachedNetworkImage( + imageUrl: post.thumbnailUrl, + width: 70, + height: 70, + fit: BoxFit.cover, + errorWidget: (context, url, error) => + Text(error.toString()), + )), + Positioned( + top: 8, + right: 8, + child: Icon( + Icons.launch, + size: 20, + ), + ) + ]), + ) + ], + ), + ); + } + + /// assemble link preview + Widget linkPreview() { + assert(post.url != null); + + var url = post.url.split('/')[2]; + if (url.startsWith('www.')) { + url = url.substring(4); + } + + return Padding( + padding: const EdgeInsets.all(10), + child: InkWell( + onTap: _openLink, + child: Container( + decoration: BoxDecoration( + border: Border.all(width: 1), + borderRadius: BorderRadius.circular(5)), + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + Row(children: [ + Spacer(), + Text('$url ', + style: theme.textTheme.caption + .apply(fontStyle: FontStyle.italic)), + Icon(Icons.launch, size: 12), + ]), + Row(children: [ + Flexible( + child: Text(post.embedTitle, + style: theme.textTheme.subtitle1 + .apply(fontWeightDelta: 2))) + ]), + Row(children: [Flexible(child: Text(post.embedDescription))]), + ], + ), + ), + ), + ), + ); + } + + /// assemble image + Widget postImage() { + assert(post.url != null); + + return InkWell( + onTap: _openFullImage, + child: CachedNetworkImage( + imageUrl: post.url, + progressIndicatorBuilder: (context, url, progress) => + CircularProgressIndicator(value: progress.progress), + ), + ); + } + + /// assemble actions section + Widget actions() { + return Padding( + padding: const EdgeInsets.fromLTRB(10, 5, 10, 5), + child: Row( + children: [ + Icon(Icons.comment), + Expanded( + flex: 999, + child: Text( + ''' ${NumberFormat.compact().format(post.numberOfComments)} comment${post.numberOfComments == 1 ? '' : 's'}''', + overflow: TextOverflow.fade, + softWrap: false, + ), + ), + Spacer(), + IconButton( + icon: Icon(Icons.share), + onPressed: () => Share.text('Share post url', post.apId, + 'text/plain')), // TODO: find a way to mark it as url + IconButton( + icon: post.saved == true + ? Icon(Icons.bookmark) + : Icon(Icons.bookmark_border), + onPressed: _savePost), + IconButton(icon: Icon(Icons.arrow_upward), onPressed: _upvotePost), + Text(NumberFormat.compact().format(post.score)), + IconButton( + icon: Icon(Icons.arrow_downward), onPressed: _downvotePost), + ], + ), + ); + } return Container( decoration: BoxDecoration( boxShadow: [BoxShadow(blurRadius: 10, color: Colors.black54)], - color: _theme.colorScheme.surface, + color: theme.colorScheme.surface, borderRadius: BorderRadius.all(Radius.circular(20)), ), child: InkWell( - onTap: _goToPost, + onTap: () => _goToPost(context), child: Column( children: [ - _info(), - _title(), + info(), + title(), if (whatType(post.url) != MediaType.other) - _postImage() + postImage() else if (post.url != null) - _linkPreview(), - if (post.body != null) _textBody(), - _actions(), + linkPreview(), + if (post.body != null) + Padding( + padding: const EdgeInsets.all(10), + child: MarkdownText(post.body)), + actions(), ], ), ), ); } - - Widget _info() { - return Column(children: [ - Padding( - padding: const EdgeInsets.all(10), - child: Row(children: [ - Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (post.communityIcon != null) - Padding( - padding: const EdgeInsets.only(right: 10), - child: InkWell( - onTap: _goToCommunity, - child: SizedBox( - height: 40, - width: 40, - child: CachedNetworkImage( - imageBuilder: (context, imageProvider) => Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - image: DecorationImage( - fit: BoxFit.cover, - image: imageProvider, - ), - ), - ), - imageUrl: post.communityIcon, - errorWidget: (context, url, error) => - Text(error.toString()), - ), - ), - ), - ), - ], - ), - Column( - children: [ - Row(children: [ - RichText( - overflow: TextOverflow.ellipsis, // TODO: fix overflowing - text: TextSpan( - style: TextStyle( - fontSize: 15, color: _theme.textTheme.bodyText1.color), - children: [ - TextSpan( - text: '!', - style: TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: post.communityName, - style: TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = _goToCommunity), - TextSpan( - text: '@', - style: TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: hostUrl, - style: TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = _goToInstance), - ], - ), - ) - ]), - Row(children: [ - RichText( - overflow: TextOverflow.ellipsis, - text: TextSpan( - style: TextStyle( - fontSize: 13, - color: _theme.textTheme.bodyText1.color), - children: [ - TextSpan( - text: 'by', - style: TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: - ''' ${post.creatorPreferredUsername ?? post.creatorName}''', - style: TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer()..onTap = _goToUser, - ), - TextSpan( - text: - ''' 路 ${timeago.format(post.published, locale: 'en_short')}'''), - if (linkPostDomain != null) - TextSpan(text: ' 路 $linkPostDomain'), - if (post.locked) TextSpan(text: ' 路 馃敀'), - ], - )) - ]), - ], - crossAxisAlignment: CrossAxisAlignment.start, - ), - Spacer(), - Column( - children: [ - IconButton( - onPressed: _showMoreMenu, - icon: Icon(Icons.more_vert), - ) - ], - ) - ]), - ), - ]); - } - - Widget _title() { - return Padding( - padding: const EdgeInsets.only(left: 10, right: 10, bottom: 10), - child: Row( - children: [ - Flexible( - child: Text( - '${post.name}', - textAlign: TextAlign.left, - softWrap: true, - style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), - ), - ), - if (post.url != null && - whatType(post.url) == MediaType.other && - post.thumbnailUrl != null) - Spacer(), - if (post.url != null && - whatType(post.url) == MediaType.other && - post.thumbnailUrl != null) - InkWell( - onTap: _openLink, - child: Stack(children: [ - ClipRRect( - borderRadius: BorderRadius.circular(20), - child: CachedNetworkImage( - imageUrl: post.thumbnailUrl, - width: 70, - height: 70, - fit: BoxFit.cover, - errorWidget: (context, url, error) => - Text(error.toString()), - )), - Positioned( - top: 8, - right: 8, - child: Icon( - Icons.launch, - size: 20, - ), - ) - ]), - ) - ], - ), - ); - } - - Widget _postImage() { - assert(post.url != null); - - return InkWell( - onTap: _openFullImage, - child: CachedNetworkImage( - imageUrl: post.url, - progressIndicatorBuilder: (context, url, progress) => - CircularProgressIndicator(value: progress.progress), - ), - ); - } - - Widget _linkPreview() { - assert(post.url != null); - - var url = post.url.split('/')[2]; - if (url.startsWith('www.')) { - url = url.substring(4); - } - - return Padding( - padding: const EdgeInsets.all(10), - child: InkWell( - onTap: _openLink, - child: Container( - decoration: BoxDecoration( - border: Border.all(width: 1), - borderRadius: BorderRadius.circular(5)), - child: Padding( - padding: const EdgeInsets.all(10), - child: Column( - children: [ - Row(children: [ - Spacer(), - Text('$url ', - style: _theme.textTheme.caption - .apply(fontStyle: FontStyle.italic)), - Icon(Icons.launch, size: 12), - ]), - Row(children: [ - Flexible( - child: Text(post.embedTitle, - style: _theme.textTheme.subtitle1 - .apply(fontWeightDelta: 2))) - ]), - Row(children: [Flexible(child: Text(post.embedDescription))]), - ], - ), - ), - ), - ), - ); - } - - Widget _textBody() { - return Padding( - padding: const EdgeInsets.all(10), - child: MarkdownText(post.body), - ); - } - - Widget _actions() { - return Padding( - padding: const EdgeInsets.fromLTRB(10, 5, 10, 5), - child: Row( - children: [ - Icon(Icons.comment), - Expanded( - flex: 999, - child: Text( - ''' ${NumberFormat.compact().format(post.numberOfComments)} comment${post.numberOfComments == 1 ? '' : 's'}''', - overflow: TextOverflow.fade, - softWrap: false, - ), - ), - Spacer(), - IconButton( - icon: Icon(Icons.share), - onPressed: () => Share.text('Share post url', post.apId, - 'text/plain')), // TODO: find a way to mark it as url - IconButton( - icon: post.saved == true - ? Icon(Icons.bookmark) - : Icon(Icons.bookmark_border), - onPressed: _savePost), - IconButton(icon: Icon(Icons.arrow_upward), onPressed: _upvotePost), - Text(NumberFormat.compact().format(post.score)), - IconButton( - icon: Icon(Icons.arrow_downward), onPressed: _downvotePost), - ], - ), - ); - } } From 19047de57db8ad0bee02380e7e59ddefd5a13056 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 21:32:34 +0200 Subject: [PATCH 25/27] Remove useless code --- lib/widgets/comments.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/widgets/comments.dart b/lib/widgets/comments.dart index 0300eba..7a34f58 100644 --- a/lib/widgets/comments.dart +++ b/lib/widgets/comments.dart @@ -17,7 +17,6 @@ class Comments extends HookWidget { @override Widget build(BuildContext context) { - var sorting = useState(SortType.active); return Column(children: [ // sorting menu goes here if (comments.isEmpty) From a6486f6e5149355ceb17918bfcb2d32ef48c418e Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 21:35:54 +0200 Subject: [PATCH 26/27] Convert functions with single return statements to `=>` --- lib/widgets/post.dart | 336 +++++++++++++++++++++--------------------- 1 file changed, 166 insertions(+), 170 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 4f71346..8609e9d 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -86,164 +86,161 @@ class Post extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); + // TODO: add NSFW, locked, removed, deleted, stickied /// assemble info section - Widget info() { - // TODO: add NSFW, locked, removed, deleted, stickied - return Column(children: [ - Padding( - padding: const EdgeInsets.all(10), - child: Row(children: [ - Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (post.communityIcon != null) - Padding( - padding: const EdgeInsets.only(right: 10), - child: InkWell( - onTap: _goToCommunity, - child: SizedBox( - height: 40, - width: 40, - child: CachedNetworkImage( - imageBuilder: (context, imageProvider) => Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - image: DecorationImage( - fit: BoxFit.cover, - image: imageProvider, + Widget info() => Column(children: [ + Padding( + padding: const EdgeInsets.all(10), + child: Row(children: [ + Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (post.communityIcon != null) + Padding( + padding: const EdgeInsets.only(right: 10), + child: InkWell( + onTap: _goToCommunity, + child: SizedBox( + height: 40, + width: 40, + child: CachedNetworkImage( + imageBuilder: (context, imageProvider) => Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + fit: BoxFit.cover, + image: imageProvider, + ), ), ), + imageUrl: post.communityIcon, + errorWidget: (context, url, error) => + Text(error.toString()), ), - imageUrl: post.communityIcon, - errorWidget: (context, url, error) => - Text(error.toString()), ), ), ), - ), - ], - ), - Column( - children: [ - Row(children: [ - RichText( - overflow: TextOverflow.ellipsis, // TODO: fix overflowing - text: TextSpan( - style: TextStyle( - fontSize: 15, color: theme.textTheme.bodyText1.color), - children: [ - TextSpan( - text: '!', - style: TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: post.communityName, - style: TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = _goToCommunity), - TextSpan( - text: '@', - style: TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: instanceUrl, - style: TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = _goToInstance), - ], - ), - ) - ]), - Row(children: [ - RichText( - overflow: TextOverflow.ellipsis, + ], + ), + Column( + children: [ + Row(children: [ + RichText( + overflow: TextOverflow.ellipsis, // TODO: fix overflowing text: TextSpan( style: TextStyle( - fontSize: 13, + fontSize: 15, color: theme.textTheme.bodyText1.color), children: [ TextSpan( - text: 'by', + text: '!', style: TextStyle(fontWeight: FontWeight.w300)), TextSpan( - text: - ''' ${post.creatorPreferredUsername ?? post.creatorName}''', - style: TextStyle(fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = _goToUser, - ), + text: post.communityName, + style: TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = _goToCommunity), TextSpan( - text: - ''' 路 ${timeago.format(post.published, locale: 'en_short')}'''), - if (postUrlDomain != null) - TextSpan(text: ' 路 $postUrlDomain'), - if (post.locked) TextSpan(text: ' 路 馃敀'), + text: '@', + style: TextStyle(fontWeight: FontWeight.w300)), + TextSpan( + text: instanceUrl, + style: TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = _goToInstance), ], - )) - ]), - ], - crossAxisAlignment: CrossAxisAlignment.start, - ), - Spacer(), - Column( - children: [ - IconButton( - onPressed: _showMoreMenu, - icon: Icon(Icons.more_vert), - ) - ], - ) - ]), - ), - ]); - } + ), + ) + ]), + Row(children: [ + RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: TextStyle( + fontSize: 13, + color: theme.textTheme.bodyText1.color), + children: [ + TextSpan( + text: 'by', + style: TextStyle(fontWeight: FontWeight.w300)), + TextSpan( + text: + ''' ${post.creatorPreferredUsername ?? post.creatorName}''', + style: TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = _goToUser, + ), + TextSpan( + text: + ''' 路 ${timeago.format(post.published, locale: 'en_short')}'''), + if (postUrlDomain != null) + TextSpan(text: ' 路 $postUrlDomain'), + if (post.locked) TextSpan(text: ' 路 馃敀'), + ], + )) + ]), + ], + crossAxisAlignment: CrossAxisAlignment.start, + ), + Spacer(), + Column( + children: [ + IconButton( + onPressed: _showMoreMenu, + icon: Icon(Icons.more_vert), + ) + ], + ) + ]), + ), + ]); /// assemble title section - Widget title() { - return Padding( - padding: const EdgeInsets.only(left: 10, right: 10, bottom: 10), - child: Row( - children: [ - Flexible( - child: Text( - '${post.name}', - textAlign: TextAlign.left, - softWrap: true, - style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), + Widget title() => Padding( + padding: const EdgeInsets.only(left: 10, right: 10, bottom: 10), + child: Row( + children: [ + Flexible( + child: Text( + '${post.name}', + textAlign: TextAlign.left, + softWrap: true, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), + ), ), - ), - if (post.url != null && - whatType(post.url) == MediaType.other && - post.thumbnailUrl != null) - Spacer(), - if (post.url != null && - whatType(post.url) == MediaType.other && - post.thumbnailUrl != null) - InkWell( - onTap: _openLink, - child: Stack(children: [ - ClipRRect( - borderRadius: BorderRadius.circular(20), - child: CachedNetworkImage( - imageUrl: post.thumbnailUrl, - width: 70, - height: 70, - fit: BoxFit.cover, - errorWidget: (context, url, error) => - Text(error.toString()), - )), - Positioned( - top: 8, - right: 8, - child: Icon( - Icons.launch, - size: 20, - ), - ) - ]), - ) - ], - ), - ); - } + if (post.url != null && + whatType(post.url) == MediaType.other && + post.thumbnailUrl != null) + Spacer(), + if (post.url != null && + whatType(post.url) == MediaType.other && + post.thumbnailUrl != null) + InkWell( + onTap: _openLink, + child: Stack(children: [ + ClipRRect( + borderRadius: BorderRadius.circular(20), + child: CachedNetworkImage( + imageUrl: post.thumbnailUrl, + width: 70, + height: 70, + fit: BoxFit.cover, + errorWidget: (context, url, error) => + Text(error.toString()), + )), + Positioned( + top: 8, + right: 8, + child: Icon( + Icons.launch, + size: 20, + ), + ) + ]), + ) + ], + ), + ); /// assemble link preview Widget linkPreview() { @@ -303,38 +300,37 @@ class Post extends StatelessWidget { } /// assemble actions section - Widget actions() { - return Padding( - padding: const EdgeInsets.fromLTRB(10, 5, 10, 5), - child: Row( - children: [ - Icon(Icons.comment), - Expanded( - flex: 999, - child: Text( - ''' ${NumberFormat.compact().format(post.numberOfComments)} comment${post.numberOfComments == 1 ? '' : 's'}''', - overflow: TextOverflow.fade, - softWrap: false, + Widget actions() => Padding( + padding: const EdgeInsets.fromLTRB(10, 5, 10, 5), + child: Row( + children: [ + Icon(Icons.comment), + Expanded( + flex: 999, + child: Text( + ''' ${NumberFormat.compact().format(post.numberOfComments)} comment${post.numberOfComments == 1 ? '' : 's'}''', + overflow: TextOverflow.fade, + softWrap: false, + ), ), - ), - Spacer(), - IconButton( - icon: Icon(Icons.share), - onPressed: () => Share.text('Share post url', post.apId, - 'text/plain')), // TODO: find a way to mark it as url - IconButton( - icon: post.saved == true - ? Icon(Icons.bookmark) - : Icon(Icons.bookmark_border), - onPressed: _savePost), - IconButton(icon: Icon(Icons.arrow_upward), onPressed: _upvotePost), - Text(NumberFormat.compact().format(post.score)), - IconButton( - icon: Icon(Icons.arrow_downward), onPressed: _downvotePost), - ], - ), - ); - } + Spacer(), + IconButton( + icon: Icon(Icons.share), + onPressed: () => Share.text('Share post url', post.apId, + 'text/plain')), // TODO: find a way to mark it as url + IconButton( + icon: post.saved == true + ? Icon(Icons.bookmark) + : Icon(Icons.bookmark_border), + onPressed: _savePost), + IconButton( + icon: Icon(Icons.arrow_upward), onPressed: _upvotePost), + Text(NumberFormat.compact().format(post.score)), + IconButton( + icon: Icon(Icons.arrow_downward), onPressed: _downvotePost), + ], + ), + ); return Container( decoration: BoxDecoration( From d902c3d2aa81e2b5ae401416c13579f192a5c71d Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 31 Aug 2020 21:37:24 +0200 Subject: [PATCH 27/27] Rename `Comments` to `CommentSection` --- lib/widgets/comment_section.dart | 31 ++++++++++++++++++++++++++++++ lib/widgets/comments.dart | 33 -------------------------------- 2 files changed, 31 insertions(+), 33 deletions(-) create mode 100644 lib/widgets/comment_section.dart delete mode 100644 lib/widgets/comments.dart diff --git a/lib/widgets/comment_section.dart b/lib/widgets/comment_section.dart new file mode 100644 index 0000000..3b73205 --- /dev/null +++ b/lib/widgets/comment_section.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:lemmy_api_client/lemmy_api_client.dart'; + +import '../comment_tree.dart'; +import 'comment.dart'; + +/// Manages comments section, sorts them +class CommentSection extends HookWidget { + final List rawComments; + final List comments; + final int postCreatorId; + + CommentSection(this.rawComments, {@required this.postCreatorId}) + : comments = CommentTree.fromList(rawComments), + 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), + ), + ), + for (var com in comments) Comment(com, postCreatorId: postCreatorId), + ]); +} diff --git a/lib/widgets/comments.dart b/lib/widgets/comments.dart deleted file mode 100644 index 7a34f58..0000000 --- a/lib/widgets/comments.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:lemmy_api_client/lemmy_api_client.dart'; - -import '../comment_tree.dart'; -import 'comment.dart'; - -/// Manages comments section, sorts them -class Comments extends HookWidget { - final List rawComments; - final List comments; - final int postCreatorId; - - Comments(this.rawComments, {@required this.postCreatorId}) - : comments = CommentTree.fromList(rawComments), - assert(postCreatorId != null); - - @override - Widget build(BuildContext context) { - return 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), - ), - ), - for (var com in comments) Comment(com, postCreatorId: postCreatorId), - ]); - } -}