From 864c8a3948f1bdd3001d54a3ee6150b7b6d47ca5 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 5 Oct 2020 21:55:33 +0200 Subject: [PATCH 01/25] make header pretty and functional --- lib/pages/home_tab.dart | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index d3c907c..4fefa2d 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -93,6 +93,16 @@ class HomeTab extends HookWidget { } } + final title = () { + final first = selectedList.value.listingType == PostListingType.subscribed + ? 'Subscribed' + : 'All'; + final last = selectedList.value.instanceUrl == null + ? '' + : '@${selectedList.value.instanceUrl}'; + return '$first$last'; + }(); + return Scaffold( appBar: AppBar( actions: [ @@ -115,8 +125,14 @@ class HomeTab extends HookWidget { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text('Subscribed'), - Icon(Icons.arrow_drop_down), + Text( + title, + style: TextStyle(color: theme.textTheme.headline6.color), + ), + Icon( + Icons.arrow_drop_down, + color: theme.textTheme.headline6.color, + ), ], )), ), From 571f6beb61709f5b069169138a068a933fad9458 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 5 Oct 2020 23:09:36 +0200 Subject: [PATCH 02/25] Add instance icons --- lib/pages/home_tab.dart | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 4fefa2d..26285cd 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -1,8 +1,10 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; import '../hooks/infinite_scroll.dart'; +import '../hooks/memo_future.dart'; import '../hooks/stores.dart'; import '../util/goto.dart'; import '../widgets/bottom_modal.dart'; @@ -19,6 +21,17 @@ class HomeTab extends HookWidget { final accStore = useAccountsStore(); final isc = useInfiniteScrollController(); final theme = Theme.of(context); + final instancesIcons = useMemoFuture(() async { + final map = {}; + final instances = accStore.instances.toList(growable: false); + final sites = await Future.wait(instances + .map((e) => LemmyApi(e).v1.getSite().catchError((e) => null))); + for (var i in Iterable.generate(sites.length)) { + map[instances[i]] = sites[i].site.icon; + } + + return map; + }); handleListChange() async { final val = await showModalBottomSheet( @@ -30,13 +43,14 @@ class HomeTab extends HookWidget { return BottomModal( child: Column( children: [ + SizedBox(height: 5), ListTile( title: Text('EVERYTHING'), dense: true, contentPadding: EdgeInsets.zero, visualDensity: VisualDensity(vertical: VisualDensity.minimumDensity), - leading: SizedBox(width: 20, height: 20), + leading: SizedBox.shrink(), ), ListTile( title: Text('Subscribed'), @@ -51,7 +65,10 @@ class HomeTab extends HookWidget { pop(SelectedList(listingType: PostListingType.all)), ), for (final instance in accStore.instances) ...[ - Divider(), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Divider(), + ), ListTile( title: Text( instance.toUpperCase(), @@ -63,7 +80,25 @@ class HomeTab extends HookWidget { contentPadding: EdgeInsets.zero, visualDensity: VisualDensity(vertical: VisualDensity.minimumDensity), - leading: SizedBox(width: 30), + leading: (instancesIcons.hasData && + instancesIcons.data[instance] != null) + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(width: 20), + SizedBox( + width: 25, + height: 25, + child: CachedNetworkImage( + imageUrl: instancesIcons.data[instance], + height: 25, + width: 25, + ), + ), + ], + ) + : SizedBox(width: 30), ), ListTile( title: Text('Subscribed'), From 3e7b70eb66193699343e242700173c2d1d2b8eb2 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 5 Oct 2020 23:11:41 +0200 Subject: [PATCH 03/25] make text overflow into ellipsis --- lib/pages/home_tab.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 26285cd..a1de359 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -160,9 +160,12 @@ class HomeTab extends HookWidget { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( - title, - style: TextStyle(color: theme.textTheme.headline6.color), + Flexible( + child: Text( + title, + style: TextStyle(color: theme.textTheme.headline6.color), + overflow: TextOverflow.ellipsis, + ), ), Icon( Icons.arrow_drop_down, From f127528aaadd7855177ce45764e65d39e069d3d4 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 5 Oct 2020 23:11:55 +0200 Subject: [PATCH 04/25] remove useless comment --- lib/pages/home_tab.dart | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index a1de359..6d4a60e 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -286,11 +286,3 @@ class SelectedList { String toString() => 'SelectedList({instanceUrl: $instanceUrl, listingType: $listingType})'; } - -// class _Divider extends StatelessWidget { -// @override -// Widget build(BuildContext context) => Padding( -// padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), -// child: Divider(), -// ); -// } From 0ef538b7c7b156750896a24201bf2c5a7f0d8b8c Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 5 Oct 2020 23:14:36 +0200 Subject: [PATCH 05/25] add a todo --- lib/pages/home_tab.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 6d4a60e..e3afdac 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -139,6 +139,7 @@ class HomeTab extends HookWidget { }(); return Scaffold( + // TODO: make appbar autohide when scrolling down appBar: AppBar( actions: [ IconButton( From 976f27680a6fca183358d4a6381fd1336f173ace Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 5 Oct 2020 23:23:27 +0200 Subject: [PATCH 06/25] add ontap for instances --- lib/pages/home_tab.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index e3afdac..9f983aa 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -76,6 +76,7 @@ class HomeTab extends HookWidget { color: theme.textTheme.bodyText1.color.withOpacity(0.7)), ), + onTap: () => goToInstance(context, instance), dense: true, contentPadding: EdgeInsets.zero, visualDensity: From 83a488c1343c4d0db38d4d6314ef8bbee9adf483 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 00:19:34 +0200 Subject: [PATCH 07/25] distribute posts evenly, kinda like zip function in python regular sorting wasn't working unfortunately :/ --- lib/pages/home_tab.dart | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 9f983aa..11418be 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -1,3 +1,5 @@ +import 'dart:math' show max; + import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -229,10 +231,17 @@ class InfiniteHomeList extends HookWidget { limit: limit, auth: accStore.defaultTokenFor(instanceUrl)?.raw, )); - final posts = - await Future.wait(futures).then((value) => value.expand((e) => e)); - // TODO: sorting - return posts.toList(); // .sort(); + final posts = (await Future.wait(futures)); + final newPosts = []; + for (final i + in Iterable.generate(posts.map((e) => e.length).reduce(max))) { + for (final el in posts) { + if (el.elementAt(i) != null) { + newPosts.add(el[i]); + } + } + } + return newPosts; } Future> Function(int, int) _fetcherFromInstance( From f8733da21d554178d56f4843d3634429efe8c332 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 00:54:17 +0200 Subject: [PATCH 08/25] make title color match the color of the button on the right --- lib/pages/home_tab.dart | 49 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 11418be..be84f3c 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -152,31 +152,32 @@ class HomeTab extends HookWidget { ], centerTitle: true, title: TextButton( - style: TextButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(10))), - padding: EdgeInsets.symmetric(horizontal: 15), - primary: theme.buttonColor, - textStyle: theme.textTheme.headline6, - ), - onPressed: handleListChange, - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Flexible( - child: Text( - title, - style: TextStyle(color: theme.textTheme.headline6.color), - overflow: TextOverflow.ellipsis, - ), + style: TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(10))), + padding: EdgeInsets.symmetric(horizontal: 15), + primary: theme.buttonColor, + textStyle: theme.primaryTextTheme.headline6, + ), + onPressed: handleListChange, + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Flexible( + child: Text( + title, + style: theme.primaryTextTheme.headline6, + overflow: TextOverflow.ellipsis, ), - Icon( - Icons.arrow_drop_down, - color: theme.textTheme.headline6.color, - ), - ], - )), + ), + Icon( + Icons.arrow_drop_down, + color: theme.primaryTextTheme.headline6.color, + ), + ], + ), + ), ), body: InfiniteHomeList( controller: isc, From bb99c9d9f4953a8a909119daf813fdc3e8329bdb Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 01:00:13 +0200 Subject: [PATCH 09/25] Make "subscribed" tile gray if user not logged in to that instance --- lib/pages/home_tab.dart | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index be84f3c..3ca5714 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -104,11 +104,19 @@ class HomeTab extends HookWidget { : SizedBox(width: 30), ), ListTile( - title: Text('Subscribed'), - onTap: () => pop(SelectedList( - listingType: PostListingType.subscribed, - instanceUrl: instance, - )), + title: Text( + 'Subscribed', + style: TextStyle( + color: accStore.isAnonymousFor(instance) + ? theme.textTheme.bodyText1.color.withOpacity(0.4) + : null), + ), + onTap: accStore.isAnonymousFor(instance) + ? null + : () => pop(SelectedList( + listingType: PostListingType.subscribed, + instanceUrl: instance, + )), leading: SizedBox(width: 20), ), ListTile( From ddf3e522aa6e441b3f087ad90caa95cfa4d6afc5 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 01:04:49 +0200 Subject: [PATCH 10/25] show log in popup on tapping "subscribed" --- lib/pages/home_tab.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 3ca5714..c7a6de3 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -1,6 +1,7 @@ import 'dart:math' show max; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; @@ -13,6 +14,7 @@ import '../widgets/bottom_modal.dart'; import '../widgets/infinite_scroll.dart'; import '../widgets/post.dart'; import '../widgets/post_list_options.dart'; +import 'add_account.dart'; import 'inbox.dart'; class HomeTab extends HookWidget { @@ -112,7 +114,9 @@ class HomeTab extends HookWidget { : null), ), onTap: accStore.isAnonymousFor(instance) - ? null + ? () => showCupertinoModalPopup( + context: context, + builder: (_) => AddAccountPage(instanceUrl: instance)) : () => pop(SelectedList( listingType: PostListingType.subscribed, instanceUrl: instance, From b4673be5cda740686181517c090782e34169f2d9 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 01:07:42 +0200 Subject: [PATCH 11/25] add todo --- lib/pages/home_tab.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index c7a6de3..014c774 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -22,6 +22,7 @@ class HomeTab extends HookWidget { Widget build(BuildContext context) { final selectedList = useState(SelectedList(listingType: PostListingType.subscribed)); + // TODO: needs to be an observer? for accounts changes final accStore = useAccountsStore(); final isc = useInfiniteScrollController(); final theme = Theme.of(context); From 4058ebc200c26a3af19dedf73e19ce3261d1b20d Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 12:06:29 +0200 Subject: [PATCH 12/25] convert some returns to => --- lib/pages/home_tab.dart | 17 ++++++++--------- lib/pages/inbox.dart | 28 +++++++++++++--------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 014c774..4f74668 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -259,15 +259,14 @@ class InfiniteHomeList extends HookWidget { } Future> Function(int, int) _fetcherFromInstance( - String instanceUrl, PostListingType listingType, SortType sort) { - return (page, batchSize) => LemmyApi(instanceUrl).v1.getPosts( - type: listingType, - sort: sort, - page: page, - limit: batchSize, - auth: accStore.defaultTokenFor(instanceUrl)?.raw, - ); - } + String instanceUrl, PostListingType listingType, SortType sort) => + (page, batchSize) => LemmyApi(instanceUrl).v1.getPosts( + type: listingType, + sort: sort, + page: page, + limit: batchSize, + auth: accStore.defaultTokenFor(instanceUrl)?.raw, + ); return InfiniteScroll( prepend: Column( diff --git a/lib/pages/inbox.dart b/lib/pages/inbox.dart index 84a8820..bfb17af 100644 --- a/lib/pages/inbox.dart +++ b/lib/pages/inbox.dart @@ -3,20 +3,18 @@ import 'package:flutter_hooks/flutter_hooks.dart'; class InboxPage extends HookWidget { @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '🚧 WORK IN PROGRESS 🚧', - style: Theme.of(context).textTheme.headline5, - ) - ], + Widget build(BuildContext context) => Scaffold( + appBar: AppBar(), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '🚧 WORK IN PROGRESS 🚧', + style: Theme.of(context).textTheme.headline5, + ) + ], + ), ), - ), - ); - } + ); } From c4ed57d39385a80d4394eab3147f5d3492400d66 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 12:07:12 +0200 Subject: [PATCH 13/25] acomodate for situations where instance has less than 6 communities --- lib/pages/instance.dart | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/pages/instance.dart b/lib/pages/instance.dart index 85d7d5f..57d88d2 100644 --- a/lib/pages/instance.dart +++ b/lib/pages/instance.dart @@ -8,7 +8,6 @@ import 'package:lemmy_api_client/lemmy_api_client.dart'; import 'package:url_launcher/url_launcher.dart' as ul; import '../hooks/stores.dart'; -import '../util/extensions/api.dart'; import '../util/goto.dart'; import '../util/text_color.dart'; import '../widgets/badge.dart'; @@ -353,7 +352,7 @@ class _AboutTab extends HookWidget { ), ), if (commSnap.hasData) - ...commSnap.data.getRange(0, 6).map((e) => ListTile( + ...commSnap.data.getRangeOrShorter(0, 6).map((e) => ListTile( onTap: () => goToCommunity.byId(context, e.instanceUrl, e.id), title: Text(e.name), @@ -469,3 +468,13 @@ class _Divider extends StatelessWidget { child: Divider(), ); } + +extension GetRangeOrShorter on List { + Iterable getRangeOrShorter(int start, int end) { + if (length < end) { + return getRange(start, length); + } else { + return getRange(start, end); + } + } +} From 56a77187b910b79e355d068dcc12570277e9467d Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 15:47:51 +0200 Subject: [PATCH 14/25] replace unnecesairy custom method with .take --- lib/pages/instance.dart | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/lib/pages/instance.dart b/lib/pages/instance.dart index 57d88d2..73dd575 100644 --- a/lib/pages/instance.dart +++ b/lib/pages/instance.dart @@ -8,6 +8,7 @@ import 'package:lemmy_api_client/lemmy_api_client.dart'; import 'package:url_launcher/url_launcher.dart' as ul; import '../hooks/stores.dart'; +import '../util/extensions/api.dart'; import '../util/goto.dart'; import '../util/text_color.dart'; import '../widgets/badge.dart'; @@ -352,7 +353,7 @@ class _AboutTab extends HookWidget { ), ), if (commSnap.hasData) - ...commSnap.data.getRangeOrShorter(0, 6).map((e) => ListTile( + ...commSnap.data.take(6).map((e) => ListTile( onTap: () => goToCommunity.byId(context, e.instanceUrl, e.id), title: Text(e.name), @@ -468,13 +469,3 @@ class _Divider extends StatelessWidget { child: Divider(), ); } - -extension GetRangeOrShorter on List { - Iterable getRangeOrShorter(int start, int end) { - if (length < end) { - return getRange(start, length); - } else { - return getRange(start, end); - } - } -} From fe494a3b0b4e4770f0878a93969ef20baa9a2a2f Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 15:58:58 +0200 Subject: [PATCH 15/25] move clean up to lemmyApi extensions --- lib/util/extensions/api.dart | 16 ++++++++++------ lib/widgets/post.dart | 3 +-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/util/extensions/api.dart b/lib/util/extensions/api.dart index 6e3ae8c..e7800cd 100644 --- a/lib/util/extensions/api.dart +++ b/lib/util/extensions/api.dart @@ -1,5 +1,7 @@ import 'package:lemmy_api_client/lemmy_api_client.dart'; +import '../cleanup_url.dart'; + // Extensions to lemmy api objects which give a [.instanceUrl] getter // allowing for a convenient way of knowing from which instance did this // object come from @@ -7,25 +9,27 @@ import 'package:lemmy_api_client/lemmy_api_client.dart'; // TODO: change it to something more robust? regex? extension GetInstanceCommunityView on CommunityView { - String get instanceUrl => actorId.split('/')[2]; + String get instanceUrl => extract(actorId); } extension GetInstanceUserView on UserView { - String get instanceUrl => actorId.split('/')[2]; + String get instanceUrl => extract(actorId); } extension GetInstanceCommunityModeratorView on CommunityModeratorView { - String get instanceUrl => userActorId.split('/')[2]; + String get instanceUrl => extract(userActorId); } extension GetInstancePostView on PostView { - String get instanceUrl => apId.split('/')[2]; + String get instanceUrl => extract(apId); } extension GetInstanceUser on User { - String get instanceUrl => actorId.split('/')[2]; + String get instanceUrl => extract(actorId); } extension GetInstanceCommentView on CommentView { - String get instanceUrl => apId.split('/')[2]; + String get instanceUrl => extract(apId); } + +String extract(String s) => cleanUpUrl(s.split('/')[2]); diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 2f4b3fb..a079841 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -13,7 +13,6 @@ import '../hooks/delayed_loading.dart'; import '../hooks/logged_in_action.dart'; import '../pages/full_post.dart'; import '../url_launcher.dart'; -import '../util/cleanup_url.dart'; import '../util/extensions/api.dart'; import '../util/goto.dart'; import 'bottom_modal.dart'; @@ -210,7 +209,7 @@ class Post extends HookWidget { text: '@', style: TextStyle(fontWeight: FontWeight.w300)), TextSpan( - text: cleanUpUrl(instanceUrl), + text: instanceUrl, style: TextStyle(fontWeight: FontWeight.w600), recognizer: TapGestureRecognizer() ..onTap = From 17f64e24e0bde45840f70d9aac00674d9fadfed4 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:19:03 +0200 Subject: [PATCH 16/25] implement cleanupurl in addInstancePage --- lib/pages/add_instance.dart | 22 +++------------------- lib/util/cleanup_url.dart | 3 +++ 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/lib/pages/add_instance.dart b/lib/pages/add_instance.dart index de8bb8a..7e988e4 100644 --- a/lib/pages/add_instance.dart +++ b/lib/pages/add_instance.dart @@ -1,6 +1,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:lemmur/util/cleanup_url.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; import '../hooks/debounce.dart'; @@ -26,7 +27,7 @@ class AddInstancePage extends HookWidget { final debounce = useDebounce(() async { if (prevInput == instanceController.text) return; - final inst = _fixInstanceUrl(instanceController.text); + final inst = cleanUpUrl(instanceController.text); if (inst.isEmpty) { isSite.value = null; return; @@ -47,7 +48,7 @@ class AddInstancePage extends HookWidget { instanceController.removeListener(debounce); }; }, []); - final inst = _fixInstanceUrl(instanceController.text); + final inst = cleanUpUrl(instanceController.text); handleOnAdd() async { try { await accountsStore.addInstance(inst, assumeValid: true); @@ -145,20 +146,3 @@ class AddInstancePage extends HookWidget { ); } } - -/// removes protocol and trailing slash -String _fixInstanceUrl(String inst) { - if (inst.startsWith('https://')) { - inst = inst.substring(8); - } - - if (inst.startsWith('http://')) { - inst = inst.substring(7); - } - - if (inst.endsWith('/')) { - inst = inst.substring(0, inst.length - 1); - } - - return inst; -} diff --git a/lib/util/cleanup_url.dart b/lib/util/cleanup_url.dart index af542be..b380eb6 100644 --- a/lib/util/cleanup_url.dart +++ b/lib/util/cleanup_url.dart @@ -5,6 +5,9 @@ String cleanUpUrl(String url) { if (url.startsWith('www.')) { url = url.substring(4); } + if (url.endsWith('/')) { + url = url.substring(0, url.length - 1); + } return url; } From 585baf58f9cd1a7776590436040057f56413a320 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:22:49 +0200 Subject: [PATCH 17/25] add docs --- lib/pages/home_tab.dart | 3 +++ lib/util/cleanup_url.dart | 1 + 2 files changed, 4 insertions(+) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 4f74668..8b36869 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -17,6 +17,8 @@ import '../widgets/post_list_options.dart'; import 'add_account.dart'; import 'inbox.dart'; +/// First thing users sees when opening the app +/// Shows list of posts from all or just specific instances class HomeTab extends HookWidget { @override Widget build(BuildContext context) { @@ -200,6 +202,7 @@ class HomeTab extends HookWidget { } } +/// Infinite list of posts class InfiniteHomeList extends HookWidget { final Function onStyleChange; final InfiniteScrollController controller; diff --git a/lib/util/cleanup_url.dart b/lib/util/cleanup_url.dart index b380eb6..6108c09 100644 --- a/lib/util/cleanup_url.dart +++ b/lib/util/cleanup_url.dart @@ -1,3 +1,4 @@ +/// Strips protocol, 'www.', and trailing '/' from [url] aka. cleans it up String cleanUpUrl(String url) { if (url.startsWith('https://')) { url = url.substring(8); From b82622190fc7028b23479f379cb8a6ff40b5a0ea Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:23:29 +0200 Subject: [PATCH 18/25] add comma to make formatting more sane --- lib/pages/home_tab.dart | 158 ++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 78 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 8b36869..137312b 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -48,95 +48,97 @@ class HomeTab extends HookWidget { builder: (context) { pop(SelectedList thing) => Navigator.of(context).pop(thing); return BottomModal( - child: Column( - children: [ - SizedBox(height: 5), - ListTile( - title: Text('EVERYTHING'), - dense: true, - contentPadding: EdgeInsets.zero, - visualDensity: - VisualDensity(vertical: VisualDensity.minimumDensity), - leading: SizedBox.shrink(), - ), - ListTile( - title: Text('Subscribed'), - leading: SizedBox(width: 20, height: 20), - onTap: () => - pop(SelectedList(listingType: PostListingType.subscribed)), - ), - ListTile( - title: Text('All'), - leading: SizedBox(width: 20, height: 20), - onTap: () => - pop(SelectedList(listingType: PostListingType.all)), - ), - for (final instance in accStore.instances) ...[ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Divider(), - ), + child: Column( + children: [ + SizedBox(height: 5), ListTile( - title: Text( - instance.toUpperCase(), - style: TextStyle( - color: - theme.textTheme.bodyText1.color.withOpacity(0.7)), - ), - onTap: () => goToInstance(context, instance), + title: Text('EVERYTHING'), dense: true, contentPadding: EdgeInsets.zero, visualDensity: VisualDensity(vertical: VisualDensity.minimumDensity), - leading: (instancesIcons.hasData && - instancesIcons.data[instance] != null) - ? Row( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(width: 20), - SizedBox( - width: 25, - height: 25, - child: CachedNetworkImage( - imageUrl: instancesIcons.data[instance], - height: 25, - width: 25, - ), - ), - ], - ) - : SizedBox(width: 30), + leading: SizedBox.shrink(), ), ListTile( - title: Text( - 'Subscribed', - style: TextStyle( - color: accStore.isAnonymousFor(instance) - ? theme.textTheme.bodyText1.color.withOpacity(0.4) - : null), - ), - onTap: accStore.isAnonymousFor(instance) - ? () => showCupertinoModalPopup( - context: context, - builder: (_) => AddAccountPage(instanceUrl: instance)) - : () => pop(SelectedList( - listingType: PostListingType.subscribed, - instanceUrl: instance, - )), - leading: SizedBox(width: 20), + title: Text('Subscribed'), + leading: SizedBox(width: 20, height: 20), + onTap: () => pop( + SelectedList(listingType: PostListingType.subscribed)), ), ListTile( title: Text('All'), - onTap: () => pop(SelectedList( - listingType: PostListingType.all, - instanceUrl: instance, - )), - leading: SizedBox(width: 20), + leading: SizedBox(width: 20, height: 20), + onTap: () => + pop(SelectedList(listingType: PostListingType.all)), ), - ] - ], - )); + for (final instance in accStore.instances) ...[ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Divider(), + ), + ListTile( + title: Text( + instance.toUpperCase(), + style: TextStyle( + color: + theme.textTheme.bodyText1.color.withOpacity(0.7)), + ), + onTap: () => goToInstance(context, instance), + dense: true, + contentPadding: EdgeInsets.zero, + visualDensity: + VisualDensity(vertical: VisualDensity.minimumDensity), + leading: (instancesIcons.hasData && + instancesIcons.data[instance] != null) + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(width: 20), + SizedBox( + width: 25, + height: 25, + child: CachedNetworkImage( + imageUrl: instancesIcons.data[instance], + height: 25, + width: 25, + ), + ), + ], + ) + : SizedBox(width: 30), + ), + ListTile( + title: Text( + 'Subscribed', + style: TextStyle( + color: accStore.isAnonymousFor(instance) + ? theme.textTheme.bodyText1.color.withOpacity(0.4) + : null), + ), + onTap: accStore.isAnonymousFor(instance) + ? () => showCupertinoModalPopup( + context: context, + builder: (_) => + AddAccountPage(instanceUrl: instance)) + : () => pop(SelectedList( + listingType: PostListingType.subscribed, + instanceUrl: instance, + )), + leading: SizedBox(width: 20), + ), + ListTile( + title: Text('All'), + onTap: () => pop(SelectedList( + listingType: PostListingType.all, + instanceUrl: instance, + )), + leading: SizedBox(width: 20), + ), + ] + ], + ), + ); }, ); if (val != null) { From acbf2089e08d880a37dc37f839e48fe6cf713466 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:27:35 +0200 Subject: [PATCH 19/25] replace row + sizedbox with padding --- lib/pages/home_tab.dart | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 137312b..318f855 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -90,21 +90,17 @@ class HomeTab extends HookWidget { VisualDensity(vertical: VisualDensity.minimumDensity), leading: (instancesIcons.hasData && instancesIcons.data[instance] != null) - ? Row( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(width: 20), - SizedBox( - width: 25, + ? Padding( + padding: const EdgeInsets.only(left: 20), + child: SizedBox( + width: 25, + height: 25, + child: CachedNetworkImage( + imageUrl: instancesIcons.data[instance], height: 25, - child: CachedNetworkImage( - imageUrl: instancesIcons.data[instance], - height: 25, - width: 25, - ), + width: 25, ), - ], + ), ) : SizedBox(width: 30), ), From 465ee7c7f2f69941baefb50724301d4165a0ff37 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:27:57 +0200 Subject: [PATCH 20/25] remove debug print --- lib/pages/home_tab.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 318f855..99b2f5b 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -138,7 +138,6 @@ class HomeTab extends HookWidget { }, ); if (val != null) { - print(val); selectedList.value = val; isc.clear(); } From 8cafde3ba4c4376276fa3fd39b4c67665e804104 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:28:38 +0200 Subject: [PATCH 21/25] add a single newline --- lib/pages/home_tab.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 99b2f5b..c8c6b85 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -209,6 +209,7 @@ class InfiniteHomeList extends HookWidget { this.onStyleChange, this.controller, }) : assert(selectedList != null); + @override Widget build(BuildContext context) { final accStore = useAccountsStore(); From 98557f922048b56a8d04f24324c686c42fa3bdee Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:29:19 +0200 Subject: [PATCH 22/25] remove useless parentheses --- lib/pages/home_tab.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index c8c6b85..328b772 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -246,7 +246,7 @@ class InfiniteHomeList extends HookWidget { limit: limit, auth: accStore.defaultTokenFor(instanceUrl)?.raw, )); - final posts = (await Future.wait(futures)); + final posts = await Future.wait(futures); final newPosts = []; for (final i in Iterable.generate(posts.map((e) => e.length).reduce(max))) { From 5c0fcce1f488f6a14a8ef1b47e2c85950872c115 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:30:52 +0200 Subject: [PATCH 23/25] make ultimatefetcher more descriptive --- lib/pages/home_tab.dart | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 328b772..44aa774 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -221,7 +221,11 @@ class InfiniteHomeList extends HookWidget { controller.clear(); } - Future> ultimateFetcher( + /// fetches post from many instances at once and combines them into a single + /// list + /// + /// Process of combining them works sort of like zip function in python + Future> generalFetcher( int page, int limit, SortType sort, @@ -259,7 +263,7 @@ class InfiniteHomeList extends HookWidget { return newPosts; } - Future> Function(int, int) _fetcherFromInstance( + Future> Function(int, int) fetcherFromInstance( String instanceUrl, PostListingType listingType, SortType sort) => (page, batchSize) => LemmyApi(instanceUrl).v1.getPosts( type: listingType, @@ -288,8 +292,8 @@ class InfiniteHomeList extends HookWidget { padding: EdgeInsets.zero, fetchMore: selectedList.instanceUrl == null ? (page, limit) => - ultimateFetcher(page, limit, sort.value, selectedList.listingType) - : _fetcherFromInstance( + generalFetcher(page, limit, sort.value, selectedList.listingType) + : fetcherFromInstance( selectedList.instanceUrl, selectedList.listingType, sort.value, From 1a4d231b1b0fc5558432c7882905f35df95a6658 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 16:34:03 +0200 Subject: [PATCH 24/25] convert absolute import to relative --- lib/pages/add_instance.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/add_instance.dart b/lib/pages/add_instance.dart index 7e988e4..eb0f9aa 100644 --- a/lib/pages/add_instance.dart +++ b/lib/pages/add_instance.dart @@ -1,11 +1,11 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:lemmur/util/cleanup_url.dart'; import 'package:lemmy_api_client/lemmy_api_client.dart'; import '../hooks/debounce.dart'; import '../hooks/stores.dart'; +import '../util/cleanup_url.dart'; import '../widgets/fullscreenable_image.dart'; /// A page that let's user add a new instance. Pops a url of the added instance From 21fe2e9bac7b4a7b54d3ae4c38e3a90ccf0d8c01 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 6 Oct 2020 17:28:11 +0200 Subject: [PATCH 25/25] mark some stuff as private if it doesn't need to be accessible from outside the file --- lib/pages/home_tab.dart | 20 ++++++++++---------- lib/util/extensions/api.dart | 14 +++++++------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/pages/home_tab.dart b/lib/pages/home_tab.dart index 44aa774..5464dfa 100644 --- a/lib/pages/home_tab.dart +++ b/lib/pages/home_tab.dart @@ -23,7 +23,7 @@ class HomeTab extends HookWidget { @override Widget build(BuildContext context) { final selectedList = - useState(SelectedList(listingType: PostListingType.subscribed)); + useState(_SelectedList(listingType: PostListingType.subscribed)); // TODO: needs to be an observer? for accounts changes final accStore = useAccountsStore(); final isc = useInfiniteScrollController(); @@ -41,12 +41,12 @@ class HomeTab extends HookWidget { }); handleListChange() async { - final val = await showModalBottomSheet( + final val = await showModalBottomSheet<_SelectedList>( backgroundColor: Colors.transparent, isScrollControlled: true, context: context, builder: (context) { - pop(SelectedList thing) => Navigator.of(context).pop(thing); + pop(_SelectedList thing) => Navigator.of(context).pop(thing); return BottomModal( child: Column( children: [ @@ -63,13 +63,13 @@ class HomeTab extends HookWidget { title: Text('Subscribed'), leading: SizedBox(width: 20, height: 20), onTap: () => pop( - SelectedList(listingType: PostListingType.subscribed)), + _SelectedList(listingType: PostListingType.subscribed)), ), ListTile( title: Text('All'), leading: SizedBox(width: 20, height: 20), onTap: () => - pop(SelectedList(listingType: PostListingType.all)), + pop(_SelectedList(listingType: PostListingType.all)), ), for (final instance in accStore.instances) ...[ Padding( @@ -117,7 +117,7 @@ class HomeTab extends HookWidget { context: context, builder: (_) => AddAccountPage(instanceUrl: instance)) - : () => pop(SelectedList( + : () => pop(_SelectedList( listingType: PostListingType.subscribed, instanceUrl: instance, )), @@ -125,7 +125,7 @@ class HomeTab extends HookWidget { ), ListTile( title: Text('All'), - onTap: () => pop(SelectedList( + onTap: () => pop(_SelectedList( listingType: PostListingType.all, instanceUrl: instance, )), @@ -203,7 +203,7 @@ class HomeTab extends HookWidget { class InfiniteHomeList extends HookWidget { final Function onStyleChange; final InfiniteScrollController controller; - final SelectedList selectedList; + final _SelectedList selectedList; InfiniteHomeList({ @required this.selectedList, this.onStyleChange, @@ -304,10 +304,10 @@ class InfiniteHomeList extends HookWidget { } } -class SelectedList { +class _SelectedList { final String instanceUrl; final PostListingType listingType; - SelectedList({ + _SelectedList({ @required this.listingType, this.instanceUrl, }); diff --git a/lib/util/extensions/api.dart b/lib/util/extensions/api.dart index e7800cd..505cf1d 100644 --- a/lib/util/extensions/api.dart +++ b/lib/util/extensions/api.dart @@ -9,27 +9,27 @@ import '../cleanup_url.dart'; // TODO: change it to something more robust? regex? extension GetInstanceCommunityView on CommunityView { - String get instanceUrl => extract(actorId); + String get instanceUrl => _extract(actorId); } extension GetInstanceUserView on UserView { - String get instanceUrl => extract(actorId); + String get instanceUrl => _extract(actorId); } extension GetInstanceCommunityModeratorView on CommunityModeratorView { - String get instanceUrl => extract(userActorId); + String get instanceUrl => _extract(userActorId); } extension GetInstancePostView on PostView { - String get instanceUrl => extract(apId); + String get instanceUrl => _extract(apId); } extension GetInstanceUser on User { - String get instanceUrl => extract(actorId); + String get instanceUrl => _extract(actorId); } extension GetInstanceCommentView on CommentView { - String get instanceUrl => extract(apId); + String get instanceUrl => _extract(apId); } -String extract(String s) => cleanUpUrl(s.split('/')[2]); +String _extract(String s) => cleanUpUrl(s.split('/')[2]);