From 917a8018f30bd961750f4d042715f02d1ef80af9 Mon Sep 17 00:00:00 2001 From: Rongjian Zhang Date: Mon, 14 Jun 2021 01:23:16 +0800 Subject: [PATCH] refactor: list scaffold --- lib/models/account.dart | 1 - lib/models/theme.dart | 1 - lib/scaffolds/list_stateful.dart | 73 ++++++++++++-------------------- lib/screens/bb_repo.dart | 53 ++++++++++++----------- lib/screens/ge_repo.dart | 53 ++++++++++++----------- lib/screens/gh_commits.dart | 2 +- lib/screens/gh_gists.dart | 2 +- lib/screens/gh_releases.dart | 2 +- lib/screens/gh_repo.dart | 2 +- lib/screens/gh_repos.dart | 4 +- lib/screens/gh_users.dart | 10 ++--- lib/screens/go_repo.dart | 6 +-- lib/utils/utils.dart | 7 +-- lib/widgets/release_item.dart | 4 +- 14 files changed, 94 insertions(+), 126 deletions(-) diff --git a/lib/models/account.dart b/lib/models/account.dart index 609bd80..7b61ba6 100644 --- a/lib/models/account.dart +++ b/lib/models/account.dart @@ -1,5 +1,4 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:meta/meta.dart'; part 'account.g.dart'; diff --git a/lib/models/theme.dart b/lib/models/theme.dart index 6ef5d6e..35f2c0f 100644 --- a/lib/models/theme.dart +++ b/lib/models/theme.dart @@ -415,7 +415,6 @@ class ThemeModel with ChangeNotifier { } showActions(BuildContext context, List actionItems) async { - if (actionItems == null) return; final value = await showCupertinoModalPopup( context: context, builder: (BuildContext context) { diff --git a/lib/scaffolds/list_stateful.dart b/lib/scaffolds/list_stateful.dart index c3a1e96..9f80969 100644 --- a/lib/scaffolds/list_stateful.dart +++ b/lib/scaffolds/list_stateful.dart @@ -5,14 +5,14 @@ import 'package:git_touch/models/theme.dart'; import 'package:git_touch/scaffolds/common.dart'; import 'package:git_touch/utils/utils.dart'; import 'package:provider/provider.dart'; -import '../widgets/error_reload.dart'; -import '../widgets/loading.dart'; -import '../widgets/empty.dart'; +import 'package:git_touch/widgets/error_reload.dart'; +import 'package:git_touch/widgets/loading.dart'; +import 'package:git_touch/widgets/empty.dart'; class ListPayload { K cursor; - Iterable? items; - bool? hasMore; + Iterable items; + bool hasMore; ListPayload({ required this.items, @@ -56,7 +56,15 @@ class _ListStatefulScaffoldState void initState() { super.initState(); _refresh(); - _controller.addListener(onScroll); + _controller.addListener(() { + if (_controller.position.maxScrollExtent - _controller.offset < 100 && + !_controller.position.outOfRange && + !loading && + !loadingMore && + hasMore != false) { + _loadMore(); + } + }); } @override @@ -65,40 +73,17 @@ class _ListStatefulScaffoldState super.dispose(); } - void onScroll() { - // Fimber.d(_controller.position.maxScrollExtent - _controller.offset); - if (_controller.position.maxScrollExtent - _controller.offset < 100 && - !_controller.position.outOfRange && - !loading && - !loadingMore && - hasMore!) { - _loadMore(); - } - } - - // if items not enough, fetch next page - // This should be triggered after build - // TODO: disabled - void _makeSureItemsFill() { - // Future.delayed(Duration(milliseconds: 300)).then((_) { - // onScroll(); - // }); - } - - Future _refresh({bool force = false}) async { + Future _refresh() async { // Fimber.d('list scaffold refresh'); setState(() { error = ''; loading = true; - if (force) { - items = []; - } }); try { - final ListPayload _payload = await widget.fetch(null); - items = _payload.items!.toList(); - cursor = _payload.cursor; - hasMore = _payload.hasMore; + final ListPayload p = await widget.fetch(null); + items = p.items.toList(); + cursor = p.cursor; + hasMore = p.hasMore; } catch (err) { error = err.toString(); throw err; @@ -107,7 +92,6 @@ class _ListStatefulScaffoldState setState(() { loading = false; }); - _makeSureItemsFill(); } } } @@ -118,10 +102,10 @@ class _ListStatefulScaffoldState loadingMore = true; }); try { - ListPayload _payload = await widget.fetch(cursor); - items.addAll(_payload.items!); - cursor = _payload.cursor; - hasMore = _payload.hasMore; + ListPayload p = await widget.fetch(cursor); + items.addAll(p.items); + cursor = p.cursor; + hasMore = p.hasMore; } catch (err) { error = err.toString(); throw err; @@ -130,25 +114,22 @@ class _ListStatefulScaffoldState setState(() { loadingMore = false; }); - _makeSureItemsFill(); } } } Widget _buildItem(BuildContext context, int index) { if (index == 2 * items.length) { - if (hasMore!) { + if (hasMore != false) { return Loading(more: true); } else { return Container(); } - } - - if (index % 2 == 1) { + } else if (index % 2 == 1) { return CommonStyle.border; + } else { + return widget.itemBuilder(items[index ~/ 2]); } - - return widget.itemBuilder(items[index ~/ 2]); } Widget _buildCupertinoSliver() { diff --git a/lib/screens/bb_repo.dart b/lib/screens/bb_repo.dart index 6ca34ff..cc2e1b7 100644 --- a/lib/screens/bb_repo.dart +++ b/lib/screens/bb_repo.dart @@ -82,34 +82,33 @@ class BbRepoScreen extends StatelessWidget { url: '/bitbucket/$owner/$name/commits/${branch ?? p.mainbranch!.name}', ), - if (branches != null) - TableViewItem( - leftIconData: Octicons.git_branch, - text: Text(AppLocalizations.of(context)!.branches), - rightWidget: Text((branch ?? p.mainbranch!.name)! + - ' • ' + - branches.length.toString()), - onTap: () async { - if (branches.length < 2) return; + TableViewItem( + leftIconData: Octicons.git_branch, + text: Text(AppLocalizations.of(context)!.branches), + rightWidget: Text((branch ?? p.mainbranch!.name)! + + ' • ' + + branches.length.toString()), + onTap: () async { + if (branches.length < 2) return; - await theme.showPicker( - context, - PickerGroupItem( - value: branch, - items: branches - .map((b) => PickerItem(b.name, text: b.name)) - .toList(), - onClose: (ref) { - if (ref != branch) { - theme.push(context, - '/bitbucket/$owner/$name?branch=$ref', - replace: true); - } - }, - ), - ); - }, - ), + await theme.showPicker( + context, + PickerGroupItem( + value: branch, + items: branches + .map((b) => PickerItem(b.name, text: b.name)) + .toList(), + onClose: (ref) { + if (ref != branch) { + theme.push( + context, '/bitbucket/$owner/$name?branch=$ref', + replace: true); + } + }, + ), + ); + }, + ), ], ), CommonStyle.verticalGap, diff --git a/lib/screens/ge_repo.dart b/lib/screens/ge_repo.dart index a611f29..a532ed4 100644 --- a/lib/screens/ge_repo.dart +++ b/lib/screens/ge_repo.dart @@ -159,34 +159,33 @@ class GeRepoScreen extends StatelessWidget { url: '/gitee/$owner/$name/commits?branch=${branch ?? p.defaultBranch}', ), - if (branches != null) - TableViewItem( - leftIconData: Octicons.git_branch, - text: Text(AppLocalizations.of(context)!.branches), - rightWidget: Text((branch ?? p.defaultBranch)! + - ' • ' + - branches.length.toString()), - onTap: () async { - if (branches.length < 2) return; + TableViewItem( + leftIconData: Octicons.git_branch, + text: Text(AppLocalizations.of(context)!.branches), + rightWidget: Text((branch ?? p.defaultBranch)! + + ' • ' + + branches.length.toString()), + onTap: () async { + if (branches.length < 2) return; - await theme.showPicker( - context, - PickerGroupItem( - value: branch, - items: branches - .map((b) => PickerItem(b.name, text: b.name)) - .toList(), - onClose: (ref) { - if (ref != branch) { - theme.push( - context, '/gitee/$owner/$name?branch=$ref', - replace: true); - } - }, - ), - ); - }, - ), + await theme.showPicker( + context, + PickerGroupItem( + value: branch, + items: branches + .map((b) => PickerItem(b.name, text: b.name)) + .toList(), + onClose: (ref) { + if (ref != branch) { + theme.push( + context, '/gitee/$owner/$name?branch=$ref', + replace: true); + } + }, + ), + ); + }, + ), TableViewItem( leftIconData: Octicons.organization, text: Text('Contributors'), diff --git a/lib/screens/gh_commits.dart b/lib/screens/gh_commits.dart index bc4bc19..eb1745d 100644 --- a/lib/screens/gh_commits.dart +++ b/lib/screens/gh_commits.dart @@ -50,7 +50,7 @@ class GhCommits extends StatelessWidget { return ListPayload( cursor: history.pageInfo.endCursor, hasMore: history.pageInfo.hasNextPage, - items: history.nodes, + items: history.nodes ?? [], ); }, itemBuilder: (p) { diff --git a/lib/screens/gh_gists.dart b/lib/screens/gh_gists.dart index af01a85..6ab2c50 100644 --- a/lib/screens/gh_gists.dart +++ b/lib/screens/gh_gists.dart @@ -28,7 +28,7 @@ class GhGistsScreen extends StatelessWidget { final gists = res.data!.user!.gists; return ListPayload( cursor: gists.pageInfo.endCursor, - items: gists.nodes, + items: gists.nodes ?? [], hasMore: gists.pageInfo.hasNextPage, ); }, diff --git a/lib/screens/gh_releases.dart b/lib/screens/gh_releases.dart index cca7aa6..40996be 100644 --- a/lib/screens/gh_releases.dart +++ b/lib/screens/gh_releases.dart @@ -30,7 +30,7 @@ class GhReleasesScreen extends StatelessWidget { final releases = res.data!.repository!.releases; return ListPayload( cursor: releases.pageInfo.endCursor, - items: releases.nodes, + items: releases.nodes ?? [], hasMore: releases.pageInfo.hasNextPage, ); }, diff --git a/lib/screens/gh_repo.dart b/lib/screens/gh_repo.dart index dea0265..90fe92e 100644 --- a/lib/screens/gh_repo.dart +++ b/lib/screens/gh_repo.dart @@ -75,7 +75,7 @@ class GhRepoScreen extends StatelessWidget { return res.body; }).catchError((err) { // 404 - return null; + return ''; }); }; }; diff --git a/lib/screens/gh_repos.dart b/lib/screens/gh_repos.dart index 391180b..cd008fc 100644 --- a/lib/screens/gh_repos.dart +++ b/lib/screens/gh_repos.dart @@ -30,7 +30,7 @@ class GhRepos extends StatelessWidget { return ListPayload( cursor: p.pageInfo.endCursor, hasMore: p.pageInfo.hasNextPage, - items: p.nodes, + items: p.nodes!, ); }, itemBuilder: (p) { @@ -61,7 +61,7 @@ class GhStars extends StatelessWidget { return ListPayload( cursor: p.pageInfo.endCursor, hasMore: p.pageInfo.hasNextPage, - items: p.nodes, + items: p.nodes!, ); }, itemBuilder: (p) { diff --git a/lib/screens/gh_users.dart b/lib/screens/gh_users.dart index bbda958..ec2bee1 100644 --- a/lib/screens/gh_users.dart +++ b/lib/screens/gh_users.dart @@ -29,7 +29,7 @@ class GhFollowers extends StatelessWidget { return ListPayload( cursor: p.pageInfo.endCursor, hasMore: p.pageInfo.hasNextPage, - items: p.nodes, + items: p.nodes!, ); }, itemBuilder: (p) { @@ -59,7 +59,7 @@ class GhFollowing extends StatelessWidget { return ListPayload( cursor: p.pageInfo.endCursor, hasMore: p.pageInfo.hasNextPage, - items: p.nodes, + items: p.nodes!, ); }, itemBuilder: (p) { @@ -89,7 +89,7 @@ class GhMembers extends StatelessWidget { return ListPayload( cursor: p.pageInfo.endCursor, hasMore: p.pageInfo.hasNextPage, - items: p.nodes, + items: p.nodes!, ); }, itemBuilder: (p) { @@ -121,7 +121,7 @@ class GhWachers extends StatelessWidget { return ListPayload( cursor: p.pageInfo.endCursor, hasMore: p.pageInfo.hasNextPage, - items: p.nodes, + items: p.nodes!, ); }, itemBuilder: (p) { @@ -153,7 +153,7 @@ class GhStargazers extends StatelessWidget { return ListPayload( cursor: p.pageInfo.endCursor, hasMore: p.pageInfo.hasNextPage, - items: p.nodes, + items: p.nodes!, ); }, itemBuilder: (p) { diff --git a/lib/screens/go_repo.dart b/lib/screens/go_repo.dart index 8b3eb55..5e5bc71 100644 --- a/lib/screens/go_repo.dart +++ b/lib/screens/go_repo.dart @@ -114,12 +114,10 @@ class GoRepoScreen extends StatelessWidget { TableViewItem( leftIconData: Octicons.git_branch, text: Text(AppLocalizations.of(context)!.branches), - rightWidget: Text((branch ?? 'master')! + + rightWidget: Text((branch ?? 'master') + ' • ' + - '${branches == null ? '1' : branches.length.toString()}'), + '${branches.length.toString()}'), onTap: () async { - if (branches == null) return; - await theme.showPicker( context, PickerGroupItem( diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 0c287c1..a0e1eb3 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -119,7 +119,7 @@ List join(T seperator, List xs) { List joinAll(T seperator, List> xss) { List result = []; xss.asMap().forEach((index, x) { - if (x == null || x.isEmpty) return; + if (x.isEmpty) return; result.addAll(x); if (index < xss.length - 1) { @@ -136,11 +136,6 @@ bool isNotNullOrEmpty(String? text) { return text != null && text.isNotEmpty; } -String getBranchQueryKey(String branch, {bool withParams = false}) { - if (branch == null) return 'defaultBranchRef'; - return 'ref' + (withParams ? '(qualifiedName: "$branch")' : ''); -} - // TODO: Primer class PrimerBranchName extends StatelessWidget { final String? name; diff --git a/lib/widgets/release_item.dart b/lib/widgets/release_item.dart index 15bbb82..e8a8bae 100644 --- a/lib/widgets/release_item.dart +++ b/lib/widgets/release_item.dart @@ -101,9 +101,7 @@ class ReleaseItem extends StatelessWidget { ), rightWidget: IconButton( onPressed: () { - if (asset.downloadUrl != null) { - theme.push(context, asset.downloadUrl); - } + theme.push(context, asset.downloadUrl); }, icon: Icon(Ionicons.download_outline)), hideRightChevron: true,