feat: user screen

This commit is contained in:
Rongjian Zhang
2019-02-03 15:50:17 +08:00
parent f7cb6ab068
commit a374a57f8f
8 changed files with 218 additions and 86 deletions

0
lib/screens/repos.dart Normal file
View File

View File

@@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import '../widgets/loading.dart';
import '../providers/settings.dart';
import '../widgets/refresh_scaffold.dart';
import '../widgets/avatar.dart';
import '../widgets/link.dart';
import '../utils/utils.dart';
Future queryUser(String login) async {
@@ -12,9 +13,6 @@ Future queryUser(String login) async {
avatarUrl
bio
email
repositories {
totalCount
}
starredRepositories {
totalCount
}
@@ -24,6 +22,26 @@ Future queryUser(String login) async {
following {
totalCount
}
repositories(first: 6, ownerAffiliations: OWNER, orderBy: {field: STARGAZERS, direction: DESC}) {
totalCount
nodes {
owner {
login
}
name
stargazers {
totalCount
}
}
}
pinnedRepositories(first: 6) {
nodes {
owner {
login
}
name
}
}
}
}
''');
@@ -44,82 +62,106 @@ class UserScreen extends StatefulWidget {
class _UserScreenState extends State<UserScreen> {
var payload;
@override
void initState() {
super.initState();
_refresh();
}
Future _refresh() async {
queryUser(widget.login).then((_payload) {
setState(() {
payload = _payload;
});
});
}
Widget _buildBody(BuildContext context) {
if (payload == null) {
return Loading(more: false);
}
return Text('loaded');
// return SafeArea(
// child: CupertinoSliverRefreshControl(
// // key: _refreshIndicatorKey,
// onRefresh: _refresh,
// child: Column(
// children: <Widget>[
// Container(
// margin: EdgeInsets.symmetric(vertical: 20.0),
// child: ClipOval(
// child: Image.network(
// payload['avatarUrl'],
// fit: BoxFit.fill,
// width: 64,
// height: 64,
// ),
// ),
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: <Widget>[
// GestureDetector(
// child: Column(
// children: <Widget>[
// Text(payload['followers']['totalCount'].toString()),
// Text('Followers'),
// ],
// ),
// onTap: () {
// // print(1);
// },
// ),
// Column(
// children: <Widget>[
// Text(payload['following']['totalCount'].toString()),
// Text('Following')
// ],
// )
// ],
// ),
// ],
// ),
// ),
// );
}
@override
Widget build(BuildContext context) {
switch (SettingsProvider.of(context).layout) {
case LayoutMap.cupertino:
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(middle: Text(widget.login)),
child: _buildBody(context),
);
default:
return Scaffold(appBar: AppBar(title: Text(widget.login)));
}
return RefreshScaffold(
onRefresh: () async {
var _payload = await queryUser(widget.login);
setState(() {
payload = _payload;
});
},
title: widget.login,
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.black12))),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Avatar(
login: widget.login,
url: payload['avatarUrl'],
size: 28,
),
Padding(padding: EdgeInsets.only(left: 10)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(payload['name'], style: TextStyle(height: 1.2)),
Padding(padding: EdgeInsets.only(top: 10)),
Row(children: <Widget>[
Icon(
Octicons.mail,
color: Colors.black54,
size: 16,
),
Padding(padding: EdgeInsets.only(left: 4)),
Text(
payload['email'],
style: TextStyle(color: Colors.black54, fontSize: 16),
)
])
],
),
)
],
),
),
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.black12))),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Link(
child: Column(
children: <Widget>[
Text(payload['repositories']['totalCount'].toString()),
Text('Repos')
],
),
onTap: () {},
),
Link(
child: Column(
children: <Widget>[
Text(payload['starredRepositories']['totalCount']
.toString()),
Text('Stars')
],
),
onTap: () {},
),
Link(
child: Column(
children: <Widget>[
Text(payload['followers']['totalCount'].toString()),
Text('Followers'),
],
),
onTap: () {
// print(1);
},
),
Link(
child: Column(
children: <Widget>[
Text(payload['following']['totalCount'].toString()),
Text('Following')
],
),
onTap: () {},
),
],
),
),
],
),
);
}
}

0
lib/screens/users.dart Normal file
View File

View File

@@ -12,7 +12,7 @@ TextSpan createLinkSpan(BuildContext context, String text, Function handle) {
style: TextStyle(
color: Color(0xff0366d6),
fontWeight: FontWeight.w600,
decoration: TextDecoration.underline,
// decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()
..onTap = () {

View File

@@ -6,8 +6,13 @@ import 'link.dart';
class Avatar extends StatelessWidget {
final String login;
final String url;
final double size;
Avatar(this.login, this.url);
Avatar({
@required this.login,
@required this.url,
this.size = 18,
});
@override
Widget build(BuildContext context) {
@@ -19,7 +24,7 @@ class Avatar extends StatelessWidget {
child: CircleAvatar(
backgroundColor: Colors.transparent,
backgroundImage: NetworkImage(url),
radius: 18,
radius: size,
),
);
}

View File

@@ -12,7 +12,10 @@ class CommentItem extends StatelessWidget {
Widget build(BuildContext context) {
return Column(children: <Widget>[
Row(children: <Widget>[
Avatar(item['author']['login'], item['author']['avatarUrl']),
Avatar(
login: item['author']['login'],
url: item['author']['avatarUrl'],
),
Padding(padding: EdgeInsets.only(left: 10)),
Expanded(
child: Column(

View File

@@ -149,7 +149,7 @@ class EventItem extends StatelessWidget {
children: <Widget>[
Row(
children: <Widget>[
Avatar(event.actor.login, event.actor.avatarUrl),
Avatar(login: event.actor.login, url: event.actor.avatarUrl),
Padding(padding: EdgeInsets.only(left: 10)),
Expanded(
child: RichText(
@@ -183,7 +183,7 @@ class EventItem extends StatelessWidget {
maxLines: 3,
style: TextStyle(
color: Colors.black87,
fontSize: 15,
fontSize: 14,
height: 1.2,
fontWeight: FontWeight.w300,
),

View File

@@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import '../providers/settings.dart';
import 'loading.dart';
typedef RefreshCallback = Future<void> Function();
class RefreshScaffold extends StatefulWidget {
final String title;
final Widget body;
final RefreshCallback onRefresh;
RefreshScaffold({
@required this.title,
@required this.body,
@required this.onRefresh,
});
@override
_RefreshScaffoldState createState() => _RefreshScaffoldState();
}
class _RefreshScaffoldState extends State<RefreshScaffold> {
bool loading = false;
@override
void initState() {
super.initState();
_refresh();
}
Future<void> _refresh() async {
print('refresh');
setState(() {
loading = true;
});
try {
await widget.onRefresh();
} catch (err) {
print(err);
} finally {
setState(() {
loading = false;
});
}
}
Widget _buildBody(BuildContext context) {
if (loading) {
return Loading(more: false);
} else {
return widget.body;
}
}
@override
Widget build(BuildContext context) {
switch (SettingsProvider.of(context).layout) {
case LayoutMap.cupertino:
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(middle: Text(widget.title)),
child: SafeArea(
child: CustomScrollView(
slivers: <Widget>[
CupertinoSliverRefreshControl(onRefresh: widget.onRefresh),
SliverToBoxAdapter(child: _buildBody(context))
],
),
),
);
default:
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: RefreshIndicator(
onRefresh: widget.onRefresh,
child: _buildBody(context),
),
);
}
}
}