From 7a97bc22abdef9afaf6d27bfb6fabf5408d0afec Mon Sep 17 00:00:00 2001 From: Shreyas Thirumalai <shreyasthirumalai@gmail.com> Date: Sun, 17 May 2020 09:50:11 +0530 Subject: [PATCH] feat: bitbucket issues, prs screens (#91) --- lib/models/bitbucket.dart | 28 ++++++++++++++++++++ lib/models/bitbucket.g.dart | 48 ++++++++++++++++++++++++++++++++++ lib/router.dart | 12 +++++++++ lib/screens/bb_issues.dart | 51 +++++++++++++++++++++++++++++++++++++ lib/screens/bb_pulls.dart | 51 +++++++++++++++++++++++++++++++++++++ lib/screens/bb_repo.dart | 10 ++++++++ 6 files changed, 200 insertions(+) create mode 100644 lib/screens/bb_issues.dart create mode 100644 lib/screens/bb_pulls.dart diff --git a/lib/models/bitbucket.dart b/lib/models/bitbucket.dart index 1f6072b..9f1cdd4 100644 --- a/lib/models/bitbucket.dart +++ b/lib/models/bitbucket.dart @@ -95,3 +95,31 @@ class BbCommitAuthor { factory BbCommitAuthor.fromJson(Map<String, dynamic> json) => _$BbCommitAuthorFromJson(json); } + +@JsonSerializable(fieldRename: FieldRename.snake) +class BbIssues { + String priority; + String state; + BbRepo repository; + String title; + BbRepoOwner reporter; + DateTime createdOn; + Map<String, dynamic> links; + String get issueLink => links['self']['href']; + BbIssues(); + factory BbIssues.fromJson(Map<String, dynamic> json) => + _$BbIssuesFromJson(json); +} + +@JsonSerializable(fieldRename: FieldRename.snake) +class BbPulls { + String description; + BbRepoOwner author; + String title; + Map<String, dynamic> links; + String get pullRequestLink => links['self']['href']; + DateTime createdOn; + BbPulls(); + factory BbPulls.fromJson(Map<String, dynamic> json) => + _$BbPullsFromJson(json); +} diff --git a/lib/models/bitbucket.g.dart b/lib/models/bitbucket.g.dart index 286c24b..1f34ae3 100644 --- a/lib/models/bitbucket.g.dart +++ b/lib/models/bitbucket.g.dart @@ -166,3 +166,51 @@ Map<String, dynamic> _$BbCommitAuthorToJson(BbCommitAuthor instance) => 'raw': instance.raw, 'user': instance.user, }; + +BbIssues _$BbIssuesFromJson(Map<String, dynamic> json) { + return BbIssues() + ..priority = json['priority'] as String + ..state = json['state'] as String + ..repository = json['repository'] == null + ? null + : BbRepo.fromJson(json['repository'] as Map<String, dynamic>) + ..title = json['title'] as String + ..reporter = json['reporter'] == null + ? null + : BbRepoOwner.fromJson(json['reporter'] as Map<String, dynamic>) + ..createdOn = json['created_on'] == null + ? null + : DateTime.parse(json['created_on'] as String) + ..links = json['links'] as Map<String, dynamic>; +} + +Map<String, dynamic> _$BbIssuesToJson(BbIssues instance) => <String, dynamic>{ + 'priority': instance.priority, + 'state': instance.state, + 'repository': instance.repository, + 'title': instance.title, + 'reporter': instance.reporter, + 'created_on': instance.createdOn?.toIso8601String(), + 'links': instance.links, + }; + +BbPulls _$BbPullsFromJson(Map<String, dynamic> json) { + return BbPulls() + ..description = json['description'] as String + ..author = json['author'] == null + ? null + : BbRepoOwner.fromJson(json['author'] as Map<String, dynamic>) + ..title = json['title'] as String + ..links = json['links'] as Map<String, dynamic> + ..createdOn = json['created_on'] == null + ? null + : DateTime.parse(json['created_on'] as String); +} + +Map<String, dynamic> _$BbPullsToJson(BbPulls instance) => <String, dynamic>{ + 'description': instance.description, + 'author': instance.author, + 'title': instance.title, + 'links': instance.links, + 'created_on': instance.createdOn?.toIso8601String(), + }; diff --git a/lib/router.dart b/lib/router.dart index 65431ec..091cca9 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -2,6 +2,8 @@ import 'package:fluro/fluro.dart'; import 'package:git_touch/screens/bb_commits.dart'; import 'package:git_touch/screens/bb_object.dart'; import 'package:git_touch/screens/bb_repo.dart'; +import 'package:git_touch/screens/bb_issues.dart'; +import 'package:git_touch/screens/bb_pulls.dart'; import 'package:git_touch/screens/bb_user.dart'; import 'package:git_touch/screens/code_theme.dart'; import 'package:git_touch/screens/gh_commits.dart'; @@ -298,6 +300,8 @@ class BitbucketRouter { BitbucketRouter.repo, BitbucketRouter.object, BitbucketRouter.commits, + BitbucketRouter.issues, + BitbucketRouter.pulls, ]; static final user = RouterScreen( '/:login', @@ -317,8 +321,16 @@ class BitbucketRouter { path: params['path']?.first, ), ); + static final issues = RouterScreen( + '/:owner/:name/issues/:ref', + (_, p) => + BbIssuesScreen(p['owner'].first, p['name'].first, p['ref'].first)); static final commits = RouterScreen( '/:owner/:name/commits/:ref', (_, p) => BbCommitsScreen(p['owner'].first, p['name'].first, p['ref'].first)); + static final pulls = RouterScreen( + '/:owner/:name/pulls/:ref', + (_, p) => + BbPullsScreen(p['owner'].first, p['name'].first, p['ref'].first)); } diff --git a/lib/screens/bb_issues.dart b/lib/screens/bb_issues.dart new file mode 100644 index 0000000..286f3d4 --- /dev/null +++ b/lib/screens/bb_issues.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:git_touch/models/auth.dart'; +import 'package:git_touch/models/bitbucket.dart'; +import 'package:git_touch/scaffolds/list_stateful.dart'; +import 'package:git_touch/widgets/app_bar_title.dart'; +import 'package:git_touch/widgets/issue_item.dart'; +import 'package:provider/provider.dart'; + +class BbIssuesScreen extends StatelessWidget { + final String owner; + final String name; + final String ref; + BbIssuesScreen(this.owner, this.name, this.ref); + + Future<ListPayload<BbIssues, String>> _query(BuildContext context, + [String nextUrl]) async { + final auth = Provider.of<AuthModel>(context); + final res = await auth + .fetchBbWithPage(nextUrl ?? '/repositories/$owner/$name/issues'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: <BbIssues>[ + for (var v in res.data) BbIssues.fromJson(v), + ], + ); + } + + @override + Widget build(BuildContext context) { + final auth = Provider.of<AuthModel>(context); + return ListStatefulScaffold<BbIssues, String>( + title: AppBarTitle('Issues'), + onRefresh: () => _query(context), + onLoadMore: (page) => _query(context, page), + itemBuilder: (v) { + int issueNumber = + int.parse(v.issueLink.replaceFirst(RegExp(r'.*\/'), '')); + return IssueItem( + avatarUrl: v.reporter.avatarUrl, + author: v.reporter.displayName, + title: v.title, + number: issueNumber, + commentCount: 0, + updatedAt: v.createdOn, + url: '${auth.activeAccount.domain}/$owner/$name/issues/$issueNumber', + ); + }, + ); + } +} diff --git a/lib/screens/bb_pulls.dart b/lib/screens/bb_pulls.dart new file mode 100644 index 0000000..c2246dd --- /dev/null +++ b/lib/screens/bb_pulls.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:git_touch/models/auth.dart'; +import 'package:git_touch/models/bitbucket.dart'; +import 'package:git_touch/scaffolds/list_stateful.dart'; +import 'package:git_touch/widgets/app_bar_title.dart'; +import 'package:git_touch/widgets/issue_item.dart'; +import 'package:provider/provider.dart'; + +class BbPullsScreen extends StatelessWidget { + final String owner; + final String name; + final String ref; + BbPullsScreen(this.owner, this.name, this.ref); + + Future<ListPayload<BbPulls, String>> _query(BuildContext context, + [String nextUrl]) async { + final auth = Provider.of<AuthModel>(context); + final res = await auth + .fetchBbWithPage(nextUrl ?? '/repositories/$owner/$name/pullrequests'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: <BbPulls>[ + for (var v in res.data) BbPulls.fromJson(v), + ], + ); + } + + @override + Widget build(BuildContext context) { + final auth = Provider.of<AuthModel>(context); + return ListStatefulScaffold<BbPulls, String>( + title: AppBarTitle('Pull requests'), + onRefresh: () => _query(context), + onLoadMore: (page) => _query(context, page), + itemBuilder: (v) { + int pullNumber = + int.parse(v.pullRequestLink.replaceFirst(RegExp(r'.*\/'), '')); + return IssueItem( + avatarUrl: v.author.avatarUrl, + author: v.author.displayName, + title: v.title, + number: pullNumber, + commentCount: 0, + updatedAt: v.createdOn, + url: '${auth.activeAccount.domain}/$owner/$name/issues/$pullNumber', + ); + }, + ); + } +} diff --git a/lib/screens/bb_repo.dart b/lib/screens/bb_repo.dart index 813d439..51003d3 100644 --- a/lib/screens/bb_repo.dart +++ b/lib/screens/bb_repo.dart @@ -57,6 +57,16 @@ class BbRepoScreen extends StatelessWidget { rightWidget: Text(filesize(p.size)), url: '/bitbucket/$owner/$name/src/${p.mainbranch.name}', ), + TableViewItem( + leftIconData: Octicons.issue_opened, + text: Text('Issues'), + url: '/bitbucket/$owner/$name/issues/${p.mainbranch.name}', + ), + TableViewItem( + leftIconData: Octicons.git_pull_request, + text: Text('Pull requests'), + url: '/bitbucket/$owner/$name/pulls/${p.mainbranch.name}', + ), TableViewItem( leftIconData: Octicons.history, text: Text('Commits'),