mirror of
https://github.com/git-touch/git-touch
synced 2025-02-20 13:30:38 +01:00
feat: add issue and pull request state
This commit is contained in:
parent
c0629c5739
commit
fb9fd4cb3a
@ -7,16 +7,84 @@ import '../widgets/list_group.dart';
|
||||
import '../widgets/link.dart';
|
||||
import '../utils/utils.dart';
|
||||
|
||||
Future<List<NotificationPayload>> fetchNotifications([int page = 1]) async {
|
||||
List items = await getWithCredentials('/notifications?page=$page&all=true');
|
||||
return items.map((item) => NotificationPayload.fromJson(item)).toList();
|
||||
String getRepoKey(NotificationGroup group) {
|
||||
return '_' + group.owner + '_' + group.name;
|
||||
}
|
||||
|
||||
String getItemKey(NotificationPayload item) {
|
||||
return '_' + item.number.toString();
|
||||
}
|
||||
|
||||
Future<Map<String, NotificationGroup>> fetchNotifications(
|
||||
[int page = 1]) async {
|
||||
List items = await getWithCredentials(
|
||||
'/notifications?page=$page&all=true&per_page=100');
|
||||
var ns = items.map((item) => NotificationPayload.fromJson(item)).toList();
|
||||
|
||||
Map<String, NotificationGroup> _groupMap = {};
|
||||
|
||||
ns.forEach((item) {
|
||||
String repo = item.owner + '/' + item.name;
|
||||
if (_groupMap[repo] == null) {
|
||||
_groupMap[repo] = NotificationGroup(item.owner, item.name);
|
||||
}
|
||||
|
||||
_groupMap[repo].items.add(item);
|
||||
});
|
||||
|
||||
var schema = '{';
|
||||
_groupMap.forEach((repo, group) {
|
||||
var repoKey = getRepoKey(group);
|
||||
schema +=
|
||||
'$repoKey: repository(owner: "${group.owner}", name: "${group.name}") {';
|
||||
|
||||
group.items.forEach((item) {
|
||||
var key = getItemKey(item);
|
||||
|
||||
switch (item.type) {
|
||||
case 'Issue':
|
||||
schema += '''
|
||||
$key: issue(number: ${item.number}) {
|
||||
state
|
||||
}
|
||||
''';
|
||||
break;
|
||||
case 'PullRequest':
|
||||
schema += '''
|
||||
$key: pullRequest(number: ${item.number}) {
|
||||
state
|
||||
}
|
||||
''';
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
schema += '}';
|
||||
});
|
||||
schema += '}';
|
||||
|
||||
// print(schema);
|
||||
var data = await query(schema);
|
||||
_groupMap.forEach((repo, group) {
|
||||
group.items.forEach((item) {
|
||||
var itemData = data[getRepoKey(group)][getItemKey(item)];
|
||||
if (itemData != null) {
|
||||
item.state = itemData['state'];
|
||||
}
|
||||
});
|
||||
});
|
||||
// print(data);
|
||||
|
||||
return _groupMap;
|
||||
}
|
||||
|
||||
class NotificationGroup {
|
||||
String repo;
|
||||
String owner;
|
||||
String name;
|
||||
get repo => owner + '/' + name;
|
||||
List<NotificationPayload> items = [];
|
||||
|
||||
NotificationGroup(this.repo);
|
||||
NotificationGroup(this.owner, this.name);
|
||||
}
|
||||
|
||||
class NotificationScreen extends StatefulWidget {
|
||||
@ -71,37 +139,16 @@ class NotificationScreenState extends State<NotificationScreen> {
|
||||
// loading = true;
|
||||
// });
|
||||
|
||||
var ns = await fetchNotifications();
|
||||
var _groupMap = await fetchNotifications();
|
||||
|
||||
// NotificationProvider.of(context).setCount(ns.length);
|
||||
|
||||
Map<String, NotificationGroup> _groupMap = {};
|
||||
ns.forEach((item) {
|
||||
String repo = item.owner + '/' + item.name;
|
||||
if (_groupMap[repo] == null) {
|
||||
_groupMap[repo] = NotificationGroup(repo);
|
||||
}
|
||||
|
||||
_groupMap[repo].items.add(item);
|
||||
});
|
||||
|
||||
setState(() {
|
||||
groupMap = _groupMap;
|
||||
// loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: filter
|
||||
// CupertinoSegmentedControl(
|
||||
// groupValue: active,
|
||||
// onValueChanged: (index) => _onSwitchTab(context, index),
|
||||
// children: {
|
||||
// 0: Text('Unread'),
|
||||
// 1: Text('Paticipating'),
|
||||
// 2: Text('All')
|
||||
// },
|
||||
// )
|
||||
|
||||
Future<void> _refresh() async {
|
||||
print('onrefresh');
|
||||
await _onSwitchTab(context, active);
|
||||
@ -113,9 +160,18 @@ class NotificationScreenState extends State<NotificationScreen> {
|
||||
title: Text('Notifications'),
|
||||
onRefresh: _refresh,
|
||||
bodyBuilder: () {
|
||||
var children = groupMap.entries
|
||||
.map((entry) => _buildGroupItem(entry.key, entry.value))
|
||||
.toList();
|
||||
List<Widget> children = [];
|
||||
children.add(CupertinoSegmentedControl(
|
||||
groupValue: active,
|
||||
onValueChanged: (index) => _onSwitchTab(context, index),
|
||||
children: {
|
||||
0: Text('Unread'),
|
||||
1: Text('Paticipating'),
|
||||
2: Text('All')
|
||||
},
|
||||
));
|
||||
children.addAll(groupMap.entries
|
||||
.map((entry) => _buildGroupItem(entry.key, entry.value)));
|
||||
|
||||
return Column(children: children);
|
||||
},
|
||||
|
@ -86,12 +86,12 @@ class _PullRequestScreenState extends State<PullRequestScreen> {
|
||||
|
||||
Widget _buildBadge() {
|
||||
bool merged = payload['merged'];
|
||||
int bgColor = merged ? Palette.purple : Palette.green;
|
||||
Color bgColor = merged ? Palette.purple : Palette.green;
|
||||
IconData iconData = merged ? Octicons.git_merge : Octicons.git_pull_request;
|
||||
String text = merged ? 'Merged' : 'Open';
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(bgColor),
|
||||
color: bgColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(4)),
|
||||
),
|
||||
padding: EdgeInsets.all(6),
|
||||
|
@ -138,10 +138,10 @@ TextSpan createRepoLinkSpan(BuildContext context, String owner, String name) {
|
||||
}
|
||||
|
||||
class Palette {
|
||||
static const green = 0xff2cbe4e;
|
||||
static const purple = 0xff6f42c1;
|
||||
static const red = 0xffcb2431;
|
||||
static const gray = 0xff959da5;
|
||||
static const green = Color(0xff2cbe4e);
|
||||
static const purple = Color(0xff6f42c1);
|
||||
static const red = Color(0xffcb2431);
|
||||
static const gray = Color(0xff959da5);
|
||||
}
|
||||
|
||||
final pageSize = 20;
|
||||
|
@ -15,6 +15,8 @@ class NotificationPayload {
|
||||
String updateAt;
|
||||
bool unread;
|
||||
|
||||
String state;
|
||||
|
||||
NotificationPayload.fromJson(input) {
|
||||
id = input['id'];
|
||||
type = input['subject']['type'];
|
||||
@ -55,22 +57,47 @@ class _NotificationItemState extends State<NotificationItem> {
|
||||
return IssueScreen(payload.number, payload.owner, payload.name);
|
||||
case 'PullRequest':
|
||||
return PullRequestScreen(payload.number, payload.owner, payload.name);
|
||||
case 'Release':
|
||||
// return
|
||||
default:
|
||||
// throw new Exception('Unhandled notification type: $type');
|
||||
return Text('test');
|
||||
}
|
||||
}
|
||||
|
||||
IconData _buildIconData() {
|
||||
Widget _buildIcon(IconData data, [Color color = Colors.black54]) {
|
||||
return Icon(data, color: color, size: 20);
|
||||
}
|
||||
|
||||
Widget _buildIconData() {
|
||||
switch (payload.type) {
|
||||
case 'Issue':
|
||||
return Octicons.issue_opened;
|
||||
// color: Color.fromRGBO(0x28, 0xa7, 0x45, 1),
|
||||
switch (payload.state) {
|
||||
case 'OPEN':
|
||||
return _buildIcon(Octicons.issue_opened, Palette.green);
|
||||
case 'CLOSED':
|
||||
return _buildIcon(Octicons.issue_closed, Palette.red);
|
||||
default:
|
||||
return _buildIcon(Octicons.person);
|
||||
}
|
||||
break;
|
||||
case 'PullRequest':
|
||||
return Octicons.git_pull_request;
|
||||
switch (payload.state) {
|
||||
case 'OPEN':
|
||||
return _buildIcon(Octicons.git_pull_request, Palette.green);
|
||||
case 'CLOSED':
|
||||
return _buildIcon(Octicons.git_pull_request, Palette.red);
|
||||
case 'MERGED':
|
||||
return _buildIcon(Octicons.git_merge, Palette.purple);
|
||||
default:
|
||||
return _buildIcon(Octicons.person);
|
||||
}
|
||||
break;
|
||||
// color: Color.fromRGBO(0x6f, 0x42, 0xc1, 1),
|
||||
case 'Release':
|
||||
return _buildIcon(Octicons.tag);
|
||||
default:
|
||||
return Octicons.person;
|
||||
return _buildIcon(Octicons.person);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +125,7 @@ class _NotificationItemState extends State<NotificationItem> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(right: 8),
|
||||
child: Icon(_buildIconData(), color: Colors.black45, size: 20),
|
||||
child: _buildIconData(),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
|
@ -5,11 +5,11 @@ import '../providers/settings.dart';
|
||||
import 'loading.dart';
|
||||
|
||||
typedef RefreshCallback = Future<void> Function();
|
||||
typedef BodyBuilder = Widget Function();
|
||||
typedef WidgetBuilder = Widget Function();
|
||||
|
||||
class RefreshScaffold extends StatefulWidget {
|
||||
final Widget title;
|
||||
final BodyBuilder bodyBuilder;
|
||||
final WidgetBuilder bodyBuilder;
|
||||
final RefreshCallback onRefresh;
|
||||
|
||||
RefreshScaffold({
|
||||
|
@ -24,13 +24,13 @@ class TimelineItem extends StatelessWidget {
|
||||
Widget _buildItem({
|
||||
String actor,
|
||||
IconData iconData = Octicons.octoface,
|
||||
int iconColor = Palette.gray,
|
||||
Color iconColor = Palette.gray,
|
||||
TextSpan textSpan,
|
||||
item,
|
||||
}) {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
Icon(iconData, color: Color(iconColor), size: 16),
|
||||
Icon(iconData, color: iconColor, size: 16),
|
||||
Padding(padding: EdgeInsets.only(left: 4)),
|
||||
Expanded(
|
||||
child: RichText(
|
||||
@ -198,7 +198,7 @@ class TimelineItem extends StatelessWidget {
|
||||
case 'PullRequestReview':
|
||||
return _buildItem(
|
||||
actor: item['author']['login'],
|
||||
iconColor: 0xff28a745,
|
||||
iconColor: Color(0xff28a745),
|
||||
iconData: Octicons.check,
|
||||
textSpan: _buildReviewText(context, item),
|
||||
item: item,
|
||||
@ -207,7 +207,7 @@ class TimelineItem extends StatelessWidget {
|
||||
return _buildItem(
|
||||
actor: item['actor']['login'],
|
||||
iconData: Octicons.git_merge,
|
||||
iconColor: 0xff6f42c1,
|
||||
iconColor: Color(0xff6f42c1),
|
||||
textSpan: TextSpan(children: [
|
||||
TextSpan(text: ' merged commit '),
|
||||
TextSpan(text: item['commit']['oid'].substring(0, 8)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user