diff --git a/lib/models/theme.dart b/lib/models/theme.dart index bb7bac1..76235c5 100644 --- a/lib/models/theme.dart +++ b/lib/models/theme.dart @@ -109,8 +109,8 @@ class ThemeModel with ChangeNotifier { return Palette( primary: Colors.blueAccent.shade700, text: Colors.black, - secondaryText: Colors.grey.shade900, - tertiaryText: Colors.grey.shade800, + secondaryText: Colors.grey.shade800, + tertiaryText: Colors.grey.shade600, background: Colors.white, grayBackground: Colors.grey.shade100, border: Colors.grey.shade400, diff --git a/lib/screens/issue.dart b/lib/screens/issue.dart index f2cfeb5..70d9c72 100644 --- a/lib/screens/issue.dart +++ b/lib/screens/issue.dart @@ -2,8 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:git_touch/graphql/gh.dart'; import 'package:git_touch/models/auth.dart'; +import 'package:git_touch/models/theme.dart'; import 'package:git_touch/utils/utils.dart'; import 'package:git_touch/widgets/action_button.dart'; +import 'package:git_touch/widgets/avatar.dart'; +import 'package:git_touch/widgets/link.dart'; import 'package:primer/primer.dart'; import 'package:provider/provider.dart'; import '../scaffolds/long_list.dart'; @@ -53,6 +56,11 @@ class _IssueScreenState extends State { String get issueChunk { var base = ''' + repository { + owner { + avatarUrl + } + } title closed url @@ -67,6 +75,7 @@ class _IssueScreenState extends State { merged additions deletions +changedFiles commits { totalCount } @@ -366,7 +375,7 @@ mutation { Widget build(BuildContext context) { final auth = Provider.of(context); return LongListStatefulScaffold( - title: Text('Issue #$number'), + title: Text(isPullRequest ? 'Pull Request' : 'Issue'), trailingBuilder: (payload, setState) { return ActionButton( title: (isPullRequest ? 'Pull Request' : 'Issue') + ' Actions', @@ -396,7 +405,8 @@ mutation { ], ); }, - headerBuilder: (payload) { + headerBuilder: (p) { + final theme = Provider.of(context); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ @@ -406,25 +416,89 @@ mutation { crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( - mainAxisAlignment: MainAxisAlignment.end, children: [ - Expanded( - child: Text( - payload['title'], - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - ), + Avatar( + url: p['repository']['owner']['avatarUrl'], + size: AvatarSize.extraSmall, + ), + SizedBox(width: 4), + Text( + '$owner / $name', + style: TextStyle( + fontSize: 17, + color: theme.palette.secondaryText, + ), + ), + SizedBox(width: 4), + Text( + '#$number', + style: TextStyle( + fontSize: 17, + color: theme.palette.tertiaryText, ), ), - Padding(padding: EdgeInsets.only(right: 8)), - StateLabel(_getLabelStatus(payload)) ], ), - Padding(padding: EdgeInsets.only(bottom: 16)), + SizedBox(height: 8), + Text( + p['title'], + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + StateLabel(_getLabelStatus(p), small: true), + SizedBox(height: 8), + CommonStyle.border, + if (isPullRequest) ...[ + Link( + child: Container( + padding: EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '${p['changedFiles']} files changed', + style: TextStyle( + color: theme.palette.secondaryText, + fontSize: 17, + ), + ), + Row( + children: [ + Text( + '+${p['additions']}', + style: TextStyle( + color: Colors.green, + fontSize: 15, + ), + ), + SizedBox(width: 2), + Text( + '-${p['deletions']}', + style: TextStyle( + color: Colors.red, + fontSize: 15, + ), + ), + Icon( + Icons.chevron_right, + color: theme.palette.border, + ), + ], + ) + ], + ), + ), + url: 'https://github.com/$owner/$name/pull/$number/files', + ), + CommonStyle.border, + ], + SizedBox(height: 8), CommentItem( - payload, - onReaction: _handleReaction(payload), + p, + onReaction: _handleReaction(p), ), ], ), diff --git a/lib/widgets/comment_item.dart b/lib/widgets/comment_item.dart index e82845a..14d9a5a 100644 --- a/lib/widgets/comment_item.dart +++ b/lib/widgets/comment_item.dart @@ -66,7 +66,7 @@ class CommentItem extends StatelessWidget { ), ]), SizedBox(height: 12), - MarkdownView(payload['body'] as String), + MarkdownView(payload['body'] as String), // TODO: link SizedBox(height: 12), Wrap( crossAxisAlignment: WrapCrossAlignment.center, diff --git a/lib/widgets/issue_item.dart b/lib/widgets/issue_item.dart index 4ab7230..802bc5b 100644 --- a/lib/widgets/issue_item.dart +++ b/lib/widgets/issue_item.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:git_touch/models/theme.dart'; import 'package:git_touch/widgets/avatar.dart'; +import 'package:git_touch/widgets/label.dart'; import 'package:provider/provider.dart'; import 'package:timeago/timeago.dart' as timeago; import '../utils/utils.dart'; @@ -58,7 +59,7 @@ class IssueItem extends StatelessWidget { ? Octicons.git_pull_request : Octicons.issue_opened, color: GithubPalette.open, - size: 18), + size: 20), SizedBox(width: 6), Expanded( child: Container( @@ -66,49 +67,41 @@ class IssueItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: join(SizedBox(height: 8), [ Text.rich( - TextSpan(children: [ - TextSpan(text: payload['title'] + ' '), - TextSpan( - text: '#${payload['number']}', - style: - TextStyle(color: theme.palette.tertiaryText), - ), - ]), + TextSpan( + children: [ + TextSpan(text: payload['title'] + ' '), + TextSpan( + text: '#${payload['number']}', + style: TextStyle( + color: theme.palette.tertiaryText, + fontSize: 15, + ), + ), + ], + ), style: TextStyle( - fontSize: 16, + fontSize: 17, color: theme.palette.primary, fontWeight: FontWeight.w600, ), ), if ((payload['labels']['nodes'] as List).isNotEmpty) Wrap( - spacing: 2, - runSpacing: 2, + spacing: 4, + runSpacing: 4, children: (payload['labels']['nodes'] as List) .map((label) { - final color = convertColor(label['color']); - return Container( - padding: EdgeInsets.symmetric( - vertical: 1, horizontal: 3), - decoration: BoxDecoration( - color: color, - borderRadius: - BorderRadius.all(Radius.circular(2)), - ), - child: Text( - label['name'], - style: TextStyle( - fontSize: 12, - color: getFontColorByBrightness(color), - fontWeight: FontWeight.w600, - ), - ), + return Label( + name: label['name'], + cssColor: label['color'], ); }).toList(), ), DefaultTextStyle( style: TextStyle( - fontSize: 13, color: theme.palette.secondaryText), + fontSize: 14, + color: theme.palette.secondaryText, + ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -124,7 +117,7 @@ class IssueItem extends StatelessWidget { SizedBox(width: 4), Text( payload['author']['login'], - style: TextStyle(fontWeight: FontWeight.w500), + style: TextStyle(fontWeight: FontWeight.w600), ), ], Text(' opened ' + @@ -133,9 +126,9 @@ class IssueItem extends StatelessWidget { if (payload['comments']['totalCount'] > 0) ...[ Expanded(child: SizedBox()), Icon(Octicons.comment, - size: 13, + size: 14, color: theme.palette.secondaryText), - SizedBox(width: 4), + SizedBox(width: 3), Text(numberFormat .format(payload['comments']['totalCount'])) ], diff --git a/lib/widgets/label.dart b/lib/widgets/label.dart new file mode 100644 index 0000000..91e3ae3 --- /dev/null +++ b/lib/widgets/label.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:git_touch/utils/utils.dart'; + +class Label extends StatelessWidget { + final String name; + final String cssColor; + + Label({this.name, this.cssColor}); + + @override + Widget build(BuildContext context) { + final color = convertColor(cssColor); + return Container( + padding: EdgeInsets.symmetric(vertical: 2, horizontal: 6), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.all(Radius.circular(4)), + ), + child: Text( + name, + style: TextStyle( + fontSize: 12, + color: getFontColorByBrightness(color), + fontWeight: FontWeight.w600, + ), + ), + ); + } +} diff --git a/lib/widgets/timeline_item.dart b/lib/widgets/timeline_item.dart index 762c1cc..b71473c 100644 --- a/lib/widgets/timeline_item.dart +++ b/lib/widgets/timeline_item.dart @@ -2,7 +2,7 @@ import 'dart:core'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:git_touch/models/theme.dart'; -import 'package:primer/primer.dart'; +import 'package:git_touch/widgets/label.dart'; import 'package:provider/provider.dart'; import '../utils/utils.dart'; import 'comment_item.dart'; @@ -17,7 +17,7 @@ class TimelineEventItem extends StatelessWidget { TimelineEventItem({ this.actor, this.iconData = Octicons.octoface, - this.iconColor = PrimerColors.gray400, + this.iconColor = Colors.grey, this.textSpan, this.item, }); @@ -34,7 +34,7 @@ class TimelineEventItem extends StatelessWidget { Expanded( child: RichText( text: TextSpan( - style: TextStyle(color: theme.palette.text), + style: TextStyle(color: theme.palette.text, fontSize: 16), children: [ // TODO: actor is null createUserSpan(context, actor), @@ -66,17 +66,11 @@ class TimelineItem extends StatelessWidget { } } - TextSpan _buildLabel(item) { - // FIXME: - var color = convertColor(item['label']['color']); - return TextSpan( - text: item['label']['name'], - style: TextStyle( - color: getFontColorByBrightness(color), - backgroundColor: color, - // https://stackoverflow.com/a/52592679 - // ..strokeWidth = 16.5 - // ..style = PaintingStyle.stroke + InlineSpan _buildLabel(p) { + return WidgetSpan( + child: Label( + name: p['label']['name'], + cssColor: p['label']['color'], ), ); }