diff --git a/app/api/CircleCI.js b/app/api/CircleCI.js
index 9269a40..53de0a2 100644
--- a/app/api/CircleCI.js
+++ b/app/api/CircleCI.js
@@ -6,15 +6,34 @@ function JSONify(response) {
return response.json();
}
+const [GET] = ['GET'];
+
export function checkToken(possibleToken) {
const url = endpoints.get('USER_INFO');
- return request(url, 'GET', {}, possibleToken).then(function (response) {
+ return request(url, GET, {}, possibleToken).then(function (response) {
return response.ok;
});
}
+export async function getUserDetails() {
+ const CIToken = await token.get();
+ const url = endpoints.get('USER_INFO');
+ return await request(url, GET, {}, CIToken).then(JSONify);
+}
+
export async function getProjects() {
const CIToken = await token.get();
const url = endpoints.get('ALL_PROJECTS');
- return await request(url, 'GET', {}, CIToken).then(JSONify);
+ return await request(url, GET, {}, CIToken).then(JSONify);
+}
+
+export async function getProjectRecentBuilds(user, repo) {
+ const CIToken = await token.get();
+ const url = endpoints.get('PROJECT_RECENTS').param({ user, repo });
+ return await request(
+ url,
+ GET,
+ {},
+ CIToken)
+ .then(JSONify);
}
diff --git a/app/api/endpoints.js b/app/api/endpoints.js
index 25f4399..088ec8d 100644
--- a/app/api/endpoints.js
+++ b/app/api/endpoints.js
@@ -5,5 +5,7 @@ const URL_BASE = UrlAssembler('https://circleci.com/api/v1');
export default Map({
USER_INFO: URL_BASE.segment('/me'),
- ALL_PROJECTS: URL_BASE.segment('/projects')
+ ALL_PROJECTS: URL_BASE.segment('/projects'),
+ RECENT_BUILDS: URL_BASE.segment('/recent-builds'),
+ PROJECT_RECENTS: URL_BASE.template('/project/:user/:repo')
});
diff --git a/app/components/app.js b/app/components/app.js
index 396f8e7..c8d65ea 100644
--- a/app/components/app.js
+++ b/app/components/app.js
@@ -32,7 +32,7 @@ export default class extends React.Component {
diff --git a/app/components/projects/ProjectItem.js b/app/components/projects/ProjectItem.js
index f0ac41b..6cdd62f 100644
--- a/app/components/projects/ProjectItem.js
+++ b/app/components/projects/ProjectItem.js
@@ -1,15 +1,84 @@
import React from 'react-native';
+import GlobalStyles from '../../settings/styles';
+import { getProjectRecentBuilds } from '../../api/CircleCI';
-var {
+const {
View,
Text,
- StyleSheet,
+ StyleSheet
} = React;
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ height: 70,
+ alignItems: 'stretch',
+ backgroundColor: GlobalStyles.get('CIRCLE_ITEM_BG'),
+ borderBottomColor: GlobalStyles.get('CIRCLE_ITEM_BORDER'),
+ borderBottomWidth: 1,
+ marginBottom: 5,
+ flexDirection: 'row'
+ },
+ cell: {
+ paddingHorizontal: 4,
+ paddingVertical: 2
+ },
+ imageCell: {
+ width: 45,
+ },
+ repoName: {
+ fontSize: 14,
+ fontWeight: '500'
+ }
+});
+
export default class ProjectItem extends React.Component {
- render() {
+ constructor() {
+ super();
+ this.state = {
+ recentBuild: false
+ };
+ this._displayMoreInfo = this._displayMoreInfo.bind(this);
+ }
+
+ componentDidMount() {
+ getProjectRecentBuilds(this.props.project.username, this.props.project.reponame).then(function (recentBuild) {
+ this.setState({ recentBuild: recentBuild[0] });
+ }.bind(this));
+ }
+
+ _displayMoreInfo(mostRecentBuild) {
+ let seconds = Math.floor(mostRecentBuild.build_time_millis / 1000);
+ const minutes = Math.floor(seconds / 60);
+ seconds = seconds - (minutes * 60);
+ const format = minutes + ':' + seconds;
return (
- {this.props.project.reponame}
+ { format }
+ );
+ }
+
+ render() {
+ console.log(this.props.userDetails);
+ const project = this.props.project;
+ const mostRecentBuild = this.state.recentBuild;
+ const statusColour = mostRecentBuild.failed ? '#ED5C5C' : '#42C88A';
+ let username;
+ if (this.props.userDetails && this.props.userDetails.login !== project.username) {
+ username = project.username;
+ } else {
+ username = 'me';
+ }
+ const buildDetails = mostRecentBuild ? this._displayMoreInfo(mostRecentBuild) : null;
+
+ return (
+
+
+
+
+ {username}/{project.reponame}
+ { buildDetails }
+
+
);
}
};
diff --git a/app/components/projects/ProjectList.js b/app/components/projects/ProjectList.js
index bd1d60d..2acda9b 100644
--- a/app/components/projects/ProjectList.js
+++ b/app/components/projects/ProjectList.js
@@ -2,20 +2,19 @@ import React from 'react-native';
import ProjectItem from './ProjectItem';
-var {
+const {
ListView,
StyleSheet,
- Text,
ScrollView
} = React;
-var styles = StyleSheet.create({
- composerListView: {
+const styles = StyleSheet.create({
+ listView: {
flex: 1,
- flexDirection: 'row',
+ flexDirection: 'column',
+ alignItems: 'stretch',
justifyContent: 'center',
flexWrap: 'wrap',
- padding: 15
},
});
@@ -23,24 +22,32 @@ export default class ProjectList extends React.Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
- console.log(JSON.stringify(this.props.data));
+ const sortedProjects = this._sortByDate(this.props.data);
this.state = {
- dataSource: ds.cloneWithRows(this.props.data)
+ dataSource: ds.cloneWithRows(sortedProjects),
};
this.renderRow = this.renderRow.bind(this);
}
+ _sortByDate(projects) {
+ return projects.sort(function (a, b) {
+ const keyA = a.username + '/' + a.reponame;
+ const keyB = b.reponame + '/' + b.username;
+ if (keyA < keyB) { return -1; }
+ if (keyA > keyB) { return 1; }
+ return 0;
+ }.bind(this));
+ }
+
renderRow(project) {
- return (
-
- );
+ return ;
}
render() {
return (
diff --git a/app/components/routes/home.js b/app/components/routes/home.js
index 352d4fa..9f19bcc 100644
--- a/app/components/routes/home.js
+++ b/app/components/routes/home.js
@@ -1,12 +1,12 @@
import React from 'react-native';
-import { getProjects } from '../../api/CircleCI';
+import { getProjects, getUserDetails } from '../../api/CircleCI';
import loaderHandler from 'react-native-busy-indicator/LoaderHandler';
import ProjectList from '../projects/ProjectList';
import GlobalStyles from '../../settings/styles';
+
const {
StyleSheet,
- Text,
View,
BackAndroid,
} = React;
@@ -23,7 +23,8 @@ export default class Home extends React.Component {
super();
this.state = {
- projects: ''
+ projects: '',
+ userDetails: ''
};
}
@@ -37,18 +38,26 @@ export default class Home extends React.Component {
}
componentDidMount() {
+ this.props.nav.navigationContext.addListener('didfocus', function () {
+ this.props.nav.immediatelyResetRouteStack([this.props.currentRoute]);
+ }.bind(this));
+
getProjects().then(function (data) {
this.setState({
projects: data
});
}.bind(this));
+
+ getUserDetails().then(function (userDetails) {
+ this.setState({userDetails});
+ }.bind(this));
}
render() {
let list;
if (this.state.projects) {
list = (
-
+
);
loaderHandler.hideLoader();
} else {