mirror of
https://github.com/git-touch/git-touch
synced 2025-02-22 22:37:43 +01:00
feat(gitee): watch, star a repo (#157)
* feat(gitee): watch, star a repo * fix: pass in props as Tuple * feat: bitbucket branches * fix: use class instead of map
This commit is contained in:
parent
2017014ffd
commit
c75288ef97
@ -337,7 +337,15 @@ class AuthModel with ChangeNotifier {
|
||||
'${activeAccount.domain}/api/v5$p',
|
||||
headers: headers,
|
||||
);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
case 'PUT':
|
||||
{
|
||||
await http.put(
|
||||
'${activeAccount.domain}/api/v5$p',
|
||||
headers: headers,
|
||||
);
|
||||
return;
|
||||
}
|
||||
case 'POST':
|
||||
{
|
||||
@ -357,6 +365,12 @@ class AuthModel with ChangeNotifier {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'NO CONTENT':
|
||||
{
|
||||
res = await http.get('${activeAccount.domain}/api/v5$p',
|
||||
headers: headers);
|
||||
return res;
|
||||
}
|
||||
default:
|
||||
{
|
||||
res = await http.get('${activeAccount.domain}/api/v5$p',
|
||||
@ -364,11 +378,8 @@ class AuthModel with ChangeNotifier {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (requestType != 'DELETE') {
|
||||
final info = json.decode(utf8.decode(res.bodyBytes));
|
||||
return info;
|
||||
}
|
||||
return;
|
||||
final info = json.decode(utf8.decode(res.bodyBytes));
|
||||
return info;
|
||||
}
|
||||
|
||||
Future<DataWithPage> fetchGiteeWithPage(String path,
|
||||
|
@ -144,3 +144,12 @@ class BbComment {
|
||||
factory BbComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbCommentFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbBranch {
|
||||
String name;
|
||||
String type;
|
||||
BbBranch();
|
||||
factory BbBranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbBranchFromJson(json);
|
||||
}
|
||||
|
@ -247,3 +247,14 @@ Map<String, dynamic> _$BbCommentToJson(BbComment instance) => <String, dynamic>{
|
||||
'content': instance.content,
|
||||
'user': instance.user,
|
||||
};
|
||||
|
||||
BbBranch _$BbBranchFromJson(Map<String, dynamic> json) {
|
||||
return BbBranch()
|
||||
..name = json['name'] as String
|
||||
..type = json['type'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$BbBranchToJson(BbBranch instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'type': instance.type,
|
||||
};
|
||||
|
@ -426,11 +426,14 @@ class BitbucketRouter {
|
||||
'/:login',
|
||||
(context, parameters) => BbUserScreen(parameters['login'].first,
|
||||
isTeam: parameters['team'].first == '1'));
|
||||
static final repo = RouterScreen(
|
||||
'/:owner/:name',
|
||||
(context, parameters) =>
|
||||
BbRepoScreen(parameters['owner'].first, parameters['name'].first),
|
||||
);
|
||||
static final repo = RouterScreen('/:owner/:name', (context, parameters) {
|
||||
if (parameters['branch'] == null) {
|
||||
return BbRepoScreen(parameters['owner'].first, parameters['name'].first);
|
||||
} else {
|
||||
return BbRepoScreen(parameters['owner'].first, parameters['name'].first,
|
||||
branch: parameters['branch'].first);
|
||||
}
|
||||
});
|
||||
static final object = RouterScreen(
|
||||
'/:owner/:name/src/:ref',
|
||||
(context, parameters) => BbObjectScreen(
|
||||
|
@ -18,11 +18,12 @@ import '../generated/l10n.dart';
|
||||
class BbRepoScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
BbRepoScreen(this.owner, this.name);
|
||||
final String branch;
|
||||
BbRepoScreen(this.owner, this.name, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<BbRepo, String>>(
|
||||
return RefreshStatefulScaffold<Tuple3<BbRepo, String, List<BbBranch>>>(
|
||||
title: AppBarTitle(S.of(context).repository),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
@ -32,11 +33,17 @@ class BbRepoScreen extends StatelessWidget {
|
||||
'/repositories/$owner/$name/src/${repo.mainbranch.name}/README.md');
|
||||
final readme =
|
||||
res.statusCode >= 400 ? null : utf8.decode(res.bodyBytes);
|
||||
return Tuple2(repo, readme);
|
||||
final branches = await auth
|
||||
.fetchBbWithPage('/repositories/$owner/$name/refs/branches')
|
||||
.then((v) {
|
||||
return [for (var branch in v.data) BbBranch.fromJson(branch)];
|
||||
});
|
||||
return Tuple3(repo, readme, branches);
|
||||
},
|
||||
bodyBuilder: (t, setState) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final p = t.item1;
|
||||
final branches = t.item3;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
@ -56,7 +63,8 @@ class BbRepoScreen extends StatelessWidget {
|
||||
leftIconData: Octicons.code,
|
||||
text: Text('Code'),
|
||||
rightWidget: Text(filesize(p.size)),
|
||||
url: '/bitbucket/$owner/$name/src/${p.mainbranch.name}',
|
||||
url:
|
||||
'/bitbucket/$owner/$name/src/${branch == null ? p.mainbranch.name : branch}',
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.issue_opened,
|
||||
@ -71,8 +79,38 @@ class BbRepoScreen extends StatelessWidget {
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.history,
|
||||
text: Text('Commits'),
|
||||
url: '/bitbucket/$owner/$name/commits/${p.mainbranch.name}',
|
||||
url:
|
||||
'/bitbucket/$owner/$name/commits/${branch == null ? p.mainbranch.name : branch}',
|
||||
),
|
||||
if (branches != null)
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_branch,
|
||||
text: Text(S.of(context).branches),
|
||||
rightWidget: Text(
|
||||
(branch == null ? p.mainbranch.name : 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,
|
||||
'/bitbucket/$owner/$name?branch=$ref',
|
||||
replace: true);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
@ -8,6 +9,7 @@ import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/entry_item.dart';
|
||||
import 'package:git_touch/widgets/markdown_view.dart';
|
||||
import 'package:git_touch/widgets/mutation_button.dart';
|
||||
import 'package:git_touch/widgets/repo_header.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -15,6 +17,12 @@ import 'package:tuple/tuple.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../generated/l10n.dart';
|
||||
|
||||
class StatusPayload {
|
||||
bool isWatching;
|
||||
bool isStarred;
|
||||
StatusPayload(this.isWatching, this.isStarred);
|
||||
}
|
||||
|
||||
class GeRepoScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
@ -24,7 +32,7 @@ class GeRepoScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<
|
||||
Tuple3<GiteeRepo, MarkdownViewData, List<GiteeBranch>>>(
|
||||
Tuple4<GiteeRepo, MarkdownViewData, List<GiteeBranch>, StatusPayload>>(
|
||||
title: AppBarTitle(S.of(context).repository),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
@ -49,7 +57,15 @@ class GeRepoScreen extends StatelessWidget {
|
||||
await auth.fetchGitee('/repos/$owner/$name/branches').then((v) {
|
||||
return [for (var branch in v) GiteeBranch.fromJson(branch)];
|
||||
});
|
||||
return Tuple3(repo, readmeData, branches);
|
||||
bool isStarred = await auth
|
||||
.fetchGitee('/user/starred/$owner/$name', requestType: 'NO CONTENT')
|
||||
.then((v) => v.statusCode == HttpStatus.noContent);
|
||||
bool isWatching = await auth
|
||||
.fetchGitee('/user/subscriptions/$owner/$name',
|
||||
requestType: 'NO CONTENT')
|
||||
.then((v) => v.statusCode == HttpStatus.noContent);
|
||||
StatusPayload statusPayload = StatusPayload(isWatching, isStarred);
|
||||
return Tuple4(repo, readmeData, branches, statusPayload);
|
||||
},
|
||||
bodyBuilder: (t, setState) {
|
||||
final p = t.item1;
|
||||
@ -59,17 +75,48 @@ class GeRepoScreen extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
RepoHeader(
|
||||
avatarUrl: p.owner.avatarUrl,
|
||||
avatarLink: '/gitee/${p.namespace.path}',
|
||||
owner: p.namespace.path,
|
||||
name: p.path,
|
||||
description: p.description,
|
||||
homepageUrl: p.homepage,
|
||||
),
|
||||
CommonStyle.border,
|
||||
avatarUrl: p.owner.avatarUrl,
|
||||
avatarLink: '/gitee/${p.namespace.path}',
|
||||
owner: p.namespace.path,
|
||||
name: p.path,
|
||||
description: p.description,
|
||||
homepageUrl: p.homepage,
|
||||
actions: [
|
||||
Row(children: <Widget>[
|
||||
MutationButton(
|
||||
active: t.item4.isWatching,
|
||||
text: t.item4.isWatching ? 'Ignore' : 'Watch',
|
||||
onTap: () async {
|
||||
final String watchType =
|
||||
t.item4.isWatching ? 'ignoring' : 'watching';
|
||||
await context.read<AuthModel>().fetchGitee(
|
||||
'/user/subscriptions/$owner/$name?watch_type=$watchType',
|
||||
requestType: t.item4.isWatching ? 'DELETE' : 'PUT');
|
||||
setState(() {
|
||||
t.item4.isWatching = !t.item4.isWatching;
|
||||
});
|
||||
},
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
MutationButton(
|
||||
active: t.item4.isStarred,
|
||||
text: t.item4.isStarred ? 'Unstar' : 'Star',
|
||||
onTap: () async {
|
||||
await context.read<AuthModel>().fetchGitee(
|
||||
'/user/starred/$owner/$name',
|
||||
requestType: t.item4.isStarred ? 'DELETE' : 'PUT');
|
||||
|
||||
setState(() {
|
||||
t.item4.isStarred = !t.item4.isStarred;
|
||||
});
|
||||
},
|
||||
)
|
||||
])
|
||||
]),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
EntryItem(
|
||||
count: p.watchersCount,
|
||||
text: 'Watchers',
|
||||
url: '/gitee/$owner/$name/watchers',
|
||||
),
|
||||
|
Loading…
x
Reference in New Issue
Block a user