Torrent list styling
* Download button is a lot easier to read: white down arrow when off, animated and pulsating green down arrow when downloading, solid green up arrow when seeding * Play button shows a spinner if you click play before a torrent is ready, then an exclamation point if the torrent still isn't ready after 10 seconds * Drop target shows up always, not just when the torrent list is empty. Lights up when you drag something * Fixed alignment, the Xs to delete torrents are now aligned with the + to add a new torrent
This commit is contained in:
@@ -26,7 +26,7 @@ function createMainWindow (menu) {
|
|||||||
title: config.APP_NAME,
|
title: config.APP_NAME,
|
||||||
titleBarStyle: 'hidden-inset', // Hide OS chrome, except traffic light buttons (OS X)
|
titleBarStyle: 'hidden-inset', // Hide OS chrome, except traffic light buttons (OS X)
|
||||||
width: 450,
|
width: 450,
|
||||||
height: 450
|
height: 600
|
||||||
})
|
})
|
||||||
win.loadURL(config.INDEX)
|
win.loadURL(config.INDEX)
|
||||||
|
|
||||||
|
|||||||
@@ -215,17 +215,6 @@ a:not(.disabled):hover, i:not(.disabled):hover {
|
|||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.drag::before {
|
|
||||||
content: '';
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
background: rgba(255, 0, 0, 0.3);
|
|
||||||
border: 5px #f00 dashed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PLAYER
|
* PLAYER
|
||||||
*/
|
*/
|
||||||
@@ -256,15 +245,21 @@ body.drag::before {
|
|||||||
padding-top: 37px;
|
padding-top: 37px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.get-started {
|
.drop-target {
|
||||||
opacity: .5;
|
padding: 20px;
|
||||||
padding: 24px;
|
margin: 10px;
|
||||||
margin: 6px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 5px #444 dashed;
|
border: 5px #444 dashed;
|
||||||
|
color: #666;
|
||||||
|
font-size: 16px;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.drag .drop-target {
|
||||||
|
border-color: #def;
|
||||||
|
color: #def;
|
||||||
|
}
|
||||||
|
|
||||||
.torrent {
|
.torrent {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
background: linear-gradient(to bottom right, #4B79A1, #283E51);
|
background: linear-gradient(to bottom right, #4B79A1, #283E51);
|
||||||
@@ -305,8 +300,8 @@ body.drag::before {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.torrent .buttons > :not(:first-child) {
|
.torrent .buttons > * {
|
||||||
margin-left: 10px; /* space buttons by 10px */
|
margin-right: 6px; /* space buttons apart, align the Xs under the + */
|
||||||
}
|
}
|
||||||
|
|
||||||
.torrent .buttons .download {
|
.torrent .buttons .download {
|
||||||
@@ -316,6 +311,7 @@ body.drag::before {
|
|||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
|
margin-right: 10px; /* download and play btns need more space to look good */
|
||||||
}
|
}
|
||||||
|
|
||||||
.torrent .buttons .download.downloading {
|
.torrent .buttons .download.downloading {
|
||||||
@@ -326,8 +322,14 @@ body.drag::before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes greenpulse {
|
@keyframes greenpulse {
|
||||||
0% { color: #ffffff }
|
0% {
|
||||||
100% { color: #44dd44 }
|
color: #ffffff;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
color: #44dd44;
|
||||||
|
padding-top: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.torrent .buttons .download.seeding {
|
.torrent .buttons .download.seeding {
|
||||||
@@ -339,6 +341,25 @@ body.drag::before {
|
|||||||
background-color: #F44336;
|
background-color: #F44336;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.torrent.requested .play {
|
||||||
|
border-top: 6px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-right: 6px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-bottom: 6px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-left: 6px solid #ffffff;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: transparent;
|
||||||
|
animation: load8 1.1s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes load8 {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.torrent .buttons .delete {
|
.torrent .buttons .delete {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ function init () {
|
|||||||
} else {
|
} else {
|
||||||
dispatch('back')
|
dispatch('back')
|
||||||
}
|
}
|
||||||
} else if (e.which === 32) {
|
} else if (e.which === 32) { /* spacebar pauses or plays the video */
|
||||||
dispatch('playPause')
|
dispatch('playPause')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -434,10 +434,21 @@ function stopServer () {
|
|||||||
state.server = null
|
state.server = null
|
||||||
}
|
}
|
||||||
|
|
||||||
function openPlayer (infoHash) {
|
function openPlayer (torrentSummary) {
|
||||||
startServer(infoHash, function () {
|
torrentSummary.playStatus = 'requested'
|
||||||
|
var timeout = setTimeout(function () {
|
||||||
|
torrentSummary.playStatus = 'timeout' /* no seeders available? */
|
||||||
|
}, 10000) /* give it a few seconds */
|
||||||
|
startServer(torrentSummary.infoHash, function () {
|
||||||
|
// if we timed out (user clicked play a long time ago), don't autoplay
|
||||||
|
clearTimeout(timeout)
|
||||||
|
var timedOut = torrentSummary.playStatus === 'timeout'
|
||||||
|
delete torrentSummary.playStatus
|
||||||
|
if (timedOut) return
|
||||||
|
|
||||||
|
// otherwise, play the video
|
||||||
state.url = '/player'
|
state.url = '/player'
|
||||||
/* TODO: set state.title to the clean name of the torrent */
|
state.title = torrentSummary.name
|
||||||
update()
|
update()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -455,9 +466,7 @@ function closePlayer () {
|
|||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTorrent (infoHash) {
|
function toggleTorrent (torrentSummary) {
|
||||||
var torrentSummary = getTorrentSummary(infoHash)
|
|
||||||
if (!torrentSummary) return
|
|
||||||
if (torrentSummary.status === 'paused') {
|
if (torrentSummary.status === 'paused') {
|
||||||
torrentSummary.status = 'new'
|
torrentSummary.status = 'new'
|
||||||
startTorrenting(torrentSummary.infoHash)
|
startTorrenting(torrentSummary.infoHash)
|
||||||
@@ -467,7 +476,8 @@ function toggleTorrent (infoHash) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteTorrent (infoHash) {
|
function deleteTorrent (torrentSummary) {
|
||||||
|
var infoHash = torrentSummary.infoHash
|
||||||
var torrent = getTorrent(infoHash)
|
var torrent = getTorrent(infoHash)
|
||||||
torrent.destroy()
|
torrent.destroy()
|
||||||
|
|
||||||
|
|||||||
@@ -17,17 +17,13 @@ function prettyBytes (b) {
|
|||||||
function TorrentList (state, dispatch) {
|
function TorrentList (state, dispatch) {
|
||||||
var list = state.saved.torrents.map(
|
var list = state.saved.torrents.map(
|
||||||
(torrentSummary) => renderTorrent(torrentSummary, state, dispatch))
|
(torrentSummary) => renderTorrent(torrentSummary, state, dispatch))
|
||||||
if (list.length === 0) list = emptyList()
|
|
||||||
return hx`<div class='torrent-list'>${list}</div>`
|
|
||||||
}
|
|
||||||
|
|
||||||
function emptyList () {
|
|
||||||
return hx`
|
return hx`
|
||||||
<div class="get-started">
|
<div class='torrent-list'>
|
||||||
<p>No torrents here yet.</p>
|
${list}
|
||||||
<p>Drop a file or paste an address to get started!</p>
|
<div class='drop-target'>
|
||||||
</div>
|
<p>Drop a torrent file here or paste a magnet link</p>
|
||||||
`
|
</div>
|
||||||
|
</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renders a torrent in the torrent list
|
// Renders a torrent in the torrent list
|
||||||
@@ -48,7 +44,7 @@ function renderTorrent (torrentSummary, state, dispatch) {
|
|||||||
// Foreground: name of the torrent, basic info like size, play button,
|
// Foreground: name of the torrent, basic info like size, play button,
|
||||||
// cast buttons if available, and delete
|
// cast buttons if available, and delete
|
||||||
return hx`
|
return hx`
|
||||||
<div class='torrent' style=${style}>
|
<div class='torrent ${torrentSummary.playStatus || ''}' style=${style}>
|
||||||
${renderTorrentMetadata(torrent, torrentSummary)}
|
${renderTorrentMetadata(torrent, torrentSummary)}
|
||||||
${renderTorrentButtons(torrentSummary, dispatch)}
|
${renderTorrentButtons(torrentSummary, dispatch)}
|
||||||
</div>
|
</div>
|
||||||
@@ -103,21 +99,20 @@ function renderTorrentMetadata (torrent, torrentSummary) {
|
|||||||
// Download button toggles between torrenting (DL/seed) and paused
|
// Download button toggles between torrenting (DL/seed) and paused
|
||||||
// Play button starts streaming the torrent immediately, unpausing if needed
|
// Play button starts streaming the torrent immediately, unpausing if needed
|
||||||
function renderTorrentButtons (torrentSummary, dispatch) {
|
function renderTorrentButtons (torrentSummary, dispatch) {
|
||||||
var infoHash = torrentSummary.infoHash
|
|
||||||
return hx`
|
return hx`
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<i.btn.icon.download
|
<i.btn.icon.download
|
||||||
class='${torrentSummary.status}'
|
class='${torrentSummary.status}'
|
||||||
onclick=${() => dispatch('toggleTorrent', infoHash)}>
|
onclick=${() => dispatch('toggleTorrent', torrentSummary)}>
|
||||||
file_download
|
${torrentSummary.status === 'seeding' ? 'file_upload' : 'file_download'}
|
||||||
</i>
|
</i>
|
||||||
<i.btn.icon.play
|
<i.btn.icon.play
|
||||||
onclick=${() => dispatch('openPlayer', infoHash)}>
|
onclick=${() => dispatch('openPlayer', torrentSummary)}>
|
||||||
play_arrow
|
${torrentSummary.playStatus === 'timeout' ? 'warning' : 'play_arrow'}
|
||||||
</i>
|
</i>
|
||||||
<i
|
<i
|
||||||
class='icon delete'
|
class='icon delete'
|
||||||
onclick=${() => dispatch('deleteTorrent', infoHash)}>
|
onclick=${() => dispatch('deleteTorrent', torrentSummary)}>
|
||||||
close
|
close
|
||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user