2019-01-29 06:34:52 +01:00
|
|
|
import 'dart:core';
|
2019-01-28 14:32:01 +01:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
2019-05-12 09:14:28 +02:00
|
|
|
import 'package:primer/primer.dart';
|
2019-01-31 07:37:25 +01:00
|
|
|
import '../utils/utils.dart';
|
2019-02-07 07:35:19 +01:00
|
|
|
import 'comment_item.dart';
|
|
|
|
import 'user_name.dart';
|
2019-01-28 14:32:01 +01:00
|
|
|
|
2019-09-07 11:48:59 +02:00
|
|
|
class TimelineEventItem extends StatelessWidget {
|
|
|
|
final String actor;
|
|
|
|
final IconData iconData;
|
|
|
|
final Color iconColor;
|
|
|
|
final TextSpan textSpan;
|
|
|
|
final item;
|
2019-01-28 14:32:01 +01:00
|
|
|
|
2019-09-07 11:48:59 +02:00
|
|
|
TimelineEventItem({
|
|
|
|
this.actor,
|
|
|
|
this.iconData = Octicons.octoface,
|
|
|
|
this.iconColor = PrimerColors.gray400,
|
|
|
|
this.textSpan,
|
|
|
|
this.item,
|
|
|
|
});
|
2019-01-28 14:32:01 +01:00
|
|
|
|
2019-09-07 11:48:59 +02:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2019-01-28 14:32:01 +01:00
|
|
|
return Row(
|
|
|
|
children: <Widget>[
|
2019-09-07 11:48:59 +02:00
|
|
|
SizedBox(width: 6),
|
2019-02-09 08:33:06 +01:00
|
|
|
Icon(iconData, color: iconColor, size: 20),
|
2019-09-07 11:48:59 +02:00
|
|
|
SizedBox(width: 12),
|
2019-01-28 14:32:01 +01:00
|
|
|
Expanded(
|
|
|
|
child: RichText(
|
|
|
|
text: TextSpan(style: TextStyle(color: Colors.black), children: [
|
2019-02-18 11:54:06 +01:00
|
|
|
// TODO: actor is null
|
2019-09-07 11:48:59 +02:00
|
|
|
createUserSpan(context, actor),
|
2019-01-28 14:32:01 +01:00
|
|
|
textSpan,
|
|
|
|
// TextSpan(text: ' ' + TimeAgo.formatFromString(item['createdAt']))
|
|
|
|
]),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2019-09-07 11:48:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class TimelineItem extends StatelessWidget {
|
|
|
|
final Map<String, dynamic> payload;
|
|
|
|
final Function(String emojiKey, bool isRemove) onReaction;
|
|
|
|
|
|
|
|
TimelineItem(this.payload, {@required this.onReaction});
|
|
|
|
|
|
|
|
TextSpan _buildReviewText(BuildContext context, item) {
|
|
|
|
switch (item['state']) {
|
|
|
|
case 'APPROVED':
|
|
|
|
return TextSpan(text: ' approved these changes');
|
|
|
|
case 'COMMENTED':
|
|
|
|
return TextSpan(text: ' commented ');
|
|
|
|
default:
|
|
|
|
return warningSpan;
|
|
|
|
}
|
|
|
|
}
|
2019-01-28 14:32:01 +01:00
|
|
|
|
2019-01-29 06:34:52 +01:00
|
|
|
TextSpan _buildLabel(item) {
|
2019-09-14 09:39:38 +02:00
|
|
|
// FIXME:
|
2019-02-09 08:33:06 +01:00
|
|
|
var color = convertColor(item['label']['color']);
|
2019-01-29 06:34:52 +01:00
|
|
|
return TextSpan(
|
|
|
|
text: item['label']['name'],
|
|
|
|
style: TextStyle(
|
2019-09-14 09:39:38 +02:00
|
|
|
color: getFontColorByBrightness(color),
|
|
|
|
backgroundColor: color,
|
2019-02-04 11:32:39 +01:00
|
|
|
// https://stackoverflow.com/a/52592679
|
|
|
|
// ..strokeWidth = 16.5
|
|
|
|
// ..style = PaintingStyle.stroke
|
|
|
|
),
|
2019-01-29 06:34:52 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-01-28 14:32:01 +01:00
|
|
|
Widget _buildByType(BuildContext context) {
|
2019-02-19 08:25:15 +01:00
|
|
|
String type = payload['__typename'];
|
2019-01-28 14:32:01 +01:00
|
|
|
|
2019-09-07 11:48:59 +02:00
|
|
|
var defaultItem = TimelineEventItem(
|
2019-02-08 07:30:22 +01:00
|
|
|
actor: '',
|
|
|
|
iconData: Octicons.octoface,
|
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: 'Woops, $type type not implemented yet'),
|
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-02-08 07:30:22 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
// common types
|
|
|
|
case 'Commit':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['author']['user'] == null
|
2019-02-18 11:54:06 +01:00
|
|
|
? null
|
2019-02-19 08:25:15 +01:00
|
|
|
: payload['author']['user']['login'],
|
2019-02-08 07:30:22 +01:00
|
|
|
iconData: Octicons.git_commit,
|
2019-01-28 14:32:01 +01:00
|
|
|
textSpan: TextSpan(children: [
|
2019-02-08 07:30:22 +01:00
|
|
|
TextSpan(text: ' added commit '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['oid'].substring(0, 8))
|
2019-01-28 14:32:01 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'IssueComment':
|
2019-04-05 15:19:00 +02:00
|
|
|
return CommentItem(payload, onReaction: onReaction);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'CrossReferencedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-02-08 07:30:22 +01:00
|
|
|
iconData: Octicons.primitive_dot,
|
|
|
|
iconColor: Palette.green,
|
|
|
|
textSpan: TextSpan(
|
|
|
|
text: ' referenced this on #' +
|
2019-02-19 08:25:15 +01:00
|
|
|
payload['source']['number'].toString()),
|
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
|
|
|
case 'ClosedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-28 14:32:01 +01:00
|
|
|
iconData: Octicons.circle_slash,
|
2019-05-12 09:14:28 +02:00
|
|
|
iconColor: PrimerColors.red600,
|
2019-01-28 14:32:01 +01:00
|
|
|
textSpan: TextSpan(text: ' closed this '),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
|
2019-01-28 14:32:01 +01:00
|
|
|
case 'ReopenedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-28 14:32:01 +01:00
|
|
|
iconData: Octicons.primitive_dot,
|
|
|
|
iconColor: Palette.green,
|
|
|
|
textSpan: TextSpan(text: ' reopened this '),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'SubscribedEvent':
|
|
|
|
case 'UnsubscribedEvent':
|
|
|
|
return defaultItem; // TODO:
|
|
|
|
case 'ReferencedEvent':
|
|
|
|
// TODO: isCrossRepository
|
2019-02-19 08:25:15 +01:00
|
|
|
if (payload['commit'] == null) {
|
2019-02-08 07:30:22 +01:00
|
|
|
return Container();
|
|
|
|
}
|
|
|
|
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-02-08 07:30:22 +01:00
|
|
|
iconData: Octicons.bookmark,
|
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: ' referenced this pull request from commit '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['commit']['oid'].substring(0, 8)),
|
2019-02-08 07:30:22 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-02-08 07:30:22 +01:00
|
|
|
);
|
|
|
|
case 'AssignedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-02-08 07:30:22 +01:00
|
|
|
iconData: Octicons.key,
|
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: ' assigned this to '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['user']['login'])
|
2019-02-08 07:30:22 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'UnassignedEvent':
|
|
|
|
return defaultItem; // TODO:
|
2019-01-29 06:34:52 +01:00
|
|
|
case 'LabeledEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-29 06:34:52 +01:00
|
|
|
iconData: Octicons.tag,
|
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: ' added '),
|
2019-02-19 08:25:15 +01:00
|
|
|
_buildLabel(payload),
|
2019-01-29 06:34:52 +01:00
|
|
|
TextSpan(text: ' label'),
|
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-29 06:34:52 +01:00
|
|
|
);
|
|
|
|
case 'UnlabeledEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-29 06:34:52 +01:00
|
|
|
iconData: Octicons.tag,
|
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: ' removed '),
|
2019-02-19 08:25:15 +01:00
|
|
|
_buildLabel(payload),
|
2019-01-29 06:34:52 +01:00
|
|
|
TextSpan(text: ' label'),
|
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-29 06:34:52 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
|
2019-01-29 06:34:52 +01:00
|
|
|
case 'MilestonedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-29 06:34:52 +01:00
|
|
|
iconData: Octicons.milestone,
|
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: ' added this to '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['milestoneTitle']),
|
2019-01-29 06:34:52 +01:00
|
|
|
TextSpan(text: ' milestone'),
|
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-29 06:34:52 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'DemilestonedEvent':
|
|
|
|
return defaultItem; // TODO:
|
|
|
|
case 'RenamedTitleEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-02-08 07:30:22 +01:00
|
|
|
iconData: Octicons.pencil,
|
2019-01-29 06:34:52 +01:00
|
|
|
textSpan: TextSpan(children: [
|
2019-02-08 07:30:22 +01:00
|
|
|
TextSpan(text: ' changed the title '),
|
|
|
|
TextSpan(
|
2019-02-19 08:25:15 +01:00
|
|
|
text: payload['previousTitle'],
|
2019-02-08 07:30:22 +01:00
|
|
|
style: TextStyle(decoration: TextDecoration.lineThrough),
|
|
|
|
),
|
|
|
|
TextSpan(text: ' to '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['currentTitle'])
|
2019-01-29 06:34:52 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-29 06:34:52 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'LockedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-02-08 07:30:22 +01:00
|
|
|
iconData: Octicons.lock,
|
2019-01-29 06:34:52 +01:00
|
|
|
textSpan: TextSpan(children: [
|
2019-02-08 07:30:22 +01:00
|
|
|
TextSpan(text: ' locked this conversation '),
|
2019-01-29 06:34:52 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-29 06:34:52 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'UnlockedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-29 06:34:52 +01:00
|
|
|
iconData: Octicons.key,
|
|
|
|
textSpan: TextSpan(children: [
|
2019-02-08 07:30:22 +01:00
|
|
|
TextSpan(text: ' unlocked this conversation '),
|
2019-01-29 06:34:52 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-29 06:34:52 +01:00
|
|
|
);
|
2019-01-28 14:32:01 +01:00
|
|
|
|
2019-02-08 07:30:22 +01:00
|
|
|
// issue only types
|
|
|
|
case 'TransferredEvent':
|
|
|
|
return defaultItem; // TODO:
|
|
|
|
|
|
|
|
// pull request only types
|
|
|
|
case 'CommitCommentThread':
|
|
|
|
return defaultItem; // TODO:
|
2019-01-28 14:32:01 +01:00
|
|
|
case 'PullRequestReview':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['author']['login'],
|
2019-02-06 12:14:11 +01:00
|
|
|
iconColor: Color(0xff28a745),
|
2019-01-28 14:32:01 +01:00
|
|
|
iconData: Octicons.check,
|
2019-02-19 08:25:15 +01:00
|
|
|
textSpan: _buildReviewText(context, payload),
|
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'PullRequestReviewThread':
|
|
|
|
case 'PullRequestReviewComment':
|
|
|
|
return defaultItem; // TODO:
|
2019-01-28 14:32:01 +01:00
|
|
|
case 'MergedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-28 14:32:01 +01:00
|
|
|
iconData: Octicons.git_merge,
|
2019-02-06 12:14:11 +01:00
|
|
|
iconColor: Color(0xff6f42c1),
|
2019-01-28 14:32:01 +01:00
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: ' merged commit '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['commit']['oid'].substring(0, 8)),
|
2019-01-28 14:32:01 +01:00
|
|
|
TextSpan(text: ' into '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['mergeRefName']),
|
2019-01-28 14:32:01 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'DeployedEvent':
|
|
|
|
case 'DeploymentEnvironmentChangedEvent':
|
|
|
|
return defaultItem; // TODO:
|
2019-01-28 14:32:01 +01:00
|
|
|
case 'HeadRefDeletedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-19 08:25:15 +01:00
|
|
|
actor: payload['actor']['login'],
|
2019-01-28 14:32:01 +01:00
|
|
|
iconData: Octicons.git_branch,
|
|
|
|
textSpan: TextSpan(children: [
|
|
|
|
TextSpan(text: ' deleted the '),
|
2019-02-19 08:25:15 +01:00
|
|
|
TextSpan(text: payload['headRefName']),
|
2019-01-28 14:32:01 +01:00
|
|
|
TextSpan(text: ' branch'),
|
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'HeadRefRestoredEvent':
|
|
|
|
case 'HeadRefForcePushedEvent':
|
|
|
|
case 'BaseRefForcePushedEvent':
|
|
|
|
return defaultItem; // TODO:
|
|
|
|
case 'ReviewRequestedEvent':
|
2019-09-07 11:48:59 +02:00
|
|
|
return TimelineEventItem(
|
2019-02-08 07:30:22 +01:00
|
|
|
iconData: Octicons.eye,
|
|
|
|
// actor: payload['author']['login'],
|
|
|
|
// TODO:
|
|
|
|
actor: 'test',
|
2019-01-28 14:32:01 +01:00
|
|
|
textSpan: TextSpan(children: [
|
2019-02-08 07:30:22 +01:00
|
|
|
TextSpan(text: ' requested a review from '),
|
2019-09-07 11:48:59 +02:00
|
|
|
createUserSpan(context, payload['requestedReviewer']['login']),
|
2019-01-28 14:32:01 +01:00
|
|
|
]),
|
2019-02-19 08:25:15 +01:00
|
|
|
item: payload,
|
2019-01-28 14:32:01 +01:00
|
|
|
);
|
2019-02-08 07:30:22 +01:00
|
|
|
case 'ReviewRequestRemovedEvent':
|
|
|
|
case 'ReviewDismissedEvent':
|
|
|
|
return defaultItem; // TODO:
|
2019-01-28 14:32:01 +01:00
|
|
|
default:
|
2019-02-08 07:30:22 +01:00
|
|
|
return defaultItem;
|
2019-01-28 14:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Container(
|
2019-04-05 15:19:00 +02:00
|
|
|
padding: EdgeInsets.all(12),
|
2019-01-28 14:32:01 +01:00
|
|
|
child: _buildByType(context),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|