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/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
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](http://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
[](https://travis-ci.org/gitpoint/git-point)
-[](#contributors)
+[](#contributors)
[](http://makeapullrequest.com)
[](http://commitizen.github.io/cz-cli/)
[](https://gitter.im/git-point)
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.github.com/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.github.com',
call: async (url, parameters) => {
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 && (
-
-
- )}
+ userHasPushPermission &&
+
+ }
);
}
diff --git a/src/components/issue-list-item.component.js b/src/components/issue-list-item.component.js
index cd0d47bfb..10cfdf8e3 100644
--- a/src/components/issue-list-item.component.js
+++ b/src/components/issue-list-item.component.js
@@ -55,55 +55,58 @@ 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';
};
-export const IssueListItem = ({ type, issue, navigation, language }: Props) =>
-
- navigation.navigate('Issue', {
- issue,
- isPR: !!issue.pull_request,
- language,
- })}
- underlayColor={colors.greyLight}
- >
-
-
-
-
-
- {issue.comments}
-
+export const IssueListItem = ({ type, issue, navigation, language }: Props) => {
+ return (
+
+ navigation.navigate('Issue', {
+ issue,
+ isPR: type !== 'issue',
+ language,
+ })}
+ underlayColor={colors.greyLight}
+ >
+
+
+
+
+
+ {issue.comments.totalCount}
+
+
-
- ;
+
+ );
+};
diff --git a/src/issue/screens/issue.screen.js b/src/issue/screens/issue.screen.js
index b88576c9f..2669ba1a4 100644
--- a/src/issue/screens/issue.screen.js
+++ b/src/issue/screens/issue.screen.js
@@ -35,7 +35,7 @@ const mapStateToProps = state => ({
authUser: state.auth.user,
repository: state.repository.repository,
contributors: state.repository.contributors,
- issue: state.issue.issue,
+ issue: state.issue,
diff: state.issue.diff,
pr: state.issue.pr,
isMerged: state.issue.isMerged,
@@ -175,21 +175,30 @@ class Issue extends Component {
} = this.props;
const params = navigation.state.params;
- const issueURL = params.issueURL || params.issue.url;
- const issueRepository = issueURL
- .replace(`${v3.root}/repos/`, '')
- .replace(/([^/]+\/[^/]+)\/issues\/\d+$/, '$1');
+ let issueURL = params.issueURL || params.issue.url;
+ 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 = `${v3.root}/repos/${issueRepository}`;
+
+ if (!issueURL) {
+ issueURL = `${repositoryUrl}/issues/${params.issue.number}`;
+ }
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 +342,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..52469ad7e 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,
@@ -14,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,
@@ -26,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) => {
@@ -120,18 +123,51 @@ export const getRepositoryFile = url => {
};
};
-export const getIssues = url => {
+export const getPullRequests = repoFullName => {
return (dispatch, getState) => {
const accessToken = getState().auth.accessToken;
+ const [owner, name] = repoFullName.split('/');
+ const body = {
+ query: pullRequestsQuery,
+ variables: { owner, name },
+ };
+
+ 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;
+ const [owner, name] = repoFullName.split('/');
+ const body = {
+ query: issuesQuery,
+ variables: { owner, name },
+ };
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 => {
@@ -237,14 +273,11 @@ export const getRepositoryInfo = url => {
return (dispatch, getState) => {
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'
- );
+ const contributorsUrl = repo.contributors_url;
+ dispatch(getIssues(repo.full_name));
+ dispatch(getPullRequests(repo.full_name));
dispatch(getContributors(contributorsUrl));
- dispatch(getIssues(issuesUrl));
dispatch(
checkReadMe(
`${v3.root}/repos/${repo.owner.login}/${repo.name}/readme?ref=master`
diff --git a/src/repository/repository.query.js b/src/repository/repository.query.js
new file mode 100644
index 000000000..1897ae81b
--- /dev/null
+++ b/src/repository/repository.query.js
@@ -0,0 +1,49 @@
+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 = `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
+ }
+ }
+ }
+ }
+}`;
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 d7452e053..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;
@@ -280,43 +278,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 (issues.length > 0) {
+ navigation.navigate('IssueList', {
+ title: translate('repository.issueList.title', language),
+ type: 'issue',
+ issues,
+ });
+ } 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 =>
+
+ )}
+ }
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
.slice(0, 3)
- .map(item => (
+ .map(item =>
- ))}
+ )}