refactor: user header widget
This commit is contained in:
parent
3db932b284
commit
c583257867
|
@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
|
||||||
import 'package:git_touch/models/auth.dart';
|
import 'package:git_touch/models/auth.dart';
|
||||||
import 'package:git_touch/models/notification.dart';
|
import 'package:git_touch/models/notification.dart';
|
||||||
import 'package:git_touch/models/theme.dart';
|
import 'package:git_touch/models/theme.dart';
|
||||||
|
import 'package:git_touch/screens/gitlab_project.dart';
|
||||||
import 'package:git_touch/screens/gitlab_todos.dart';
|
import 'package:git_touch/screens/gitlab_todos.dart';
|
||||||
import 'package:git_touch/screens/gitlab_user.dart';
|
import 'package:git_touch/screens/gitlab_user.dart';
|
||||||
import 'package:git_touch/screens/login.dart';
|
import 'package:git_touch/screens/login.dart';
|
||||||
|
@ -50,7 +51,7 @@ class _HomeState extends State<Home> {
|
||||||
case 0:
|
case 0:
|
||||||
return GitlabTodosScreen();
|
return GitlabTodosScreen();
|
||||||
case 1:
|
case 1:
|
||||||
return GitlabUserScreen(auth.activeAccount.gitlabId);
|
return GitlabUserScreen(null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,9 @@ class GitlabUser {
|
||||||
String username;
|
String username;
|
||||||
String name;
|
String name;
|
||||||
String avatarUrl;
|
String avatarUrl;
|
||||||
|
String bio;
|
||||||
|
DateTime createdAt;
|
||||||
GitlabUser();
|
GitlabUser();
|
||||||
|
|
||||||
factory GitlabUser.fromJson(Map<String, dynamic> json) =>
|
factory GitlabUser.fromJson(Map<String, dynamic> json) =>
|
||||||
_$GitlabUserFromJson(json);
|
_$GitlabUserFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,11 @@ GitlabUser _$GitlabUserFromJson(Map<String, dynamic> json) {
|
||||||
..id = json['id'] as int
|
..id = json['id'] as int
|
||||||
..username = json['username'] as String
|
..username = json['username'] as String
|
||||||
..name = json['name'] as String
|
..name = json['name'] as String
|
||||||
..avatarUrl = json['avatar_url'] as String;
|
..avatarUrl = json['avatar_url'] as String
|
||||||
|
..bio = json['bio'] as String
|
||||||
|
..createdAt = json['created_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['created_at'] as String);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _$GitlabUserToJson(GitlabUser instance) =>
|
Map<String, dynamic> _$GitlabUserToJson(GitlabUser instance) =>
|
||||||
|
@ -48,6 +52,8 @@ Map<String, dynamic> _$GitlabUserToJson(GitlabUser instance) =>
|
||||||
'username': instance.username,
|
'username': instance.username,
|
||||||
'name': instance.name,
|
'name': instance.name,
|
||||||
'avatar_url': instance.avatarUrl,
|
'avatar_url': instance.avatarUrl,
|
||||||
|
'bio': instance.bio,
|
||||||
|
'created_at': instance.createdAt?.toIso8601String(),
|
||||||
};
|
};
|
||||||
|
|
||||||
GitlabTodoProject _$GitlabTodoProjectFromJson(Map<String, dynamic> json) {
|
GitlabTodoProject _$GitlabTodoProjectFromJson(Map<String, dynamic> json) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import 'package:git_touch/models/theme.dart';
|
||||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||||
import 'package:git_touch/widgets/action_entry.dart';
|
import 'package:git_touch/widgets/action_entry.dart';
|
||||||
import 'package:git_touch/widgets/repository_item.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:provider/provider.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:git_touch/utils/utils.dart';
|
import 'package:git_touch/utils/utils.dart';
|
||||||
|
@ -53,10 +53,12 @@ class GitlabUserScreen extends StatelessWidget {
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
UserItem(
|
UserHeader(
|
||||||
login: user.username,
|
login: user.username,
|
||||||
avatarUrl: user.avatarUrl,
|
avatarUrl: user.avatarUrl,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
|
createdAt: user.createdAt,
|
||||||
|
bio: user.bio,
|
||||||
),
|
),
|
||||||
CommonStyle.border,
|
CommonStyle.border,
|
||||||
Column(
|
Column(
|
||||||
|
|
|
@ -15,6 +15,7 @@ import 'package:git_touch/widgets/repository_item.dart';
|
||||||
import 'package:git_touch/widgets/table_view.dart';
|
import 'package:git_touch/widgets/table_view.dart';
|
||||||
import 'package:git_touch/widgets/text_contains_organization.dart';
|
import 'package:git_touch/widgets/text_contains_organization.dart';
|
||||||
import 'package:git_touch/models/auth.dart';
|
import 'package:git_touch/models/auth.dart';
|
||||||
|
import 'package:git_touch/widgets/user_header.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:git_touch/widgets/action_button.dart';
|
import 'package:git_touch/widgets/action_button.dart';
|
||||||
|
|
||||||
|
@ -83,77 +84,6 @@ class UserScreen extends StatelessWidget {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildHeader(BuildContext context, String avatarUrl, String name,
|
|
||||||
String login, DateTime createdAt, String bio,
|
|
||||||
{Widget followWidget}) {
|
|
||||||
final theme = Provider.of<ThemeModel>(context);
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
padding: CommonStyle.padding,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Avatar(url: avatarUrl, size: AvatarSize.extraLarge),
|
|
||||||
if (followWidget != null) ...[
|
|
||||||
Expanded(child: Container()),
|
|
||||||
followWidget,
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
if (name != null) ...[
|
|
||||||
Text(
|
|
||||||
name,
|
|
||||||
style: TextStyle(
|
|
||||||
color: theme.palette.text,
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 4),
|
|
||||||
],
|
|
||||||
Text(
|
|
||||||
login,
|
|
||||||
style: TextStyle(
|
|
||||||
color: theme.palette.primary,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Icon(
|
|
||||||
Octicons.clock,
|
|
||||||
size: 16,
|
|
||||||
color: theme.palette.tertiaryText,
|
|
||||||
),
|
|
||||||
SizedBox(width: 4),
|
|
||||||
Text(
|
|
||||||
'Joined on ${dateFormat.format(createdAt)}',
|
|
||||||
style: TextStyle(
|
|
||||||
color: theme.palette.tertiaryText,
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (bio != null && bio.isNotEmpty) ...[
|
|
||||||
SizedBox(height: 10),
|
|
||||||
Text(
|
|
||||||
bio,
|
|
||||||
style: TextStyle(
|
|
||||||
color: theme.palette.secondaryText,
|
|
||||||
fontSize: 17,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildUser(BuildContext context, GhUserUser p,
|
Widget _buildUser(BuildContext context, GhUserUser p,
|
||||||
void Function(void Function()) setState) {
|
void Function(void Function()) setState) {
|
||||||
final theme = Provider.of<ThemeModel>(context);
|
final theme = Provider.of<ThemeModel>(context);
|
||||||
|
@ -163,13 +93,12 @@ class UserScreen extends StatelessWidget {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
_buildHeader(
|
UserHeader(
|
||||||
context,
|
avatarUrl: p.avatarUrl,
|
||||||
p.avatarUrl,
|
name: p.name,
|
||||||
p.name,
|
login: p.login,
|
||||||
p.login,
|
createdAt: p.createdAt,
|
||||||
p.createdAt,
|
bio: p.bio,
|
||||||
p.bio,
|
|
||||||
followWidget: p.viewerCanFollow == true
|
followWidget: p.viewerCanFollow == true
|
||||||
? MutationButton(
|
? MutationButton(
|
||||||
text: p.viewerIsFollowing ? 'Unfollow' : 'Follow',
|
text: p.viewerIsFollowing ? 'Unfollow' : 'Follow',
|
||||||
|
@ -322,8 +251,13 @@ class UserScreen extends StatelessWidget {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
_buildHeader(
|
UserHeader(
|
||||||
context, p.avatarUrl, p.name, p.login, p.createdAt, p.description),
|
avatarUrl: p.avatarUrl,
|
||||||
|
name: p.name,
|
||||||
|
login: p.login,
|
||||||
|
createdAt: p.createdAt,
|
||||||
|
bio: p.description,
|
||||||
|
),
|
||||||
CommonStyle.border,
|
CommonStyle.border,
|
||||||
Row(children: [
|
Row(children: [
|
||||||
EntryItem(
|
EntryItem(
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:git_touch/models/theme.dart';
|
||||||
|
import 'package:git_touch/utils/utils.dart';
|
||||||
|
import 'package:git_touch/widgets/avatar.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class UserHeader extends StatelessWidget {
|
||||||
|
final String avatarUrl;
|
||||||
|
final String name;
|
||||||
|
final String login;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final String bio;
|
||||||
|
final Widget followWidget;
|
||||||
|
|
||||||
|
UserHeader({
|
||||||
|
@required this.avatarUrl,
|
||||||
|
@required this.name,
|
||||||
|
@required this.login,
|
||||||
|
@required this.createdAt,
|
||||||
|
@required this.bio,
|
||||||
|
this.followWidget,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Provider.of<ThemeModel>(context);
|
||||||
|
return Container(
|
||||||
|
padding: CommonStyle.padding,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Avatar(url: avatarUrl, size: AvatarSize.extraLarge),
|
||||||
|
if (followWidget != null) ...[
|
||||||
|
Expanded(child: Container()),
|
||||||
|
followWidget,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
if (name != null) ...[
|
||||||
|
Text(
|
||||||
|
name,
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.palette.text,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 4),
|
||||||
|
],
|
||||||
|
Text(
|
||||||
|
login,
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.palette.primary,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Icon(
|
||||||
|
Octicons.clock,
|
||||||
|
size: 16,
|
||||||
|
color: theme.palette.tertiaryText,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'Joined on ${dateFormat.format(createdAt)}',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.palette.tertiaryText,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (bio != null && bio.isNotEmpty) ...[
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
bio,
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.palette.secondaryText,
|
||||||
|
fontSize: 17,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue