2018-07-05 16:08:19 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2019-02-02 17:28:51 +01:00
|
|
|
import 'package:flutter/cupertino.dart';
|
2019-09-23 12:28:33 +02:00
|
|
|
import 'package:git_touch/screens/repository.dart';
|
2019-08-31 15:37:29 +02:00
|
|
|
import 'package:timeago/timeago.dart' as timeago;
|
2019-05-12 09:14:28 +02:00
|
|
|
import 'package:primer/primer.dart';
|
2019-02-07 07:35:19 +01:00
|
|
|
import '../screens/issue.dart';
|
|
|
|
import '../screens/user.dart';
|
|
|
|
import 'avatar.dart';
|
2019-03-13 15:51:48 +01:00
|
|
|
import '../widgets/link.dart';
|
2019-02-07 12:17:29 +01:00
|
|
|
import '../utils/utils.dart';
|
2018-07-05 16:08:19 +02:00
|
|
|
|
2019-02-10 05:54:48 +01:00
|
|
|
class EventPayload {
|
|
|
|
String actorLogin;
|
|
|
|
String actorAvatarUrl;
|
|
|
|
String type;
|
|
|
|
String repoFullName;
|
|
|
|
Map<String, dynamic> payload;
|
2019-08-31 15:37:29 +02:00
|
|
|
DateTime createdAt;
|
2019-02-10 05:54:48 +01:00
|
|
|
|
|
|
|
EventPayload.fromJson(input) {
|
|
|
|
actorLogin = input['actor']['login'];
|
|
|
|
actorAvatarUrl = input['actor']['avatar_url'];
|
|
|
|
type = input['type'];
|
|
|
|
payload = input['payload'];
|
|
|
|
repoFullName = input['repo']['name'];
|
2019-08-31 15:37:29 +02:00
|
|
|
createdAt = DateTime.parse(input['created_at']);
|
2019-02-10 05:54:48 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-05 16:08:19 +02:00
|
|
|
class EventItem extends StatelessWidget {
|
2019-02-10 05:54:48 +01:00
|
|
|
final EventPayload event;
|
2019-02-09 06:29:44 +01:00
|
|
|
|
2018-07-05 16:08:19 +02:00
|
|
|
EventItem(this.event);
|
|
|
|
|
2019-01-26 15:10:18 +01:00
|
|
|
TextSpan _buildRepo(BuildContext context) {
|
2019-02-10 05:54:48 +01:00
|
|
|
String name = event.repoFullName;
|
2019-01-27 17:37:44 +01:00
|
|
|
var arr = name.split('/');
|
2019-01-29 12:41:24 +01:00
|
|
|
return createRepoLinkSpan(context, arr[0], arr[1]);
|
2019-01-26 15:10:18 +01:00
|
|
|
}
|
2018-07-05 16:08:19 +02:00
|
|
|
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan _buildIssue(BuildContext context,
|
|
|
|
{@required int number, bool isPullRequest = false}) {
|
|
|
|
// var resource = isPullRequest ? 'pull_request' : 'issue';
|
|
|
|
// int number = event.payload['issue']['number'];
|
2018-07-05 16:08:19 +02:00
|
|
|
|
2019-09-23 14:33:27 +02:00
|
|
|
return createLinkSpan(
|
|
|
|
context,
|
|
|
|
'#' + number.toString(),
|
|
|
|
(_) => IssueScreen.fromFullName(
|
2019-02-19 08:25:15 +01:00
|
|
|
number: number,
|
|
|
|
fullName: event.repoFullName,
|
|
|
|
isPullRequest: isPullRequest,
|
2019-09-23 14:33:27 +02:00
|
|
|
),
|
|
|
|
);
|
2019-01-26 15:10:18 +01:00
|
|
|
}
|
|
|
|
|
2019-02-07 10:19:08 +01:00
|
|
|
Widget _buildItem({
|
|
|
|
@required BuildContext context,
|
2019-09-25 07:34:13 +02:00
|
|
|
@required List<InlineSpan> spans,
|
2019-02-07 10:19:08 +01:00
|
|
|
String detail,
|
2019-03-13 15:51:48 +01:00
|
|
|
Widget detailWidget,
|
2019-02-07 10:19:08 +01:00
|
|
|
IconData iconData = Octicons.octoface,
|
2019-02-10 12:32:30 +01:00
|
|
|
WidgetBuilder screenBuilder,
|
2019-09-08 14:33:04 +02:00
|
|
|
String url,
|
2019-02-07 10:19:08 +01:00
|
|
|
}) {
|
2019-09-07 11:08:24 +02:00
|
|
|
if (detailWidget == null && detail != null) {
|
|
|
|
detailWidget =
|
|
|
|
Text(detail.trim(), overflow: TextOverflow.ellipsis, maxLines: 5);
|
2019-08-31 15:37:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return Link(
|
|
|
|
screenBuilder: screenBuilder,
|
2019-09-08 14:33:04 +02:00
|
|
|
url: url,
|
2019-08-31 15:37:29 +02:00
|
|
|
child: Container(
|
2019-10-02 10:09:54 +02:00
|
|
|
padding: CommonStyle.padding,
|
2019-08-31 15:37:29 +02:00
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: <Widget>[
|
|
|
|
Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: <Widget>[
|
2019-10-02 09:23:33 +02:00
|
|
|
Avatar.medium(
|
2019-09-07 11:08:24 +02:00
|
|
|
url: event.actorAvatarUrl,
|
|
|
|
login: event.actorLogin,
|
|
|
|
),
|
|
|
|
SizedBox(width: 10),
|
2019-08-31 15:37:29 +02:00
|
|
|
Expanded(
|
2019-09-07 11:08:24 +02:00
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
2019-09-08 14:33:04 +02:00
|
|
|
children: join(SizedBox(height: 8), [
|
2019-09-07 11:08:24 +02:00
|
|
|
RichText(
|
|
|
|
text: TextSpan(
|
|
|
|
style: TextStyle(
|
2019-09-13 09:55:58 +02:00
|
|
|
fontSize: 16,
|
|
|
|
color: PrimerColors.gray900,
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
),
|
2019-09-07 11:08:24 +02:00
|
|
|
children: [
|
|
|
|
createLinkSpan(
|
|
|
|
context,
|
|
|
|
event.actorLogin,
|
2019-09-23 14:33:27 +02:00
|
|
|
(_) => UserScreen(event.actorLogin),
|
2019-09-07 11:08:24 +02:00
|
|
|
),
|
|
|
|
...spans,
|
|
|
|
],
|
2019-08-31 15:37:29 +02:00
|
|
|
),
|
2019-09-07 11:08:24 +02:00
|
|
|
),
|
2019-09-12 10:30:35 +02:00
|
|
|
if (detailWidget != null)
|
|
|
|
DefaultTextStyle(
|
|
|
|
style: TextStyle(
|
2019-09-13 09:55:58 +02:00
|
|
|
color: PrimerColors.gray900, fontSize: 14),
|
2019-09-12 10:30:35 +02:00
|
|
|
child: detailWidget,
|
|
|
|
),
|
2019-09-07 11:08:24 +02:00
|
|
|
Row(
|
2019-09-13 09:55:58 +02:00
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
2019-09-07 11:08:24 +02:00
|
|
|
children: <Widget>[
|
2019-09-13 09:55:58 +02:00
|
|
|
Icon(iconData, color: PrimerColors.gray500, size: 14),
|
2019-09-07 11:08:24 +02:00
|
|
|
SizedBox(width: 4),
|
|
|
|
Text(timeago.format(event.createdAt),
|
|
|
|
style: TextStyle(
|
2019-09-13 09:55:58 +02:00
|
|
|
fontSize: 13,
|
|
|
|
color: PrimerColors.gray500,
|
|
|
|
))
|
2019-09-07 11:08:24 +02:00
|
|
|
],
|
|
|
|
),
|
|
|
|
]),
|
2019-01-26 15:10:18 +01:00
|
|
|
),
|
2019-01-31 07:37:25 +01:00
|
|
|
),
|
2019-08-31 15:37:29 +02:00
|
|
|
],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
2018-07-05 16:08:19 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2019-02-07 10:19:08 +01:00
|
|
|
|
|
|
|
@override
|
|
|
|
build(BuildContext context) {
|
2019-02-07 10:39:27 +01:00
|
|
|
var defaultItem = _buildItem(
|
|
|
|
context: context,
|
2019-02-10 05:54:48 +01:00
|
|
|
spans: [
|
|
|
|
TextSpan(
|
|
|
|
text: ' ' + event.type,
|
2019-09-13 09:55:58 +02:00
|
|
|
style: TextStyle(color: PrimerColors.blue500),
|
2019-02-10 05:54:48 +01:00
|
|
|
)
|
|
|
|
],
|
2019-02-07 10:39:27 +01:00
|
|
|
iconData: Octicons.octoface,
|
|
|
|
detail: 'Woops, ${event.type} not implemented yet',
|
|
|
|
);
|
|
|
|
|
|
|
|
// all events types here:
|
|
|
|
// https://developer.github.com/v3/activity/events/types/#event-types--payloads
|
2019-02-07 10:19:08 +01:00
|
|
|
switch (event.type) {
|
2019-02-07 10:39:27 +01:00
|
|
|
case 'CheckRunEvent':
|
|
|
|
case 'CheckSuiteEvent':
|
|
|
|
case 'CommitCommentEvent':
|
|
|
|
case 'ContentReferenceEvent':
|
|
|
|
case 'CreateEvent':
|
|
|
|
case 'DeleteEvent':
|
|
|
|
case 'DeploymentEvent':
|
|
|
|
case 'DeploymentStatusEvent':
|
|
|
|
case 'DownloadEvent':
|
|
|
|
case 'FollowEvent':
|
|
|
|
// TODO:
|
|
|
|
return defaultItem;
|
|
|
|
case 'ForkEvent':
|
2019-02-07 10:19:08 +01:00
|
|
|
return _buildItem(
|
|
|
|
context: context,
|
|
|
|
spans: [
|
2019-02-07 10:39:27 +01:00
|
|
|
TextSpan(text: ' forked '),
|
|
|
|
createRepoLinkSpan(
|
|
|
|
context,
|
|
|
|
event.payload['forkee']['owner']['login'],
|
|
|
|
event.payload['forkee']['name']),
|
|
|
|
TextSpan(text: ' from '),
|
|
|
|
_buildRepo(context),
|
|
|
|
],
|
|
|
|
iconData: Octicons.repo_forked,
|
2019-09-23 12:28:33 +02:00
|
|
|
screenBuilder: (_) => RepositoryScreen(
|
2019-09-08 14:33:04 +02:00
|
|
|
event.payload['forkee']['owner']['login'],
|
|
|
|
event.payload['forkee']['name']),
|
2019-02-07 10:39:27 +01:00
|
|
|
);
|
|
|
|
case 'ForkApplyEvent':
|
|
|
|
case 'GitHubAppAuthorizationEvent':
|
|
|
|
case 'GistEvent':
|
|
|
|
case 'GollumEvent':
|
|
|
|
case 'InstallationEvent':
|
|
|
|
case 'InstallationRepositoriesEvent':
|
|
|
|
// TODO:
|
|
|
|
return defaultItem;
|
|
|
|
case 'IssueCommentEvent':
|
2019-02-19 08:25:15 +01:00
|
|
|
bool isPullRequest = event.payload['issue']['pull_request'] != null;
|
|
|
|
String resource = isPullRequest ? 'pull request' : 'issue';
|
|
|
|
int number = event.payload['issue']['number'];
|
2019-02-07 10:39:27 +01:00
|
|
|
|
|
|
|
return _buildItem(
|
|
|
|
context: context,
|
|
|
|
spans: [
|
|
|
|
TextSpan(text: ' commented on $resource '),
|
2019-02-19 08:25:15 +01:00
|
|
|
_buildIssue(
|
|
|
|
context,
|
|
|
|
number: number,
|
|
|
|
isPullRequest: isPullRequest,
|
|
|
|
),
|
2019-02-07 10:19:08 +01:00
|
|
|
TextSpan(text: ' at '),
|
|
|
|
_buildRepo(context),
|
2019-02-07 10:39:27 +01:00
|
|
|
// TextSpan(text: event.payload['comment']['body'])
|
2019-02-07 10:19:08 +01:00
|
|
|
],
|
2019-02-07 10:39:27 +01:00
|
|
|
detail: event.payload['comment']['body'],
|
|
|
|
iconData: Octicons.comment_discussion,
|
2019-02-10 12:32:30 +01:00
|
|
|
screenBuilder: (_) => IssueScreen.fromFullName(
|
2019-07-28 15:59:18 +02:00
|
|
|
number: number,
|
|
|
|
fullName: event.repoFullName,
|
|
|
|
isPullRequest: isPullRequest,
|
|
|
|
),
|
2019-02-07 10:19:08 +01:00
|
|
|
);
|
2019-02-07 10:39:27 +01:00
|
|
|
case 'IssuesEvent':
|
2019-02-19 08:25:15 +01:00
|
|
|
int number = event.payload['issue']['number'];
|
|
|
|
|
2019-02-07 10:19:08 +01:00
|
|
|
return _buildItem(
|
|
|
|
context: context,
|
|
|
|
spans: [
|
2019-02-07 10:39:27 +01:00
|
|
|
TextSpan(text: ' ${event.payload['action']} issue '),
|
2019-02-19 08:25:15 +01:00
|
|
|
_buildIssue(context, number: number),
|
2019-02-07 10:19:08 +01:00
|
|
|
TextSpan(text: ' at '),
|
|
|
|
_buildRepo(context),
|
|
|
|
],
|
2019-02-07 10:39:27 +01:00
|
|
|
iconData: Octicons.issue_opened,
|
|
|
|
detail: event.payload['issue']['title'],
|
2019-02-10 12:32:30 +01:00
|
|
|
screenBuilder: (_) => IssueScreen.fromFullName(
|
2019-07-28 15:59:18 +02:00
|
|
|
number: number,
|
|
|
|
fullName: event.repoFullName,
|
|
|
|
),
|
2019-02-07 10:19:08 +01:00
|
|
|
);
|
2019-02-07 10:39:27 +01:00
|
|
|
case 'LabelEvent':
|
|
|
|
case 'MarketplacePurchaseEvent':
|
|
|
|
case 'MemberEvent':
|
|
|
|
case 'MembershipEvent':
|
|
|
|
case 'MilestoneEvent':
|
|
|
|
case 'OrganizationEvent':
|
|
|
|
case 'OrgBlockEvent':
|
|
|
|
case 'PageBuildEvent':
|
|
|
|
case 'ProjectCardEvent':
|
|
|
|
case 'ProjectColumnEvent':
|
|
|
|
case 'ProjectEvent':
|
|
|
|
case 'PublicEvent':
|
|
|
|
// TODO:
|
|
|
|
return defaultItem;
|
2019-02-07 10:19:08 +01:00
|
|
|
case 'PullRequestEvent':
|
|
|
|
return _buildItem(
|
|
|
|
context: context,
|
|
|
|
spans: [
|
|
|
|
TextSpan(text: ' ${event.payload['action']} pull request '),
|
2019-02-19 08:25:15 +01:00
|
|
|
_buildIssue(context,
|
|
|
|
number: event.payload['number'], isPullRequest: true),
|
2019-02-07 10:19:08 +01:00
|
|
|
TextSpan(text: ' at '),
|
|
|
|
_buildRepo(context),
|
|
|
|
],
|
|
|
|
iconData: Octicons.git_pull_request,
|
|
|
|
detail: event.payload['pull_request']['title'],
|
2019-02-19 08:25:15 +01:00
|
|
|
screenBuilder: (_) => IssueScreen.fromFullName(
|
2019-07-28 15:59:18 +02:00
|
|
|
number: event.payload['pull_request']['number'],
|
|
|
|
fullName: event.repoFullName,
|
|
|
|
isPullRequest: true,
|
|
|
|
),
|
2019-02-07 10:19:08 +01:00
|
|
|
);
|
2019-02-07 10:39:27 +01:00
|
|
|
case 'PullRequestReviewEvent':
|
|
|
|
// TODO:
|
|
|
|
return defaultItem;
|
2019-02-07 10:19:08 +01:00
|
|
|
case 'PullRequestReviewCommentEvent':
|
|
|
|
return _buildItem(
|
|
|
|
context: context,
|
|
|
|
spans: [
|
|
|
|
TextSpan(text: ' reviewed pull request '),
|
2019-02-19 08:25:15 +01:00
|
|
|
_buildIssue(context,
|
|
|
|
number: event.payload['pull_request']['number'],
|
|
|
|
isPullRequest: true),
|
2019-02-07 10:19:08 +01:00
|
|
|
TextSpan(text: ' at '),
|
|
|
|
_buildRepo(context),
|
|
|
|
],
|
|
|
|
detail: event.payload['comment']['body'],
|
2019-02-19 08:25:15 +01:00
|
|
|
screenBuilder: (_) => IssueScreen.fromFullName(
|
2019-07-28 15:59:18 +02:00
|
|
|
number: event.payload['pull_request']['number'],
|
|
|
|
fullName: event.repoFullName,
|
|
|
|
isPullRequest: true,
|
|
|
|
),
|
2019-02-07 10:19:08 +01:00
|
|
|
);
|
2019-02-07 10:39:27 +01:00
|
|
|
case 'PushEvent':
|
2019-09-25 07:34:13 +02:00
|
|
|
var ref = event.payload['ref'] as String;
|
|
|
|
var commits = event.payload['commits'] as List;
|
2019-03-13 15:51:48 +01:00
|
|
|
|
2019-02-07 10:19:08 +01:00
|
|
|
return _buildItem(
|
|
|
|
context: context,
|
|
|
|
spans: [
|
2019-08-31 15:37:29 +02:00
|
|
|
TextSpan(text: ' pushed to '),
|
2019-09-25 07:34:13 +02:00
|
|
|
WidgetSpan(
|
|
|
|
child: PrimerBranchName(ref.replaceFirst('refs/heads/', '')),
|
2019-02-07 10:39:27 +01:00
|
|
|
),
|
2019-02-07 10:19:08 +01:00
|
|
|
TextSpan(text: ' at '),
|
2019-08-31 15:37:29 +02:00
|
|
|
_buildRepo(context)
|
2019-02-07 10:19:08 +01:00
|
|
|
],
|
2019-02-07 10:39:27 +01:00
|
|
|
iconData: Octicons.repo_push,
|
2019-09-08 14:33:04 +02:00
|
|
|
detailWidget: Column(
|
|
|
|
children: commits.map((commit) {
|
2019-09-13 09:55:58 +02:00
|
|
|
return Row(
|
|
|
|
children: <Widget>[
|
|
|
|
Text(
|
|
|
|
(commit['sha'] as String).substring(0, 7),
|
|
|
|
style: TextStyle(
|
|
|
|
color: PrimerColors.blue500,
|
|
|
|
fontSize: 13,
|
2019-10-02 10:09:54 +02:00
|
|
|
fontFamily: CommonStyle.monospace,
|
2019-09-13 09:55:58 +02:00
|
|
|
),
|
2019-08-31 15:37:29 +02:00
|
|
|
),
|
2019-09-13 09:55:58 +02:00
|
|
|
SizedBox(width: 6),
|
|
|
|
Expanded(
|
|
|
|
child: Text(
|
|
|
|
commit['message'],
|
|
|
|
overflow: TextOverflow.ellipsis,
|
|
|
|
maxLines: 1,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
);
|
2019-09-08 14:33:04 +02:00
|
|
|
}).toList(),
|
2019-03-13 15:51:48 +01:00
|
|
|
),
|
2019-09-08 14:33:04 +02:00
|
|
|
url: 'https://github.com/' +
|
|
|
|
event.repoFullName +
|
|
|
|
'/compare/' +
|
|
|
|
event.payload['before'] +
|
|
|
|
'...' +
|
|
|
|
event.payload['head'],
|
2019-02-07 10:19:08 +01:00
|
|
|
);
|
2019-02-07 10:39:27 +01:00
|
|
|
case 'ReleaseEvent':
|
|
|
|
case 'RepositoryEvent':
|
|
|
|
case 'RepositoryImportEvent':
|
|
|
|
case 'RepositoryVulnerabilityAlertEvent':
|
|
|
|
case 'SecurityAdvisoryEvent':
|
|
|
|
case 'StatusEvent':
|
|
|
|
case 'TeamEvent':
|
|
|
|
case 'TeamAddEvent':
|
|
|
|
// TODO:
|
|
|
|
return defaultItem;
|
|
|
|
case 'WatchEvent':
|
2019-02-07 10:19:08 +01:00
|
|
|
return _buildItem(
|
|
|
|
context: context,
|
2019-03-13 15:14:30 +01:00
|
|
|
spans: [TextSpan(text: ' starred '), _buildRepo(context)],
|
2019-02-07 10:39:27 +01:00
|
|
|
iconData: Octicons.star,
|
2019-09-23 12:28:33 +02:00
|
|
|
screenBuilder: (_) =>
|
|
|
|
RepositoryScreen.fromFullName(event.repoFullName),
|
2019-02-07 10:19:08 +01:00
|
|
|
);
|
|
|
|
default:
|
2019-02-07 10:39:27 +01:00
|
|
|
return defaultItem;
|
2019-02-07 10:19:08 +01:00
|
|
|
}
|
|
|
|
}
|
2018-07-05 16:08:19 +02:00
|
|
|
}
|