Skip to content

Commit

Permalink
Coincap (#6)
Browse files Browse the repository at this point in the history
* Use coincap for realtime updates

* Update GIF
  • Loading branch information
harshjv authored Oct 18, 2016
1 parent 2dfe47d commit 9b528ab
Show file tree
Hide file tree
Showing 23 changed files with 585 additions and 197 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"bitcoin",
"ethereum"
],
"homepage": "https://github.com/harshjv/donut",
"homepage": "https://harshjv.github.io/donut/",
"ignore": [
"**/.*",
"node_modules",
Expand Down
Binary file modified donut.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 17 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "donut",
"version": "1.2.0",
"version": "2.0.0",
"description": "Cross platform cryptocurrency tracker",
"main": "main.js",
"scripts": {
Expand Down Expand Up @@ -31,24 +31,27 @@
"babelify": "^7.3.0",
"bower": "^1.7.9",
"browserify": "^13.1.0",
"bufferutil": "^1.2.1",
"classnames": "^2.2.5",
"electron": "^1.4.1",
"electron-builder": "^7.11.4",
"envify": "^3.4.1",
"flux": "^3.0.0",
"gulp": "^3.9.1",
"gulp-cssnano": "^2.1.2",
"gulp-rename": "^1.2.2",
"gulp-sass": "^2.3.2",
"uglifyify": "^3.0.3",
"vinyl-source-stream": "^1.1.0",
"classnames": "^2.2.5",
"humanize-duration": "^3.9.1",
"flux": "^3.0.0",
"halogen": "^0.2.0",
"keymirror": "^0.1.1",
"numeral": "^1.5.3",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-search-input": "^0.10.3",
"request": "^2.75.0"
"request": "^2.75.0",
"socket.io-client": "^1.5.0",
"uglifyify": "^3.0.3",
"utf-8-validate": "^1.2.1",
"vinyl-source-stream": "^1.1.0"
},
"build": {
"appId": "com.harshjv.donut",
Expand All @@ -58,7 +61,13 @@
},
"linux": {
"category": "Utility",
"target": [ "AppImage", "deb", "rpm", "freebsd", "zip" ]
"target": [
"AppImage",
"deb",
"rpm",
"freebsd",
"zip"
]
}
}
}
103 changes: 85 additions & 18 deletions src/app/actions/Actions.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,88 @@
import { ActionTypes } from '../constants/Constants'
/* global Notification */

import io from 'socket.io-client'

const { shell } = window.require('electron')

import ActionTypes from '../constants/ActionTypes'
import AppDispatcher from '../dispatcher/Dispatcher'

import api from '../utils/api'
import checkForUpdate from '../utils/checkForUpdate'
import pkg from '../../package.json'

const dispatchTrade = (trade) => {
AppDispatcher.dispatch({
type: ActionTypes.NEW_TRADE,
data: {
trade: trade
}
})
}

const dispatchOnline = () => {
AppDispatcher.dispatch({
type: ActionTypes.ONLINE
})
}

const dispatchOffline = () => {
AppDispatcher.dispatch({
type: ActionTypes.OFFLINE
})
}

export default {
initSocketConnection () {
let socket = io.connect('http://coincap.io')

socket.on('connect', () => {
console.log('Connected to CoinCap server')

AppDispatcher.dispatch({
type: ActionTypes.ONLINE
})
})

socket.on('trades', dispatchTrade)
window.addEventListener('online', dispatchOnline)
window.addEventListener('offline', dispatchOffline)
},

fetchCurrencyData () {
console.log('Fetching currency data')

api.currencyAPI((error, currency_data) => {
if (error) throw new Error(error)

console.log('Currency data fetched successfully')

AppDispatcher.dispatch({
type: ActionTypes.CURRENCY_DATA,
data: {
currency_data: currency_data
}
})
})
},

fetchCoinData () {
console.log('Fetching coin data')

api.frontAPI((error, coin_data) => {
if (error) throw new Error(error)

console.log('Coin map fetched successfully')

AppDispatcher.dispatch({
type: ActionTypes.COIN_DATA,
data: {
coin_data: coin_data
}
})
})
},

checkForUpdate () {
console.log('Checking for update')

Expand All @@ -16,6 +94,12 @@ export default {
if (updateAvailable) {
console.log('Update available', updateAvailable)

const updateNotification = new Notification('New version available', {
body: `Click here to download ${updateAvailable}. You have v${pkg.version}.`
})

updateNotification.onclick = () => shell.openExternal(`${pkg.repository}/releases/latest`)

AppDispatcher.dispatch({
type: ActionTypes.UPDATE_AVAILABLE,
data: {
Expand All @@ -24,22 +108,5 @@ export default {
})
}
})
},

fetchData () {
console.log('Fetching data')

api((error, data) => {
if (error) throw new Error(error)

console.log('Data fetched successfully')

AppDispatcher.dispatch({
type: ActionTypes.COIN_DATA,
data: {
coins: data
}
})
})
}
}
34 changes: 21 additions & 13 deletions src/app/components/App.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react'
import SearchInput from 'react-search-input'
import ScaleLoader from 'halogen/ScaleLoader'

import coinStore from '../stores/CoinStore'
import CoinStore from '../stores/CoinStore'
import Actions from '../actions/Actions'

import Coin from './Coin.jsx'
import Footer from './Footer.jsx'
Expand All @@ -14,42 +16,48 @@ export default class App extends React.Component {
query: ''
}

this.onChange = this.onChange.bind(this)
this.searchUpdated = this.searchUpdated.bind(this)
this.onCoinStoreUpdate = this.onCoinStoreUpdate.bind(this)
this.onSearch = this.onSearch.bind(this)
}

shouldComponentUpdate (nextProps, nextState) {
if (!this.state.coinIDs) return true
else return this.state.coinIDs.length !== nextState.coinIDs.length
}

componentDidMount () {
coinStore.addChangeListener(this.onChange)
Actions.initSocketConnection()
CoinStore.addChangeListener(this.onCoinStoreUpdate)
}

componentWillUnmount () {
coinStore.removeChangeListener(this.onChange)
CoinStore.removeChangeListener(this.onCoinStoreUpdate)
}

onChange () {
onCoinStoreUpdate () {
this.setState({
coin_ids: coinStore.getCoinIDs(this.state.query)
coinIDs: CoinStore.getCoinIDs(this.state.query)
})
}

renderCoins () {
if (this.state.coin_ids) {
return this.state.coin_ids.map((coin_id) => <Coin id={coin_id} key={coin_id} />)
if (this.state.coinIDs) {
return this.state.coinIDs.map((coinID) => <Coin id={coinID} key={coinID} />)
} else {
return (
<li className='list-group-item'>
<div className='media-body text-center'>
<strong>Loading...</strong>
<ScaleLoader color='#d1cfd1' size='32px'/>
</div>
</li>
)
}
}

searchUpdated (query) {
onSearch (query) {
this.setState({
query: query,
coin_ids: coinStore.getCoinIDs(query)
coinIDs: CoinStore.getCoinIDs(query)
})
}

Expand All @@ -60,7 +68,7 @@ export default class App extends React.Component {
<div className='window'>
<header className='toolbar toolbar-header'>
<span className='icon icon-search' />
<SearchInput type='text' className='search-bar' placeholder='Search for a coin e.g. btc or ethereum' onChange={this.searchUpdated} />
<SearchInput type='text' className='search-bar' placeholder='Search for a coin or token e.g. btc or digixdao' onChange={this.onSearch} />
</header>
<div className='window-content'>
<ul className='list-group'>
Expand Down
Loading

0 comments on commit 9b528ab

Please sign in to comment.