From bf3f077efa416220e486c20ea138f741a506320f Mon Sep 17 00:00:00 2001 From: Rongjian Zhang Date: Fri, 13 Sep 2019 17:45:09 +0800 Subject: [PATCH] feat: issues screen info --- lib/main.dart | 2 + lib/screens/issues.dart | 104 +++++++++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 29 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 74a426b..4f8c5a2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:git_touch/models/settings.dart'; import 'package:git_touch/models/theme.dart'; +import 'package:git_touch/screens/issues.dart'; import 'package:git_touch/screens/repo.dart'; import 'package:git_touch/screens/user.dart'; import 'package:primer/primer.dart'; @@ -91,6 +92,7 @@ class _HomeState extends State { } _buildScreen(int index) { + // return IssuesScreen(owner: 'flutter', name: 'flutter', isPullRequest: true); // return IssueScreen(number: 29, owner: 'reactjs', name: 'rfcs'); // return IssueScreen( // number: 68, owner: 'reactjs', name: 'rfcs', isPullRequest: true); diff --git a/lib/screens/issues.dart b/lib/screens/issues.dart index d2b5f65..8861e42 100644 --- a/lib/screens/issues.dart +++ b/lib/screens/issues.dart @@ -1,13 +1,16 @@ import 'package:flutter/material.dart'; import 'package:git_touch/models/settings.dart'; import 'package:git_touch/widgets/app_bar_title.dart'; +import 'package:git_touch/widgets/avatar.dart'; +import 'package:primer/primer.dart'; import 'package:provider/provider.dart'; +import 'package:timeago/timeago.dart' as timeago; import '../scaffolds/list.dart'; import '../utils/utils.dart'; import '../widgets/link.dart'; import '../screens/issue.dart'; -class IssuesScreen extends StatefulWidget { +class IssuesScreen extends StatelessWidget { final String owner; final String name; final bool isPullRequest; @@ -18,23 +21,14 @@ class IssuesScreen extends StatefulWidget { this.isPullRequest = false, }); - @override - _IssuesScreenState createState() => _IssuesScreenState(); -} - -class _IssuesScreenState extends State { - String get owner => widget.owner; - String get name => widget.name; - bool get isPullRequest => widget.isPullRequest; - - Future _query([String cursor]) async { + Future _query(BuildContext context, [String cursor]) async { var cursorChunk = cursor == null ? '' : ', after: "$cursor"'; var resource = isPullRequest ? 'pullRequests' : 'issues'; var data = await Provider.of(context).query(''' { repository(owner: "$owner", name: "$name") { - $resource(states: OPEN, first: $pageSize$cursorChunk) { + $resource(states: OPEN, orderBy: {field: CREATED_AT, direction: DESC}, first: $pageSize$cursorChunk) { pageInfo { hasNextPage endCursor @@ -43,6 +37,19 @@ class _IssuesScreenState extends State { number title updatedAt + author { + login + avatarUrl + } + labels(first: 10) { + nodes { + name + color + } + } + comments { + totalCount + } } } } @@ -59,9 +66,7 @@ class _IssuesScreenState extends State { } IconData _buildIconData() { - return widget.isPullRequest - ? Octicons.git_pull_request - : Octicons.issue_opened; + return isPullRequest ? Octicons.git_pull_request : Octicons.issue_opened; } Widget _buildItem(payload) { @@ -75,7 +80,7 @@ class _IssuesScreenState extends State { ); }, child: Container( - padding: EdgeInsets.all(8), + padding: EdgeInsets.all(12), // color: payload.unread ? Colors.white : Colors.black12, child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -83,15 +88,17 @@ class _IssuesScreenState extends State { Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - padding: EdgeInsets.only(right: 8, top: 4), - child: Icon(_buildIconData(), color: Palette.green), + Avatar( + login: payload['author']['login'], + url: payload['author']['avatarUrl'], + size: 12, ), + SizedBox(width: 10), Expanded( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: join(SizedBox(height: 6), [ // Text( // owner + // '/' + @@ -103,20 +110,59 @@ class _IssuesScreenState extends State { // Padding(padding: EdgeInsets.only(top: 4)), Text( payload['title'], - style: TextStyle(fontSize: 15), + style: TextStyle( + fontSize: 16, color: PrimerColors.gray900), maxLines: 3, overflow: TextOverflow.ellipsis, ), - Padding(padding: EdgeInsets.only(top: 6)), - Text( - payload['updatedAt'], + Wrap( + spacing: 2, + runSpacing: 2, + 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: PrimerColors.gray900, // FIXME: + fontWeight: FontWeight.w600, + ), + ), + ); + }).toList(), + ), + DefaultTextStyle( style: TextStyle( - fontSize: 12, - // fontWeight: FontWeight.w300, - color: Colors.black54, + fontSize: 13, color: PrimerColors.gray700), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(_buildIconData(), + color: Palette.green, size: 13), + SizedBox(width: 4), + Text(timeago.format( + DateTime.parse(payload['updatedAt']))), + if (payload['comments']['totalCount'] > 0) ...[ + Expanded(child: SizedBox()), + Icon(Octicons.comment, + size: 13, color: PrimerColors.gray700), + SizedBox(width: 4), + Text(payload['comments']['totalCount'] + .toString()) + ], + ], ), ) - ], + ]), ), ), ), @@ -138,7 +184,7 @@ class _IssuesScreenState extends State { Widget build(BuildContext context) { return ListScaffold( title: AppBarTitle('Issues of $owner/$name'), - onRefresh: () => _query(), + onRefresh: () => _query(context), onLoadMore: (cursor) => _query(cursor), itemBuilder: _buildItem, );