@@ -436,7 +436,8 @@ input {
|
|||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.torrent.requested .play {
|
.torrent.requested .play,
|
||||||
|
.loading-spinner {
|
||||||
border-top: 6px solid rgba(255, 255, 255, 0.2);
|
border-top: 6px solid rgba(255, 255, 255, 0.2);
|
||||||
border-right: 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-bottom: 6px solid rgba(255, 255, 255, 0.2);
|
||||||
@@ -708,10 +709,10 @@ body.drag .torrent-placeholder span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AUDIO DETAILS
|
* MEDIA OVERLAY / AUDIO DETAILS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.audio-metadata {
|
.media-overlay {
|
||||||
width: 500px;
|
width: 500px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -723,6 +724,12 @@ body.drag .torrent-placeholder span {
|
|||||||
line-height: 2;
|
line-height: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.media-stalled .loading-spinner {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.audio-metadata .audio-title {
|
.audio-metadata .audio-title {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,6 +284,15 @@ function dispatch (action, ...args) {
|
|||||||
state.playing.isPaused = true
|
state.playing.isPaused = true
|
||||||
ipcRenderer.send('unblockPowerSave')
|
ipcRenderer.send('unblockPowerSave')
|
||||||
}
|
}
|
||||||
|
if (action === 'mediaStalled') {
|
||||||
|
state.playing.isStalled = true
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
if (action === 'mediaTimeUpdate') {
|
||||||
|
state.playing.lastTimeUpdate = new Date().getTime()
|
||||||
|
state.playing.isStalled = false
|
||||||
|
update()
|
||||||
|
}
|
||||||
if (action === 'toggleFullScreen') {
|
if (action === 'toggleFullScreen') {
|
||||||
ipcRenderer.send('toggleFullScreen', args[0] /* optional bool */)
|
ipcRenderer.send('toggleFullScreen', args[0] /* optional bool */)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ module.exports = {
|
|||||||
currentTime: 0, /* seconds */
|
currentTime: 0, /* seconds */
|
||||||
duration: 1, /* seconds */
|
duration: 1, /* seconds */
|
||||||
isPaused: true,
|
isPaused: true,
|
||||||
|
isStalled: false,
|
||||||
|
lastTimeUpdate: 0, /* Unix time in ms */
|
||||||
mouseStationarySince: 0 /* Unix time in ms */
|
mouseStationarySince: 0 /* Unix time in ms */
|
||||||
},
|
},
|
||||||
audioInfo: null, /* set whenever an audio file is playing */
|
audioInfo: null, /* set whenever an audio file is playing */
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ function renderMedia (state) {
|
|||||||
mediaElement.currentTime = state.playing.jumpToTime
|
mediaElement.currentTime = state.playing.jumpToTime
|
||||||
state.playing.jumpToTime = null
|
state.playing.jumpToTime = null
|
||||||
}
|
}
|
||||||
// set volume
|
// Set volume
|
||||||
if (state.playing.setVolume !== null && isFinite(state.playing.setVolume)) {
|
if (state.playing.setVolume !== null && isFinite(state.playing.setVolume)) {
|
||||||
mediaElement.volume = state.playing.setVolume
|
mediaElement.volume = state.playing.setVolume
|
||||||
state.playing.setVolume = null
|
state.playing.setVolume = null
|
||||||
@@ -60,6 +60,8 @@ function renderMedia (state) {
|
|||||||
onended=${onEnded}
|
onended=${onEnded}
|
||||||
onplay=${dispatcher('mediaPlaying')}
|
onplay=${dispatcher('mediaPlaying')}
|
||||||
onpause=${dispatcher('mediaPaused')}
|
onpause=${dispatcher('mediaPaused')}
|
||||||
|
onstalling=${dispatcher('mediaStalled')}
|
||||||
|
ontimeupdate=${dispatcher('mediaTimeUpdate')}
|
||||||
autoplay>
|
autoplay>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@@ -78,7 +80,7 @@ function renderMedia (state) {
|
|||||||
style=${style}
|
style=${style}
|
||||||
onmousemove=${dispatcher('mediaMouseMoved')}>
|
onmousemove=${dispatcher('mediaMouseMoved')}>
|
||||||
${mediaTag}
|
${mediaTag}
|
||||||
${renderAudioMetadata(state)}
|
${renderOverlay(state)}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -99,6 +101,18 @@ function renderMedia (state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderOverlay (state) {
|
||||||
|
var audioMetadataElem = renderAudioMetadata(state)
|
||||||
|
var spinnerElem = renderLoadingSpinner(state)
|
||||||
|
|
||||||
|
var elems = []
|
||||||
|
if (audioMetadataElem) elems.push(audioMetadataElem)
|
||||||
|
if (spinnerElem) elems.push(spinnerElem)
|
||||||
|
if (elems.length === 0) return
|
||||||
|
|
||||||
|
return hx`<div class='media-overlay'>${elems}</div>`
|
||||||
|
}
|
||||||
|
|
||||||
function renderAudioMetadata (state) {
|
function renderAudioMetadata (state) {
|
||||||
if (!state.playing.audioInfo) return
|
if (!state.playing.audioInfo) return
|
||||||
var info = state.playing.audioInfo
|
var info = state.playing.audioInfo
|
||||||
@@ -127,6 +141,20 @@ function renderAudioMetadata (state) {
|
|||||||
return hx`<div class='audio-metadata'>${elems}</div>`
|
return hx`<div class='audio-metadata'>${elems}</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderLoadingSpinner (state) {
|
||||||
|
if (state.playing.isPaused) return
|
||||||
|
var isProbablyStalled = state.playing.isStalled ||
|
||||||
|
(new Date().getTime() - state.playing.lastTimeUpdate > 2000)
|
||||||
|
console.log("STALLED? " + isProbablyStalled)
|
||||||
|
if (!isProbablyStalled) return
|
||||||
|
|
||||||
|
return hx`
|
||||||
|
<div class='media-stalled'>
|
||||||
|
<div class='loading-spinner'> </div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
function renderCastScreen (state) {
|
function renderCastScreen (state) {
|
||||||
var isChromecast = state.playing.location.startsWith('chromecast')
|
var isChromecast = state.playing.location.startsWith('chromecast')
|
||||||
var isAirplay = state.playing.location.startsWith('airplay')
|
var isAirplay = state.playing.location.startsWith('airplay')
|
||||||
@@ -282,7 +310,7 @@ function renderLoadingBar (state) {
|
|||||||
lastPartPresent = partPresent
|
lastPartPresent = partPresent
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output an list of rectangles to show loading progress
|
// Output some bars to show which parts of the file are loaded
|
||||||
return hx`
|
return hx`
|
||||||
<div class='loading-bar'>
|
<div class='loading-bar'>
|
||||||
${parts.map(function (part) {
|
${parts.map(function (part) {
|
||||||
|
|||||||
Reference in New Issue
Block a user