mirror of
https://github.com/git-touch/git-touch
synced 2025-02-02 17:07:06 +01:00
feat(gitlab): branches, issueAdd, router path fix (#165)
This commit is contained in:
parent
c75288ef97
commit
d826107621
@ -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);
|
||||
}
|
||||
|
@ -364,3 +364,15 @@ Map<String, dynamic> _$GitlabStarrerToJson(GitlabStarrer instance) =>
|
||||
'starred_since': instance.starredSince?.toIso8601String(),
|
||||
'user': instance.user,
|
||||
};
|
||||
|
||||
GitlabBranch _$GitlabBranchFromJson(Map<String, dynamic> json) {
|
||||
return GitlabBranch()
|
||||
..name = json['name'] as String
|
||||
..merged = json['merged'] as bool;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabBranchToJson(GitlabBranch instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'merged': instance.merged,
|
||||
};
|
||||
|
@ -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';
|
||||
@ -246,6 +247,7 @@ class GitlabRouter {
|
||||
GitlabRouter.commit,
|
||||
GitlabRouter.projectMembers,
|
||||
GitlabRouter.groupMembers,
|
||||
GitlabRouter.issueAdd,
|
||||
GitlabRouter.issue,
|
||||
];
|
||||
static final user = RouterScreen('/user/:id',
|
||||
@ -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) =>
|
||||
@ -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) =>
|
||||
@ -301,7 +314,7 @@ 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),
|
||||
@ -309,6 +322,10 @@ class GitlabRouter {
|
||||
);
|
||||
},
|
||||
);
|
||||
static final issueAdd =
|
||||
RouterScreen('/projects/:id/issues/new', (context, parameters) {
|
||||
return GlIssueFormScreen(int.parse(parameters['id'].first));
|
||||
});
|
||||
}
|
||||
|
||||
class GiteaRouter {
|
||||
|
@ -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) {
|
||||
@ -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,
|
||||
|
76
lib/screens/gl_issue_form.dart
Normal file
76
lib/screens/gl_issue_form.dart
Normal file
@ -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,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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';
|
||||
@ -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>();
|
||||
@ -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,
|
||||
@ -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}',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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>();
|
||||
@ -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(
|
||||
@ -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);
|
||||
@ -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(
|
||||
@ -186,7 +196,37 @@ 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);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
Loading…
x
Reference in New Issue
Block a user