Add user page
This commit is contained in:
parent
dfb32cc0fd
commit
675d39a966
|
@ -1,81 +0,0 @@
|
|||
import 'dart:async';
|
||||
// import 'dart:convert';
|
||||
import '../utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'home/event.dart';
|
||||
|
||||
class IosHomeTab extends StatefulWidget {
|
||||
@override
|
||||
createState() {
|
||||
return new IosHomeTabState();
|
||||
}
|
||||
}
|
||||
|
||||
class IosHomeTabState extends State<IosHomeTab> {
|
||||
int page = 1;
|
||||
List<Event> events = [];
|
||||
|
||||
loadFirst() async {
|
||||
events = await fetchEvents();
|
||||
page = 1;
|
||||
return events;
|
||||
}
|
||||
|
||||
loadMore() async {
|
||||
events.addAll(await fetchEvents(page + 1));
|
||||
page++;
|
||||
return events;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
return new FutureBuilder(
|
||||
future: loadFirst(),
|
||||
builder: (context, snapshot) {
|
||||
Widget widget;
|
||||
if (snapshot.hasData) {
|
||||
// List<Event> events = snapshot.data;
|
||||
widget = new CustomScrollView(
|
||||
slivers: [
|
||||
new CupertinoRefreshControl(
|
||||
onRefresh: () {
|
||||
return loadFirst();
|
||||
},
|
||||
),
|
||||
new SliverSafeArea(
|
||||
// top: true,
|
||||
sliver: new SliverList(
|
||||
delegate: new SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
var event = events[index];
|
||||
switch (event.type) {
|
||||
case 'IssuesEvent':
|
||||
return new IssuesEvent(event);
|
||||
case 'PushEvent':
|
||||
return new PushEvent(event);
|
||||
case 'PullRequestEvent':
|
||||
return new PullRequestEvent(event);
|
||||
case 'WatchEvent':
|
||||
return new WatchEvent(event);
|
||||
default:
|
||||
return new Text('Not implement yet');
|
||||
}
|
||||
},
|
||||
childCount: 30,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
widget = new Text("${snapshot.error}");
|
||||
} else {
|
||||
widget = new CupertinoActivityIndicator();
|
||||
}
|
||||
|
||||
return widget;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,27 +1,34 @@
|
|||
import '../../utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import '../issue.dart';
|
||||
import '../user.dart';
|
||||
|
||||
class _Avatar extends StatelessWidget {
|
||||
final String avatar;
|
||||
_Avatar(this.avatar);
|
||||
|
||||
@override
|
||||
build(context) {
|
||||
return new CircleAvatar(
|
||||
backgroundImage: NetworkImage(avatar),
|
||||
radius: 24.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TextSpan _strong(String text) {
|
||||
TextSpan _strong(String text, [GestureRecognizer recognizer]) {
|
||||
return new TextSpan(
|
||||
text: text,
|
||||
style: new TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: new Color(0xff24292e),
|
||||
),
|
||||
recognizer: recognizer,
|
||||
);
|
||||
}
|
||||
|
||||
TextSpan _user(Event event, context) {
|
||||
return _strong(
|
||||
event.actor,
|
||||
new TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
Navigator.of(context).push(
|
||||
new CupertinoPageRoute(
|
||||
builder: (context) {
|
||||
return new IosUserPage(event.actor, event.avatar);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -30,29 +37,22 @@ class PushEvent extends StatelessWidget {
|
|||
PushEvent(this.event);
|
||||
|
||||
@override
|
||||
build(ctx) {
|
||||
return new Row(
|
||||
children: [
|
||||
new _Avatar(event.avatar),
|
||||
new Expanded(
|
||||
child: new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_strong(event.actor),
|
||||
new TextSpan(text: ' pushed to '),
|
||||
new TextSpan(
|
||||
text: event.payload['ref'],
|
||||
style: new TextStyle(color: CupertinoColors.activeBlue),
|
||||
),
|
||||
new TextSpan(text: ' in '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(text: '')
|
||||
],
|
||||
),
|
||||
build(context) {
|
||||
return new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_user(event, context),
|
||||
new TextSpan(text: ' pushed to '),
|
||||
new TextSpan(
|
||||
text: event.payload['ref'],
|
||||
style: new TextStyle(color: CupertinoColors.activeBlue),
|
||||
),
|
||||
),
|
||||
],
|
||||
new TextSpan(text: ' in '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(text: '')
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -62,26 +62,22 @@ class IssuesEvent extends StatelessWidget {
|
|||
IssuesEvent(this.event);
|
||||
|
||||
@override
|
||||
build(ctx) {
|
||||
return new Row(
|
||||
children: <Widget>[
|
||||
new _Avatar(event.avatar),
|
||||
new Expanded(
|
||||
child: new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_strong(event.actor),
|
||||
new TextSpan(text: ' ${event.payload['action']} issue '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(
|
||||
text: '#' + event.payload['issue']['number'].toString()),
|
||||
new TextSpan(text: event.payload['issue']['title'])
|
||||
],
|
||||
),
|
||||
build(context) {
|
||||
return new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_user(event, context),
|
||||
new TextSpan(text: ' ${event.payload['action']} issue '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(
|
||||
text: '#' + event.payload['issue']['number'].toString(),
|
||||
),
|
||||
),
|
||||
],
|
||||
new TextSpan(
|
||||
text: event.payload['issue']['title'],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -91,25 +87,18 @@ class PullRequestEvent extends StatelessWidget {
|
|||
PullRequestEvent(this.event);
|
||||
|
||||
@override
|
||||
build(ctx) {
|
||||
return new Row(
|
||||
children: <Widget>[
|
||||
new _Avatar(event.avatar),
|
||||
new Expanded(
|
||||
child: new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_strong(event.actor),
|
||||
new TextSpan(text: ' ${event.payload['action']} pull request '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(text: '#' + event.payload['number'].toString()),
|
||||
new TextSpan(text: event.payload['pull_request']['title'])
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
build(context) {
|
||||
return new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_user(event, context),
|
||||
new TextSpan(text: ' ${event.payload['action']} pull request '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(text: '#' + event.payload['number'].toString()),
|
||||
new TextSpan(text: event.payload['pull_request']['title'])
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -119,26 +108,18 @@ class IssueCommentEvent extends StatelessWidget {
|
|||
IssueCommentEvent(this.event);
|
||||
|
||||
@override
|
||||
build(ctx) {
|
||||
return new Row(
|
||||
children: <Widget>[
|
||||
new _Avatar(event.avatar),
|
||||
new Expanded(
|
||||
child: new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_strong(event.actor),
|
||||
new TextSpan(text: ' commented on issue '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(
|
||||
text: '#' + event.payload['issue']['number'].toString()),
|
||||
new TextSpan(text: event.payload['comment']['body'])
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
build(context) {
|
||||
return new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_user(event, context),
|
||||
new TextSpan(text: ' commented on issue '),
|
||||
_strong(event.repo),
|
||||
new TextSpan(text: '#' + event.payload['issue']['number'].toString()),
|
||||
new TextSpan(text: event.payload['comment']['body'])
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -148,23 +129,16 @@ class WatchEvent extends StatelessWidget {
|
|||
WatchEvent(this.event);
|
||||
|
||||
@override
|
||||
build(ctx) {
|
||||
return new Row(
|
||||
children: <Widget>[
|
||||
new _Avatar(event.avatar),
|
||||
new Expanded(
|
||||
child: new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_strong(event.actor),
|
||||
new TextSpan(text: ' ${event.payload['action']} '),
|
||||
_strong(event.repo),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
build(context) {
|
||||
return new RichText(
|
||||
text: new TextSpan(
|
||||
style: new TextStyle(color: CupertinoColors.black),
|
||||
children: [
|
||||
_user(event, context),
|
||||
new TextSpan(text: ' ${event.payload['action']} '),
|
||||
_strong(event.repo),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
// import 'dart:async';
|
||||
// import 'dart:convert';
|
||||
import '../../utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'event.dart';
|
||||
import '../user.dart';
|
||||
|
||||
class _Avatar extends StatelessWidget {
|
||||
final String avatar;
|
||||
_Avatar(this.avatar);
|
||||
|
||||
@override
|
||||
build(context) {
|
||||
return new CircleAvatar(
|
||||
backgroundImage: NetworkImage(avatar),
|
||||
radius: 24.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _EventItem extends StatelessWidget {
|
||||
final Event event;
|
||||
final Widget child;
|
||||
_EventItem(this.event, this.child);
|
||||
|
||||
@override
|
||||
build(context) {
|
||||
// const Padding(padding: const EdgeInsets.only(top: 16.0)),
|
||||
return new Row(
|
||||
children: [
|
||||
new _Avatar(event.avatar),
|
||||
new Expanded(child: child),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class IosHomeTab extends StatefulWidget {
|
||||
@override
|
||||
createState() {
|
||||
return new IosHomeTabState();
|
||||
}
|
||||
}
|
||||
|
||||
class IosHomeTabState extends State<IosHomeTab> {
|
||||
int page = 1;
|
||||
List<Event> events = [];
|
||||
|
||||
loadFirst() async {
|
||||
events = await fetchEvents();
|
||||
page = 1;
|
||||
return events;
|
||||
}
|
||||
|
||||
loadMore() async {
|
||||
events.addAll(await fetchEvents(page + 1));
|
||||
page++;
|
||||
return events;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
return new CupertinoPageScaffold(
|
||||
navigationBar: new CupertinoNavigationBar(
|
||||
middle: new Text('Home'),
|
||||
),
|
||||
child: new FutureBuilder(
|
||||
future: loadFirst(),
|
||||
builder: (context, snapshot) {
|
||||
Widget widget;
|
||||
if (snapshot.hasData) {
|
||||
// List<Event> events = snapshot.data;
|
||||
widget = new CustomScrollView(
|
||||
slivers: [
|
||||
new CupertinoRefreshControl(
|
||||
onRefresh: () {
|
||||
return loadFirst();
|
||||
},
|
||||
),
|
||||
new SliverSafeArea(
|
||||
// top: true,
|
||||
sliver: new SliverList(
|
||||
delegate: new SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
var event = events[index];
|
||||
var child = (() {
|
||||
switch (event.type) {
|
||||
case 'IssuesEvent':
|
||||
return new IssuesEvent(event);
|
||||
case 'PushEvent':
|
||||
return new PushEvent(event);
|
||||
case 'PullRequestEvent':
|
||||
return new PullRequestEvent(event);
|
||||
case 'WatchEvent':
|
||||
return new WatchEvent(event);
|
||||
default:
|
||||
return new Text('Not implement yet');
|
||||
}
|
||||
})();
|
||||
return new _EventItem(event, child);
|
||||
},
|
||||
childCount: 30,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
widget = new Text("${snapshot.error}");
|
||||
} else {
|
||||
widget = new CupertinoActivityIndicator();
|
||||
}
|
||||
|
||||
return widget;
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// import 'dart:async';
|
||||
// import 'dart:convert';
|
||||
// import '../utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class IosIssue extends StatelessWidget {
|
||||
@override
|
||||
Widget build(context) {
|
||||
return new Text('Issue');
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'home.dart';
|
||||
import 'home/index.dart';
|
||||
import 'notification.dart';
|
||||
import 'profile.dart';
|
||||
import 'issue.dart';
|
||||
|
||||
class IosApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
build(context) {
|
||||
return new MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
theme: new ThemeData(
|
||||
|
@ -14,6 +15,7 @@ class IosApp extends StatelessWidget {
|
|||
),
|
||||
home: new IosHomePage(title: 'GitFlux'),
|
||||
routes: {
|
||||
'/issue': (context) => new IosIssue()
|
||||
// '/notification': (context) => new IosNotificationTab(),
|
||||
// '/profile': (context) => new IosProfileTab(),
|
||||
},
|
||||
|
@ -42,9 +44,6 @@ class _IosHomePageState extends State<IosHomePage> {
|
|||
@override
|
||||
Widget build(context) {
|
||||
return new CupertinoPageScaffold(
|
||||
navigationBar: new CupertinoNavigationBar(
|
||||
middle: new Text(widget.title),
|
||||
),
|
||||
child: new CupertinoTabScaffold(
|
||||
tabBar: new CupertinoTabBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import '../utils.dart';
|
||||
|
||||
class IosUserPage extends StatelessWidget {
|
||||
String login;
|
||||
String avatar;
|
||||
IosUserPage(this.login, this.avatar);
|
||||
|
||||
@override
|
||||
build(context) {
|
||||
return new CupertinoPageScaffold(
|
||||
navigationBar: new CupertinoNavigationBar(
|
||||
leading: new CupertinoButton(
|
||||
child: const Text('Cancel'),
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(false);
|
||||
},
|
||||
),
|
||||
middle: new Text(login),
|
||||
),
|
||||
child: new FutureBuilder(
|
||||
future: fetchUser(login),
|
||||
builder: (context, snapshot) {
|
||||
Widget widget;
|
||||
if (snapshot.hasData) {
|
||||
User user = snapshot.data;
|
||||
return new Text('');
|
||||
} else if (snapshot.hasError) {
|
||||
widget = new Text("${snapshot.error}");
|
||||
} else {
|
||||
widget = new CupertinoActivityIndicator();
|
||||
}
|
||||
return widget;
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
|
@ -6,20 +6,6 @@ import 'token.dart';
|
|||
|
||||
final prefix = 'https://api.github.com';
|
||||
|
||||
// class PushEvent extends Event {
|
||||
// PushEvent(Map<String, dynamic> json) : super(json) {}
|
||||
// }
|
||||
|
||||
// class IssuesEvent extends Event {
|
||||
// String issueTitle;
|
||||
// String issueUrl;
|
||||
|
||||
// IssuesEvent(Map<String, dynamic> json) : super(json) {
|
||||
// issueTitle = json['issue']['title'];
|
||||
// issueUrl = json['issue']['url'];
|
||||
// }
|
||||
// }
|
||||
|
||||
class Event {
|
||||
String type;
|
||||
String actor;
|
||||
|
@ -28,23 +14,32 @@ class Event {
|
|||
String repo;
|
||||
Map<String, dynamic> payload;
|
||||
|
||||
Event(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
actor = json['actor']['login'];
|
||||
avatar = json['actor']['avatar_url'];
|
||||
repo = json['repo']['name'];
|
||||
payload = json['payload'];
|
||||
Event(data) {
|
||||
id = data['id'];
|
||||
type = data['type'];
|
||||
actor = data['actor']['login'];
|
||||
avatar = data['actor']['avatar_url'];
|
||||
repo = data['repo']['name'];
|
||||
payload = data['payload'];
|
||||
}
|
||||
}
|
||||
|
||||
// factory Event.fromJson(Map<String, dynamic> json) {
|
||||
// switch (json['type']) {
|
||||
// case 'PushEvent':
|
||||
// return new PushEvent(json);
|
||||
// default:
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
class User {
|
||||
String login;
|
||||
String avatar;
|
||||
String name;
|
||||
int repos;
|
||||
int followers;
|
||||
int following;
|
||||
|
||||
User(data) {
|
||||
login = data['login'];
|
||||
avatar = data['avatar_url'];
|
||||
name = data['name'];
|
||||
repos = data['public_repos'];
|
||||
followers = data['followers'];
|
||||
following = data['following'];
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Event>> fetchEvents([int page = 1]) async {
|
||||
|
@ -52,9 +47,19 @@ Future<List<Event>> fetchEvents([int page = 1]) async {
|
|||
prefix + '/users/pd4d10/received_events/public?page=$page',
|
||||
headers: {HttpHeaders.AUTHORIZATION: 'token $token'},
|
||||
);
|
||||
List<dynamic> resJson = json.decode(res.body);
|
||||
List<dynamic> data = json.decode(res.body);
|
||||
|
||||
return resJson.map((item) {
|
||||
return data.map((item) {
|
||||
return new Event(item);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future<User> fetchUser(String login) async {
|
||||
final res = await http.get(
|
||||
prefix + '/users/$login',
|
||||
headers: {HttpHeaders.AUTHORIZATION: 'token $token'},
|
||||
);
|
||||
Map<String, dynamic> data = json.decode(res.body);
|
||||
|
||||
return new User(data);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue