Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gitlab): branches, issueAdd, router path fix #165

Merged
merged 2 commits into from Jan 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/models/gitlab.dart
Expand Up @@ -210,3 +210,12 @@ class GitlabStarrer {
factory GitlabStarrer.fromJson(Map<String, dynamic> json) =>
_$GitlabStarrerFromJson(json);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class GitlabBranch {
String name;
bool merged;
GitlabBranch();
factory GitlabBranch.fromJson(Map<String, dynamic> json) =>
_$GitlabBranchFromJson(json);
}
12 changes: 12 additions & 0 deletions lib/models/gitlab.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 26 additions & 9 deletions lib/router.dart
Expand Up @@ -33,6 +33,7 @@ import 'package:git_touch/screens/gh_files.dart';
import 'package:git_touch/screens/gh_gists_files.dart';
import 'package:git_touch/screens/gh_org_repos.dart';
import 'package:git_touch/screens/gl_commit.dart';
import 'package:git_touch/screens/gl_issue_form.dart';
import 'package:git_touch/screens/gl_starrers.dart';
import 'package:git_touch/screens/gt_commits.dart';
import 'package:git_touch/screens/gt_issue.dart';
Expand Down Expand Up @@ -246,6 +247,7 @@ class GitlabRouter {
GitlabRouter.commit,
GitlabRouter.projectMembers,
GitlabRouter.groupMembers,
GitlabRouter.issueAdd,
GitlabRouter.issue,
];
static final user = RouterScreen('/user/:id',
Expand All @@ -264,10 +266,14 @@ class GitlabRouter {
(context, parameters) => GlTreeScreen(
int.parse(parameters['id'].first), parameters['ref'].first,
path: parameters['path']?.first));
static final project = RouterScreen(
'/projects/:id',
(context, parameters) =>
GlProjectScreen(int.parse(parameters['id'].first)));
static final project = RouterScreen('/projects/:id', (context, parameters) {
if (parameters['branch'] == null) {
return GlProjectScreen(int.parse(parameters['id'].first));
} else {
return GlProjectScreen(int.parse(parameters['id'].first),
branch: parameters['branch'].first);
}
});
static final starrers = RouterScreen(
'/projects/:id/starrers',
(context, parameters) =>
Expand All @@ -284,10 +290,17 @@ class GitlabRouter {
parameters['id'].first,
prefix: parameters['prefix'].first,
));
static final commits = RouterScreen(
'/projects/:id/commits',
(context, parameters) => GlCommitsScreen(parameters['id'].first,
prefix: parameters['prefix'].first));
static final commits =
RouterScreen('/projects/:id/commits', (context, parameters) {
if (parameters['branch'] == null) {
return GlCommitsScreen(parameters['id'].first,
prefix: parameters['prefix'].first);
} else {
return GlCommitsScreen(parameters['id'].first,
prefix: parameters['prefix'].first,
branch: parameters['branch'].first);
}
});
static final commit = RouterScreen(
'/projects/:id/commit/:sha',
(context, parameters) =>
Expand All @@ -301,14 +314,18 @@ class GitlabRouter {
(context, parameters) =>
GlMembersScreen(int.parse(parameters['id'].first), 'groups'));
static final issue = RouterScreen(
'/gitlab/projects/:id/issues/:iid',
'/projects/:id/issues/:iid',
(context, parameters) {
return GlIssueScreen(
int.parse(parameters['id'].first),
int.parse(parameters['iid'].first),
);
},
);
static final issueAdd =
RouterScreen('/projects/:id/issues/new', (context, parameters) {
return GlIssueFormScreen(int.parse(parameters['id'].first));
});
}

class GiteaRouter {
Expand Down
8 changes: 4 additions & 4 deletions lib/screens/gl_commits.dart
Expand Up @@ -10,8 +10,8 @@ import '../generated/l10n.dart';
class GlCommitsScreen extends StatelessWidget {
final String id;
final String prefix;
// final String branch; // TODO:
GlCommitsScreen(this.id, {this.prefix});
final String branch;
GlCommitsScreen(this.id, {this.prefix, this.branch});

@override
Widget build(BuildContext context) {
Expand All @@ -20,8 +20,8 @@ class GlCommitsScreen extends StatelessWidget {
fetch: (page) async {
page = page ?? 1;
final auth = context.read<AuthModel>();
final res = await auth
.fetchGitlabWithPage('/projects/$id/repository/commits?page=$page');
final res = await auth.fetchGitlabWithPage(
'/projects/$id/repository/commits?ref_name=$branch&page=$page');
return ListPayload(
cursor: res.cursor,
hasMore: res.hasMore,
Expand Down
76 changes: 76 additions & 0 deletions lib/screens/gl_issue_form.dart
@@ -0,0 +1,76 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/gitlab.dart';
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';

class GlIssueFormScreen extends StatefulWidget {
final int id;
GlIssueFormScreen(this.id);

@override
_GlIssueFormScreenState createState() => _GlIssueFormScreenState();
}

class _GlIssueFormScreenState extends State<GlIssueFormScreen> {
var _title = '';
var _body = '';

@override
Widget build(BuildContext context) {
final theme = Provider.of<ThemeModel>(context);
final auth = Provider.of<AuthModel>(context);
return CommonScaffold(
title: Text('Submit an issue'),
body: Column(
children: <Widget>[
Padding(
padding: CommonStyle.padding,
child: CupertinoTextField(
style: TextStyle(color: theme.palette.text),
placeholder: 'Title',
onChanged: (v) {
setState(() {
_title = v;
});
},
),
),
Padding(
padding: CommonStyle.padding,
child: CupertinoTextField(
style: TextStyle(color: theme.palette.text),
placeholder: 'Body',
onChanged: (v) {
setState(() {
_body = v;
});
},
maxLines: 10,
),
),
CupertinoButton.filled(
child: Text('Submit'),
onPressed: () async {
final res = await auth.fetchGitlab(
'/projects/${widget.id}/issues',
isPost: true,
body: {'description': _body, 'title': _title},
).then((v) {
return GitlabIssue.fromJson(v);
});
await theme.push(
context,
'/gitlab/projects/${widget.id}/issues/${res.iid}',
replace: true,
);
},
),
],
),
);
}
}
10 changes: 7 additions & 3 deletions lib/screens/gl_issues.dart
Expand Up @@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/gitlab.dart';
import 'package:git_touch/scaffolds/list_stateful.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/action_entry.dart';
import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/issue_item.dart';
import 'package:git_touch/widgets/label.dart';
Expand All @@ -17,7 +19,6 @@ class GlIssuesScreen extends StatelessWidget {
Widget build(BuildContext context) {
return ListStatefulScaffold<GitlabIssue, int>(
title: AppBarTitle(S.of(context).issues),
// TODO: create issue
fetch: (page) async {
page = page ?? 1;
final auth = context.read<AuthModel>();
Expand All @@ -30,6 +31,10 @@ class GlIssuesScreen extends StatelessWidget {
(res.data as List).map((v) => GitlabIssue.fromJson(v)).toList(),
);
},
actionBuilder: () => ActionEntry(
iconData: Octicons.plus,
url: '/gitlab/projects/$id/issues/new',
),
itemBuilder: (p) => IssueItem(
author: p.author.username,
avatarUrl: p.author.avatarUrl,
Expand All @@ -43,8 +48,7 @@ class GlIssuesScreen extends StatelessWidget {
for (var label in p.labels)
MyLabel(name: label, cssColor: '#428BCA')
]),
// url: '/gitlab/projects/${p.projectId}/issues/${p.iid}',
url: '$prefix/issues/${p.iid}', // TODO:
url: '/gitlab/projects/${p.projectId}/issues/${p.iid}',
),
);
}
Expand Down
52 changes: 46 additions & 6 deletions lib/screens/gl_project.dart
Expand Up @@ -19,13 +19,14 @@ import '../generated/l10n.dart';

class GlProjectScreen extends StatelessWidget {
final int id;
GlProjectScreen(this.id);
final String branch;
GlProjectScreen(this.id, {this.branch});

@override
Widget build(BuildContext context) {
return RefreshStatefulScaffold<
Tuple4<GitlabProject, Future<Map<String, double>>, Future<int>,
MarkdownViewData>>(
Tuple5<GitlabProject, Future<Map<String, double>>, Future<int>,
MarkdownViewData, List<GitlabBranch>>>(
title: AppBarTitle(S.of(context).project),
fetch: () async {
final auth = context.read<AuthModel>();
Expand Down Expand Up @@ -64,7 +65,14 @@ class GlProjectScreen extends StatelessWidget {
}),
);
}
return Tuple4(p, langFuture, memberCountFuture, readmeData);

final branches = await auth
.fetchGitlab('/projects/$id/repository/branches')
.then((v) {
return [for (var branch in v) GitlabBranch.fromJson(branch)];
});

return Tuple5(p, langFuture, memberCountFuture, readmeData, branches);
},
actionBuilder: (t, setState) {
return ActionButton(
Expand All @@ -79,6 +87,7 @@ class GlProjectScreen extends StatelessWidget {
final langFuture = t.item2;
final memberCountFuture = t.item3;
final readmeData = t.item4;
final branches = t.item5;

final theme = Provider.of<ThemeModel>(context);
final auth = Provider.of<AuthModel>(context);
Expand Down Expand Up @@ -165,7 +174,8 @@ class GlProjectScreen extends StatelessWidget {
rightWidget: p.statistics == null
? null
: Text(filesize(p.statistics.repositorySize)),
url: '/gitlab/projects/$id/tree/${p.defaultBranch}',
url:
'/gitlab/projects/$id/tree/${branch == null ? p.defaultBranch : branch}',
),
if (p.issuesEnabled)
TableViewItem(
Expand All @@ -186,8 +196,38 @@ class GlProjectScreen extends StatelessWidget {
rightWidget: p.statistics == null
? null
: Text(p.statistics.commitCount.toString()),
url: '/gitlab/projects/$id/commits?prefix=$prefix',
url:
'/gitlab/projects/$id/commits?prefix=$prefix&branch=${branch == null ? p.defaultBranch : branch}', // EDIT
),
if (branches != null)
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(S.of(context).branches),
rightWidget: Text(
(branch == null ? p.defaultBranch : branch) +
' • ' +
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, '/gitlab/projects/$id?branch=$ref',
replace: true);
}
},
),
);
},
),
],
),
CommonStyle.verticalGap,
Expand Down