From dfe838cce74d9753f4ecae260ad1dd9aefcda13c Mon Sep 17 00:00:00 2001 From: Matthew Clark Date: Wed, 2 Oct 2019 03:01:14 -0500 Subject: [PATCH 1/2] *getting it to build with latest flutter and dart *added dependency *small crash fix --- .gitignore | 1 + ios/Runner.xcodeproj/project.pbxproj | 12 ++++++------ lib/pages/dashboard.dart | 5 ++--- lib/pages/issuelistview.dart | 5 ++--- lib/pages/issuetimelineview.dart | 8 ++++---- lib/pages/prlistview.dart | 4 ++-- lib/pages/prtimelineview.dart | 10 +++++----- lib/pages/repolist.dart | 6 +++--- pubspec.yaml | 9 +++------ 9 files changed, 28 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index e487bb2..656b423 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .packages .pub/ +ios/Flutter/flutter_export_environment.sh ios/.generated/ ios/Pods/ ios/Podfile.lock diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index f890aef..eedf60f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -42,7 +41,6 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 3C7768A1A9B58B43E3392FD3 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -58,6 +56,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B741F99116C4D73239D86FB5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + D4DA25AA4E199BEC1F6A1526 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +85,8 @@ 5873D7D88706813638AF142B /* Pods */ = { isa = PBXGroup; children = ( + B741F99116C4D73239D86FB5 /* Pods-Runner.debug.xcconfig */, + D4DA25AA4E199BEC1F6A1526 /* Pods-Runner.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -92,7 +94,6 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEBA1CF902C7004384FC /* Flutter.framework */, @@ -213,7 +214,6 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -255,7 +255,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -264,7 +264,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; F297033013D4A6E17D61E7E7 /* [CP] Check Pods Manifest.lock */ = { diff --git a/lib/pages/dashboard.dart b/lib/pages/dashboard.dart index 5f99aa0..e6204fd 100644 --- a/lib/pages/dashboard.dart +++ b/lib/pages/dashboard.dart @@ -366,14 +366,14 @@ class _DashboardState extends State { } - void _refreshDashboard(bool b) { + void _refreshDashboard() { setState(() { prList = graphql.getPRs(widget.repo); issueList = graphql.getIssues(widget.repo); branches = graphql.getBranches(widget.repo); releases = graphql.getReleases(widget.repo); - rc.sendBack(true, RefreshStatus.completed); + rc.loadComplete(); Navigator.pushReplacement( context, @@ -404,7 +404,6 @@ class _DashboardState extends State { ); }); - b = true; } } diff --git a/lib/pages/issuelistview.dart b/lib/pages/issuelistview.dart index 4aa11e9..df1a052 100644 --- a/lib/pages/issuelistview.dart +++ b/lib/pages/issuelistview.dart @@ -90,8 +90,9 @@ class IssueListViewState extends State { } } - void _refreshIssueList(bool b) { + void _refreshIssueList() { issueList = getIssues(widget.repo); + rc.loadComplete(); //rc.sendBack(true, RefreshStatus.completed); // makes it break, but works without. // can look into making this better later on @@ -118,8 +119,6 @@ class IssueListViewState extends State { ); }), ); - - b = true; } Widget _createIssueListWidget(BuildContext context, List issues) { diff --git a/lib/pages/issuetimelineview.dart b/lib/pages/issuetimelineview.dart index 50a0b05..00625cd 100644 --- a/lib/pages/issuetimelineview.dart +++ b/lib/pages/issuetimelineview.dart @@ -116,9 +116,10 @@ class IssueTimelineViewState extends State { ); } - void _refreshIssueTimelineList(bool b) { + void _refreshIssueTimelineList() { setState(() { issueTimelineList = getIssueTimeline(widget.issue); + rc.loadComplete(); //rc.sendBack(true, RefreshStatus.completed); // makes it break, but works without. // can look into making this better later on @@ -146,7 +147,6 @@ class IssueTimelineViewState extends State { ), ), ); - b = true; }); } @@ -154,7 +154,7 @@ class IssueTimelineViewState extends State { if (comment != null) { addComment(widget.issue, null, comment).then( (IssueComment comment) { - _refreshIssueTimelineList(true); + _refreshIssueTimelineList(); }, ); } @@ -190,7 +190,7 @@ class IssueTimelineViewState extends State { // print(labelIds); addLabel(widget.issue, null, labelIds).then( (List labels) { - _refreshIssueTimelineList(true); + _refreshIssueTimelineList(); }); } diff --git a/lib/pages/prlistview.dart b/lib/pages/prlistview.dart index 7a1382d..1f6e200 100644 --- a/lib/pages/prlistview.dart +++ b/lib/pages/prlistview.dart @@ -105,8 +105,9 @@ class PRListViewState extends State { ); } - void _refreshPRList(bool b) { + void _refreshPRList() { prList = getPRs(widget.repo); + rc.loadComplete(); //rc.sendBack(true, RefreshStatus.completed); // makes it break, but works without. // can look into making this better later on @@ -133,6 +134,5 @@ class PRListViewState extends State { ); }), ); - b = true; } } diff --git a/lib/pages/prtimelineview.dart b/lib/pages/prtimelineview.dart index 8b7d731..ae77b70 100644 --- a/lib/pages/prtimelineview.dart +++ b/lib/pages/prtimelineview.dart @@ -44,8 +44,9 @@ class PRTimelineViewState extends State { ); } - void _refreshPRTimelineList(bool b) { + void _refreshPRTimelineList() { prTimelineList = getPRTimeline(widget.pr); + rc.loadComplete(); //rc.sendBack(true, RefreshStatus.completed); // makes it break, but works without. // can look into making this better later on @@ -71,7 +72,6 @@ class PRTimelineViewState extends State { }, ), ); - b = true; } Widget _buildPRTimelineList( @@ -156,10 +156,10 @@ class PRTimelineViewState extends State { if (comment != null) { addComment(null, widget.pr, comment).then( (IssueComment comment) { - _refreshPRTimelineList(true); + _refreshPRTimelineList(); }, ); - _refreshPRTimelineList(true); + _refreshPRTimelineList(); } _textEditingController.clear(); } @@ -197,7 +197,7 @@ class PRTimelineViewState extends State { // print(labelIds); addLabel(null, widget.pr, labelIds).then( (List labels) { - _refreshPRTimelineList(true); + _refreshPRTimelineList(); }); } } diff --git a/lib/pages/repolist.dart b/lib/pages/repolist.dart index 44815e1..fc83612 100644 --- a/lib/pages/repolist.dart +++ b/lib/pages/repolist.dart @@ -54,8 +54,9 @@ class RepoListViewState extends State { )); } - void _refreshRepoList(bool b) { + void _refreshRepoList() { repoList = fetchUserRepos(); + rc.loadComplete(); //rc.sendBack(true, RefreshStatus.completed); // makes it break, but works without. // can look into making this better later on @@ -81,7 +82,6 @@ class RepoListViewState extends State { }, ), ); - b = true; } Widget _buildRepoList( @@ -89,7 +89,7 @@ class RepoListViewState extends State { AsyncSnapshot> snapshot, ) { if (snapshot.connectionState == ConnectionState.done) { - return snapshot.data.length != 0 + return snapshot.data!= null && snapshot.data.length != 0 ? _createRepoListWidget(context, snapshot.data) : SmartRefresher( enablePullDown: true, diff --git a/pubspec.yaml b/pubspec.yaml index 2b95d74..c9782c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,13 +7,10 @@ dependencies: flutter: sdk: flutter font_awesome_flutter: ^8.1.0 - flutter_staggered_grid_view: "^0.2.2" + flutter_staggered_grid_view: "^0.3.0" pull_to_refresh: ^1.1.5 - bidirectional_scroll_view: - # Until a new version of this plugin that works with Dart 2.0 is released, - # use this fork by a Googler. - git: - url: git://github.com/efortuna/flutter-bidirectional_scrollview_plugin.git + bidirectional_scroll_view: ^0.1.1 + graphql: ^2.0.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. From 478855b13bccda8e87f25e00f80baf4a1c205794 Mon Sep 17 00:00:00 2001 From: Matthew Clark Date: Wed, 2 Oct 2019 03:02:03 -0500 Subject: [PATCH 2/2] *moved to graphql lib and updated parsers to use the received objects instead of strings --- lib/github/graphql.dart | 112 +++++++++++++++++++++++++++++++--------- lib/github/parsers.dart | 45 ++++++++-------- 2 files changed, 109 insertions(+), 48 deletions(-) diff --git a/lib/github/graphql.dart b/lib/github/graphql.dart index 302d535..9b3e7b4 100644 --- a/lib/github/graphql.dart +++ b/lib/github/graphql.dart @@ -8,6 +8,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; +import 'package:graphql/client.dart'; import 'parsers.dart'; import 'pullrequest.dart'; @@ -18,11 +19,28 @@ import 'token.dart'; import 'user.dart'; import 'label.dart'; -final url = 'https://api.github.com/graphql'; +// final url = 'https://api.github.com/graphql'; // updated this to allow use of preview stuff in the GraphQL API -final headers = {'Authorization': 'bearer $token', 'Accept': 'application/vnd.github.starfire-preview+json'}; +// final headers = {'Authorization': 'bearer $token', 'Accept': 'application/vnd.github.starfire-preview+json'}; final postHeaders = {'Authorization': 'token $token'}; +final HttpLink _httpLink = HttpLink( + uri: 'https://api.github.com/graphql', + headers: {'Accept': 'application/vnd.github.starfire-preview+json'} +); + +final AuthLink _authLink = AuthLink( + getToken: () async => 'bearer $token', + +); + +final Link _link = _authLink.concat(_httpLink); + +final GraphQLClient _client = GraphQLClient( + cache: InMemoryCache(), + link: _link, + ); + /// Fetches the details of the specified user Future user(String login) async { final query = ''' @@ -98,22 +116,61 @@ addEmoji(String id, String reaction) async { } } '''; - await _query(query); + await _mutation(query); } -acceptPR(String reviewUrl) async { - var response = await http.put('$reviewUrl/merge', headers: postHeaders); - return response.statusCode == 200 - ? response.body - : throw Exception('Error: ${response.statusCode} ${response.body}'); +acceptPR(String pullRequestID) async { + var mutation = ''' + mutation MergePullRequest { + mergePullRequest(input:{pullRequestID:"$pullRequestID"}) { + clientMutationId + pullRequest { + url + title + id + number + labels (first: 30) { + nodes { + name + color + id + } + } + author { + login + } + } + } + } + '''; + return await _mutation(mutation); } -closePR(String reviewUrl) async { - var response = await http.patch(reviewUrl, - headers: postHeaders, body: '{"state": "closed"}'); - return response.statusCode == 200 - ? response.body - : throw Exception('Error: ${response.statusCode} ${response.body}'); +closePR(String pullRequestID) async { + var mutation = ''' + mutation ClosePullRequest { + closePullRequest(input:{pullRequestID:"$pullRequestID"}) { + clientMutationId + pullRequest { + url + title + id + number + labels (first: 30) { + nodes { + name + color + id + } + } + author { + login + } + } + } + } + '''; + return await _mutation(mutation); } getDiff(PullRequest pullRequest) async { @@ -121,16 +178,21 @@ getDiff(PullRequest pullRequest) async { return response.body; } -/// Sends a GraphQL query to Github and returns raw response -Future _query(String query) async { - final gqlQuery = json.encode({'query': _removeSpuriousSpacing(query)}); - final response = await http.post(url, headers: headers, body: gqlQuery); - return response.statusCode == 200 - ? response.body - : throw Exception('Error: ${response.statusCode}'); +/// Sends a GraphQL query to Github and returns response +Future _query(String query) async { + final QueryResult response = await _client.query(QueryOptions(document: query)); + return !response.hasErrors + ? response.data + : throw Exception('Error: ${response.errors}'); } -_removeSpuriousSpacing(String str) => str.replaceAll(RegExp(r'\s+'), ' '); +/// Sends a GraphQL mutation to Github and returns response +Future _mutation(String mutation) async { + final QueryResult response = await _client.mutate(MutationOptions(document: mutation)); + return !response.hasErrors + ? response.data + : throw Exception('Error: ${response.errors}'); +} // ------------------------------------------------------------------------------------- @@ -377,7 +439,7 @@ Future addComment(Issue issue, PullRequest pr, String commentBody) } '''; - final result = await _query(mutation); + final result = await _mutation(mutation); return parseAddedComment(result, pr, issue); } @@ -414,7 +476,7 @@ Future addLabel(Issue issue, PullRequest pr, List labelIds) async } } '''; - result = await _query(mutationPR); + result = await _mutation(mutationPR); } else { print("issue id: " + id); @@ -438,7 +500,7 @@ Future addLabel(Issue issue, PullRequest pr, List labelIds) async } '''; print(mutationIss); - result = await _query(mutationIss); + result = await _mutation(mutationIss); print('issue'); } print(result); diff --git a/lib/github/parsers.dart b/lib/github/parsers.dart index e123ada..4441164 100644 --- a/lib/github/parsers.dart +++ b/lib/github/parsers.dart @@ -13,8 +13,7 @@ import 'user.dart'; import 'label.dart'; /// Parses a Github GraphQL user response -User parseUser(String resBody) { - final jsonRes = json.decode(resBody)['data']; +User parseUser(Map jsonRes) { final userJson = jsonRes['viewer'] ?? jsonRes['user']; return User(userJson['login'], userJson['name'], userJson['avatarUrl']); } @@ -44,23 +43,23 @@ User parseUser(String resBody) { // NON CHROMIUM AUTHOR CODE BELOW (the code below is under MIT license) // parseBranches parses the result from the GraphQL query for fetching the # of branches -int parseBranches(String resBody) { +int parseBranches(Map resBody) { int jsonRes = - json.decode(resBody)['data']['repository']['refs']['totalCount']; + resBody['repository']['refs']['totalCount']; return jsonRes; } // parseReleases parses the result from the GraphQL query for fetching the # of releases -int parseReleases(String resBody) { +int parseReleases(Map resBody) { int jsonRes = - json.decode(resBody)['data']['repository']['refs']['totalCount']; + resBody['repository']['refs']['totalCount']; return jsonRes; } // parsePullRequests parses the result from the GraphQL query for fetching the PRs for a repo List parsePullRequests( - String resBody, Repository repo) { - List jsonRes = json.decode(resBody)['data']['search']['edges']; + Map resBody, Repository repo) { + List jsonRes = resBody['search']['edges']; List prs = []; @@ -114,8 +113,8 @@ List parsePullRequests( } // parseIssues parses the result from the GraphQL query for fetching the issues for a repo -List parseIssues(String resBody, Repository repo) { - List jsonRes = json.decode(resBody)['data']['search']['edges']; +List parseIssues(Map resBody, Repository repo) { + List jsonRes = resBody['search']['edges']; List issues = []; for (var i = 0; i < jsonRes.length; i++) { @@ -171,12 +170,12 @@ List parseIssues(String resBody, Repository repo) { } // parsePRTimeline parses the result from the GraphQL query for fetching the timeline for a PR -List parsePRTimeline(String resBody, PullRequest pr) { - List jsonRes = json.decode(resBody)['data']['repository']['pullRequest'] +List parsePRTimeline(Map resBody, PullRequest pr) { + List jsonRes = resBody['repository']['pullRequest'] ['timeline']['edges']; List prTimeline = []; - Map tmp = json.decode(resBody)['data']['repository']['pullRequest']; + Map tmp = resBody['repository']['pullRequest']; prTimeline.add( IssueComment(pr, null, "", "", "", tmp['author']['login'], tmp['body'])); for (var i = 0; i < jsonRes.length; i++) { @@ -222,12 +221,12 @@ List parsePRTimeline(String resBody, PullRequest pr) { } // parseIssueTimeline parses the result from the GraphQL query for fetching the timeline for an issue -List parseIssueTimeline(String resBody, Issue issue) { +List parseIssueTimeline(Map resBody, Issue issue) { List jsonRes = - json.decode(resBody)['data']['repository']['issue']['timeline']['edges']; + resBody['repository']['issue']['timeline']['edges']; List issueTimeline = []; - Map tmp = json.decode(resBody)['data']['repository']['issue']; + Map tmp = resBody['repository']['issue']; issueTimeline.add(IssueComment( null, issue, "", "", "", tmp['author']['login'], tmp['body'])); for (var i = 0; i < jsonRes.length; i++) { @@ -273,9 +272,9 @@ List parseIssueTimeline(String resBody, Issue issue) { } // parseUserRepos parses the result from the GraphQL query for fetching the repositories for a user -List parseUserRepos(String resBody) { +List parseUserRepos(Map resBody) { List jsonRes = - json.decode(resBody)['data']['viewer']['repositories']['nodes']; + resBody['viewer']['repositories']['nodes']; List repos = []; @@ -294,17 +293,17 @@ List parseUserRepos(String resBody) { } // parseAddedComment parses the response received after calling addComment mutation -IssueComment parseAddedComment(String resBody, PullRequest pr, Issue issue) { +IssueComment parseAddedComment(Map resBody, PullRequest pr, Issue issue) { Map jsonRes = - json.decode(resBody)['data']['addComment']['commentEdge']['node']; - Map jsonTemp = json.decode(resBody)['data']['addComment']; + resBody['addComment']['commentEdge']['node']; + Map jsonTemp = resBody['addComment']; return IssueComment(pr, issue, "", jsonRes['url'], jsonTemp['subject']['id'], jsonRes['author']['login'], jsonRes['bodyText']); } -List parseAddedLabels(String resBody, PullRequest pr, Issue issue) { +List parseAddedLabels(Map resBody, PullRequest pr, Issue issue) { List labels = - json.decode(resBody)['data']['addLabelsToLabelable']['labelable']['labels']['nodes']; + resBody['addLabelsToLabelable']['labelable']['labels']['nodes']; return labels; } \ No newline at end of file