feat(gitea): user screen

This commit is contained in:
Rongjian Zhang 2020-01-29 18:00:48 +08:00
parent 76c6948b05
commit 7039a8905f
7 changed files with 49 additions and 29 deletions

View File

@ -45,7 +45,7 @@ class _HomeState extends State<Home> {
case 3:
return SearchScreen();
case 4:
return UserScreen('');
return UserScreen(null);
}
break;
case PlatformType.gitlab:

View File

@ -193,8 +193,8 @@ class AuthModel with ChangeNotifier {
}
Future fetchGitea(String p) async {
final res = await http.get('https://try.gitea.io' + '/api/v1' + p,
headers: {'Authorization': ''});
final res = await http.get('${activeAccount.domain}/api/v1$p',
headers: {'Authorization': 'token $token'});
final info = json.decode(utf8.decode(res.bodyBytes));
return info;
}

View File

@ -8,14 +8,13 @@ class GiteaUser {
String login;
String fullName;
String avatarUrl;
DateTime created;
GiteaUser();
factory GiteaUser.fromJson(Map<String, dynamic> json) =>
_$GiteaUserFromJson(json);
}
@JsonSerializable()
@JsonSerializable(fieldRename: FieldRename.snake)
class GiteaRepository {
int id;
GiteaUser owner;
@ -23,9 +22,8 @@ class GiteaRepository {
String description;
int starsCount;
int forksCount;
DateTime updatedAt;
GiteaRepository();
factory GiteaRepository.fromJson(Map<String, dynamic> json) =>
_$GiteaRepositoryFromJson(json);
}

View File

@ -11,7 +11,10 @@ GiteaUser _$GiteaUserFromJson(Map<String, dynamic> json) {
..id = json['id'] as int
..login = json['login'] as String
..fullName = json['full_name'] as String
..avatarUrl = json['avatar_url'] as String;
..avatarUrl = json['avatar_url'] as String
..created = json['created'] == null
? null
: DateTime.parse(json['created'] as String);
}
Map<String, dynamic> _$GiteaUserToJson(GiteaUser instance) => <String, dynamic>{
@ -19,6 +22,7 @@ Map<String, dynamic> _$GiteaUserToJson(GiteaUser instance) => <String, dynamic>{
'login': instance.login,
'full_name': instance.fullName,
'avatar_url': instance.avatarUrl,
'created': instance.created?.toIso8601String(),
};
GiteaRepository _$GiteaRepositoryFromJson(Map<String, dynamic> json) {
@ -29,8 +33,11 @@ GiteaRepository _$GiteaRepositoryFromJson(Map<String, dynamic> json) {
: GiteaUser.fromJson(json['owner'] as Map<String, dynamic>)
..name = json['name'] as String
..description = json['description'] as String
..starsCount = json['starsCount'] as int
..forksCount = json['forksCount'] as int;
..starsCount = json['stars_count'] as int
..forksCount = json['forks_count'] as int
..updatedAt = json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String);
}
Map<String, dynamic> _$GiteaRepositoryToJson(GiteaRepository instance) =>
@ -39,6 +46,7 @@ Map<String, dynamic> _$GiteaRepositoryToJson(GiteaRepository instance) =>
'owner': instance.owner,
'name': instance.name,
'description': instance.description,
'starsCount': instance.starsCount,
'forksCount': instance.forksCount,
'stars_count': instance.starsCount,
'forks_count': instance.forksCount,
'updated_at': instance.updatedAt?.toIso8601String(),
};

View File

@ -1,44 +1,58 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/gitea.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/action_entry.dart';
import 'package:git_touch/widgets/repository_item.dart';
import 'package:git_touch/widgets/user_item.dart';
import 'package:git_touch/widgets/user_header.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:timeago/timeago.dart' as timeago;
class GiteaUserScreen extends StatelessWidget {
final String login;
GiteaUserScreen(this.login);
bool get isViewer => login == null;
@override
Widget build(BuildContext context) {
return RefreshStatefulScaffold<
Tuple2<GiteaUser, Iterable<GiteaRepository>>>(
title: Text(login == null ? 'Me' : 'User'),
return RefreshStatefulScaffold<Tuple2<GiteaUser, List<GiteaRepository>>>(
title: Text(isViewer ? 'Me' : 'User'),
fetchData: () async {
final auth = Provider.of<AuthModel>(context);
final u = login ?? auth.activeAccount.login;
final items = await Future.wait([
auth.fetchGitea('/users/$u'),
auth.fetchGitea('/users/$u/repos'),
final res = await Future.wait([
auth.fetchGitea(isViewer ? '/user' : '/users/$login'),
auth.fetchGitea(isViewer ? '/user/repos' : '/users/$login/repos'),
]);
return Tuple2(
GiteaUser.fromJson(items[0]),
(items[1] as List).map((v) => GiteaRepository.fromJson(v)),
GiteaUser.fromJson(res[0]),
[for (var v in res[1]) GiteaRepository.fromJson(v)],
);
},
action: isViewer
? ActionEntry(
iconData: Icons.settings,
onTap: () {
final theme = Provider.of<ThemeModel>(context);
theme.push(context, '/settings');
},
)
: null,
bodyBuilder: (data, _) {
final user = data.item1;
final repos = data.item2;
return Column(
children: <Widget>[
UserItem(
UserHeader(
login: user.login,
avatarUrl: user.avatarUrl,
name: user.fullName,
createdAt: user.created,
bio: '',
),
CommonStyle.border,
Column(
@ -51,6 +65,7 @@ class GiteaUserScreen extends StatelessWidget {
description: v.description,
starCount: v.starsCount,
forkCount: v.forksCount,
note: 'Updated ${timeago.format(v.updatedAt)}',
url: '', // TODO:
)
],

View File

@ -43,10 +43,8 @@ final userRouter = RouterScreen(
class UserScreen extends StatelessWidget {
final String login;
UserScreen(this.login);
bool get isViewer => login.isEmpty;
bool get isViewer => login == null;
Iterable<Widget> _buildPinnedItems(Iterable<GhUserRepository> pinnedItems,
Iterable<GhUserRepository> repositories) {
@ -326,7 +324,8 @@ class UserScreen extends StatelessWidget {
return RefreshStatefulScaffold<GhUserRepositoryOwner>(
fetchData: () async {
final data = await auth.gqlClient.execute(GhUserQuery(
variables: GhUserArguments(login: login, isViewer: isViewer)));
variables:
GhUserArguments(login: login ?? '', isViewer: isViewer)));
return isViewer ? data.data.viewer : data.data.repositoryOwner;
},
title: AppBarTitle(isViewer ? 'Me' : login),

View File

@ -39,7 +39,7 @@ class UserHeader extends StatelessWidget {
],
),
SizedBox(height: 8),
if (name != null) ...[
if (name != null && name.isNotEmpty) ...[
Text(
name,
style: TextStyle(