diff --git a/package.json b/package.json
index 33d5b4e9..e80a07b6 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"create-torrent": "^3.22.1",
"debug": "^2.2.0",
"drag-drop": "^2.3.1",
+ "hyperx": "^1.4.0",
"network-address": "^1.1.0",
"pretty-bytes": "^3.0.0",
"throttleit": "^1.0.0",
diff --git a/renderer/views/app.js b/renderer/views/app.js
index 3659c5b5..b691ba06 100644
--- a/renderer/views/app.js
+++ b/renderer/views/app.js
@@ -1,22 +1,26 @@
module.exports = App
var h = require('virtual-dom/h')
+var hyperx = require('hyperx')
+var hx = hyperx(h)
var Header = require('./header')
var Player = require('./player')
var TorrentList = require('./torrent-list')
function App (state, dispatch) {
- return h('.app', [
- Header(state, dispatch),
- h('.content', [
- (function () {
- if (state.view.url === '/') {
- return TorrentList(state, dispatch)
- } else if (state.view.url === '/player') {
- return Player(state, dispatch)
- }
- })()
- ])
- ])
+ function getView () {
+ if (state.view.url === '/') {
+ return TorrentList(state, dispatch)
+ } else if (state.view.url === '/player') {
+ return Player(state, dispatch)
+ }
+ }
+
+ return hx`
+
+ ${Header(state, dispatch)}
+ ${getView()}
+
+ `
}
diff --git a/renderer/views/header.js b/renderer/views/header.js
index ca0c3f0e..eb9bd3cf 100644
--- a/renderer/views/header.js
+++ b/renderer/views/header.js
@@ -1,32 +1,34 @@
module.exports = Header
var h = require('virtual-dom/h')
+var hyperx = require('hyperx')
+var hx = hyperx(h)
function Header (state, dispatch) {
- return h('.header', [
- (function () {
- if (process.platform === 'darwin') {
- return h('.title', state.view.title)
- }
- })(),
- h('.nav.left', [
- h('i.icon.back', {
- onclick: onBack
- }, 'chevron_left'),
- h('i.icon.forward', {
- onclick: onForward
- }, 'chevron_right')
- ]),
- (function () {
- if (state.view.url !== '/player') {
- return h('.nav.right', [
- h('i.icon.add', {
- onclick: onAddTorrent
- }, 'add')
- ])
- }
- })()
- ])
+ return hx`
+
+ ${getTitle()}
+
+ chevron_left
+ chevron_right
+
+
+ ${plusButton()}
+
+
+ `
+
+ function getTitle () {
+ if (process.platform === 'darwin') {
+ return hx`${state.view.title}`
+ }
+ }
+
+ function plusButton () {
+ if (state.view.url !== '/player') {
+ return hx`add`
+ }
+ }
function onBack (e) {
dispatch('back')
diff --git a/renderer/views/player.js b/renderer/views/player.js
index 2b0405f1..49c8f08b 100644
--- a/renderer/views/player.js
+++ b/renderer/views/player.js
@@ -1,6 +1,8 @@
module.exports = Player
var h = require('virtual-dom/h')
+var hyperx = require('hyperx')
+var hx = hyperx(h)
var electron = require('electron')
function Player (state, dispatch) {
@@ -23,14 +25,16 @@ function Player (state, dispatch) {
}
// Show the video as large as will fit in the window, play immediately
- return h('.player', [
- h('video', {
- src: state.server.localURL,
- autoplay: true,
- onloadedmetadata: onLoadedMetadata
- }),
- renderPlayerControls(state, dispatch)
- ])
+ return hx`
+
+
+ ${renderPlayerControls(state, dispatch)}
+
+ `
// As soon as the video loads far enough to know the dimensions, resize the
// window to match the video resolution
@@ -48,22 +52,22 @@ function Player (state, dispatch) {
// TODO: cast buttons
function renderPlayerControls (state, dispatch) {
var positionPercent = 100 * state.video.currentTime / state.video.duration
- return h('.player-controls', [
- h('.scrub-bar', {
- onclick: handleScrub,
- ondrag: handleScrub
- }, [
- h('.loading-bar', renderLoadingBar(state)),
- h('.playback-cursor', {
- style: {
- left: 'calc(' + positionPercent + '% - 4px)'
- }
- })
- ]),
- h('i.icon.play-pause', {
- onclick: () => dispatch('playPause')
- }, state.video.isPaused ? 'play_arrow' : 'pause')
- ])
+ var playbackCursorStyle = { left: 'calc(' + positionPercent + '% - 4px)' }
+
+ return hx`
+
+
+ ${renderLoadingBar(state)}
+
+
+ dispatch('playPause')}>
+ ${state.video.isPaused ? 'play_arrow' : 'pause'}
+
+
+ `
// Handles a click or drag to scrub (jump to another position in the video)
function handleScrub (e) {
@@ -99,12 +103,16 @@ function renderLoadingBar (state) {
}
// Output an list of rectangles to show loading progress
- return parts.map(function (part) {
- return h('.loading-bar-part', {
- style: {
- left: (100 * part.start / numParts) + '%',
- width: (100 * part.count / numParts) + '%'
- }
- })
- })
+ return hx`
+
+ ${parts.map(function (part) {
+ var style = {
+ left: (100 * part.start / numParts) + '%',
+ width: (100 * part.count / numParts) + '%'
+ }
+
+ return hx``
+ })}
+
+ `
}
diff --git a/renderer/views/torrent-list.js b/renderer/views/torrent-list.js
index 88dfca3f..1c387bdd 100644
--- a/renderer/views/torrent-list.js
+++ b/renderer/views/torrent-list.js
@@ -1,6 +1,8 @@
module.exports = TorrentList
var h = require('virtual-dom/h')
+var hyperx = require('hyperx')
+var hx = hyperx(h)
var prettyBytes = require('pretty-bytes')
function TorrentList (state, dispatch) {
@@ -9,7 +11,7 @@ function TorrentList (state, dispatch) {
: []
var list = torrents.map((torrent) => renderTorrent(state, dispatch, torrent))
- return h('.torrent-list', list)
+ return hx`${list}`
}
// Renders a torrent in the torrent list
@@ -19,51 +21,74 @@ function renderTorrent (state, dispatch, torrent) {
// Background image: show some nice visuals, like a frame from the movie, if possible
var style = {}
if (torrent.posterURL) {
- style['background-image'] = 'linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 100%), url("' + torrent.posterURL + '")'
+ style['background-image'] = `linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 100%), url("${torrent.posterURL}")`
}
// Foreground: name of the torrent, basic info like size, play button,
// cast buttons if available, and delete
var elements = [
renderTorrentMetadata(torrent),
- h('i.icon.delete', {
- onclick: () => dispatch('deleteTorrent', torrent)
- }, 'close'),
- h('i.btn.icon.play', {
- className: !torrent.ready ? 'disabled' : '',
- onclick: () => dispatch('openPlayer', torrent)
- }, 'play_arrow')
+ hx`
+ dispatch('deleteTorrent', torrent)}>
+ close
+
+ `,
+ hx`
+ dispatch('openPlayer', torrent)}>
+ play_arrow
+
+ `
]
+
if (state.view.chromecast) {
- elements.push(h('i.btn.icon.chromecast', {
- className: !torrent.ready ? 'disabled' : '',
- onclick: () => dispatch('openChromecast', torrent)
- }, 'cast'))
- }
- if (state.view.devices.airplay) {
- elements.push(h('i.btn.icon.airplay', {
- className: !torrent.ready ? 'disabled' : '',
- onclick: () => dispatch('openAirplay', torrent)
- }, 'airplay'))
+ elements.push(hx`
+ dispatch('openChromecast', torrent)}>
+ cast
+
+ `)
}
- return h('.torrent', {style: style}, elements)
+ if (state.view.devices.airplay) {
+ elements.push(hx`
+ dispatch('openAirplay', torrent)}>
+ airplay
+
+ `)
+ }
+
+ return hx`${elements}`
}
// Renders the torrent name and download progress
function renderTorrentMetadata (torrent) {
- return h('.metadata', [
- h('.name.ellipsis', torrent.name || 'Loading torrent...'),
- h('.status', [
- h('span.progress', Math.floor(100 * torrent.progress) + '%'),
- (function () {
- if (torrent.ready && torrent.files.length > 1) {
- return h('span.files', torrent.files.length + ' files')
- }
- })(),
- h('span', torrent.numPeers + ' ' + (torrent.numPeers === 1 ? 'peer' : 'peers')),
- h('span', prettyBytes(torrent.downloadSpeed) + '/s'),
- h('span', prettyBytes(torrent.uploadSpeed) + '/s')
- ])
- ])
+ return hx`
+
+ ${torrent.name || 'Loading torrent...'}
+
+ ${Math.floor(100 * torrent.progress)}%
+
+ ${getFilesLength()}
+ ${getPeers()}
+ ${prettyBytes(torrent.downloadSpeed)}/s
+ ${prettyBytes(torrent.uploadSpeed)}/s
+
+ `
+
+ function getPeers () {
+ var count = torrent.numPeers === 1 ? 'peer' : 'peers'
+ return `${torrent.numPeers} ${count}`
+ }
+
+ function getFilesLength () {
+ if (torrent.ready && torrent.files.length > 1) {
+ return hx`${torrent.files.length} files`
+ }
+ }
}