1
0
mirror of https://github.com/git-touch/git-touch synced 2025-02-20 13:30:38 +01:00

feat(bb): repo screen

This commit is contained in:
Rongjian Zhang 2020-02-02 18:58:05 +08:00
parent 3542c36dcc
commit 7f2649c691
6 changed files with 182 additions and 16 deletions

View File

@ -53,6 +53,10 @@ void main() async {
themeModel.router.define(GiteaRouter.prefix + screen.path,
handler: Handler(handlerFunc: screen.handler));
});
BitbucketRouter.routes.forEach((screen) {
themeModel.router.define(BitbucketRouter.prefix + screen.path,
handler: Handler(handlerFunc: screen.handler));
});
GithubRouter.routes.forEach((screen) {
themeModel.router.define(GithubRouter.prefix + screen.path,
handler: Handler(handlerFunc: screen.handler));

View File

@ -284,6 +284,19 @@ class AuthModel with ChangeNotifier {
);
}
Future<String> fetchBbReadme(String p) async {
if (p.startsWith('/') && !p.startsWith('/api')) p = '/api/2.0$p';
final input = Uri.parse(p);
final uri = Uri.parse(activeAccount.domain).replace(
userInfo: '${activeAccount.login}:${activeAccount.appPassword}',
path: input.path,
query: input.query,
);
final res = await http.get(uri);
if (res.statusCode >= 400) return null;
return res.body;
}
Future<void> init() async {
// Listen scheme
_sub = getUriLinksStream().listen(_onSchemeDetected, onError: (err) {

View File

@ -14,15 +14,22 @@ class BbPagination {
}
@JsonSerializable(fieldRename: FieldRename.snake)
class BbUser {
String username;
class BbRepoOwner {
String nickname;
String displayName;
String type; // user, team
bool isStaff;
DateTime createdOn;
Map<String, dynamic> links;
String get avatarUrl => links['avatar']['href'];
BbRepoOwner();
factory BbRepoOwner.fromJson(Map<String, dynamic> json) =>
_$BbRepoOwnerFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class BbUser extends BbRepoOwner {
String username;
bool isStaff;
DateTime createdOn;
BbUser();
factory BbUser.fromJson(Map<String, dynamic> json) => _$BbUserFromJson(json);
}
@ -30,7 +37,7 @@ class BbUser {
@JsonSerializable(fieldRename: FieldRename.snake)
class BbRepo {
String name;
BbUser owner;
BbRepoOwner owner;
String website;
String language;
int size;
@ -40,8 +47,19 @@ class BbRepo {
DateTime updatedOn;
String description;
String fullName;
String slug;
BbRepoMainbranch mainbranch;
Map<String, dynamic> links;
String get avatarUrl => links['avatar']['href'];
BbRepo();
factory BbRepo.fromJson(Map<String, dynamic> json) => _$BbRepoFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class BbRepoMainbranch {
String type;
String name;
BbRepoMainbranch();
factory BbRepoMainbranch.fromJson(Map<String, dynamic> json) =>
_$BbRepoMainbranchFromJson(json);
}

View File

@ -24,27 +24,43 @@ Map<String, dynamic> _$BbPaginationToJson(BbPagination instance) =>
'values': instance.values,
};
BbUser _$BbUserFromJson(Map<String, dynamic> json) {
return BbUser()
..username = json['username'] as String
BbRepoOwner _$BbRepoOwnerFromJson(Map<String, dynamic> json) {
return BbRepoOwner()
..nickname = json['nickname'] as String
..displayName = json['display_name'] as String
..type = json['type'] as String
..isStaff = json['is_staff'] as bool
..createdOn = json['created_on'] == null
? null
: DateTime.parse(json['created_on'] as String)
..links = json['links'] as Map<String, dynamic>;
}
Map<String, dynamic> _$BbUserToJson(BbUser instance) => <String, dynamic>{
'username': instance.username,
Map<String, dynamic> _$BbRepoOwnerToJson(BbRepoOwner instance) =>
<String, dynamic>{
'nickname': instance.nickname,
'display_name': instance.displayName,
'type': instance.type,
'links': instance.links,
};
BbUser _$BbUserFromJson(Map<String, dynamic> json) {
return BbUser()
..nickname = json['nickname'] as String
..displayName = json['display_name'] as String
..type = json['type'] as String
..links = json['links'] as Map<String, dynamic>
..username = json['username'] as String
..isStaff = json['is_staff'] as bool
..createdOn = json['created_on'] == null
? null
: DateTime.parse(json['created_on'] as String);
}
Map<String, dynamic> _$BbUserToJson(BbUser instance) => <String, dynamic>{
'nickname': instance.nickname,
'display_name': instance.displayName,
'type': instance.type,
'links': instance.links,
'username': instance.username,
'is_staff': instance.isStaff,
'created_on': instance.createdOn?.toIso8601String(),
'links': instance.links,
};
BbRepo _$BbRepoFromJson(Map<String, dynamic> json) {
@ -52,7 +68,7 @@ BbRepo _$BbRepoFromJson(Map<String, dynamic> json) {
..name = json['name'] as String
..owner = json['owner'] == null
? null
: BbUser.fromJson(json['owner'] as Map<String, dynamic>)
: BbRepoOwner.fromJson(json['owner'] as Map<String, dynamic>)
..website = json['website'] as String
..language = json['language'] as String
..size = json['size'] as int
@ -66,6 +82,10 @@ BbRepo _$BbRepoFromJson(Map<String, dynamic> json) {
: DateTime.parse(json['updated_on'] as String)
..description = json['description'] as String
..fullName = json['full_name'] as String
..slug = json['slug'] as String
..mainbranch = json['mainbranch'] == null
? null
: BbRepoMainbranch.fromJson(json['mainbranch'] as Map<String, dynamic>)
..links = json['links'] as Map<String, dynamic>;
}
@ -81,5 +101,19 @@ Map<String, dynamic> _$BbRepoToJson(BbRepo instance) => <String, dynamic>{
'updated_on': instance.updatedOn?.toIso8601String(),
'description': instance.description,
'full_name': instance.fullName,
'slug': instance.slug,
'mainbranch': instance.mainbranch,
'links': instance.links,
};
BbRepoMainbranch _$BbRepoMainbranchFromJson(Map<String, dynamic> json) {
return BbRepoMainbranch()
..type = json['type'] as String
..name = json['name'] as String;
}
Map<String, dynamic> _$BbRepoMainbranchToJson(BbRepoMainbranch instance) =>
<String, dynamic>{
'type': instance.type,
'name': instance.name,
};

View File

@ -1,4 +1,6 @@
import 'package:fluro/fluro.dart';
import 'package:git_touch/screens/bb_repo.dart';
import 'package:git_touch/screens/bb_user.dart';
import 'package:git_touch/screens/code_theme.dart';
import 'package:git_touch/screens/commits.dart';
import 'package:git_touch/screens/gitea_commits.dart';
@ -232,3 +234,22 @@ class GiteaRouter {
(_, p) =>
GiteaIssuesScreen(p['owner'].first, p['name'].first, isPr: true));
}
class BitbucketRouter {
static const prefix = '/bitbucket';
static final routes = [
BitbucketRouter.user,
BitbucketRouter.repo,
];
static final user = RouterScreen(
'/:login',
(context, params) => params['team'].first == '1'
? BbUserScreen(params['login'].first)
: BbUserScreen(params['login'].first),
);
static final repo = RouterScreen(
'/:owner/:name',
(context, params) =>
BbRepoScreen(params['owner'].first, params['name'].first),
);
}

76
lib/screens/bb_repo.dart Normal file
View File

@ -0,0 +1,76 @@
import 'package:filesize/filesize.dart';
import 'package:flutter/material.dart';
import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/bitbucket.dart';
import 'package:git_touch/models/theme.dart';
import 'package:git_touch/scaffolds/refresh_stateful.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/markdown_view.dart';
import 'package:git_touch/widgets/repo_header.dart';
import 'package:git_touch/widgets/table_view.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
class BbRepoScreen extends StatelessWidget {
final String owner;
final String name;
BbRepoScreen(this.owner, this.name);
@override
Widget build(BuildContext context) {
return RefreshStatefulScaffold<Tuple2<BbRepo, String>>(
title: AppBarTitle('Repository'),
fetchData: () async {
final auth = Provider.of<AuthModel>(context);
final res = await auth.fetchBb('/repositories/$owner/$name');
final repo = BbRepo.fromJson(res);
final readme = await auth.fetchBbReadme(
'/repositories/$owner/$name/src/${repo.mainbranch.name}/README.md');
return Tuple2(repo, readme);
},
bodyBuilder: (t, setState) {
final theme = Provider.of<ThemeModel>(context);
final p = t.item1;
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RepoHeader(
avatarUrl: p.avatarUrl,
avatarLink: null,
owner: p.owner.displayName, // TODO:
name: p.slug,
description: p.description,
homepageUrl: p.website,
),
CommonStyle.border,
TableView(
hasIcon: true,
items: [
TableViewItem(
leftIconData: Octicons.code,
text: Text('Code'),
rightWidget: Text(filesize(p.size)),
url: '/bitbucket/$owner/$name/src/${p.mainbranch.name}',
),
TableViewItem(
leftIconData: Octicons.history,
text: Text('Commits'),
url: '/bitbucket/$owner/$name/commits',
),
],
),
CommonStyle.verticalGap,
if (t.item2 != null)
Container(
padding: CommonStyle.padding,
color: theme.palette.background,
child: MarkdownView(t.item2),
),
CommonStyle.verticalGap,
],
);
},
);
}
}