react github timeline
by Victor Melnik
HTML
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="timeline">
</div>
CSS
body {
font-family: Helvetica, Verdana, Arial, sans-serif;
font-size: 16px;
font-weight: 300;
}
#timeline h1 {
text-align: center;
}
.progress {
position: relative;
display: block;
height: 2px;
margin: 0 auto;
width: 70%;
}
.progress div {
position: absolute;
top: 0;
display: block;
height: 2px;
}
.progress .background {
background-color: #c7c7c7;
width: 100%;
}
.progress .line {
background-color: #5282d2;
z-index: 999;
}
#timeline {
width: 90%;
margin: 0 auto;
}
#timeline ul {
list-style: none;
margin: 10px 0;
padding: 0;
}
#timeline li {
display: block;
position: relative;
background-color: #FEFEFE;
border: 2px solid #FEFEFE;
margin: 0 auto 10px;
padding: 6px;
padding-bottom: 5px;
box-shadow: 0px 1px 2px rgba(34, 25, 25, 0.4);
}
.avatar {
float: left;
max-width: 48px;
max-height: 48px;
margin-bottom: 5px;
}
.headline {
float: left;
margin-left: 8px;
}
.user {
color: #000;
font-size: 120%;
font-weight: bold;
}
.small,
.time {
font-size: 80%;
color: #777;
}
.time {
margin-bottom: 5px;
font-size: small;
}
.clearfix {
clear: both;
}
Babel + JSX
// Hack for jsfiddle, in normal app you would write it as follows:
// import React, { Component } from 'react';
const { Component } = React;
class App extends Component {
state = {
time: 0,
timeMax: 6,
events: []
}
componentWillMount() {
this.onUpdate();
}
onUpdate = () => {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.github.com/events');
xhr.onload = () => {
const events = JSON.parse(xhr.responseText);
const timeMax = xhr.getResponseHeader("X-Poll-Interval");
this.setState({ time: 0, timeMax, events })
this.startTimer();
};
xhr.send();
};
startTimer = () => {
this.timerID = setInterval(this.tick, 1000);
};
tick = () => {
const {time, timeMax} = this.state
if (time >= timeMax) {
clearInterval(this.timerID);
this.setState({ time: 0, timeMax: 10 })
this.onUpdate()
} else {
this.setState({ time: time + 1, timeMax })
}
};
render() {
return (
<div>
<h1>GitHub Timeline</h1>
<Timeline time={this.state.time} timeMax={this.state.timeMax} />
<Events events={this.state.events} />
</div>
)
}
}
class Timeline extends Component {
render() {
const { time, timeMax } = this.props;
const width = (Math.floor(time * 100 / timeMax) + '%')
return (
<div className="progress">
<div className="line" style={{ width }}></div>
<div className="background"></div>
</div>
)
}
}
class Events extends Component {
render() {
return (
<ul>
{
this.props.events.map(e => <Event key={e.id} event={e} />)
}
</ul>
)
}
}
class Event extends Component {
formatDate = (v) => v.replace(/T|Z/g, ' ');
renderEvent(event) {
switch (event.type) {
case 'CommitCommentEvent':
return <CommitComment event={event}/>
case 'CreateEvent':
return <Create event={event}/>
case 'DeleteEvent':
...