diff options
Diffstat (limited to 'webui')
-rw-r--r-- | webui/src/Components/Timeline/DateNode.js | 12 | ||||
-rw-r--r-- | webui/src/Components/Timeline/EndNode.js | 9 | ||||
-rw-r--r-- | webui/src/Components/Timeline/EventMessages.js | 9 | ||||
-rw-r--r-- | webui/src/Components/Timeline/EventNode.js | 76 | ||||
-rw-r--r-- | webui/src/Event.js | 88 | ||||
-rw-r--r-- | webui/src/Timeline.js | 294 |
6 files changed, 325 insertions, 163 deletions
diff --git a/webui/src/Components/Timeline/DateNode.js b/webui/src/Components/Timeline/DateNode.js index 6f3b78f..a8013f0 100644 --- a/webui/src/Components/Timeline/DateNode.js +++ b/webui/src/Components/Timeline/DateNode.js @@ -2,20 +2,12 @@ import React, { Component } from 'react'; import './DateNode.scss'; class DateNode extends Component { - constructor(props) { - super(props); - - this.state = { - date: props.date, - first: props.first - }; - } render() { return ( - <div className={"DateNode " + (this.state.first ? 'first' : '')}> + <div className={"DateNode " + (this.props.first ? 'first' : '')}> <span className="horizontal-line"></span> - <p className="date">{this.state.date}</p> + <p className="date">{this.props.date}</p> </div> ); } diff --git a/webui/src/Components/Timeline/EndNode.js b/webui/src/Components/Timeline/EndNode.js index 072872c..6844b40 100644 --- a/webui/src/Components/Timeline/EndNode.js +++ b/webui/src/Components/Timeline/EndNode.js @@ -2,19 +2,12 @@ import React, { Component } from 'react'; import './EndNode.scss'; class EndNode extends Component { - constructor(props) { - super(props); - - this.state = { - date: props.date - }; - } render() { return ( <div className={"EndNode"}> <span className="horizontal-line"></span> - <p className="date">{this.state.date}</p> + <p className="date">{this.props.date}</p> </div> ); } diff --git a/webui/src/Components/Timeline/EventMessages.js b/webui/src/Components/Timeline/EventMessages.js index 309df6e..b3a277f 100644 --- a/webui/src/Components/Timeline/EventMessages.js +++ b/webui/src/Components/Timeline/EventMessages.js @@ -2,17 +2,10 @@ import React, { Component } from 'react'; import './EventMessages.scss'; class EventMessages extends Component { - constructor(props) { - super(props); - - this.state = { - event: props.event - }; - } getMessages() { - var messages = this.state.event.messages; + var messages = this.props.event.messages; if(!messages) return; diff --git a/webui/src/Components/Timeline/EventNode.js b/webui/src/Components/Timeline/EventNode.js index 9b2a308..74022a7 100644 --- a/webui/src/Components/Timeline/EventNode.js +++ b/webui/src/Components/Timeline/EventNode.js @@ -1,97 +1,31 @@ import React, { Component } from 'react'; import './EventNode.scss'; -import moment from 'moment'; class EventNode extends Component { - constructor(props) { - super(props); - - this.state = { - event: props.event, - alignment: props.alignment - }; - } - - getColorClass() { - - if(this.state.event.type === "StartupEvent") - return "green"; - - if(this.state.event.type === "WebhookAction") - return "blue"; - - return "purple"; - } - - getTitle() { - - if(this.state.event.type === "StartupEvent") - return "Startup"; - - if(this.state.event.type === "WebhookAction") - return "Webhook"; - - return this.state.event.type; - } - - getSubtitle() { - - if(this.state.event.type === "StartupEvent") { - - if(this.state.event.address) - return "Listening on " + this.state.event.address + " port " + this.state.event.port; - - return "Starting up.." - } - - if(this.state.event.type === "WebhookAction") - return "Incoming request from " + this.state.event['client-address']; - - return this.state.event.type; - } - - getDate() { - return moment.unix(this.state.event.timestamp).format("YYYY-MM-DD"); - } - - getTime() { - return moment.unix(this.state.event.timestamp).format("HH:mm"); - } - - getIconName() { - - if(this.state.event.success === false) - return "alert" - - if(this.state.event.type === "StartupEvent") - return "alert-circle"; - - return "check"; - } getIconElement() { - if(this.state.event.waiting === true) { + if(this.props.event.isWaiting()) { return ( <div className="icon spinner"></div> ); } return ( - <i className={"icon mdi mdi-" + this.getIconName()} /> + <i className={"icon mdi mdi-" + this.props.event.getIconName()} /> ); } render() { return ( - <div className={"EventNode " + this.state.alignment + " " + this.getColorClass()}> + <div className={"EventNode " + this.props.alignment + " " + this.props.event.getColorClass()}> <span className="horizontal-line"></span> <span className="timeline-icon"></span> <div className="inner"> <div className="header"> {this.getIconElement()} - <p className="title">{this.getTitle()}</p> - <p className="subtitle">{this.getSubtitle()}</p> + <p className="title">{this.props.event.getTitle()}</p> + <p className="subtitle">{this.props.event.getSubtitle()}</p> </div> <div className="body"> {this.props.children} diff --git a/webui/src/Event.js b/webui/src/Event.js new file mode 100644 index 0000000..f74908d --- /dev/null +++ b/webui/src/Event.js @@ -0,0 +1,88 @@ +import moment from 'moment'; + +class Event { + + constructor(event) { + var self = this; + self.event = event; + + for(var key in event) { + if(!event.hasOwnProperty(key)) + continue; + self[key] = event[key]; + } + } + + getColorClass() { + + if(this.event.type === "StartupEvent") + return "green"; + + if(this.event.type === "WebhookAction") + return "blue"; + + return "purple"; + } + + getTitle() { + + if(this.event.type === "StartupEvent") + return "Startup"; + + if(this.event.type === "WebhookAction") + return "Webhook"; + + return this.event.type; + } + + getSubtitle() { + + if(this.event.type === "StartupEvent") { + + if(this.isWaiting()) + return "Starting up.." + + return "Listening for incoming connections"; + } + + if(this.event.type === "WebhookAction") { + if(this.event.messages.length) + return this.event.messages[this.event.messages.length - 1] + return "Incoming request from " + this.event['client-address']; + } + + return this.event.type; + } + + getDate() { + return moment.unix(this.event.timestamp).format("YYYY-MM-DD"); + } + + getTime() { + return moment.unix(this.event.timestamp).format("HH:mm"); + } + + getIconName() { + + if(this.event.success === false) + return "alert" + + if(this.event.type === "StartupEvent") + return "alert-circle"; + + return "check"; + } + + isWaiting() { + if(this.event.type === "StartupEvent") { + if(this.event['ws-started'] !== true || this.event['http-started'] !== true) { + return true; + } + } else if(this.event.waiting === true) { + return true; + } + return false; + } +} + +export default Event; diff --git a/webui/src/Timeline.js b/webui/src/Timeline.js index 52e42df..80c9d98 100644 --- a/webui/src/Timeline.js +++ b/webui/src/Timeline.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import './Timeline.scss'; import axios from 'axios'; +import Event from './Event'; import EventNode from './Components/Timeline/EventNode'; import DateNode from './Components/Timeline/DateNode'; import EndNode from './Components/Timeline/EndNode'; @@ -15,9 +16,73 @@ class Timeline extends Component { events: [], loaded: false }; + + this.wsSocket = null; + this.wsIsOpen = false; + this.wsIsRecovering = false; + this.wsPort = 9000; } componentDidMount() { + this.fetchEventList(); + this.initWebsocketConnection(); + this.initUserNotification(); + } + + initUserNotification() { + if(!('Notification' in window)) + return; + + // Not yet approved? + if (Notification.permission === 'default') { + + // Request permission + return Notification.requestPermission(function() { + //console.log("Got permission!"); + }); + } + } + + showUserNotification(event) { + + if(!('Notification' in window)) + return; + + if(Notification.permission !== "granted") + return; + + // define new notification + var n = new Notification( + event.getSubtitle(), + { + 'body': event.getTitle(), + 'tag' : "event-" + event.id + } + ); + + // notify when shown successfull + n.onshow = function () { + console.log("onshow"); + }; + + // remove the notification from Notification Center when clicked. + n.onclick = function () { + this.close(); + console.log("onclick"); + }; + + // callback function when the notification is closed. + n.onclose = function () { + console.log("onclose"); + }; + + // notification cannot be presented to the user, this event is fired if the permission level is set to denied or default. + n.onerror = function () { + console.log("onerror"); + }; + } + + fetchEventList() { var url = '/api/status'; @@ -27,79 +92,176 @@ class Timeline extends Component { axios.get(url) .then(res => { - - //const posts = res.data.data.children.map(obj => obj.data); - const events = res.data.map(obj => - { - //obj.key = obj.id; - //console.log(obj); - return obj; - } - ); - - /* - events.push({ - type: "WebhookAction", - timestamp: 1483200720 - }); - - events.push({ - "request-body": "{\"ref\":\"refs/heads/master\",\"before\":\"b24b817fc553be4abf425028e33398a6cf7da5bd\",\"after\":\"7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"created\":false,\"deleted\":false,\"forced\":false,\"base_ref\":null,\"compare\":\"https://github.com/olipo186/Git-Auto-Deploy/compare/b24b817fc553...7bb2fa6d10ca\",\"commits\":[{\"id\":\"465183e17af7b33f03047f53832ceea75140c29c\",\"tree_id\":\"c5ca854add997d6e6c840ddb37b89da26d9cc380\",\"distinct\":true,\"message\":\"Update README.md\\n\\nUpdate pip installing command\",\"timestamp\":\"2016-12-27T11:54:19+08:00\",\"url\":\"https://github.com/olipo186/Git-Auto-Deploy/commit/465183e17af7b33f03047f53832ceea75140c29c\",\"author\":{\"name\":\"Sunnyyoung\",\"email\":\"Sunnyyoung@users.noreply.github.com\",\"username\":\"Sunnyyoung\"},\"committer\":{\"name\":\"GitHub\",\"email\":\"noreply@github.com\",\"username\":\"web-flow\"},\"added\":[],\"removed\":[],\"modified\":[\"README.md\"]},{\"id\":\"7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"tree_id\":\"c5ca854add997d6e6c840ddb37b89da26d9cc380\",\"distinct\":true,\"message\":\"Merge pull request #157 from Sunnyyoung/master\\n\\nUpdate README.md\",\"timestamp\":\"2016-12-27T11:50:05+01:00\",\"url\":\"https://github.com/olipo186/Git-Auto-Deploy/commit/7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"author\":{\"name\":\"Oliver Poignant\",\"email\":\"oliver@poignant.se\",\"username\":\"olipo186\"},\"committer\":{\"name\":\"GitHub\",\"email\":\"noreply@github.com\",\"username\":\"web-flow\"},\"added\":[],\"removed\":[],\"modified\":[\"README.md\"]}],\"head_commit\":{\"id\":\"7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"tree_id\":\"c5ca854add997d6e6c840ddb37b89da26d9cc380\",\"distinct\":true,\"message\":\"Merge pull request #157 from Sunnyyoung/master\\n\\nUpdate README.md\",\"timestamp\":\"2016-12-27T11:50:05+01:00\",\"url\":\"https://github.com/olipo186/Git-Auto-Deploy/commit/7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"author\":{\"name\":\"Oliver Poignant\",\"email\":\"oliver@poignant.se\",\"username\":\"olipo186\"},\"committer\":{\"name\":\"GitHub\",\"email\":\"noreply@github.com\",\"username\":\"web-flow\"},\"added\":[],\"removed\":[],\"modified\":[\"README.md\"]},\"repository\":{\"id\":10534595,\"name\":\"Git-Auto-Deploy\",\"full_name\":\"olipo186/Git-Auto-Deploy\",\"owner\":{\"name\":\"olipo186\",\"email\":\"oliver@poignant.se\"},\"private\":false,\"html_url\":\"https://github.com/olipo186/Git-Auto-Deploy\",\"description\":\"Deploy your GitHub, GitLab or Bitbucket projects automatically on Git push events or webhooks using this small HTTP server written in Python. Continuous deployment in it's most simple form.\",\"fork\":false,\"url\":\"https://github.com/olipo186/Git-Auto-Deploy\",\"forks_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/forks\",\"keys_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/teams\",\"hooks_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/hooks\",\"issue_events_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/events\",\"assignees_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/tags\",\"blobs_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/languages\",\"stargazers_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/stargazers\",\"contributors_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/contributors\",\"subscribers_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/subscribers\",\"subscription_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/subscription\",\"commits_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/merges\",\"archive_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/downloads\",\"issues_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/deployments\",\"created_at\":1370546738,\"updated_at\":\"2016-12-27T09:44:12Z\",\"pushed_at\":1482835807,\"git_url\":\"git://github.com/olipo186/Git-Auto-Deploy.git\",\"ssh_url\":\"git@github.com:olipo186/Git-Auto-Deploy.git\",\"clone_url\":\"https://github.com/olipo186/Git-Auto-Deploy.git\",\"svn_url\":\"https://github.com/olipo186/Git-Auto-Deploy\",\"homepage\":\"http://olipo186.github.io/Git-Auto-Deploy/\",\"size\":622,\"stargazers_count\":528,\"watchers_count\":528,\"language\":\"Python\",\"has_issues\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":true,\"forks_count\":115,\"mirror_url\":null,\"open_issues_count\":11,\"forks\":115,\"open_issues\":11,\"watchers\":528,\"default_branch\":\"master\",\"stargazers\":528,\"master_branch\":\"master\"},\"pusher\":{\"name\":\"olipo186\",\"email\":\"oliver@poignant.se\"},\"sender\":{\"login\":\"olipo186\",\"id\":1056476,\"avatar_url\":\"https://avatars.githubusercontent.com/u/1056476?v=3\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/olipo186\",\"html_url\":\"https://github.com/olipo186\",\"followers_url\":\"https://api.github.com/users/olipo186/followers\",\"following_url\":\"https://api.github.com/users/olipo186/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/olipo186/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/olipo186/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/olipo186/subscriptions\",\"organizations_url\":\"https://api.github.com/users/olipo186/orgs\",\"repos_url\":\"https://api.github.com/users/olipo186/repos\",\"events_url\":\"https://api.github.com/users/olipo186/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/olipo186/received_events\",\"type\":\"User\",\"site_admin\":false}}", - "timestamp": 1483187602.554847, - "messages": [ - "Incoming request from 192.30.252.45:61279", - "Handling the request with GitHubRequestParser", - "Received 'push' event from GitHub", - "Deploying", - "Done" - ], - "request-headers": { - "content-length": "7212", - "x-github-event": "push", - "x-github-delivery": "3ade9980-cc22-11e6-9efe-3be1665744c8", - "x-hub-signature": "sha1=b73756e722ba28729aac624a48591fa83163e747", - "user-agent": "GitHub-Hookshot/7676889", - "host": "narpau.se:8001", - "content-type": "application/json" - }, - "client-port": 61279, - "client-address": "192.30.252.45", - "type": "WebhookAction", - "id": 1 - }); - - events.push( { - "request-body": "{\"ref\":\"refs/heads/master\",\"before\":\"b24b817fc553be4abf425028e33398a6cf7da5bd\",\"after\":\"7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"created\":false,\"deleted\":false,\"forced\":false,\"base_ref\":null,\"compare\":\"https://github.com/olipo186/Git-Auto-Deploy/compare/b24b817fc553...7bb2fa6d10ca\",\"commits\":[{\"id\":\"465183e17af7b33f03047f53832ceea75140c29c\",\"tree_id\":\"c5ca854add997d6e6c840ddb37b89da26d9cc380\",\"distinct\":true,\"message\":\"Update README.md\\n\\nUpdate pip installing command\",\"timestamp\":\"2016-12-27T11:54:19+08:00\",\"url\":\"https://github.com/olipo186/Git-Auto-Deploy/commit/465183e17af7b33f03047f53832ceea75140c29c\",\"author\":{\"name\":\"Sunnyyoung\",\"email\":\"Sunnyyoung@users.noreply.github.com\",\"username\":\"Sunnyyoung\"},\"committer\":{\"name\":\"GitHub\",\"email\":\"noreply@github.com\",\"username\":\"web-flow\"},\"added\":[],\"removed\":[],\"modified\":[\"README.md\"]},{\"id\":\"7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"tree_id\":\"c5ca854add997d6e6c840ddb37b89da26d9cc380\",\"distinct\":true,\"message\":\"Merge pull request #157 from Sunnyyoung/master\\n\\nUpdate README.md\",\"timestamp\":\"2016-12-27T11:50:05+01:00\",\"url\":\"https://github.com/olipo186/Git-Auto-Deploy/commit/7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"author\":{\"name\":\"Oliver Poignant\",\"email\":\"oliver@poignant.se\",\"username\":\"olipo186\"},\"committer\":{\"name\":\"GitHub\",\"email\":\"noreply@github.com\",\"username\":\"web-flow\"},\"added\":[],\"removed\":[],\"modified\":[\"README.md\"]}],\"head_commit\":{\"id\":\"7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"tree_id\":\"c5ca854add997d6e6c840ddb37b89da26d9cc380\",\"distinct\":true,\"message\":\"Merge pull request #157 from Sunnyyoung/master\\n\\nUpdate README.md\",\"timestamp\":\"2016-12-27T11:50:05+01:00\",\"url\":\"https://github.com/olipo186/Git-Auto-Deploy/commit/7bb2fa6d10ca6f7eb9a1563bf932d37a97dac5f8\",\"author\":{\"name\":\"Oliver Poignant\",\"email\":\"oliver@poignant.se\",\"username\":\"olipo186\"},\"committer\":{\"name\":\"GitHub\",\"email\":\"noreply@github.com\",\"username\":\"web-flow\"},\"added\":[],\"removed\":[],\"modified\":[\"README.md\"]},\"repository\":{\"id\":10534595,\"name\":\"Git-Auto-Deploy\",\"full_name\":\"olipo186/Git-Auto-Deploy\",\"owner\":{\"name\":\"olipo186\",\"email\":\"oliver@poignant.se\"},\"private\":false,\"html_url\":\"https://github.com/olipo186/Git-Auto-Deploy\",\"description\":\"Deploy your GitHub, GitLab or Bitbucket projects automatically on Git push events or webhooks using this small HTTP server written in Python. Continuous deployment in it's most simple form.\",\"fork\":false,\"url\":\"https://github.com/olipo186/Git-Auto-Deploy\",\"forks_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/forks\",\"keys_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/teams\",\"hooks_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/hooks\",\"issue_events_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/events\",\"assignees_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/tags\",\"blobs_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/languages\",\"stargazers_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/stargazers\",\"contributors_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/contributors\",\"subscribers_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/subscribers\",\"subscription_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/subscription\",\"commits_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/merges\",\"archive_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/downloads\",\"issues_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/olipo186/Git-Auto-Deploy/deployments\",\"created_at\":1370546738,\"updated_at\":\"2016-12-27T09:44:12Z\",\"pushed_at\":1482835807,\"git_url\":\"git://github.com/olipo186/Git-Auto-Deploy.git\",\"ssh_url\":\"git@github.com:olipo186/Git-Auto-Deploy.git\",\"clone_url\":\"https://github.com/olipo186/Git-Auto-Deploy.git\",\"svn_url\":\"https://github.com/olipo186/Git-Auto-Deploy\",\"homepage\":\"http://olipo186.github.io/Git-Auto-Deploy/\",\"size\":622,\"stargazers_count\":528,\"watchers_count\":528,\"language\":\"Python\",\"has_issues\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":true,\"forks_count\":115,\"mirror_url\":null,\"open_issues_count\":11,\"forks\":115,\"open_issues\":11,\"watchers\":528,\"default_branch\":\"master\",\"stargazers\":528,\"master_branch\":\"master\"},\"pusher\":{\"name\":\"olipo186\",\"email\":\"oliver@poignant.se\"},\"sender\":{\"login\":\"olipo186\",\"id\":1056476,\"avatar_url\":\"https://avatars.githubusercontent.com/u/1056476?v=3\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/olipo186\",\"html_url\":\"https://github.com/olipo186\",\"followers_url\":\"https://api.github.com/users/olipo186/followers\",\"following_url\":\"https://api.github.com/users/olipo186/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/olipo186/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/olipo186/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/olipo186/subscriptions\",\"organizations_url\":\"https://api.github.com/users/olipo186/orgs\",\"repos_url\":\"https://api.github.com/users/olipo186/repos\",\"events_url\":\"https://api.github.com/users/olipo186/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/olipo186/received_events\",\"type\":\"User\",\"site_admin\":false}}", - "timestamp": 1483187734.015505, - "messages": [ - "Incoming request from 192.30.252.40:33912", - "Handling the request with GitHubRequestParser", - "Received 'push' event from GitHub", - "Deploying", - "Done" - ], - "request-headers": { - "content-length": "7212", - "x-github-event": "push", - "x-github-delivery": "3ade9980-cc22-11e6-9efe-3be1665744c8", - "x-hub-signature": "sha1=b73756e722ba28729aac624a48591fa83163e747", - "user-agent": "GitHub-Hookshot/7676889", - "host": "narpau.se:8001", - "content-type": "application/json" - }, - "client-port": 33912, - "client-address": "192.30.252.40", - "type": "WebhookAction", - "id": 1 - });*/ - + const events = res.data.events.map(obj => new Event(obj)); + this.wsPort = res.data['web-socket-port']; this.setState({ events: events, loaded: true }); }) .catch(err => { this.setState({loaded: false}); }); + + } + + addOrUpdateEvent(event) { + + this.setState((prevState, props) => { + + var newEvents = []; + var inserted = false; + + for(var key in prevState.events) { + if(prevState.hasOwnProperty(key)) + continue; + var curEvent = prevState.events[key]; + + if(curEvent.id === event.id) { + newEvents.push(event); + inserted = true; + } else { + newEvents.push(curEvent); + } + } + + if(!inserted) { + newEvents.push(event); + } + + return { + events: newEvents + } + + }); + } + + getEventWithId(id) { + var self = this; + + for(var key in self.state.events) { + + if(self.state.hasOwnProperty(key)) + continue; + + var event = self.state.events[key]; + + if(event.id === id) + return event; + + } + + return undefined; + } + + handleJSONMessage(data) { + var event; + + if(data.type === "new-event") { + + event = new Event(data.event); + this.addOrUpdateEvent(event); + + } else if(data.type === "event-updated") { + + event = new Event(data.event); + this.addOrUpdateEvent(event); + + } else if(data.type === "event-success") { + + event = this.getEventWithId(data.id); + + if(event && event.type === "WebhookAction") { + this.showUserNotification(event); + } + + } else { + console.log("Unknown event: " + data.type); + } + } + + getWebsocketURI() { + if (process.env.NODE_ENV === "development") { + return "ws://10.0.0.1:" + this.wsPort; + } + var scheme = window.location.protocol === "https" ? "wss" : "ws"; + return scheme + "://" + window.location.hostname + ":" + this.wsPort; } + initWebsocketConnection() { + var self = this; + var uri = self.getWebsocketURI(); + + self.wsSocket = new WebSocket(uri); + self.wsSocket.binaryType = "arraybuffer"; + self.wsSocket.onopen = function() { + + self.wsIsOpen = true; + + if(self.wsIsRecovering) { + self.wsIsRecovering = false; + self.fetchEventList(); + } + }; + + self.wsSocket.onmessage = (e) => { + if (typeof e.data === "string") { + try { + var data = JSON.parse(e.data); + self.handleJSONMessage(data); + } catch(e) { + console.error(e); + } + } else { + var arr = new Uint8Array(e.data); + var hex = ''; + for (var i = 0; i < arr.length; i++) { + hex += ('00' + arr[i].toString(16)).substr(-2); + } + console.log("Binary message received: " + hex); + } + }; + + self.wsSocket.onclose = function() { + + self.wsSocket.close(); + self.wsSocket = null; + self.wsIsOpen = false; + self.wsIsRecovering = true; + + if(self.wsReconnectTimeout !== undefined) { + clearTimeout(self.wsReconnectTimeout); + } + + // Try to reconnect again after 2 seconds + self.wsReconnectTimeout = setTimeout(function() { + + self.initWebsocketConnection(); + self.wsReconnectTimeout = undefined; + }, 2000); + }; + + } + + /* + function sendText() { + if (isopen) { + socket.send("Hello, world!"); + console.log("Text message sent."); + } else { + console.log("Connection not opened.") + } + }; + function sendBinary() { + if (isopen) { + var buf = new ArrayBuffer(32); + var arr = new Uint8Array(buf); + for (i = 0; i < arr.length; ++i) arr[i] = i; + socket.send(buf); + console.log("Binary message sent."); + } else { + console.log("Connection not opened.") + } + }; + */ + getDate(timestamp) { return moment.unix(timestamp).format("YYYY-MM-DD"); } |