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

343 lines
11 KiB
Dart
Raw Normal View History

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';
import 'package:url_launcher/url_launcher.dart';
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';
import '../widgets/link.dart';
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;
EventPayload.fromJson(input) {
actorLogin = input['actor']['login'];
actorAvatarUrl = input['actor']['avatar_url'];
type = input['type'];
payload = input['payload'];
repoFullName = input['repo']['name'];
}
}
2018-07-05 16:08:19 +02:00
class EventItem extends StatelessWidget {
2019-02-10 05:54:48 +01:00
final EventPayload event;
2018-07-05 16:08:19 +02:00
EventItem(this.event);
TextSpan _buildRepo(BuildContext context) {
2019-02-10 05:54:48 +01:00
String name = event.repoFullName;
var arr = name.split('/');
return createRepoLinkSpan(context, arr[0], arr[1]);
}
2018-07-05 16:08:19 +02: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
return createLinkSpan(context, '#' + number.toString(), () {
return IssueScreen.fromFullName(
number: number,
fullName: event.repoFullName,
isPullRequest: isPullRequest,
);
});
}
2019-02-07 10:19:08 +01:00
Widget _buildItem({
@required BuildContext context,
@required List<TextSpan> spans,
String detail,
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-02-07 10:19:08 +01:00
}) {
2019-02-11 17:31:06 +01:00
return Container(
2019-07-28 15:59:18 +02:00
padding: EdgeInsets.all(10),
2019-02-11 17:31:06 +01:00
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Avatar(url: event.actorAvatarUrl, login: event.actorLogin),
2019-02-11 17:31:06 +01:00
Padding(padding: EdgeInsets.only(left: 10)),
Expanded(
child: RichText(
text: TextSpan(
2019-07-28 15:59:18 +02:00
style: TextStyle(
color: PrimerColors.gray900,
height: 1.2,
fontWeight: FontWeight.w300),
2019-05-12 08:01:12 +02:00
children: [
createLinkSpan(
context,
event.actorLogin,
() => UserScreen(event.actorLogin),
),
...spans,
],
),
2019-01-31 07:37:25 +01:00
),
2019-02-11 17:31:06 +01:00
),
Padding(padding: EdgeInsets.only(left: 8)),
2019-07-28 15:59:18 +02:00
Icon(iconData, color: PrimerColors.gray400, size: 22),
2019-02-11 17:31:06 +01:00
],
),
detailWidget == null
? (detail == null
? Container()
: Container(
padding: EdgeInsets.only(left: 46, top: 6),
child: Text(
detail,
overflow: TextOverflow.ellipsis,
maxLines: 3,
style: TextStyle(
2019-07-28 15:59:18 +02:00
color: PrimerColors.gray600,
fontSize: 14,
height: 1.2,
),
),
))
: detailWidget
2019-02-11 17:31:06 +01:00
],
2018-07-05 16:08:19 +02:00
),
);
}
2019-02-07 10:19:08 +01:00
@override
build(BuildContext context) {
var defaultItem = _buildItem(
context: context,
2019-02-10 05:54:48 +01:00
spans: [
TextSpan(
text: ' ' + event.type,
style: TextStyle(color: Colors.blueAccent),
)
],
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) {
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: [
TextSpan(text: ' forked '),
createRepoLinkSpan(
context,
event.payload['forkee']['owner']['login'],
event.payload['forkee']['name']),
TextSpan(text: ' from '),
_buildRepo(context),
],
iconData: Octicons.repo_forked,
);
case 'ForkApplyEvent':
case 'GitHubAppAuthorizationEvent':
case 'GistEvent':
case 'GollumEvent':
case 'InstallationEvent':
case 'InstallationRepositoriesEvent':
// TODO:
return defaultItem;
case 'IssueCommentEvent':
bool isPullRequest = event.payload['issue']['pull_request'] != null;
String resource = isPullRequest ? 'pull request' : 'issue';
int number = event.payload['issue']['number'];
return _buildItem(
context: context,
spans: [
TextSpan(text: ' commented on $resource '),
_buildIssue(
context,
number: number,
isPullRequest: isPullRequest,
),
2019-02-07 10:19:08 +01:00
TextSpan(text: ' at '),
_buildRepo(context),
// TextSpan(text: event.payload['comment']['body'])
2019-02-07 10:19:08 +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
);
case 'IssuesEvent':
int number = event.payload['issue']['number'];
2019-02-07 10:19:08 +01:00
return _buildItem(
context: context,
spans: [
TextSpan(text: ' ${event.payload['action']} issue '),
_buildIssue(context, number: number),
2019-02-07 10:19:08 +01:00
TextSpan(text: ' at '),
_buildRepo(context),
],
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
);
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 '),
_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'],
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
);
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 '),
_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'],
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
);
case 'PushEvent':
int size = event.payload['size'];
String ref = event.payload['ref'];
var commitText = '$size commit' + (size == 1 ? '' : 's');
List commits = event.payload['commits'];
2019-02-07 10:19:08 +01:00
return _buildItem(
context: context,
spans: [
TextSpan(text: ' pushed $commitText to '),
2019-05-12 09:14:28 +02:00
// TODO: Use primer widgets
TextSpan(
text: ref.replaceFirst('refs/heads/', ''),
style: TextStyle(
2019-05-12 09:14:28 +02:00
color: PrimerColors.blue500,
backgroundColor: Color(0xffeaf5ff),
),
),
2019-02-07 10:19:08 +01:00
TextSpan(text: ' at '),
_buildRepo(context),
TextSpan(text: '')
2019-02-07 10:19:08 +01:00
],
iconData: Octicons.repo_push,
detailWidget: Container(
padding: EdgeInsets.only(left: 46, top: 6),
child: Link(
onTap: () {
launch('https://github.com/' +
event.repoFullName +
'/compare/' +
event.payload['before'] +
'...' +
event.payload['head']);
},
child: Column(
children: commits.map((commit) {
return Row(children: <Widget>[
Text(
(commit['sha'] as String).substring(0, 7),
style: TextStyle(
2019-05-12 09:14:28 +02:00
color: PrimerColors.blue500,
fontSize: 13,
fontFamily: 'Menlo',
fontFamilyFallback: ['Menlo', 'Roboto Mono'],
),
),
SizedBox(width: 6),
Expanded(
child: Text(
commit['message'],
style: TextStyle(color: Colors.black54, fontSize: 14),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
)
]);
}).toList(),
),
),
),
2019-02-07 10:19:08 +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)],
iconData: Octicons.star,
2019-02-07 10:19:08 +01:00
);
default:
return defaultItem;
2019-02-07 10:19:08 +01:00
}
}
2018-07-05 16:08:19 +02:00
}