mirror of
https://github.com/git-touch/git-touch
synced 2025-01-31 08:04:51 +01:00
feat(bb): user screen
This commit is contained in:
parent
9eec13df9a
commit
830bceaa36
@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/notification.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/screens/bb_user.dart';
|
||||
import 'package:git_touch/screens/gitea_orgs.dart';
|
||||
import 'package:git_touch/screens/gitea_user.dart';
|
||||
import 'package:git_touch/screens/gitlab_explore.dart';
|
||||
@ -60,6 +61,14 @@ class _HomeState extends State<Home> {
|
||||
return GitlabUserScreen(null);
|
||||
}
|
||||
break;
|
||||
case PlatformType.bitbucket:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return BbUserScreen(null);
|
||||
case 1:
|
||||
return BbUserScreen(null);
|
||||
}
|
||||
break;
|
||||
case PlatformType.gitea:
|
||||
switch (index) {
|
||||
case 0:
|
||||
@ -134,6 +143,17 @@ class _HomeState extends State<Home> {
|
||||
title: Text('Me'),
|
||||
),
|
||||
];
|
||||
case PlatformType.bitbucket:
|
||||
return [
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.explore),
|
||||
title: Text('Explore'),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.person),
|
||||
title: Text('Me'),
|
||||
),
|
||||
];
|
||||
case PlatformType.gitea:
|
||||
return [
|
||||
BottomNavigationBarItem(
|
||||
|
@ -32,7 +32,12 @@ class DataWithPage<T> {
|
||||
int cursor;
|
||||
bool hasMore;
|
||||
int total;
|
||||
DataWithPage({this.data, this.cursor, this.hasMore, this.total});
|
||||
DataWithPage({
|
||||
@required this.data,
|
||||
@required this.cursor,
|
||||
@required this.hasMore,
|
||||
this.total,
|
||||
});
|
||||
}
|
||||
|
||||
class AuthModel with ChangeNotifier {
|
||||
@ -242,6 +247,30 @@ class AuthModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future fetchBb(String p) async {
|
||||
if (!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);
|
||||
final info = json.decode(utf8.decode(res.bodyBytes));
|
||||
return info;
|
||||
}
|
||||
|
||||
Future<DataWithPage<List>> fetchBbWithPage(String p) async {
|
||||
final res = await fetchBb(p);
|
||||
final v = BbPagination.fromJson(res);
|
||||
return DataWithPage(
|
||||
cursor: v.page,
|
||||
total: v.size,
|
||||
data: v.values,
|
||||
hasMore: v.next != null,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
// Listen scheme
|
||||
_sub = getUriLinksStream().listen(_onSchemeDetected, onError: (err) {
|
||||
|
@ -1,10 +1,24 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
part 'bitbucket.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbPagination {
|
||||
int pagelen;
|
||||
int size;
|
||||
int page;
|
||||
String next;
|
||||
List values;
|
||||
BbPagination();
|
||||
factory BbPagination.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbPaginationFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbUser {
|
||||
String username;
|
||||
String nickname;
|
||||
String displayName;
|
||||
String type; // user, team
|
||||
bool isStaff;
|
||||
DateTime createdOn;
|
||||
Map<String, dynamic> links;
|
||||
@ -12,3 +26,22 @@ class BbUser {
|
||||
BbUser();
|
||||
factory BbUser.fromJson(Map<String, dynamic> json) => _$BbUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbRepo {
|
||||
String name;
|
||||
BbUser owner;
|
||||
String website;
|
||||
String language;
|
||||
int size;
|
||||
String type; // repository
|
||||
bool isPrivate;
|
||||
DateTime createdOn;
|
||||
DateTime updatedOn;
|
||||
String description;
|
||||
String fullName;
|
||||
Map<String, dynamic> links;
|
||||
String get avatarUrl => links['avatar']['href'];
|
||||
BbRepo();
|
||||
factory BbRepo.fromJson(Map<String, dynamic> json) => _$BbRepoFromJson(json);
|
||||
}
|
||||
|
@ -6,10 +6,30 @@ part of 'bitbucket.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
BbPagination _$BbPaginationFromJson(Map<String, dynamic> json) {
|
||||
return BbPagination()
|
||||
..pagelen = json['pagelen'] as int
|
||||
..size = json['size'] as int
|
||||
..page = json['page'] as int
|
||||
..next = json['next'] as String
|
||||
..values = json['values'] as List;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$BbPaginationToJson(BbPagination instance) =>
|
||||
<String, dynamic>{
|
||||
'pagelen': instance.pagelen,
|
||||
'size': instance.size,
|
||||
'page': instance.page,
|
||||
'next': instance.next,
|
||||
'values': instance.values,
|
||||
};
|
||||
|
||||
BbUser _$BbUserFromJson(Map<String, dynamic> json) {
|
||||
return BbUser()
|
||||
..username = json['username'] as String
|
||||
..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
|
||||
@ -19,8 +39,47 @@ BbUser _$BbUserFromJson(Map<String, dynamic> json) {
|
||||
|
||||
Map<String, dynamic> _$BbUserToJson(BbUser instance) => <String, dynamic>{
|
||||
'username': instance.username,
|
||||
'nickname': instance.nickname,
|
||||
'display_name': instance.displayName,
|
||||
'type': instance.type,
|
||||
'is_staff': instance.isStaff,
|
||||
'created_on': instance.createdOn?.toIso8601String(),
|
||||
'links': instance.links,
|
||||
};
|
||||
|
||||
BbRepo _$BbRepoFromJson(Map<String, dynamic> json) {
|
||||
return BbRepo()
|
||||
..name = json['name'] as String
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: BbUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..website = json['website'] as String
|
||||
..language = json['language'] as String
|
||||
..size = json['size'] as int
|
||||
..type = json['type'] as String
|
||||
..isPrivate = json['is_private'] as bool
|
||||
..createdOn = json['created_on'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_on'] as String)
|
||||
..updatedOn = json['updated_on'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_on'] as String)
|
||||
..description = json['description'] as String
|
||||
..fullName = json['full_name'] as String
|
||||
..links = json['links'] as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$BbRepoToJson(BbRepo instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'owner': instance.owner,
|
||||
'website': instance.website,
|
||||
'language': instance.language,
|
||||
'size': instance.size,
|
||||
'type': instance.type,
|
||||
'is_private': instance.isPrivate,
|
||||
'created_on': instance.createdOn?.toIso8601String(),
|
||||
'updated_on': instance.updatedOn?.toIso8601String(),
|
||||
'description': instance.description,
|
||||
'full_name': instance.fullName,
|
||||
'links': instance.links,
|
||||
};
|
||||
|
78
lib/screens/bb_user.dart
Normal file
78
lib/screens/bb_user.dart
Normal file
@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:git_touch/widgets/user_header.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:timeago/timeago.dart' as timeago;
|
||||
|
||||
class BbUserScreen extends StatelessWidget {
|
||||
final String login;
|
||||
BbUserScreen(this.login);
|
||||
bool get isViewer => login == null;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<BbUser, Iterable<BbRepo>>>(
|
||||
title: Text(isViewer ? 'Me' : 'User'),
|
||||
fetchData: () async {
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
final _login = login ?? auth.activeAccount.login;
|
||||
final res = await Future.wait([
|
||||
auth.fetchBb('/users/$_login'),
|
||||
auth.fetchBbWithPage('/repositories/$_login'),
|
||||
]);
|
||||
return Tuple2(
|
||||
BbUser.fromJson(res[0]),
|
||||
[
|
||||
for (var v in (res[1] as DataWithPage<List>).data)
|
||||
BbRepo.fromJson(v)
|
||||
],
|
||||
);
|
||||
},
|
||||
action: isViewer
|
||||
? ActionEntry(
|
||||
iconData: Icons.settings,
|
||||
url: '/settings',
|
||||
)
|
||||
: null,
|
||||
bodyBuilder: (data, _) {
|
||||
final user = data.item1;
|
||||
final repos = data.item2;
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
UserHeader(
|
||||
login: user.displayName,
|
||||
avatarUrl: user.avatarUrl,
|
||||
name: user.nickname,
|
||||
createdAt: user.createdOn,
|
||||
bio: null,
|
||||
),
|
||||
CommonStyle.border,
|
||||
Column(
|
||||
children: <Widget>[
|
||||
for (var v in repos)
|
||||
RepositoryItem(
|
||||
owner: v.owner.displayName,
|
||||
name: v.name,
|
||||
url: '/bitbucket/${v.fullName}',
|
||||
avatarUrl: v.avatarUrl,
|
||||
avatarLink: '/bitbucket/${v.owner.displayName}',
|
||||
note: 'Updated ${timeago.format(v.updatedOn)}',
|
||||
description: v.description,
|
||||
forkCount: 0,
|
||||
starCount: 0,
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user