Add iOS home page

This commit is contained in:
Rongjian Zhang 2018-04-21 20:50:46 +08:00
parent 036c71f7ee
commit 19bc824b32
10 changed files with 324 additions and 81 deletions

2
.gitignore vendored
View File

@ -7,3 +7,5 @@
build/
.flutter-plugins
lib/token.dart

View File

@ -1,44 +1,51 @@
// 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 StatelessWidget {
@override
Widget build(BuildContext context) {
return new DefaultTextStyle(
style: const TextStyle(
fontFamily: '.SF UI Text',
inherit: false,
fontSize: 17.0,
color: CupertinoColors.black,
),
child: new CupertinoPageScaffold(
child: new DecoratedBox(
decoration: const BoxDecoration(color: const Color(0xFFEFEFF4)),
child: new CustomScrollView(
slivers: <Widget>[
const CupertinoSliverNavigationBar(
largeTitle: const Text('Cupertino Refresh'),
),
new CupertinoRefreshControl(
onRefresh: () {
// return new Future<void>.delayed(const Duration(seconds: 2))
// ..then((_) => setState(() => repopulateList()));
},
),
new SliverSafeArea(
top: false, // Top safe area is consumed by the navigation bar.
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Text('abc');
},
childCount: 20,
),
),
),
],
),
),
),
Widget build(context) {
return new FutureBuilder(
future: fetchEvents(),
builder: (context, snapshot) {
Widget widget;
if (snapshot.hasData) {
List<Event> events = snapshot.data;
widget = new ListView(
padding: new EdgeInsets.all(8.0),
// itemExtent: 20.0,
children: events.map((event) {
switch (event.type) {
case 'IssuesEvent':
return new IssuesEvent(event);
case 'PushEvent':
return new PushEvent(event);
case 'PullRequestEvent':
return new PullRequestEvent(event);
default:
return new Text('');
}
}).toList(),
);
} else if (snapshot.hasError) {
widget = new Text("${snapshot.error}");
} else {
widget = new CupertinoActivityIndicator();
}
return widget;
// return new CustomScrollView(slivers: [
// new CupertinoRefreshControl(
// onRefresh: () {
// return fetchEvents();
// },
// ),
// // new CupertinoActivityIndicator(),
// ]);
},
);
}
}

144
lib/ios/home/event.dart Normal file
View File

@ -0,0 +1,144 @@
import '../../utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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) {
return new TextSpan(
text: text,
style: new TextStyle(
fontWeight: FontWeight.bold,
color: new Color(0xff24292e),
),
);
}
class PushEvent extends StatelessWidget {
final Event event;
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: '')
],
),
),
),
],
);
}
}
class IssuesEvent extends StatelessWidget {
final Event event;
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'])
],
),
),
),
],
);
}
}
class PullRequestEvent extends StatelessWidget {
final Event event;
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'])
],
),
),
),
],
);
}
}
class IssueCommentEvent extends StatelessWidget {
final Event event;
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'])
],
),
),
),
],
);
}
}

View File

@ -1,6 +1,8 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'home.dart';
import 'notification.dart';
import 'profile.dart';
class IosApp extends StatelessWidget {
@override
@ -11,6 +13,10 @@ class IosApp extends StatelessWidget {
primarySwatch: Colors.blue,
),
home: new IosHomePage(title: 'GitFlux'),
routes: {
// '/notification': (context) => new IosNotificationTab(),
// '/profile': (context) => new IosProfileTab(),
},
);
}
}
@ -34,53 +40,54 @@ class _IosHomePageState extends State<IosHomePage> {
// }
@override
Widget build(BuildContext context) {
Widget build(context) {
return new CupertinoPageScaffold(
navigationBar: new CupertinoNavigationBar(
middle: new Text(widget.title),
),
child: new CupertinoTabScaffold(
tabBar: new CupertinoTabBar(
items: const <BottomNavigationBarItem>[
const BottomNavigationBarItem(
icon: const Icon(CupertinoIcons.home),
title: const Text('Home'),
),
const BottomNavigationBarItem(
icon: const Icon(CupertinoIcons.conversation_bubble),
title: const Text('Notification'),
),
const BottomNavigationBarItem(
icon: const Icon(CupertinoIcons.profile_circled),
title: const Text('Profile'),
),
],
),
tabBuilder: (BuildContext context, int index) {
return new DefaultTextStyle(
style: const TextStyle(
fontFamily: '.SF UI Text',
fontSize: 17.0,
color: CupertinoColors.black,
),
child: new CupertinoTabView(
builder: (BuildContext context) {
switch (index) {
case 0:
return new IosHomeTab();
break;
case 1:
return new IosHomeTab();
break;
case 2:
return new IosHomeTab();
break;
default:
}
},
),
);
}),
tabBar: new CupertinoTabBar(
items: const <BottomNavigationBarItem>[
const BottomNavigationBarItem(
icon: const Icon(CupertinoIcons.home),
title: const Text('Home'),
),
const BottomNavigationBarItem(
icon: const Icon(CupertinoIcons.conversation_bubble),
title: const Text('Notification'),
),
const BottomNavigationBarItem(
icon: const Icon(CupertinoIcons.profile_circled),
title: const Text('Profile'),
),
],
),
tabBuilder: (context, int index) {
return new DefaultTextStyle(
style: const TextStyle(
fontFamily: '.SF UI Text',
fontSize: 17.0,
color: CupertinoColors.black,
),
child: new CupertinoTabView(
builder: (BuildContext context) {
switch (index) {
case 0:
return new IosHomeTab();
break;
case 1:
return new IosNotificationTab();
break;
case 2:
return new IosProfileTab();
break;
default:
}
},
),
);
},
),
);
}
}

11
lib/ios/notification.dart Normal file
View File

@ -0,0 +1,11 @@
// import 'dart:async';
// import 'dart:convert';
// import '../utils.dart';
import 'package:flutter/cupertino.dart';
class IosNotificationTab extends StatelessWidget {
@override
Widget build(context) {
return new Text('Notification');
}
}

11
lib/ios/profile.dart Normal file
View File

@ -0,0 +1,11 @@
// import 'dart:async';
// import 'dart:convert';
// import '../utils.dart';
import 'package:flutter/cupertino.dart';
class IosProfileTab extends StatelessWidget {
@override
Widget build(context) {
return new Text('Profile');
}
}

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
// import 'main.android.dart';
import 'android/main.dart';
import 'ios/main.dart';
void main() => runApp(new IosApp());

60
lib/utils.dart Normal file
View File

@ -0,0 +1,60 @@
import 'dart:convert';
import 'dart:async';
import 'dart:io';
import 'package:http/http.dart' as http;
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;
String id;
String avatar;
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'];
}
// factory Event.fromJson(Map<String, dynamic> json) {
// switch (json['type']) {
// case 'PushEvent':
// return new PushEvent(json);
// default:
// return null;
// }
// }
}
Future<List<Event>> fetchEvents() async {
final res = await http.get(
prefix + '/users/pd4d10/received_events/public',
headers: {HttpHeaders.AUTHORIZATION: 'token $token'},
);
List<dynamic> resJson = json.decode(res.body);
return resJson.map((item) {
return new Event(item);
}).toList();
}

View File

@ -8,6 +8,7 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.0
http: ^0.11.3
dev_dependencies:
flutter_test:
@ -53,5 +54,5 @@ flutter:
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# For details regarding fonts from package dependencies,
# see https://flutter.io/custom-fonts/#from-packages