diff --git a/src/js/pages/Video.js b/src/js/pages/Video.js index bb79b9a..c8b26ab 100644 --- a/src/js/pages/Video.js +++ b/src/js/pages/Video.js @@ -56,8 +56,6 @@ export default (routerContext) => { } downloader.setAttribute('expanded', 'true'); - const disabled = (connectionStatus.status === 'offline' && downloader.state !== 'done'); - let videoImageHTML; if (Array.isArray(thumbnail)) { @@ -72,9 +70,21 @@ export default (routerContext) => { const [videoMinutes, videoSeconds] = currentVideoData.length.split(':'); + /** + * Returns whether the current video is available for playback. + * + * @param {object} downloaderOrState Downloader instance or state object. + * @param {string} downloaderOrState.state Downloader state string, e.g. "done". + * @param {boolean} downloaderOrState.willremove Downloader willremove flag. + * @returns {boolean} Whether video is available for playback from any source (network or IDB). + */ + const isVideoAvailable = (downloaderOrState) => connectionStatus.status !== 'offline' // We're are not offline... + || downloaderOrState.state === 'done' // ... or we have the video downloaded + || downloaderOrState.willremove === true; // ... or we're about to remove it, but haven't yet. + mainContent.innerHTML = `
- +
${videoImageHTML} @@ -115,6 +125,16 @@ export default (routerContext) => { mainContent.prepend(posterWrapper); mainContent.querySelector('.downloader').appendChild(downloader); + downloader.subscribe((oldState, newState) => { + const articleEl = mainContent.querySelector('.video-article'); + + if (isVideoAvailable(newState)) { + articleEl.classList.remove('video--disabled'); + } else { + articleEl.classList.add('video--disabled'); + } + }); + const playButton = mainContent.querySelector('.play'); const categorySlug = currentVideoData.categories[0]; const { name, slug } = apiData.categories.find((obj) => obj.slug === categorySlug); diff --git a/src/js/web-components/video-download/VideoDownloader.js b/src/js/web-components/video-download/VideoDownloader.js index ee04111..2abae87 100644 --- a/src/js/web-components/video-download/VideoDownloader.js +++ b/src/js/web-components/video-download/VideoDownloader.js @@ -24,6 +24,9 @@ import getURLsForDownload from '../../utils/getURLsForDownload'; import { MEDIA_SESSION_DEFAULT_ARTWORK } from '../../constants'; export default class VideoDownloader extends HTMLElement { + /** + * @type {string[]} + */ static get observedAttributes() { return ['state', 'progress', 'downloading', 'willremove']; } @@ -55,12 +58,7 @@ export default class VideoDownloader extends HTMLElement { } set state(state) { - const oldState = this.state; this.setAttribute('state', state); - - this.internal.changeCallbacks.forEach( - (callback) => callback(oldState, state), - ); } /** @@ -114,6 +112,24 @@ export default class VideoDownloader extends HTMLElement { const percentageAsDashOffset = 82 - (82 * value); this.internal.root.host.style.setProperty('--progress', percentageAsDashOffset); } + + // Broadcast changes in several internal properties. + const currentState = { + state: this.state, + willremove: this.willremove, + }; + + if (Object.keys(currentState).includes(name)) { + const typecastBooleans = (val) => (['false', 'true'].includes(val) ? val === 'true' : val); + const oldState = { + ...currentState, + [name]: typecastBooleans(old), + }; + + this.internal.changeCallbacks.forEach( + (callback) => callback(oldState, currentState), + ); + } } /** @@ -405,14 +421,12 @@ export default class VideoDownloader extends HTMLElement { await this.removeFromIDB(); window.removeEventListener('beforeunload', this.unloadHandler); }, 5000); - } else if (e.target.classList.contains('action--undo')) { - if (this.willremove === true) { - if (this.removalTimeout) { - this.state = 'done'; - this.willremove = false; - clearTimeout(this.removalTimeout); - window.removeEventListener('beforeunload', this.unloadHandler); - } + } else if (this.willremove === true) { + if (this.removalTimeout) { + this.state = 'done'; + this.willremove = false; + clearTimeout(this.removalTimeout); + window.removeEventListener('beforeunload', this.unloadHandler); } } else if (e.target.classList.contains('action--cancel')) { this.removeFromIDB(); @@ -483,6 +497,7 @@ export default class VideoDownloader extends HTMLElement { } else { this.state = 'ready'; } + this.downloading = false; }