mirror of
https://github.com/git-touch/git-touch
synced 2025-03-06 12:17:50 +01:00
feat: add notification page
This commit is contained in:
parent
263913f60b
commit
a051a54549
@ -69,8 +69,8 @@ class _HomePageState extends State<HomePage> {
|
||||
if (index >= events.length) {
|
||||
// print(events.length);
|
||||
if (!isLoading) {
|
||||
print('index: $index');
|
||||
print('length: ${events.length}');
|
||||
// print('index: $index');
|
||||
// print('length: ${events.length}');
|
||||
loadMore();
|
||||
}
|
||||
return Text('Loading...');
|
||||
|
@ -9,21 +9,20 @@ import '../components/event.dart';
|
||||
// import 'user.dart';
|
||||
import '../models/event.dart';
|
||||
|
||||
class IosHomeTab extends StatefulWidget {
|
||||
class HomeScreen extends StatefulWidget {
|
||||
@override
|
||||
createState() {
|
||||
return IosHomeTabState();
|
||||
return HomeScreenState();
|
||||
}
|
||||
}
|
||||
|
||||
class IosHomeTabState extends State<IosHomeTab> {
|
||||
class HomeScreenState extends State<HomeScreen> {
|
||||
int page = 1;
|
||||
List<Event> events = [];
|
||||
|
||||
loadFirst() async {
|
||||
events = await fetchEvents();
|
||||
print(events);
|
||||
page = 1;
|
||||
// print(events);
|
||||
return events;
|
||||
}
|
||||
|
||||
@ -58,7 +57,7 @@ class IosHomeTabState extends State<IosHomeTab> {
|
||||
// },
|
||||
// );
|
||||
widget = ListView.builder(itemBuilder: (context, index) {
|
||||
print(index);
|
||||
// print(index);
|
||||
try {
|
||||
return EventItem(events[index]);
|
||||
} catch (err) {
|
||||
|
@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
|
||||
import 'home.dart';
|
||||
import 'notification.dart';
|
||||
import 'profile.dart';
|
||||
import 'issue.dart';
|
||||
|
||||
class IosHomePage extends StatefulWidget {
|
||||
IosHomePage({Key key, this.title}) : super(key: key);
|
||||
@ -15,58 +14,44 @@ class IosHomePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _IosHomePageState extends State<IosHomePage> {
|
||||
// int _counter = 0;
|
||||
|
||||
// void _incrementCounter() {
|
||||
// setState(() {
|
||||
// _counter++;
|
||||
// });
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
return CupertinoPageScaffold(
|
||||
child: CupertinoTabScaffold(
|
||||
tabBar: CupertinoTabBar(
|
||||
items: <BottomNavigationBarItem>[
|
||||
items: [
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.home),
|
||||
icon: Icon(Icons.home),
|
||||
title: Text('Home'),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.conversation_bubble),
|
||||
icon: Icon(Icons.notifications),
|
||||
title: Text('Notification'),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.profile_circled),
|
||||
title: Text('Profile'),
|
||||
icon: Icon(Icons.search),
|
||||
title: Text('Search'),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.person),
|
||||
title: Text('Me'),
|
||||
),
|
||||
],
|
||||
),
|
||||
tabBuilder: (context, index) {
|
||||
return DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
// fontFamily: '.SF UI Text',
|
||||
// fontSize: 17.0,
|
||||
color: CupertinoColors.black,
|
||||
),
|
||||
child: CupertinoTabView(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoTabView(builder: (context) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return IosHomeTab();
|
||||
break;
|
||||
return HomeScreen();
|
||||
case 1:
|
||||
return IosNotificationTab();
|
||||
break;
|
||||
return NotificationScreen();
|
||||
case 2:
|
||||
return IosProfileTab();
|
||||
break;
|
||||
return ProfileScreen();
|
||||
case 3:
|
||||
return ProfileScreen();
|
||||
default:
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -1,11 +1,73 @@
|
||||
// import 'dart:async';
|
||||
// import 'dart:convert';
|
||||
// import '../utils.dart';
|
||||
import 'dart:async';
|
||||
import '../utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import '../models/notification.dart';
|
||||
|
||||
class NotificationScreen extends StatefulWidget {
|
||||
@override
|
||||
NotificationScreenState createState() => NotificationScreenState();
|
||||
}
|
||||
|
||||
class NotificationScreenState extends State<NotificationScreen> {
|
||||
int tabIndex = 0;
|
||||
bool loading = false;
|
||||
List<NotificationItem> items = [];
|
||||
|
||||
initState() {
|
||||
super.initState();
|
||||
initFetch();
|
||||
}
|
||||
|
||||
initFetch() async {
|
||||
items = await fetchNotifications('all');
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
super.dispose();
|
||||
print('dispose');
|
||||
}
|
||||
|
||||
_onChange(int value) async {
|
||||
setState(() {
|
||||
loading = true;
|
||||
tabIndex = value;
|
||||
});
|
||||
items = await fetchNotifications('all');
|
||||
setState(() {
|
||||
loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
class IosNotificationTab extends StatelessWidget {
|
||||
@override
|
||||
Widget build(context) {
|
||||
return Text('Notification');
|
||||
return SafeArea(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
CupertinoSegmentedControl(
|
||||
groupValue: tabIndex,
|
||||
onValueChanged: _onChange,
|
||||
children: {
|
||||
0: Text('Unread'),
|
||||
1: Text('Paticipating'),
|
||||
2: Text('All')
|
||||
},
|
||||
),
|
||||
Flexible(
|
||||
child: loading
|
||||
? CupertinoActivityIndicator()
|
||||
: ListView.builder(
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) => RichText(
|
||||
text: TextSpan(
|
||||
text: items[index].id,
|
||||
style: TextStyle(color: CupertinoColors.black)),
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// import '../utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class IosProfileTab extends StatelessWidget {
|
||||
class ProfileScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(context) {
|
||||
return Text('Profile');
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
// import 'dart:io';
|
||||
// import 'package:graphql_flutter/graphql_flutter.dart';
|
||||
import 'android/main.dart';
|
||||
// import 'android/main.dart';
|
||||
import 'ios/main.dart';
|
||||
// import 'token.dart';
|
||||
|
||||
@ -25,9 +26,10 @@ class App extends StatelessWidget {
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
home: isIos
|
||||
? IosHomePage(title: 'GitFlux')
|
||||
: AndroidHomePage(title: 'GitFlux'),
|
||||
home: DefaultTextStyle(
|
||||
style: TextStyle(color: CupertinoColors.black),
|
||||
child: IosHomePage(title: 'GitFlux'),
|
||||
),
|
||||
routes: {
|
||||
// '/notification': (context) => IosNotificationTab(),
|
||||
// '/profile': (context) => IosProfileTab(),
|
||||
|
54
lib/models/notification.dart
Normal file
54
lib/models/notification.dart
Normal file
@ -0,0 +1,54 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'notification.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class Subject {
|
||||
Subject(this.title, this.type);
|
||||
|
||||
String title;
|
||||
String type;
|
||||
|
||||
factory Subject.fromJson(Map<String, dynamic> json) =>
|
||||
_$SubjectFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$SubjectToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class Owner {
|
||||
Owner(this.login, this.avatarUrl);
|
||||
|
||||
String login;
|
||||
String avatarUrl;
|
||||
|
||||
factory Owner.fromJson(Map<String, dynamic> json) => _$OwnerFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$OwnerToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class Repository {
|
||||
Repository(this.fullName, this.type, this.onwer);
|
||||
|
||||
String fullName;
|
||||
String type;
|
||||
Owner onwer;
|
||||
|
||||
factory Repository.fromJson(Map<String, dynamic> json) =>
|
||||
_$RepositoryFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$RepositoryToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class NotificationItem {
|
||||
NotificationItem(this.id, this.type, this.actor, this.repository);
|
||||
|
||||
String id;
|
||||
String type;
|
||||
Subject actor;
|
||||
Repository repository;
|
||||
Map<String, dynamic> payload;
|
||||
|
||||
factory NotificationItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$NotificationItemFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$NotificationItemToJson(this);
|
||||
}
|
61
lib/models/notification.g.dart
Normal file
61
lib/models/notification.g.dart
Normal file
@ -0,0 +1,61 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'notification.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Subject _$SubjectFromJson(Map<String, dynamic> json) {
|
||||
return Subject(json['title'] as String, json['type'] as String);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$SubjectToJson(Subject instance) =>
|
||||
<String, dynamic>{'title': instance.title, 'type': instance.type};
|
||||
|
||||
Owner _$OwnerFromJson(Map<String, dynamic> json) {
|
||||
return Owner(json['login'] as String, json['avatar_url'] as String);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$OwnerToJson(Owner instance) => <String, dynamic>{
|
||||
'login': instance.login,
|
||||
'avatar_url': instance.avatarUrl
|
||||
};
|
||||
|
||||
Repository _$RepositoryFromJson(Map<String, dynamic> json) {
|
||||
return Repository(
|
||||
json['full_name'] as String,
|
||||
json['type'] as String,
|
||||
json['onwer'] == null
|
||||
? null
|
||||
: Owner.fromJson(json['onwer'] as Map<String, dynamic>));
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$RepositoryToJson(Repository instance) =>
|
||||
<String, dynamic>{
|
||||
'full_name': instance.fullName,
|
||||
'type': instance.type,
|
||||
'onwer': instance.onwer
|
||||
};
|
||||
|
||||
NotificationItem _$NotificationItemFromJson(Map<String, dynamic> json) {
|
||||
return NotificationItem(
|
||||
json['id'] as String,
|
||||
json['type'] as String,
|
||||
json['actor'] == null
|
||||
? null
|
||||
: Subject.fromJson(json['actor'] as Map<String, dynamic>),
|
||||
json['repository'] == null
|
||||
? null
|
||||
: Repository.fromJson(json['repository'] as Map<String, dynamic>))
|
||||
..payload = json['payload'] as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$NotificationItemToJson(NotificationItem instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'type': instance.type,
|
||||
'actor': instance.actor,
|
||||
'repository': instance.repository,
|
||||
'payload': instance.payload
|
||||
};
|
@ -5,29 +5,40 @@ import 'package:http/http.dart' as http;
|
||||
import 'token.dart';
|
||||
import 'models/event.dart';
|
||||
import 'models/user.dart';
|
||||
import 'models/notification.dart';
|
||||
|
||||
final prefix = 'https://api.github.com';
|
||||
|
||||
Future<List<Event>> fetchEvents([int page = 1]) async {
|
||||
Future<dynamic> getWithCredentials(String url) async {
|
||||
final res = await http.get(
|
||||
prefix + '/users/pd4d10/received_events/public?page=$page',
|
||||
prefix + url,
|
||||
headers: {HttpHeaders.authorizationHeader: 'token $token'},
|
||||
);
|
||||
final data = json.decode(res.body);
|
||||
// if (res.body.startsWith('{')) {
|
||||
// throw data['message'];
|
||||
// }
|
||||
return data;
|
||||
}
|
||||
|
||||
print(res.body);
|
||||
List<dynamic> data = json.decode(res.body);
|
||||
|
||||
return data.map((item) {
|
||||
Future<List<Event>> fetchEvents([int page = 1]) async {
|
||||
List data = await getWithCredentials(
|
||||
'/users/pd4d10/received_events/public?page=$page',
|
||||
);
|
||||
return data.map<Event>((item) {
|
||||
return Event.fromJson(item);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future<User> fetchUser(String login) async {
|
||||
final res = await http.get(
|
||||
prefix + '/users/$login',
|
||||
headers: {HttpHeaders.authorizationHeader: 'token $token'},
|
||||
);
|
||||
Map<String, dynamic> data = json.decode(res.body);
|
||||
|
||||
Map<String, dynamic> data = await getWithCredentials('/users/$login');
|
||||
return User.fromJson(data);
|
||||
}
|
||||
|
||||
Future<List<NotificationItem>> fetchNotifications(String type) async {
|
||||
List data = await getWithCredentials('/notifications?$type=true');
|
||||
print(data);
|
||||
return data
|
||||
.map<NotificationItem>((item) => NotificationItem.fromJson(item))
|
||||
.toList();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user