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,
|
||||
titleBarStyle: 'hidden-inset', // Hide OS chrome, except traffic light buttons (OS X)
|
||||
width: 450,
|
||||
height: 450
|
||||
height: 600
|
||||
})
|
||||
win.loadURL(config.INDEX)
|
||||
|
||||
|
||||
@@ -215,17 +215,6 @@ a:not(.disabled):hover, i:not(.disabled):hover {
|
||||
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
|
||||
*/
|
||||
@@ -256,15 +245,21 @@ body.drag::before {
|
||||
padding-top: 37px;
|
||||
}
|
||||
|
||||
.get-started {
|
||||
opacity: .5;
|
||||
padding: 24px;
|
||||
margin: 6px;
|
||||
.drop-target {
|
||||
padding: 20px;
|
||||
margin: 10px;
|
||||
text-align: center;
|
||||
border: 5px #444 dashed;
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
body.drag .drop-target {
|
||||
border-color: #def;
|
||||
color: #def;
|
||||
}
|
||||
|
||||
.torrent {
|
||||
height: 120px;
|
||||
background: linear-gradient(to bottom right, #4B79A1, #283E51);
|
||||
@@ -305,8 +300,8 @@ body.drag::before {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.torrent .buttons > :not(:first-child) {
|
||||
margin-left: 10px; /* space buttons by 10px */
|
||||
.torrent .buttons > * {
|
||||
margin-right: 6px; /* space buttons apart, align the Xs under the + */
|
||||
}
|
||||
|
||||
.torrent .buttons .download {
|
||||
@@ -316,6 +311,7 @@ body.drag::before {
|
||||
border-radius: 14px;
|
||||
font-size: 18px;
|
||||
padding-top: 6px;
|
||||
margin-right: 10px; /* download and play btns need more space to look good */
|
||||
}
|
||||
|
||||
.torrent .buttons .download.downloading {
|
||||
@@ -326,8 +322,14 @@ body.drag::before {
|
||||
}
|
||||
|
||||
@keyframes greenpulse {
|
||||
0% { color: #ffffff }
|
||||
100% { color: #44dd44 }
|
||||
0% {
|
||||
color: #ffffff;
|
||||
padding-top: 4px;
|
||||
}
|
||||
100% {
|
||||
color: #44dd44;
|
||||
padding-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.torrent .buttons .download.seeding {
|
||||
@@ -339,6 +341,25 @@ body.drag::before {
|
||||
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 {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ function init () {
|
||||
} else {
|
||||
dispatch('back')
|
||||
}
|
||||
} else if (e.which === 32) {
|
||||
} else if (e.which === 32) { /* spacebar pauses or plays the video */
|
||||
dispatch('playPause')
|
||||
}
|
||||
})
|
||||
@@ -434,10 +434,21 @@ function stopServer () {
|
||||
state.server = null
|
||||
}
|
||||
|
||||
function openPlayer (infoHash) {
|
||||
startServer(infoHash, function () {
|
||||
function openPlayer (torrentSummary) {
|
||||
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'
|
||||
/* TODO: set state.title to the clean name of the torrent */
|
||||
state.title = torrentSummary.name
|
||||
update()
|
||||
})
|
||||
}
|
||||
@@ -455,9 +466,7 @@ function closePlayer () {
|
||||
update()
|
||||
}
|
||||
|
||||
function toggleTorrent (infoHash) {
|
||||
var torrentSummary = getTorrentSummary(infoHash)
|
||||
if (!torrentSummary) return
|
||||
function toggleTorrent (torrentSummary) {
|
||||
if (torrentSummary.status === 'paused') {
|
||||
torrentSummary.status = 'new'
|
||||
startTorrenting(torrentSummary.infoHash)
|
||||
@@ -467,7 +476,8 @@ function toggleTorrent (infoHash) {
|
||||
}
|
||||
}
|
||||
|
||||
function deleteTorrent (infoHash) {
|
||||
function deleteTorrent (torrentSummary) {
|
||||
var infoHash = torrentSummary.infoHash
|
||||
var torrent = getTorrent(infoHash)
|
||||
torrent.destroy()
|
||||
|
||||
|
||||
@@ -17,17 +17,13 @@ function prettyBytes (b) {
|
||||
function TorrentList (state, dispatch) {
|
||||
var list = state.saved.torrents.map(
|
||||
(torrentSummary) => renderTorrent(torrentSummary, state, dispatch))
|
||||
if (list.length === 0) list = emptyList()
|
||||
return hx`<div class='torrent-list'>${list}</div>`
|
||||
}
|
||||
|
||||
function emptyList () {
|
||||
return hx`
|
||||
<div class="get-started">
|
||||
<p>No torrents here yet.</p>
|
||||
<p>Drop a file or paste an address to get started!</p>
|
||||
</div>
|
||||
`
|
||||
<div class='torrent-list'>
|
||||
${list}
|
||||
<div class='drop-target'>
|
||||
<p>Drop a torrent file here or paste a magnet link</p>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
// 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,
|
||||
// cast buttons if available, and delete
|
||||
return hx`
|
||||
<div class='torrent' style=${style}>
|
||||
<div class='torrent ${torrentSummary.playStatus || ''}' style=${style}>
|
||||
${renderTorrentMetadata(torrent, torrentSummary)}
|
||||
${renderTorrentButtons(torrentSummary, dispatch)}
|
||||
</div>
|
||||
@@ -103,21 +99,20 @@ function renderTorrentMetadata (torrent, torrentSummary) {
|
||||
// Download button toggles between torrenting (DL/seed) and paused
|
||||
// Play button starts streaming the torrent immediately, unpausing if needed
|
||||
function renderTorrentButtons (torrentSummary, dispatch) {
|
||||
var infoHash = torrentSummary.infoHash
|
||||
return hx`
|
||||
<div class="buttons">
|
||||
<i.btn.icon.download
|
||||
class='${torrentSummary.status}'
|
||||
onclick=${() => dispatch('toggleTorrent', infoHash)}>
|
||||
file_download
|
||||
onclick=${() => dispatch('toggleTorrent', torrentSummary)}>
|
||||
${torrentSummary.status === 'seeding' ? 'file_upload' : 'file_download'}
|
||||
</i>
|
||||
<i.btn.icon.play
|
||||
onclick=${() => dispatch('openPlayer', infoHash)}>
|
||||
play_arrow
|
||||
onclick=${() => dispatch('openPlayer', torrentSummary)}>
|
||||
${torrentSummary.playStatus === 'timeout' ? 'warning' : 'play_arrow'}
|
||||
</i>
|
||||
<i
|
||||
class='icon delete'
|
||||
onclick=${() => dispatch('deleteTorrent', infoHash)}>
|
||||
onclick=${() => dispatch('deleteTorrent', torrentSummary)}>
|
||||
close
|
||||
</i>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user