From 1fe7e1fdc99ccc3a913e3345cc7dad4477a89406 Mon Sep 17 00:00:00 2001 From: Rongjian Zhang Date: Sun, 4 Oct 2020 22:10:05 +0800 Subject: [PATCH] refactor: list scaffold --- lib/scaffolds/list_stateful.dart | 4 +- lib/screens/bb_commits.dart | 27 +++---- lib/screens/bb_explore.dart | 26 +++---- lib/screens/bb_issues.dart | 28 +++---- lib/screens/bb_pulls.dart | 27 +++---- lib/screens/bb_teams.dart | 28 +++---- lib/screens/gh_commits.dart | 39 +++++----- lib/screens/gh_contributors.dart | 35 ++++----- lib/screens/gh_events.dart | 25 +++--- lib/screens/gh_files.dart | 33 ++++---- lib/screens/gh_gists.dart | 33 ++++---- lib/screens/gh_issues.dart | 33 ++++---- lib/screens/gh_news.dart | 32 ++++---- lib/screens/gh_org_repos.dart | 33 ++++---- lib/screens/gh_orgs.dart | 36 ++++----- lib/screens/gh_pulls.dart | 33 ++++---- lib/screens/gh_repos.dart | 44 +++++------ lib/screens/gh_users.dart | 110 +++++++++++++-------------- lib/screens/gl_commits.dart | 26 +++---- lib/screens/gl_explore.dart | 29 ++++--- lib/screens/gl_groups.dart | 27 +++---- lib/screens/gl_issues.dart | 26 +++---- lib/screens/gl_members.dart | 28 ++++--- lib/screens/gl_merge_requests.dart | 24 +++--- lib/screens/gl_project_activity.dart | 19 ++--- lib/screens/gl_starrers.dart | 29 ++++--- lib/screens/gt_commits.dart | 25 +++--- lib/screens/gt_issues.dart | 25 +++--- lib/screens/gt_orgs.dart | 29 ++++--- 29 files changed, 411 insertions(+), 502 deletions(-) diff --git a/lib/scaffolds/list_stateful.dart b/lib/scaffolds/list_stateful.dart index d3e32e2..bdc7b80 100644 --- a/lib/scaffolds/list_stateful.dart +++ b/lib/scaffolds/list_stateful.dart @@ -26,13 +26,11 @@ class ListStatefulScaffold extends StatefulWidget { final Widget title; final Widget Function() actionBuilder; final Widget Function(T payload) itemBuilder; - final Future> Function() onRefresh; final Future> Function(K cursor) onLoadMore; ListStatefulScaffold({ @required this.title, @required this.itemBuilder, - @required this.onRefresh, @required this.onLoadMore, this.actionBuilder, }); @@ -97,7 +95,7 @@ class _ListStatefulScaffoldState } }); try { - var _payload = await widget.onRefresh(); + var _payload = await widget.onLoadMore(null); items = _payload.items; cursor = _payload.cursor; hasMore = _payload.hasMore; diff --git a/lib/screens/bb_commits.dart b/lib/screens/bb_commits.dart index d979283..b1921c4 100644 --- a/lib/screens/bb_commits.dart +++ b/lib/screens/bb_commits.dart @@ -12,27 +12,22 @@ class BbCommitsScreen extends StatelessWidget { final String ref; BbCommitsScreen(this.owner, this.name, this.ref); - Future> _query(BuildContext context, - [String nextUrl]) async { - final res = await context - .read() - .fetchBbWithPage(nextUrl ?? '/repositories/$owner/$name/commits/$ref'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) BbCommit.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { final auth = Provider.of(context); return ListStatefulScaffold( title: AppBarTitle('Commits'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (nextUrl) async { + final res = await context.read().fetchBbWithPage( + nextUrl ?? '/repositories/$owner/$name/commits/$ref'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) BbCommit.fromJson(v), + ], + ); + }, itemBuilder: (v) { return CommitItem( url: '${auth.activeAccount.domain}/$owner/$name/commits/${v.hash}', diff --git a/lib/screens/bb_explore.dart b/lib/screens/bb_explore.dart index 804eed3..3843a46 100644 --- a/lib/screens/bb_explore.dart +++ b/lib/screens/bb_explore.dart @@ -7,25 +7,21 @@ import 'package:git_touch/widgets/repository_item.dart'; import 'package:provider/provider.dart'; class BbExploreScreen extends StatelessWidget { - Future> _query(BuildContext context, - [String nextUrl]) async { - final res = await context.read().fetchBbWithPage( - nextUrl ?? '/repositories?role=member&sort=-updated_on'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) BbRepo.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Explore'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (nextUrl) async { + final res = await context.read().fetchBbWithPage( + nextUrl ?? '/repositories?role=member&sort=-updated_on'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) BbRepo.fromJson(v), + ], + ); + }, itemBuilder: (v) { return RepositoryItem.bb(payload: v); }, diff --git a/lib/screens/bb_issues.dart b/lib/screens/bb_issues.dart index cfe8fa0..5b8c92b 100644 --- a/lib/screens/bb_issues.dart +++ b/lib/screens/bb_issues.dart @@ -12,27 +12,23 @@ class BbIssuesScreen extends StatelessWidget { final String ref; BbIssuesScreen(this.owner, this.name, this.ref); - Future> _query(BuildContext context, - [String nextUrl]) async { - final res = await context - .read() - .fetchBbWithPage(nextUrl ?? '/repositories/$owner/$name/issues'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) BbIssues.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { final auth = Provider.of(context); return ListStatefulScaffold( title: AppBarTitle('Issues'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (nextUrl) async { + final res = await context + .read() + .fetchBbWithPage(nextUrl ?? '/repositories/$owner/$name/issues'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) BbIssues.fromJson(v), + ], + ); + }, itemBuilder: (v) { int issueNumber = int.parse(v.issueLink.replaceFirst(RegExp(r'.*\/'), '')); diff --git a/lib/screens/bb_pulls.dart b/lib/screens/bb_pulls.dart index ceb46bc..ca00834 100644 --- a/lib/screens/bb_pulls.dart +++ b/lib/screens/bb_pulls.dart @@ -12,27 +12,22 @@ class BbPullsScreen extends StatelessWidget { final String ref; BbPullsScreen(this.owner, this.name, this.ref); - Future> _query(BuildContext context, - [String nextUrl]) async { - final res = await context - .read() - .fetchBbWithPage(nextUrl ?? '/repositories/$owner/$name/pullrequests'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) BbPulls.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { final auth = Provider.of(context); return ListStatefulScaffold( title: AppBarTitle('Pull requests'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (nextUrl) async { + final res = await context.read().fetchBbWithPage( + nextUrl ?? '/repositories/$owner/$name/pullrequests'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) BbPulls.fromJson(v), + ], + ); + }, itemBuilder: (v) { int pullNumber = int.parse(v.pullRequestLink.replaceFirst(RegExp(r'.*\/'), '')); diff --git a/lib/screens/bb_teams.dart b/lib/screens/bb_teams.dart index ce49e8f..311c118 100644 --- a/lib/screens/bb_teams.dart +++ b/lib/screens/bb_teams.dart @@ -8,26 +8,22 @@ import 'package:provider/provider.dart'; import 'package:timeago/timeago.dart' as timeago; class BbTeamsScreen extends StatelessWidget { - Future> _query(BuildContext context, - [String nextUrl]) async { - final res = await context - .read() - .fetchBbWithPage(nextUrl ?? '/teams?role=member'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) BbUser.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Teams'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (nextUrl) async { + final res = await context + .read() + .fetchBbWithPage(nextUrl ?? '/teams?role=member'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) BbUser.fromJson(v), + ], + ); + }, itemBuilder: (v) { return UserItem( login: v.username, diff --git a/lib/screens/gh_commits.dart b/lib/screens/gh_commits.dart index 1506bc6..1791586 100644 --- a/lib/screens/gh_commits.dart +++ b/lib/screens/gh_commits.dart @@ -13,25 +13,6 @@ class GhCommitsScreen extends StatelessWidget { final String branch; GhCommitsScreen(this.owner, this.name, {this.branch}); - Future> _query(BuildContext context, - [String cursor]) async { - final res = await context.read().gqlClient.execute( - GhCommitsQuery( - variables: GhCommitsArguments( - owner: owner, - name: name, - hasRef: branch != null, - ref: branch ?? '', - after: cursor))); - final ref = res.data.repository.defaultBranchRef ?? res.data.repository.ref; - final history = (ref.target as GhCommitsCommit).history; - return ListPayload( - cursor: history.pageInfo.endCursor, - hasMore: history.pageInfo.hasNextPage, - items: history.nodes, - ); - } - Widget _buildStatus(GhCommitsStatusState state) { const size = 18.0; switch (state) { @@ -48,8 +29,24 @@ class GhCommitsScreen extends StatelessWidget { Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Commits'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (cursor) async { + final res = await context.read().gqlClient.execute( + GhCommitsQuery( + variables: GhCommitsArguments( + owner: owner, + name: name, + hasRef: branch != null, + ref: branch ?? '', + after: cursor))); + final ref = + res.data.repository.defaultBranchRef ?? res.data.repository.ref; + final history = (ref.target as GhCommitsCommit).history; + return ListPayload( + cursor: history.pageInfo.endCursor, + hasMore: history.pageInfo.hasNextPage, + items: history.nodes, + ); + }, itemBuilder: (payload) { final login = payload.author?.user?.login; return CommitItem( diff --git a/lib/screens/gh_contributors.dart b/lib/screens/gh_contributors.dart index 2cdb009..1531ed1 100644 --- a/lib/screens/gh_contributors.dart +++ b/lib/screens/gh_contributors.dart @@ -12,28 +12,25 @@ class GhContributorsScreen extends StatelessWidget { final String name; GhContributorsScreen(this.owner, this.name); - Future> _query(BuildContext context, - [int page = 1]) async { - final res = await context - .read() - .ghClient - .getJSON>( - '/repos/$owner/$name/contributors?page=$page', - convert: (vs) => - [for (var v in vs) GithubContributorItem.fromJson(v)], - ); - return ListPayload( - cursor: page + 1, - items: res, - hasMore: res.isNotEmpty, - ); - } - Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Contributors'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final res = await context + .read() + .ghClient + .getJSON>( + '/repos/$owner/$name/contributors?page=$page', + convert: (vs) => + [for (var v in vs) GithubContributorItem.fromJson(v)], + ); + return ListPayload( + cursor: page + 1, + items: res, + hasMore: res.isNotEmpty, + ); + }, itemBuilder: (v) { final String login = v.login; return ContributorItem( diff --git a/lib/screens/gh_events.dart b/lib/screens/gh_events.dart index 84e9ebb..7c083d4 100644 --- a/lib/screens/gh_events.dart +++ b/lib/screens/gh_events.dart @@ -12,25 +12,22 @@ class GhEventsScreen extends StatelessWidget { final String login; GhEventsScreen(this.login); - Future> fetchEvents(BuildContext context, - [int page = 1]) async { - final events = await context.read().ghClient.getJSON( - '/users/$login/events?page=$page&per_page=$pageSize', - convert: (vs) => [for (var v in vs) GithubEvent.fromJson(v)]); - return ListPayload( - cursor: page + 1, - hasMore: events.length == pageSize, - items: events, - ); - } - @override Widget build(context) { return ListStatefulScaffold( title: AppBarTitle('Events'), itemBuilder: (payload) => EventItem(payload), - onRefresh: () => fetchEvents(context), - onLoadMore: (page) => fetchEvents(context, page), + onLoadMore: (page) async { + page = page ?? 1; + final events = await context.read().ghClient.getJSON( + '/users/$login/events?page=$page&per_page=$pageSize', + convert: (vs) => [for (var v in vs) GithubEvent.fromJson(v)]); + return ListPayload( + cursor: page + 1, + hasMore: events.length == pageSize, + items: events, + ); + }, ); } } diff --git a/lib/screens/gh_files.dart b/lib/screens/gh_files.dart index a3a0ec7..c0c7e9e 100644 --- a/lib/screens/gh_files.dart +++ b/lib/screens/gh_files.dart @@ -14,22 +14,6 @@ class GhFilesScreen extends StatelessWidget { final int pullNumber; GhFilesScreen(this.owner, this.name, this.pullNumber); - Future> _query(BuildContext context, - [int page = 1]) async { - final res = await context - .read() - .ghClient - .getJSON>( - '/repos/$owner/$name/pulls/$pullNumber/files?page=$page', - convert: (vs) => [for (var v in vs) GithubFilesItem.fromJson(v)], - ); - return ListPayload( - cursor: page + 1, - items: res, - hasMore: res.isNotEmpty, - ); - } - Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Files'), @@ -42,8 +26,21 @@ class GhFilesScreen extends StatelessWidget { ], ); }, - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final res = await context + .read() + .ghClient + .getJSON>( + '/repos/$owner/$name/pulls/$pullNumber/files?page=$page', + convert: (vs) => [for (var v in vs) GithubFilesItem.fromJson(v)], + ); + return ListPayload( + cursor: page + 1, + items: res, + hasMore: res.isNotEmpty, + ); + }, itemBuilder: (v) { return FilesItem( filename: v.filename, diff --git a/lib/screens/gh_gists.dart b/lib/screens/gh_gists.dart index b4df1c4..6fec420 100644 --- a/lib/screens/gh_gists.dart +++ b/lib/screens/gh_gists.dart @@ -11,28 +11,25 @@ class GhGistsScreen extends StatelessWidget { final String login; GhGistsScreen(this.login); - Future> _query(BuildContext context, - [int page = 1]) async { - final res = await context - .read() - .ghClient - .getJSON>( - '/users/$login/gists?page=$page', - convert: (vs) => [for (var v in vs) GithubGistsItem.fromJson(v)], - ); - return ListPayload( - cursor: page + 1, - items: res, - hasMore: res.isNotEmpty, - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Gists'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final res = await context + .read() + .ghClient + .getJSON>( + '/users/$login/gists?page=$page', + convert: (vs) => [for (var v in vs) GithubGistsItem.fromJson(v)], + ); + return ListPayload( + cursor: page + 1, + items: res, + hasMore: res.isNotEmpty, + ); + }, itemBuilder: (v) { return GistsItem( description: v.description, diff --git a/lib/screens/gh_issues.dart b/lib/screens/gh_issues.dart index fb7ac7f..8794255 100644 --- a/lib/screens/gh_issues.dart +++ b/lib/screens/gh_issues.dart @@ -14,22 +14,6 @@ class GhIssuesScreen extends StatelessWidget { final String name; GhIssuesScreen(this.owner, this.name); - Future> _query(BuildContext context, - [String cursor]) async { - final res = await context.read().gqlClient.execute(GhIssuesQuery( - variables: GhIssuesArguments( - owner: owner, - name: name, - cursor: cursor, - ))); - final issues = res.data.repository.issues; - return ListPayload( - cursor: issues.pageInfo.endCursor, - hasMore: issues.pageInfo.hasNextPage, - items: issues.nodes, - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( @@ -38,8 +22,21 @@ class GhIssuesScreen extends StatelessWidget { iconData: Octicons.plus, url: '/github/$owner/$name/issues/new', ), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (cursor) async { + final res = + await context.read().gqlClient.execute(GhIssuesQuery( + variables: GhIssuesArguments( + owner: owner, + name: name, + cursor: cursor, + ))); + final issues = res.data.repository.issues; + return ListPayload( + cursor: issues.pageInfo.endCursor, + hasMore: issues.pageInfo.hasNextPage, + items: issues.nodes, + ); + }, itemBuilder: (p) => IssueItem( author: p.author?.login, avatarUrl: p.author?.avatarUrl, diff --git a/lib/screens/gh_news.dart b/lib/screens/gh_news.dart index dca2918..0c421cf 100644 --- a/lib/screens/gh_news.dart +++ b/lib/screens/gh_news.dart @@ -32,28 +32,26 @@ class GhNewsScreenState extends State { }); } - Future> fetchEvents([int page = 1]) async { - final auth = context.read(); - final login = auth.activeAccount.login; - - final events = await auth.ghClient.getJSON( - '/users/$login/received_events?page=$page&per_page=$pageSize', - convert: (vs) => [for (var v in vs) GithubEvent.fromJson(v)], - ); - return ListPayload( - cursor: page + 1, - hasMore: events.length == pageSize, - items: events, - ); - } - @override Widget build(context) { return ListStatefulScaffold( title: AppBarTitle('News'), itemBuilder: (payload) => EventItem(payload), - onRefresh: fetchEvents, - onLoadMore: (page) => fetchEvents(page), + onLoadMore: (page) async { + page = page ?? 1; + final auth = context.read(); + final login = auth.activeAccount.login; + + final events = await auth.ghClient.getJSON( + '/users/$login/received_events?page=$page&per_page=$pageSize', + convert: (vs) => [for (var v in vs) GithubEvent.fromJson(v)], + ); + return ListPayload( + cursor: page + 1, + hasMore: events.length == pageSize, + items: events, + ); + }, ); } } diff --git a/lib/screens/gh_org_repos.dart b/lib/screens/gh_org_repos.dart index b185165..10a37bb 100644 --- a/lib/screens/gh_org_repos.dart +++ b/lib/screens/gh_org_repos.dart @@ -16,28 +16,25 @@ class GhOrgReposScreen extends StatelessWidget { final String owner; GhOrgReposScreen(this.owner); - Future> _query(BuildContext context, - [int page = 1]) async { - final rs = await context - .read() - .ghClient - .getJSON>( - '/orgs/$owner/repos?sort=updated&page=$page', - convert: (vs) => [for (var v in vs) Repository.fromJson(v)], - ); - return ListPayload( - cursor: page + 1, - items: rs, - hasMore: rs.isNotEmpty, // TODO: - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Repositories'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final rs = await context + .read() + .ghClient + .getJSON>( + '/orgs/$owner/repos?sort=updated&page=$page', + convert: (vs) => [for (var v in vs) Repository.fromJson(v)], + ); + return ListPayload( + cursor: page + 1, + items: rs, + hasMore: rs.isNotEmpty, // TODO: + ); + }, itemBuilder: (v) { return RepositoryItem.gh( owner: v.owner.login, diff --git a/lib/screens/gh_orgs.dart b/lib/screens/gh_orgs.dart index 8fe74ac..137aa1d 100644 --- a/lib/screens/gh_orgs.dart +++ b/lib/screens/gh_orgs.dart @@ -11,29 +11,25 @@ class GhUserOrganizationScreen extends StatelessWidget { final String login; GhUserOrganizationScreen(this.login); - Future> _query( - BuildContext context, - [int page = 1]) async { - final res = await context - .read() - .ghClient - .getJSON>( - '/users/$login/orgs?page=$page', - convert: (vs) => - [for (var v in vs) GithubUserOrganizationItem.fromJson(v)], - ); - return ListPayload( - cursor: page + 1, - items: res, - hasMore: res.isNotEmpty, - ); - } - Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Organizations'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final res = await context + .read() + .ghClient + .getJSON>( + '/users/$login/orgs?page=$page', + convert: (vs) => + [for (var v in vs) GithubUserOrganizationItem.fromJson(v)], + ); + return ListPayload( + cursor: page + 1, + items: res, + hasMore: res.isNotEmpty, + ); + }, itemBuilder: (v) { return UserItem.gh( avatarUrl: v.avatarUrl, diff --git a/lib/screens/gh_pulls.dart b/lib/screens/gh_pulls.dart index a7ac1ce..f85df29 100644 --- a/lib/screens/gh_pulls.dart +++ b/lib/screens/gh_pulls.dart @@ -12,28 +12,25 @@ class GhPullsScreen extends StatelessWidget { final String name; GhPullsScreen(this.owner, this.name); - Future> _query(BuildContext context, - [String cursor]) async { - final res = await context.read().gqlClient.execute(GhPullsQuery( - variables: GhPullsArguments( - owner: owner, - name: name, - cursor: cursor, - ))); - final pulls = res.data.repository.pullRequests; - return ListPayload( - cursor: pulls.pageInfo.endCursor, - hasMore: pulls.pageInfo.hasNextPage, - items: pulls.nodes, - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Pull requests'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (cursor) async { + final res = + await context.read().gqlClient.execute(GhPullsQuery( + variables: GhPullsArguments( + owner: owner, + name: name, + cursor: cursor, + ))); + final pulls = res.data.repository.pullRequests; + return ListPayload( + cursor: pulls.pageInfo.endCursor, + hasMore: pulls.pageInfo.hasNextPage, + items: pulls.nodes, + ); + }, itemBuilder: (p) => IssueItem( isPr: true, author: p.author?.login, diff --git a/lib/screens/gh_repos.dart b/lib/screens/gh_repos.dart index 5cea1db..6e137bf 100644 --- a/lib/screens/gh_repos.dart +++ b/lib/screens/gh_repos.dart @@ -19,34 +19,30 @@ class GhReposScreen extends StatelessWidget { : title = 'Stars', isStar = true; - Future> _query(BuildContext context, - [String cursor]) async { - final auth = context.read(); - final res = await auth.gqlClient.execute(GhReposQuery( - variables: - GhReposArguments(owner: owner, isStar: isStar, after: cursor))); - final data = res.data.user; - if (isStar) { - return ListPayload( - cursor: data.starredRepositories.pageInfo.endCursor, - items: data.starredRepositories.nodes, - hasMore: data.starredRepositories.pageInfo.hasNextPage, - ); - } else { - return ListPayload( - cursor: data.repositories.pageInfo.endCursor, - items: data.repositories.nodes, - hasMore: data.repositories.pageInfo.hasNextPage, - ); - } - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle(title), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (cursor) async { + final auth = context.read(); + final res = await auth.gqlClient.execute(GhReposQuery( + variables: + GhReposArguments(owner: owner, isStar: isStar, after: cursor))); + final data = res.data.user; + if (isStar) { + return ListPayload( + cursor: data.starredRepositories.pageInfo.endCursor, + items: data.starredRepositories.nodes, + hasMore: data.starredRepositories.pageInfo.hasNextPage, + ); + } else { + return ListPayload( + cursor: data.repositories.pageInfo.endCursor, + items: data.repositories.nodes, + hasMore: data.repositories.pageInfo.hasNextPage, + ); + } + }, itemBuilder: (v) { return RepositoryItem.gh( owner: v.owner.login, diff --git a/lib/screens/gh_users.dart b/lib/screens/gh_users.dart index 69873c1..55b108c 100644 --- a/lib/screens/gh_users.dart +++ b/lib/screens/gh_users.dart @@ -40,61 +40,6 @@ class GhUsersScreen extends StatelessWidget { } } - Future> _queryUsers(BuildContext context, - [String cursor]) async { - final auth = context.read(); - final res = await auth.gqlClient.execute(GhUsersQuery( - variables: GhUsersArguments( - login: login, - repoName: repoName, - isFollowers: type == UsersScreenType.follower, - isFollowing: type == UsersScreenType.following, - isStar: type == UsersScreenType.star, - isWatch: type == UsersScreenType.watch, - isMember: type == UsersScreenType.member, - after: cursor))); - - switch (type) { - case UsersScreenType.follower: - final payload = res.data.user.followers; - return ListPayload( - cursor: payload.pageInfo.endCursor, - hasMore: payload.pageInfo.hasNextPage, - items: payload.nodes, - ); - case UsersScreenType.following: - final payload = res.data.user.following; - return ListPayload( - cursor: payload.pageInfo.endCursor, - hasMore: payload.pageInfo.hasNextPage, - items: payload.nodes, - ); - case UsersScreenType.member: - final payload = res.data.organization.membersWithRole; - return ListPayload( - cursor: payload.pageInfo.endCursor, - hasMore: payload.pageInfo.hasNextPage, - items: payload.nodes, - ); - case UsersScreenType.watch: - final payload = res.data.repository.watchers; - return ListPayload( - cursor: payload.pageInfo.endCursor, - hasMore: payload.pageInfo.hasNextPage, - items: payload.nodes, - ); - case UsersScreenType.star: - final payload = res.data.repository.stargazers; - return ListPayload( - cursor: payload.pageInfo.endCursor, - hasMore: payload.pageInfo.hasNextPage, - items: payload.nodes, - ); - default: - return null; - } - } - Widget _buildBio(BuildContext context, String company, String location, DateTime createdAt) { final theme = Provider.of(context); @@ -143,8 +88,59 @@ class GhUsersScreen extends StatelessWidget { Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle(_title), - onRefresh: () => _queryUsers(context), - onLoadMore: (cursor) => _queryUsers(context, cursor), + onLoadMore: (cursor) async { + final auth = context.read(); + final res = await auth.gqlClient.execute(GhUsersQuery( + variables: GhUsersArguments( + login: login, + repoName: repoName, + isFollowers: type == UsersScreenType.follower, + isFollowing: type == UsersScreenType.following, + isStar: type == UsersScreenType.star, + isWatch: type == UsersScreenType.watch, + isMember: type == UsersScreenType.member, + after: cursor))); + + switch (type) { + case UsersScreenType.follower: + final payload = res.data.user.followers; + return ListPayload( + cursor: payload.pageInfo.endCursor, + hasMore: payload.pageInfo.hasNextPage, + items: payload.nodes, + ); + case UsersScreenType.following: + final payload = res.data.user.following; + return ListPayload( + cursor: payload.pageInfo.endCursor, + hasMore: payload.pageInfo.hasNextPage, + items: payload.nodes, + ); + case UsersScreenType.member: + final payload = res.data.organization.membersWithRole; + return ListPayload( + cursor: payload.pageInfo.endCursor, + hasMore: payload.pageInfo.hasNextPage, + items: payload.nodes, + ); + case UsersScreenType.watch: + final payload = res.data.repository.watchers; + return ListPayload( + cursor: payload.pageInfo.endCursor, + hasMore: payload.pageInfo.hasNextPage, + items: payload.nodes, + ); + case UsersScreenType.star: + final payload = res.data.repository.stargazers; + return ListPayload( + cursor: payload.pageInfo.endCursor, + hasMore: payload.pageInfo.hasNextPage, + items: payload.nodes, + ); + default: + return null; + } + }, itemBuilder: (payload) { return UserItem.gh( login: payload.login, diff --git a/lib/screens/gl_commits.dart b/lib/screens/gl_commits.dart index 6c56247..906aadc 100644 --- a/lib/screens/gl_commits.dart +++ b/lib/screens/gl_commits.dart @@ -12,24 +12,22 @@ class GlCommitsScreen extends StatelessWidget { // final String branch; // TODO: GlCommitsScreen(this.id, {this.prefix}); - Future> _query(BuildContext context, - [int page = 1]) async { - final auth = context.read(); - final res = await auth - .fetchGitlabWithPage('/projects/$id/repository/commits?page=$page'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: (res.data as List).map((v) => GitlabCommit.fromJson(v)).toList(), - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Commits'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final auth = context.read(); + final res = await auth + .fetchGitlabWithPage('/projects/$id/repository/commits?page=$page'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: + (res.data as List).map((v) => GitlabCommit.fromJson(v)).toList(), + ); + }, itemBuilder: (c) { return CommitItem( author: c.authorName, diff --git a/lib/screens/gl_explore.dart b/lib/screens/gl_explore.dart index 7426724..cd85f63 100644 --- a/lib/screens/gl_explore.dart +++ b/lib/screens/gl_explore.dart @@ -8,26 +8,23 @@ import 'package:provider/provider.dart'; import 'package:timeago/timeago.dart' as timeago; class GlExploreScreen extends StatelessWidget { - Future> _query(BuildContext context, - [int page = 1]) async { - final auth = context.read(); - final res = await auth - .fetchGitlabWithPage('/projects?order_by=last_activity_at&page=$page'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) GitlabProject.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Explore'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (page) async { + page = page ?? 1; + final auth = context.read(); + final res = await auth.fetchGitlabWithPage( + '/projects?order_by=last_activity_at&page=$page'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) GitlabProject.fromJson(v), + ], + ); + }, itemBuilder: (v) { return RepositoryItem.gl( payload: v, diff --git a/lib/screens/gl_groups.dart b/lib/screens/gl_groups.dart index 2182f0c..2f295f6 100644 --- a/lib/screens/gl_groups.dart +++ b/lib/screens/gl_groups.dart @@ -7,25 +7,22 @@ import 'package:git_touch/widgets/user_item.dart'; import 'package:provider/provider.dart'; class GlGroupsScreenn extends StatelessWidget { - Future> _query(BuildContext context, - [int page = 1]) async { - final auth = context.read(); - final res = await auth.fetchGitlabWithPage('/groups?page=$page'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) GitlabGroup.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Groups'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (page) async { + page = page ?? 1; + final auth = context.read(); + final res = await auth.fetchGitlabWithPage('/groups?page=$page'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) GitlabGroup.fromJson(v), + ], + ); + }, itemBuilder: (v) { return UserItem( avatarUrl: v.avatarUrl, diff --git a/lib/screens/gl_issues.dart b/lib/screens/gl_issues.dart index d4b4851..e0cb490 100644 --- a/lib/screens/gl_issues.dart +++ b/lib/screens/gl_issues.dart @@ -12,25 +12,23 @@ class GlIssuesScreen extends StatelessWidget { final String prefix; GlIssuesScreen(this.id, {this.prefix}); - Future> _query(BuildContext context, - [int page = 1]) async { - final auth = context.read(); - final res = await auth - .fetchGitlabWithPage('/projects/$id/issues?state=opened&page=$page'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: (res.data as List).map((v) => GitlabIssue.fromJson(v)).toList(), - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Issues'), // TODO: create issue - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final auth = context.read(); + final res = await auth.fetchGitlabWithPage( + '/projects/$id/issues?state=opened&page=$page'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: + (res.data as List).map((v) => GitlabIssue.fromJson(v)).toList(), + ); + }, itemBuilder: (p) => IssueItem( author: p.author.username, avatarUrl: p.author.avatarUrl, diff --git a/lib/screens/gl_members.dart b/lib/screens/gl_members.dart index d11a357..3d09dc5 100644 --- a/lib/screens/gl_members.dart +++ b/lib/screens/gl_members.dart @@ -11,19 +11,6 @@ class GlMembersScreen extends StatelessWidget { final String type; GlMembersScreen(this.id, this.type); - Future> _query(BuildContext context, - [int page = 1]) async { - final auth = context.read(); - final res = await auth.fetchGitlabWithPage('/$type/$id/members?page=$page'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) GitlabUser.fromJson(v), - ], - ); - } - // https://docs.gitlab.com/ee/api/access_requests.html#valid-access-levels static const accessLevelMap = { 10: 'Guest', @@ -37,8 +24,19 @@ class GlMembersScreen extends StatelessWidget { Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Members'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (page) async { + page = page ?? 1; + final auth = context.read(); + final res = + await auth.fetchGitlabWithPage('/$type/$id/members?page=$page'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) GitlabUser.fromJson(v), + ], + ); + }, itemBuilder: (v) { return UserItem( avatarUrl: v.avatarUrl, diff --git a/lib/screens/gl_merge_requests.dart b/lib/screens/gl_merge_requests.dart index 14fb9b5..6e8eac1 100644 --- a/lib/screens/gl_merge_requests.dart +++ b/lib/screens/gl_merge_requests.dart @@ -12,23 +12,21 @@ class GlMergeRequestsScreen extends StatelessWidget { final String prefix; GlMergeRequestsScreen(this.id, {this.prefix}); - Future> _query(BuildContext context, - [int page = 1]) async { - final res = await context.read().fetchGitlabWithPage( - '/projects/$id/merge_requests?state=opened&page=$page'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: (res.data as List).map((v) => GitlabIssue.fromJson(v)).toList(), - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Merge Requests'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final res = await context.read().fetchGitlabWithPage( + '/projects/$id/merge_requests?state=opened&page=$page'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: + (res.data as List).map((v) => GitlabIssue.fromJson(v)).toList(), + ); + }, itemBuilder: (p) => IssueItem( isPr: true, author: p.author.username, diff --git a/lib/screens/gl_project_activity.dart b/lib/screens/gl_project_activity.dart index e1be1f0..2ba815c 100644 --- a/lib/screens/gl_project_activity.dart +++ b/lib/screens/gl_project_activity.dart @@ -11,24 +11,21 @@ import 'package:provider/provider.dart'; class GlProjectActivityScreen extends StatelessWidget { final int id; - GlProjectActivityScreen(this.id); - Future> _query(BuildContext context, - [int page]) async { - final auth = context.read(); - final vs = await auth.fetchGitlab('/projects/$id/events'); - final events = (vs as List).map((v) => GitlabEvent.fromJson(v)).toList(); - return ListPayload(cursor: page, items: events, hasMore: false); - } - @override Widget build(BuildContext context) { final theme = Provider.of(context); return ListStatefulScaffold( title: AppBarTitle('Activity'), - onRefresh: () => _query(context), - onLoadMore: (int page) => _query(context, page), + onLoadMore: (page) async { + page = page ?? 1; + final auth = context.read(); + final vs = await auth.fetchGitlab('/projects/$id/events'); + final events = + (vs as List).map((v) => GitlabEvent.fromJson(v)).toList(); + return ListPayload(cursor: page, items: events, hasMore: false); + }, itemBuilder: (data) { return Link( url: '', diff --git a/lib/screens/gl_starrers.dart b/lib/screens/gl_starrers.dart index 9127eea..02f4740 100644 --- a/lib/screens/gl_starrers.dart +++ b/lib/screens/gl_starrers.dart @@ -11,26 +11,23 @@ class GlStarrersScreen extends StatelessWidget { final int id; GlStarrersScreen(this.id); - Future> _query(BuildContext context, - [int page = 1]) async { - final res = await context - .read() - .fetchGitlabWithPage('/projects/$id/starrers?page=$page'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: [ - for (var v in res.data) GitlabStarrer.fromJson(v), - ], - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Members'), - onRefresh: () => _query(context), - onLoadMore: (page) => _query(context, page), + onLoadMore: (page) async { + page = page ?? 1; + final res = await context + .read() + .fetchGitlabWithPage('/projects/$id/starrers?page=$page'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: [ + for (var v in res.data) GitlabStarrer.fromJson(v), + ], + ); + }, itemBuilder: (v) { return UserItem( avatarUrl: v.user.avatarUrl, diff --git a/lib/screens/gt_commits.dart b/lib/screens/gt_commits.dart index bd53b2b..da9ae3a 100644 --- a/lib/screens/gt_commits.dart +++ b/lib/screens/gt_commits.dart @@ -12,24 +12,21 @@ class GtCommitsScreen extends StatelessWidget { // final String branch; // TODO: GtCommitsScreen(this.owner, this.name); - Future> _query(BuildContext context, - [int page = 1]) async { - final res = await context - .read() - .fetchGiteaWithPage('/repos/$owner/$name/commits?page=$page&limit=20'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: (res.data as List).map((v) => GiteaCommit.fromJson(v)).toList(), - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Commits'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final res = await context.read().fetchGiteaWithPage( + '/repos/$owner/$name/commits?page=$page&limit=20'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: + (res.data as List).map((v) => GiteaCommit.fromJson(v)).toList(), + ); + }, itemBuilder: (c) { return CommitItem( author: c.author?.login ?? c.commit.author.name, diff --git a/lib/screens/gt_issues.dart b/lib/screens/gt_issues.dart index 6b41b07..56f6199 100644 --- a/lib/screens/gt_issues.dart +++ b/lib/screens/gt_issues.dart @@ -12,25 +12,22 @@ class GtIssuesScreen extends StatelessWidget { final bool isPr; GtIssuesScreen(this.owner, this.name, {this.isPr = false}); - Future> _query(BuildContext context, - [int page = 1]) async { - final type = isPr ? 'pulls' : 'issues'; - final res = await context.read().fetchGiteaWithPage( - '/repos/$owner/$name/issues?state=open&page=$page&limit=20&type=$type'); - return ListPayload( - cursor: res.cursor, - hasMore: res.hasMore, - items: (res.data as List).map((v) => GiteaIssue.fromJson(v)).toList(), - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle(isPr ? 'Pull Requests' : 'Issues'), // TODO: create issue - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + page = page ?? 1; + final type = isPr ? 'pulls' : 'issues'; + final res = await context.read().fetchGiteaWithPage( + '/repos/$owner/$name/issues?state=open&page=$page&limit=20&type=$type'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: (res.data as List).map((v) => GiteaIssue.fromJson(v)).toList(), + ); + }, itemBuilder: (p) => IssueItem( author: p.user.login, avatarUrl: p.user.avatarUrl, diff --git a/lib/screens/gt_orgs.dart b/lib/screens/gt_orgs.dart index f9d60ed..98ba94a 100644 --- a/lib/screens/gt_orgs.dart +++ b/lib/screens/gt_orgs.dart @@ -7,26 +7,23 @@ import 'package:git_touch/widgets/user_item.dart'; import 'package:provider/provider.dart'; class GtOrgsScreen extends StatelessWidget { - // final String branch; // TODO: - Future> _query(BuildContext context, - [int page = 1]) async { - final res = await context - .read() - .fetchGiteaWithPage('/orgs?limit=20&page=$page'); - // TODO: https://github.com/go-gitea/gitea/issues/10199 - return ListPayload( - cursor: page + 1, - hasMore: (res.data as List).length == 20, - items: (res.data as List).map((v) => GiteaOrg.fromJson(v)).toList(), - ); - } - @override Widget build(BuildContext context) { return ListStatefulScaffold( title: AppBarTitle('Organizations'), - onRefresh: () => _query(context), - onLoadMore: (cursor) => _query(context, cursor), + onLoadMore: (page) async { + // final String branch; // TODO: + page = page ?? 1; + final res = await context + .read() + .fetchGiteaWithPage('/orgs?limit=20&page=$page'); + // TODO: https://github.com/go-gitea/gitea/issues/10199 + return ListPayload( + cursor: page + 1, + hasMore: (res.data as List).length == 20, + items: (res.data as List).map((v) => GiteaOrg.fromJson(v)).toList(), + ); + }, itemBuilder: (v) { return UserItem( avatarUrl: v.avatarUrl,