git-touch-android-ios-app/lib/widgets/notification_item.dart

189 lines
4.9 KiB
Dart
Raw Normal View History

2019-02-06 06:06:11 +01:00
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
2019-08-31 14:44:59 +02:00
import 'package:timeago/timeago.dart' as timeago;
2019-05-12 09:14:28 +02:00
import 'package:primer/primer.dart';
2019-03-19 13:46:06 +01:00
import 'package:url_launcher/url_launcher.dart';
2019-01-31 07:37:25 +01:00
import '../utils/utils.dart';
2019-02-05 13:57:05 +01:00
import '../screens/issue.dart';
2019-03-19 13:46:06 +01:00
// import '../screens/not_found.dart';
2019-02-07 07:35:19 +01:00
import '../providers/settings.dart';
2019-01-31 07:37:25 +01:00
import 'link.dart';
2019-01-30 07:46:18 +01:00
2019-02-05 13:57:05 +01:00
class NotificationPayload {
2019-02-06 06:06:11 +01:00
String id;
2019-02-05 13:57:05 +01:00
String type;
String owner;
String name;
int number;
String title;
String updateAt;
bool unread;
2019-02-06 12:14:11 +01:00
String state;
2019-02-05 13:57:05 +01:00
NotificationPayload.fromJson(input) {
2019-02-06 06:06:11 +01:00
id = input['id'];
2019-02-05 13:57:05 +01:00
type = input['subject']['type'];
name = input['repository']['name'];
owner = input['repository']['owner']['login'];
String url = input['subject']['url'];
if (type == 'Issue' || type == 'PullRequest') {
String numberStr = url.split('/').lastWhere((_) => true);
number = int.parse(numberStr);
2019-03-19 13:46:06 +01:00
} else {
// print(input);
}
2019-02-05 13:57:05 +01:00
title = input['subject']['title'];
2019-08-31 14:44:59 +02:00
updateAt = timeago.format(DateTime.parse(input['updated_at']));
2019-02-05 13:57:05 +01:00
unread = input['unread'];
}
}
2019-02-06 06:06:11 +01:00
class NotificationItem extends StatefulWidget {
final NotificationPayload payload;
final Function markAsRead;
NotificationItem({
2019-01-30 07:46:18 +01:00
Key key,
2019-02-05 13:57:05 +01:00
@required this.payload,
2019-02-06 06:06:11 +01:00
@required this.markAsRead,
2019-01-30 07:46:18 +01:00
}) : super(key: key);
2019-02-06 06:06:11 +01:00
@override
_NotificationItemState createState() => _NotificationItemState();
}
class _NotificationItemState extends State<NotificationItem> {
NotificationPayload get payload => widget.payload;
bool loading = false;
2019-01-30 07:46:18 +01:00
2019-02-06 12:14:11 +01:00
Widget _buildIcon(IconData data, [Color color = Colors.black54]) {
return Icon(data, color: color, size: 20);
}
Widget _buildIconData() {
2019-02-05 13:57:05 +01:00
switch (payload.type) {
2019-01-30 07:46:18 +01:00
case 'Issue':
2019-02-06 12:14:11 +01:00
switch (payload.state) {
case 'OPEN':
return _buildIcon(Octicons.issue_opened, Palette.green);
case 'CLOSED':
2019-05-12 09:14:28 +02:00
return _buildIcon(Octicons.issue_closed, PrimerColors.red600);
2019-02-06 12:14:11 +01:00
default:
return _buildIcon(Octicons.person);
}
break;
2019-01-30 07:46:18 +01:00
case 'PullRequest':
2019-02-06 12:14:11 +01:00
switch (payload.state) {
case 'OPEN':
return _buildIcon(Octicons.git_pull_request, Palette.green);
case 'CLOSED':
2019-05-12 09:14:28 +02:00
return _buildIcon(Octicons.git_pull_request, PrimerColors.red600);
2019-02-06 12:14:11 +01:00
case 'MERGED':
2019-05-12 09:14:28 +02:00
return _buildIcon(Octicons.git_merge, PrimerColors.purple500);
2019-02-06 12:14:11 +01:00
default:
return _buildIcon(Octicons.person);
}
break;
2019-01-30 07:46:18 +01:00
// color: Color.fromRGBO(0x6f, 0x42, 0xc1, 1),
2019-02-06 12:14:11 +01:00
case 'Release':
return _buildIcon(Octicons.tag);
case 'Commit':
return _buildIcon(Octicons.git_commit);
2019-01-30 07:46:18 +01:00
default:
print('Unhandled notification type: ${payload.type}');
return _buildIcon(Octicons.octoface);
2019-01-30 07:46:18 +01:00
}
}
2019-02-06 06:06:11 +01:00
Widget _buildCheckIcon() {
return Icon(
payload.unread ? Octicons.check : Octicons.primitive_dot,
color: loading ? Colors.black12 : Colors.black45,
2019-02-10 12:45:08 +01:00
size: 24,
2019-02-06 06:06:11 +01:00
);
}
2019-02-06 14:35:52 +01:00
void _markAsRead() async {
if (payload.unread && !loading) {
setState(() {
loading = true;
});
try {
2019-02-07 07:35:19 +01:00
await SettingsProvider.of(context)
.patchWithCredentials('/notifications/threads/' + payload.id);
2019-02-06 14:35:52 +01:00
widget.markAsRead();
} finally {
if (mounted) {
setState(() {
loading = false;
});
}
}
}
}
2019-01-30 07:46:18 +01:00
@override
Widget build(BuildContext context) {
2019-03-19 13:46:06 +01:00
WidgetBuilder screenBuilder;
Function onTap;
switch (payload.type) {
case 'Issue':
case 'PullRequest':
screenBuilder = (_) => IssueScreen(
number: payload.number,
owner: payload.owner,
name: payload.name,
isPullRequest: payload.type == 'PullRequest',
);
break;
case 'Release':
onTap = () {
launch(
'https://github.com/${payload.owner}/${payload.name}/releases/tag/${payload.title}');
};
break;
case 'Commit':
// TODO:
// onTap = () {
// launch('urlString');
// };
break;
}
2019-01-31 07:37:25 +01:00
return Link(
2019-03-19 13:46:06 +01:00
screenBuilder: screenBuilder,
onTap: () {
_markAsRead();
if (onTap != null) onTap();
},
2019-02-06 06:06:11 +01:00
child: Opacity(
opacity: payload.unread ? 1 : 0.5,
child: Container(
padding: EdgeInsets.all(8),
child: Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(right: 8),
2019-02-06 12:14:11 +01:00
child: _buildIconData(),
2019-02-06 06:06:11 +01:00
),
Expanded(
child: Text(
payload.title,
overflow: TextOverflow.ellipsis,
2019-02-10 12:45:08 +01:00
style: TextStyle(fontSize: 15),
),
2019-02-06 06:06:11 +01:00
),
Link(child: _buildCheckIcon(), onTap: _markAsRead),
2019-02-06 06:06:11 +01:00
],
),
2019-02-05 13:57:05 +01:00
),
2019-01-30 07:46:18 +01:00
),
);
}
}