From 0fff2542b7663770a54b6826e4a0307495ecc0d5 Mon Sep 17 00:00:00 2001 From: DispatchCommit Date: Wed, 17 Feb 2021 18:53:25 -0800 Subject: [PATCH 01/16] Add custom quality selector plugin Adds custom video.js hls quality selector plugin This allows the quality selector plugin to stay active and listen for source changes on the player to prevent the need to recreate the player when switching between MP4's and M3U8's --- .../ConcreteButton.js | 85 ++++++ .../ConcreteMenuItem.js | 45 +++ .../videojs-hls-quality-selector/package.json | 109 ++++++++ .../videojs-hls-quality-selector/plugin.js | 260 ++++++++++++++++++ .../videojs-hls-quality-selector/plugin.scss | 9 + .../viewers/videoViewer/internal/videojs.jsx | 21 +- 6 files changed, 522 insertions(+), 7 deletions(-) create mode 100644 ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js create mode 100644 ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js create mode 100644 ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/package.json create mode 100644 ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js create mode 100644 ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.scss diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js new file mode 100644 index 000000000..acff46ffb --- /dev/null +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js @@ -0,0 +1,85 @@ +import videojs from 'video.js'; + +const VideoJsButtonClass = videojs.getComponent('MenuButton'); +const VideoJsMenuClass = videojs.getComponent('Menu'); +const VideoJsComponent = videojs.getComponent('Component'); +const Dom = videojs.dom; + +/** + * Convert string to title case. + * + * @param {string} string - the string to convert + * @return {string} the returned titlecase string + */ +function toTitleCase(string) { + if (typeof string !== 'string') { + return string; + } + + return string.charAt(0).toUpperCase() + string.slice(1); +} + +/** + * Extend vjs button class for quality button. + */ +export default class ConcreteButton extends VideoJsButtonClass { + + /** + * Button constructor. + * + * @param {Player} player - videojs player instance + */ + constructor(player) { + super(player, { + title: player.localize('Quality'), + name: 'QualityButton' + }); + } + + /** + * Creates button items. + * + * @return {Array} - Button items + */ + createItems() { + return []; + } + + /** + * Create the menu and add all items to it. + * + * @return {Menu} + * The constructed menu + */ + createMenu() { + const menu = new VideoJsMenuClass(this.player_, {menuButton: this}); + + this.hideThreshold_ = 0; + + // Add a title list item to the top + if (this.options_.title) { + const titleEl = Dom.createEl('li', { + className: 'vjs-menu-title', + innerHTML: toTitleCase(this.options_.title), + tabIndex: -1 + }); + const titleComponent = new VideoJsComponent(this.player_, {el: titleEl}); + + this.hideThreshold_ += 1; + + menu.addItem(titleComponent); + } + + this.items = this.createItems(); + + if (this.items) { + // Add menu items to the menu + for (let i = 0; i < this.items.length; i++) { + menu.addItem(this.items[i]); + } + } + + return menu; + + } +} diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js new file mode 100644 index 000000000..d1f90ad30 --- /dev/null +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js @@ -0,0 +1,45 @@ +import videojs from 'video.js'; + +// Concrete classes +const VideoJsMenuItemClass = videojs.getComponent('MenuItem'); + +/** + * Extend vjs menu item class. + */ +export default class ConcreteMenuItem extends VideoJsMenuItemClass { + + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {Object} item - Item object + * @param {ConcreteButton} qualityButton - The containing button. + * @param {HlsQualitySelectorPlugin} plugin - This plugin instance. + */ + constructor(player, item, qualityButton, plugin) { + super(player, { + label: item.label, + selectable: true, + selected: item.selected || false + }); + this.item = item; + this.qualityButton = qualityButton; + this.plugin = plugin; + } + + /** + * Click event for menu item. + */ + handleClick() { + + // Reset other menu items selected status. + for (let i = 0; i < this.qualityButton.items.length; ++i) { + this.qualityButton.items[i].selected(false); + } + + // Set this menu item to selected, and set quality. + this.plugin.setQuality(this.item.value); + this.selected(true); + + } +} diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/package.json b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/package.json new file mode 100644 index 000000000..ec66b9117 --- /dev/null +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/package.json @@ -0,0 +1,109 @@ +{ + "name": "videojs-hls-quality-selector", + "version": "1.1.4", + "description": "Adds a quality selector menu for HLS sources played in videojs. Requires `videojs-contrib-hls` and videojs-contrib-quality-levels plugins.", + "main": "dist/videojs-hls-quality-selector.cjs.js", + "module": "dist/videojs-hls-quality-selector.es.js", + "generator-videojs-plugin": { + "version": "5.0.3" + }, + "repository": "https://github.com/chrisboustead/videojs-hls-quality-selector.git", + "scripts": { + "prebuild": "npm run clean", + "build": "npm-run-all -p build:*", + "build:css": "npm-run-all build:css:sass build:css:bannerize", + "build:css:bannerize": "bannerize dist/videojs-hls-quality-selector.css --banner=scripts/banner.ejs", + "build:css:sass": "node-sass src/plugin.scss dist/videojs-hls-quality-selector.css --output-style=compressed --linefeed=lf", + "build:js": "npm-run-all build:js:rollup-modules build:js:rollup-umd build:js:bannerize build:js:uglify", + "build:js:bannerize": "bannerize dist/videojs-hls-quality-selector.js --banner=scripts/banner.ejs", + "build:js:rollup-modules": "rollup -c scripts/modules.rollup.config.js", + "build:js:rollup-umd": "rollup -c scripts/umd.rollup.config.js", + "build:js:uglify": "uglifyjs dist/videojs-hls-quality-selector.js --comments --mangle --compress -o dist/videojs-hls-quality-selector.min.js", + "build:test": "rollup -c scripts/test.rollup.config.js", + "clean": "rimraf dist test/dist", + "postclean": "mkdirp dist test/dist", + "docs": "npm-run-all docs:*", + "docs:api": "jsdoc src -r -c jsdoc.json -d docs/api", + "docs:toc": "doctoc README.md", + "lint": "vjsstandard", + "start": "npm-run-all -p start:server watch", + "start:server": "static -a 0.0.0.0 -p 9999 -H '{\"Cache-Control\": \"no-cache, must-revalidate\"}' .", + "pretest": "npm-run-all lint build", + "test": "karma start test/karma.conf.js", + "preversion": "npm test", + "version": "node scripts/version.js", + "watch": "npm-run-all -p watch:*", + "watch:css": "npm-run-all build:css:sass watch:css:sass", + "watch:css:sass": "node-sass src/plugin.scss dist/videojs-hls-quality-selector.css --output-style=compressed --linefeed=lf --watch src/**/*.scss", + "watch:js-modules": "rollup -c scripts/modules.rollup.config.js -w", + "watch:js-umd": "rollup -c scripts/umd.rollup.config.js -w", + "watch:test": "rollup -c scripts/test.rollup.config.js -w", + "prepublish": "npm run build", + "prepush": "npm run lint", + "precommit": "npm run docs:toc && git add README.md" + }, + "keywords": [ + "videojs", + "videojs-plugin" + ], + "author": "Chris Boustead (chris@forgemotion.com)", + "license": "MIT", + "vjsstandard": { + "ignore": [ + "dist", + "docs", + "test/dist", + "test/karma.conf.js" + ] + }, + "files": [ + "CONTRIBUTING.md", + "dist/", + "docs/", + "index.html", + "scripts/", + "src/", + "test/" + ], + "dependencies": { + "global": "^4.3.2", + "karma-safaritechpreview-launcher": "0.0.6", + "video.js": "^7.5.5", + "videojs-contrib-quality-levels": "^2.0.9" + }, + "devDependencies": { + "babel-plugin-external-helpers": "^6.22.0", + "babel-plugin-transform-object-assign": "^6.8.0", + "babel-preset-es2015": "^6.14.0", + "bannerize": "^1.1.4", + "conventional-changelog-cli": "^1.3.1", + "conventional-changelog-videojs": "^3.0.0", + "doctoc": "^1.3.0", + "husky": "^0.13.3", + "jsdoc": "^3.6.3", + "karma": "^3.1.4", + "karma-chrome-launcher": "^2.1.1", + "karma-detect-browsers": "^2.2.5", + "karma-firefox-launcher": "^1.0.1", + "karma-ie-launcher": "^1.0.0", + "karma-qunit": "^1.2.1", + "karma-safari-launcher": "^1.0.0", + "mkdirp": "^0.5.1", + "node-sass": "^4.14.1", + "node-static": "^0.7.9", + "npm-run-all": "^4.0.2", + "qunitjs": "^2.3.2", + "rimraf": "^2.6.1", + "rollup": "^0.50.0", + "rollup-plugin-babel": "^2.7.1", + "rollup-plugin-commonjs": "^8.0.2", + "rollup-plugin-json": "^2.1.1", + "rollup-plugin-multi-entry": "^2.0.1", + "rollup-plugin-node-resolve": "^3.0.0", + "rollup-watch": "^3.2.2", + "semver": "^5.3.0", + "sinon": "^2.2.0", + "uglify-js": "^3.0.7", + "videojs-standard": "^6.0.0" + } +} diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js new file mode 100644 index 000000000..1a253073a --- /dev/null +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js @@ -0,0 +1,260 @@ +import videojs from 'video.js'; +import {version as VERSION} from './package.json'; +import ConcreteButton from './ConcreteButton'; +import ConcreteMenuItem from './ConcreteMenuItem'; + +// Default options for the plugin. +const defaults = {}; + +// Cross-compatibility for Video.js 5 and 6. +const registerPlugin = videojs.registerPlugin || videojs.plugin; +// const dom = videojs.dom || videojs; + +/** + * VideoJS HLS Quality Selector Plugin class. + */ +class HlsQualitySelectorPlugin { + + /** + * Plugin Constructor. + * + * @param {Player} player - The videojs player instance. + * @param {Object} options - The plugin options. + */ + constructor(player, options) { + this.player = player; + this.config = options; + + if (!this.player.qualityLevels) { + console.warn(`WARNING: Missing video.js quality levels plugin (required)`); + return; + } + + this.setupPlugin(); + } + + setupPlugin() { + // Create the quality button. + this.createQualityButton(); + + // Bind event listeners + this.bindPlayerEvents(); + + // Listen for source changes + this.player.on('loadedmetadata', (e) => { + console.log(`Loaded Metadata detected by plugin!`, e); + this.updatePlugin(); + }); + } + + updatePlugin() { + console.log(`Updating Quality Selector...`); + + // If there is quality levels plugin and the HLS tech exists + // then continue. + if (this.getHls()) { + console.log('Show quality selector'); + // Show quality selector + this._qualityButton.show(); + } else { + console.log('Hide quality selector'); + console.log('Source type does not support multiple qulaity levels...'); + // Hide quality selector + this._qualityButton.hide(); + } + } + + /** + * Returns HLS Plugin + * + * @return {*} - videojs-hls-contrib plugin. + */ + getHls() { + return this.player.tech({ IWillNotUseThisInPlugins: true }).hls; + } + + /** + * Binds listener for quality level changes. + */ + bindPlayerEvents() { + this.player.qualityLevels().on('addqualitylevel', this.onAddQualityLevel.bind(this)); + } + + /** + * Adds the quality menu button to the player control bar. + */ + createQualityButton() { + + const player = this.player; + + this._qualityButton = new ConcreteButton(player); + + const placementIndex = player.controlBar.children().length - 2; + const concreteButtonInstance = player.controlBar.addChild(this._qualityButton, + {componentClass: 'qualitySelector'}, + this.config.placementIndex || placementIndex); + + concreteButtonInstance.addClass('vjs-quality-selector'); + if (!this.config.displayCurrentQuality) { + const icon = ` ${this.config.vjsIconClass || 'vjs-icon-hd'}`; + + concreteButtonInstance + .menuButton_.$('.vjs-icon-placeholder').className += icon; + } else { + this.setButtonInnerText('auto'); + } + concreteButtonInstance.removeClass('vjs-hidden'); + + } + + /** + *Set inner button text. + * + * @param {string} text - the text to display in the button. + */ + setButtonInnerText(text) { + this._qualityButton + .menuButton_.$('.vjs-icon-placeholder').innerHTML = text; + } + + /** + * Builds individual quality menu items. + * + * @param {Object} item - Individual quality menu item. + * @return {ConcreteMenuItem} - Menu item + */ + getQualityMenuItem(item) { + const player = this.player; + + return new ConcreteMenuItem(player, item, this._qualityButton, this); + } + + /** + * Executed when a quality level is added from HLS playlist. + */ + onAddQualityLevel() { + + const player = this.player; + const qualityList = player.qualityLevels(); + const levels = qualityList.levels_ || []; + const levelItems = []; + + for (let i = 0; i < levels.length; ++i) { + if (!levelItems.filter(_existingItem => { + return _existingItem.item && _existingItem.item.value === levels[i].height; + }).length) { + const levelItem = this.getQualityMenuItem.call(this, { + label: levels[i].height + 'p', + value: levels[i].height + }); + + levelItems.push(levelItem); + } + } + + levelItems.sort((current, next) => { + if ((typeof current !== 'object') || (typeof next !== 'object')) { + return -1; + } + if (current.item.value < next.item.value) { + return -1; + } + if (current.item.value > next.item.value) { + return 1; + } + return 0; + }); + + levelItems.push(this.getQualityMenuItem.call(this, { + label: player.localize('Auto'), + value: 'auto', + selected: true + })); + + if (this._qualityButton) { + this._qualityButton.createItems = function() { + return levelItems; + }; + this._qualityButton.update(); + } + + } + + /** + * Sets quality (based on media height) + * + * @param {number} height - A number representing HLS playlist. + */ + setQuality(height) { + const qualityList = this.player.qualityLevels(); + + // Set quality on plugin + this._currentQuality = height; + + if (this.config.displayCurrentQuality) { + this.setButtonInnerText(height === 'auto' ? height : `${height}p`); + } + + for (let i = 0; i < qualityList.length; ++i) { + const quality = qualityList[i]; + + quality.enabled = (quality.height === height || height === 'auto'); + } + this._qualityButton.unpressButton(); + } + + /** + * Return the current set quality or 'auto' + * + * @return {string} the currently set quality + */ + getCurrentQuality() { + return this._currentQuality || 'auto'; + } + +} + +/** + * Function to invoke when the player is ready. + * + * This is a great place for your plugin to initialize itself. When this + * function is called, the player will have its DOM and child components + * in place. + * + * @function onPlayerReady + * @param {Player} player + * A Video.js player object. + * + * @param {Object} [options={}] + * A plain object containing options for the plugin. + */ +const onPlayerReady = (player, options) => { + player.addClass('vjs-hls-quality-selector'); + player.hlsQualitySelector = new HlsQualitySelectorPlugin(player, options); +}; + +/** + * A video.js plugin. + * + * In the plugin function, the value of `this` is a video.js `Player` + * instance. You cannot rely on the player being in a "ready" state here, + * depending on how the plugin is invoked. This may or may not be important + * to you; if not, remove the wait for "ready"! + * + * @function hlsQualitySelector + * @param {Object} [options={}] + * An object of options left to the plugin author to define. + */ +const hlsQualitySelector = function(options) { + this.ready(() => { + onPlayerReady(this, videojs.mergeOptions(defaults, options)); + }); +}; + +// Register the plugin with video.js. +registerPlugin('hlsQualitySelector', hlsQualitySelector); + +// Include the version number. +hlsQualitySelector.VERSION = VERSION; + +export default hlsQualitySelector; diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.scss b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.scss new file mode 100644 index 000000000..f0e5c7c39 --- /dev/null +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.scss @@ -0,0 +1,9 @@ +// Sass for videojs-hls-quality-selector + +.video-js { + + // This class is added to the video.js element by the plugin by default. + &.vjs-hls-quality-selector { + display: block; + } +} diff --git a/ui/component/viewers/videoViewer/internal/videojs.jsx b/ui/component/viewers/videoViewer/internal/videojs.jsx index 4f2ef44ef..e504e8af1 100644 --- a/ui/component/viewers/videoViewer/internal/videojs.jsx +++ b/ui/component/viewers/videoViewer/internal/videojs.jsx @@ -8,7 +8,8 @@ import 'video.js/dist/alt/video-js-cdn.min.css'; import eventTracking from 'videojs-event-tracking'; import * as OVERLAY from './overlays'; import './plugins/videojs-mobile-ui/plugin'; -import qualitySelector from 'videojs-hls-quality-selector'; +// import qualitySelector from 'videojs-hls-quality-selector'; +import hlsQualitySelector from './plugins/videojs-hls-quality-selector/plugin'; import qualityLevels from 'videojs-contrib-quality-levels'; import isUserTyping from 'util/detect-typing'; @@ -102,7 +103,7 @@ if (!Object.keys(videojs.getPlugins()).includes('eventTracking')) { } if (!Object.keys(videojs.getPlugins()).includes('hlsQualitySelector')) { - videojs.registerPlugin('hlsQualitySelector', qualitySelector); + videojs.registerPlugin('hlsQualitySelector', hlsQualitySelector); } if (!Object.keys(videojs.getPlugins()).includes('qualityLevels')) { @@ -379,11 +380,6 @@ export default React.memo(function VideoJs(props: Props) { // initialize mobile UI player.mobileUi(); // Inits mobile version. No-op if Desktop. - // Add quality selector to player - player.hlsQualitySelector({ - displayCurrentQuality: true, - }); - // I think this is a callback function onPlayerReady(player); }); @@ -447,6 +443,17 @@ export default React.memo(function VideoJs(props: Props) { src: source, type: type, }); + + // Add quality selector to player + player.hlsQualitySelector({ + displayCurrentQuality: true, + }); + + // Update player source + player.src({ + src: source, + type: type, + }); }); }, [source, reload]); -- 2.45.2 From d5d97fe6e721385c4ee7e12eeec6677e86ab4901 Mon Sep 17 00:00:00 2001 From: DispatchCommit Date: Wed, 17 Feb 2021 19:32:05 -0800 Subject: [PATCH 02/16] cleanup plugin code --- package.json | 1 - .../videojs-hls-quality-selector/plugin.js | 16 ++++------------ .../viewers/videoViewer/internal/videojs.jsx | 1 - 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index acd3d2e3f..c78c543c2 100644 --- a/package.json +++ b/package.json @@ -206,7 +206,6 @@ "video.js": "^7.10.1", "videojs-contrib-quality-levels": "^2.0.9", "videojs-event-tracking": "^1.0.1", - "videojs-hls-quality-selector": "^1.1.4", "villain-react": "^1.0.9", "wavesurfer.js": "^2.2.1", "webpack": "^4.28.4", diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js index 1a253073a..df829b46b 100644 --- a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js @@ -8,7 +8,6 @@ const defaults = {}; // Cross-compatibility for Video.js 5 and 6. const registerPlugin = videojs.registerPlugin || videojs.plugin; -// const dom = videojs.dom || videojs; /** * VideoJS HLS Quality Selector Plugin class. @@ -25,8 +24,9 @@ class HlsQualitySelectorPlugin { this.player = player; this.config = options; + // Ensure dependencies are met if (!this.player.qualityLevels) { - console.warn(`WARNING: Missing video.js quality levels plugin (required)`); + console.error(`Error: Missing video.js quality levels plugin (required) - videojs-hls-quality-selector`); return; } @@ -42,23 +42,16 @@ class HlsQualitySelectorPlugin { // Listen for source changes this.player.on('loadedmetadata', (e) => { - console.log(`Loaded Metadata detected by plugin!`, e); this.updatePlugin(); }); } updatePlugin() { - console.log(`Updating Quality Selector...`); - - // If there is quality levels plugin and the HLS tech exists - // then continue. + // If there is the HLS tech if (this.getHls()) { - console.log('Show quality selector'); // Show quality selector this._qualityButton.show(); } else { - console.log('Hide quality selector'); - console.log('Source type does not support multiple qulaity levels...'); // Hide quality selector this._qualityButton.hide(); } @@ -84,7 +77,6 @@ class HlsQualitySelectorPlugin { * Adds the quality menu button to the player control bar. */ createQualityButton() { - const player = this.player; this._qualityButton = new ConcreteButton(player); @@ -145,7 +137,7 @@ class HlsQualitySelectorPlugin { }).length) { const levelItem = this.getQualityMenuItem.call(this, { label: levels[i].height + 'p', - value: levels[i].height + value: levels[i].height, }); levelItems.push(levelItem); diff --git a/ui/component/viewers/videoViewer/internal/videojs.jsx b/ui/component/viewers/videoViewer/internal/videojs.jsx index e504e8af1..796b241ec 100644 --- a/ui/component/viewers/videoViewer/internal/videojs.jsx +++ b/ui/component/viewers/videoViewer/internal/videojs.jsx @@ -8,7 +8,6 @@ import 'video.js/dist/alt/video-js-cdn.min.css'; import eventTracking from 'videojs-event-tracking'; import * as OVERLAY from './overlays'; import './plugins/videojs-mobile-ui/plugin'; -// import qualitySelector from 'videojs-hls-quality-selector'; import hlsQualitySelector from './plugins/videojs-hls-quality-selector/plugin'; import qualityLevels from 'videojs-contrib-quality-levels'; import isUserTyping from 'util/detect-typing'; -- 2.45.2 From b98178c97a46baaf43b97d2e385a804181b67fa2 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 18 Feb 2021 13:10:36 -0500 Subject: [PATCH 03/16] yarn --- yarn.lock | 85 ++----------------------------------------------------- 1 file changed, 3 insertions(+), 82 deletions(-) diff --git a/yarn.lock b/yarn.lock index 681ae0a2c..7f296e9e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2114,11 +2114,6 @@ any-observable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -5311,17 +5306,6 @@ fs-copy-file-sync@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz#11bf32c096c10d126e5f6b36d06eece776062918" -fs-extra@^0.26.5: - version "0.26.7" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" - integrity sha1-muH92UiXeY7at20JGM9C0MMYT6k= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - fs-extra@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -5355,16 +5339,6 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" -fs-promise@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-0.5.0.tgz#4347d6bf624655a7061a4319213c393276ad3ef3" - integrity sha1-Q0fWv2JGVacGGkMZITw5MnatPvM= - dependencies: - any-promise "^1.0.0" - fs-extra "^0.26.5" - mz "^2.3.1" - thenify-all "^1.6.0" - fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -5657,7 +5631,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2: +graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== @@ -6815,7 +6789,7 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jsonfile@^2.1.0, jsonfile@^2.2.3: +jsonfile@^2.2.3: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" optionalDependencies: @@ -6859,14 +6833,6 @@ jszip@~2.5.0: dependencies: pako "~0.2.5" -karma-safaritechpreview-launcher@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/karma-safaritechpreview-launcher/-/karma-safaritechpreview-launcher-0.0.6.tgz#7a841105aeb7053940e33df850edcf220eed906a" - integrity sha512-2QMxAGXPQ37H3KoR9SCdh0OoktQZ5MyrxkvBiZ+VVOQfYVrcyOQXGrPea0/DKvf8qoQvrvP2FHcP/BxsuxuyHw== - dependencies: - fs-promise "^0.5.0" - marcosc-async "^3.0.4" - keycode@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04" @@ -6908,13 +6874,6 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -7370,11 +7329,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -marcosc-async@^3.0.4: - version "3.0.5" - resolved "https://registry.yarnpkg.com/marcosc-async/-/marcosc-async-3.0.5.tgz#41e6d56c656c811859d34b97a0a26093f71dc360" - integrity sha1-QebVbGVsgRhZ00uXoKJgk/cdw2A= - markdown-escapes@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" @@ -7753,15 +7707,6 @@ mux.js@5.6.7: resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-5.6.7.tgz#d39fc85cded5a1257de9f6eeb5cf1578c4a63eb8" integrity sha512-YSr6B8MUgE4S18MptbY2XM+JKGbw9JDkgs7YkuE/T2fpDKjOhZfb/nD6vmsVxvLYOExWNaQn1UGBp6PGsnTtew== -mz@^2.3.1: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - nan@^2.12.1: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -10840,20 +10785,6 @@ text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -thenify-all@^1.0.0, thenify-all@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - three-full@^17.1.0: version "17.2.0" resolved "https://registry.yarnpkg.com/three-full/-/three-full-17.2.0.tgz#b6086360a9429e733e080093c25d02a3171ba1cc" @@ -11535,7 +11466,7 @@ vfile@^2.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" -"video.js@^6 || ^7", video.js@^7.0.0, video.js@^7.10.1, video.js@^7.5.5: +"video.js@^6 || ^7", video.js@^7.0.0, video.js@^7.10.1: version "7.10.2" resolved "https://registry.yarnpkg.com/video.js/-/video.js-7.10.2.tgz#5156aabad7820e726d72ea6c32324059c68885a4" integrity sha512-kJTTrqcQn2MhPzWR8zQs6W3HPJWpowO/ZGZcKt2dcJeJdJT0dEDLYtiFdjV37SylCmu66V0flRnV8cipbthveQ== @@ -11569,16 +11500,6 @@ videojs-font@3.2.0: resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-3.2.0.tgz#212c9d3f4e4ec3fa7345167d64316add35e92232" integrity sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA== -videojs-hls-quality-selector@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/videojs-hls-quality-selector/-/videojs-hls-quality-selector-1.1.4.tgz#281b78c6653137b08c544e806aa9c91b71d16989" - integrity sha512-wWAjlLQui02gp//t9KHGd3XnbYO7wdOptskh3ZYCrbl/5Lbkveqb9yBVjH4e0zIQBPvGdWPMcOeDukf8iuYeBw== - dependencies: - global "^4.3.2" - karma-safaritechpreview-launcher "0.0.6" - video.js "^7.5.5" - videojs-contrib-quality-levels "^2.0.9" - videojs-logo@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/videojs-logo/-/videojs-logo-2.1.4.tgz#56675b3f95949910bad3c217835ea57aa6fdf212" -- 2.45.2 From 0a8d43e932ce4586b47c9f9cf132642652126b4f Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 18 Feb 2021 13:45:39 -0500 Subject: [PATCH 04/16] lint --- .../ConcreteButton.js | 10 ++-- .../ConcreteMenuItem.js | 5 +- .../videojs-hls-quality-selector/plugin.js | 51 ++++++++++--------- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js index acff46ffb..2f4085c5b 100644 --- a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteButton.js @@ -23,7 +23,6 @@ function toTitleCase(string) { * Extend vjs button class for quality button. */ export default class ConcreteButton extends VideoJsButtonClass { - /** * Button constructor. * @@ -32,7 +31,7 @@ export default class ConcreteButton extends VideoJsButtonClass { constructor(player) { super(player, { title: player.localize('Quality'), - name: 'QualityButton' + name: 'QualityButton', }); } @@ -52,7 +51,7 @@ export default class ConcreteButton extends VideoJsButtonClass { * The constructed menu */ createMenu() { - const menu = new VideoJsMenuClass(this.player_, {menuButton: this}); + const menu = new VideoJsMenuClass(this.player_, { menuButton: this }); this.hideThreshold_ = 0; @@ -61,9 +60,9 @@ export default class ConcreteButton extends VideoJsButtonClass { const titleEl = Dom.createEl('li', { className: 'vjs-menu-title', innerHTML: toTitleCase(this.options_.title), - tabIndex: -1 + tabIndex: -1, }); - const titleComponent = new VideoJsComponent(this.player_, {el: titleEl}); + const titleComponent = new VideoJsComponent(this.player_, { el: titleEl }); this.hideThreshold_ += 1; @@ -80,6 +79,5 @@ export default class ConcreteButton extends VideoJsButtonClass { } return menu; - } } diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js index d1f90ad30..46c23e525 100644 --- a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/ConcreteMenuItem.js @@ -7,7 +7,6 @@ const VideoJsMenuItemClass = videojs.getComponent('MenuItem'); * Extend vjs menu item class. */ export default class ConcreteMenuItem extends VideoJsMenuItemClass { - /** * Menu item constructor. * @@ -20,7 +19,7 @@ export default class ConcreteMenuItem extends VideoJsMenuItemClass { super(player, { label: item.label, selectable: true, - selected: item.selected || false + selected: item.selected || false, }); this.item = item; this.qualityButton = qualityButton; @@ -31,7 +30,6 @@ export default class ConcreteMenuItem extends VideoJsMenuItemClass { * Click event for menu item. */ handleClick() { - // Reset other menu items selected status. for (let i = 0; i < this.qualityButton.items.length; ++i) { this.qualityButton.items[i].selected(false); @@ -40,6 +38,5 @@ export default class ConcreteMenuItem extends VideoJsMenuItemClass { // Set this menu item to selected, and set quality. this.plugin.setQuality(this.item.value); this.selected(true); - } } diff --git a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js index df829b46b..22ca43d5f 100644 --- a/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js +++ b/ui/component/viewers/videoViewer/internal/plugins/videojs-hls-quality-selector/plugin.js @@ -1,5 +1,6 @@ +/* eslint-disable */ import videojs from 'video.js'; -import {version as VERSION} from './package.json'; +import { version as VERSION } from './package.json'; import ConcreteButton from './ConcreteButton'; import ConcreteMenuItem from './ConcreteMenuItem'; @@ -13,7 +14,6 @@ const registerPlugin = videojs.registerPlugin || videojs.plugin; * VideoJS HLS Quality Selector Plugin class. */ class HlsQualitySelectorPlugin { - /** * Plugin Constructor. * @@ -82,21 +82,21 @@ class HlsQualitySelectorPlugin { this._qualityButton = new ConcreteButton(player); const placementIndex = player.controlBar.children().length - 2; - const concreteButtonInstance = player.controlBar.addChild(this._qualityButton, - {componentClass: 'qualitySelector'}, - this.config.placementIndex || placementIndex); + const concreteButtonInstance = player.controlBar.addChild( + this._qualityButton, + { componentClass: 'qualitySelector' }, + this.config.placementIndex || placementIndex + ); concreteButtonInstance.addClass('vjs-quality-selector'); if (!this.config.displayCurrentQuality) { const icon = ` ${this.config.vjsIconClass || 'vjs-icon-hd'}`; - concreteButtonInstance - .menuButton_.$('.vjs-icon-placeholder').className += icon; + concreteButtonInstance.menuButton_.$('.vjs-icon-placeholder').className += icon; } else { this.setButtonInnerText('auto'); } concreteButtonInstance.removeClass('vjs-hidden'); - } /** @@ -105,8 +105,7 @@ class HlsQualitySelectorPlugin { * @param {string} text - the text to display in the button. */ setButtonInnerText(text) { - this._qualityButton - .menuButton_.$('.vjs-icon-placeholder').innerHTML = text; + this._qualityButton.menuButton_.$('.vjs-icon-placeholder').innerHTML = text; } /** @@ -125,16 +124,17 @@ class HlsQualitySelectorPlugin { * Executed when a quality level is added from HLS playlist. */ onAddQualityLevel() { - const player = this.player; const qualityList = player.qualityLevels(); const levels = qualityList.levels_ || []; const levelItems = []; for (let i = 0; i < levels.length; ++i) { - if (!levelItems.filter(_existingItem => { - return _existingItem.item && _existingItem.item.value === levels[i].height; - }).length) { + if ( + !levelItems.filter((_existingItem) => { + return _existingItem.item && _existingItem.item.value === levels[i].height; + }).length + ) { const levelItem = this.getQualityMenuItem.call(this, { label: levels[i].height + 'p', value: levels[i].height, @@ -145,7 +145,7 @@ class HlsQualitySelectorPlugin { } levelItems.sort((current, next) => { - if ((typeof current !== 'object') || (typeof next !== 'object')) { + if (typeof current !== 'object' || typeof next !== 'object') { return -1; } if (current.item.value < next.item.value) { @@ -157,19 +157,20 @@ class HlsQualitySelectorPlugin { return 0; }); - levelItems.push(this.getQualityMenuItem.call(this, { - label: player.localize('Auto'), - value: 'auto', - selected: true - })); + levelItems.push( + this.getQualityMenuItem.call(this, { + label: player.localize('Auto'), + value: 'auto', + selected: true, + }) + ); if (this._qualityButton) { - this._qualityButton.createItems = function() { + this._qualityButton.createItems = function () { return levelItems; }; this._qualityButton.update(); } - } /** @@ -190,7 +191,7 @@ class HlsQualitySelectorPlugin { for (let i = 0; i < qualityList.length; ++i) { const quality = qualityList[i]; - quality.enabled = (quality.height === height || height === 'auto'); + quality.enabled = quality.height === height || height === 'auto'; } this._qualityButton.unpressButton(); } @@ -203,7 +204,6 @@ class HlsQualitySelectorPlugin { getCurrentQuality() { return this._currentQuality || 'auto'; } - } /** @@ -237,7 +237,7 @@ const onPlayerReady = (player, options) => { * @param {Object} [options={}] * An object of options left to the plugin author to define. */ -const hlsQualitySelector = function(options) { +const hlsQualitySelector = function (options) { this.ready(() => { onPlayerReady(this, videojs.mergeOptions(defaults, options)); }); @@ -250,3 +250,4 @@ registerPlugin('hlsQualitySelector', hlsQualitySelector); hlsQualitySelector.VERSION = VERSION; export default hlsQualitySelector; +/* eslint-enable */ -- 2.45.2 From b17dfc407fc75baf45df09af349638734930588f Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 18 Feb 2021 15:06:04 -0500 Subject: [PATCH 05/16] try popcorn --- ui/component/common/icon-custom.jsx | 17 +++++++++++++++++ ui/constants/icons.js | 1 + 2 files changed, 18 insertions(+) diff --git a/ui/component/common/icon-custom.jsx b/ui/component/common/icon-custom.jsx index 049e80325..ed3fb09a8 100644 --- a/ui/component/common/icon-custom.jsx +++ b/ui/component/common/icon-custom.jsx @@ -1100,4 +1100,21 @@ export const icons = { ), + [ICONS.POPCORN]: (props: CustomProps) => ( + + + + + ), }; diff --git a/ui/constants/icons.js b/ui/constants/icons.js index df733f879..b0af5a5f5 100644 --- a/ui/constants/icons.js +++ b/ui/constants/icons.js @@ -136,3 +136,4 @@ export const CHANNEL_LEVEL_2 = 'ChannelLevel2'; export const CHANNEL_LEVEL_3 = 'ChannelLevel3'; export const CHANNEL_LEVEL_4 = 'ChannelLevel4'; export const CHANNEL_LEVEL_5 = 'ChannelLevel5'; +export const POPCORN = 'Popcorn'; -- 2.45.2 From ae987b2fd83f401eeff9e7dc7795060fe6d44268 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 18 Feb 2021 15:38:02 -0500 Subject: [PATCH 06/16] different icon --- ui/component/common/icon-custom.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ui/component/common/icon-custom.jsx b/ui/component/common/icon-custom.jsx index ed3fb09a8..b39d99340 100644 --- a/ui/component/common/icon-custom.jsx +++ b/ui/component/common/icon-custom.jsx @@ -1113,8 +1113,17 @@ export const icons = { strokeLinecap="round" strokeLinejoin="round" > - - + + + + + + + + + + + ), }; -- 2.45.2 From ce54d263ddaf98d7425d8d7f39661ae186672960 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 18 Feb 2021 15:48:14 -0500 Subject: [PATCH 07/16] icon attr --- ui/component/common/icon-custom.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/component/common/icon-custom.jsx b/ui/component/common/icon-custom.jsx index b39d99340..993be921b 100644 --- a/ui/component/common/icon-custom.jsx +++ b/ui/component/common/icon-custom.jsx @@ -1107,9 +1107,9 @@ export const icons = { viewBox="0 0 24 24" width={props.size || '18'} height={props.size || '18'} - fill="currentColor" + fill="none" stroke="currentColor" - strokeWidth="0" + strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" > -- 2.45.2 From 9442d586ee1067a62c34b473b9606a7a7402e1a3 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 18 Feb 2021 02:13:54 -0500 Subject: [PATCH 08/16] Revert "Add fallback thumbnail for streams" This reverts commit 0423d30a4e9dd209df16bc7dfc6555feac05d2b0. --- config.js | 3 +-- package.json | 5 ++--- ui/component/claimPreview/view.jsx | 12 +++--------- ui/component/fileThumbnail/view.jsx | 6 ++++-- yarn.lock | 5 ----- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/config.js b/config.js index 69ea0e060..aca1591b7 100644 --- a/config.js +++ b/config.js @@ -41,8 +41,7 @@ const config = { PINNED_URI_2: process.env.PINNED_URI_2, PINNED_LABEL_2: process.env.PINNED_LABEL_2, KNOWN_APP_DOMAINS: process.env.KNOWN_APP_DOMAINS ? process.env.KNOWN_APP_DOMAINS.split(',') : [], - CHANNEL_THUMBNAIL_FALLBACK: process.env.CHANNEL_THUMBNAIL_FALLBACK, - STREAM_THUMBNAIL_FALLBACK: process.env.STREAM_THUMBNAIL_FALLBACK, + THUMBNAIL_FALLBACK: process.env.THUMBNAIL_FALLBACK, }; config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`; diff --git a/package.json b/package.json index c78c543c2..e7414cc5d 100644 --- a/package.json +++ b/package.json @@ -53,9 +53,8 @@ "electron-updater": "^4.2.4", "express": "^4.17.1", "if-env": "^1.0.4", - "remove-markdown": "^0.3.0", - "react-image": "^4.0.3", - "remark-breaks": "^2.0.1", + "remark-breaks": "^2.0.1", + "remove-markdown": "^0.3.0", "tempy": "^0.6.0", "videojs-logo": "^2.1.4" }, diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 00e0173bb..cd6b6d8d9 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -2,9 +2,8 @@ import type { Node } from 'react'; import React, { useEffect, forwardRef } from 'react'; import { NavLink, withRouter } from 'react-router-dom'; -import { useImage } from 'react-image'; import classnames from 'classnames'; -import { CHANNEL_THUMBNAIL_FALLBACK, STREAM_THUMBNAIL_FALLBACK, SIMPLE_SITE } from 'config'; +import { SIMPLE_SITE } from 'config'; import { parseURI, convertToShareLink } from 'lbry-redux'; import { openCopyLinkMenu } from 'util/context-menu'; import { formatLbryUrlForWeb } from 'util/url'; @@ -189,11 +188,6 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { // Weird placement warning // Make sure this happens after we figure out if this claim needs to be hidden const thumbnailUrl = useGetThumbnail(contentUri, claim, streamingUrl, getFile, shouldHide); - const isStream = claim && claim.value_type === 'stream'; - const { src: thumbnailUrlWithFallback } = useImage({ - srcList: [thumbnailUrl, isStream ? STREAM_THUMBNAIL_FALLBACK : CHANNEL_THUMBNAIL_FALLBACK], - useSuspense: false, - }); function handleContextMenu(e) { // @if TARGET='app' @@ -288,7 +282,7 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { <> {!pending ? ( - + {/* @if TARGET='app' */} {claim && (
@@ -304,7 +298,7 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { ) : ( - + )} )} diff --git a/ui/component/fileThumbnail/view.jsx b/ui/component/fileThumbnail/view.jsx index 8ee1d4c5e..e5fd1b18e 100644 --- a/ui/component/fileThumbnail/view.jsx +++ b/ui/component/fileThumbnail/view.jsx @@ -2,6 +2,7 @@ import type { Node } from 'react'; import { getThumbnailCdnUrl } from 'util/thumbnail'; import React from 'react'; +import { THUMBNAIL_FALLBACK } from 'config'; import FreezeframeWrapper from './FreezeframeWrapper'; import Placeholder from './placeholder.png'; import classnames from 'classnames'; @@ -14,10 +15,11 @@ type Props = { claim: ?StreamClaim, doResolveUri: string => void, className?: string, + fallbackThumbnail?: string, }; function FileThumbnail(props: Props) { - const { claim, uri, doResolveUri, thumbnail: rawThumbnail, children, allowGifs = false, className } = props; + const { claim, uri, doResolveUri, thumbnail: rawThumbnail, children, allowGifs = false, className, fallbackThumbnail = THUMBNAIL_FALLBACK } = props; const passedThumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://'); const thumbnailFromClaim = uri && claim && claim.value && claim.value.thumbnail ? claim.value.thumbnail.url : undefined; @@ -50,7 +52,7 @@ function FileThumbnail(props: Props) { return (
Date: Thu, 18 Feb 2021 02:13:54 -0500 Subject: [PATCH 09/16] Revert "Use fallback image for broken thumbnails" This reverts commit 6aae5987e6d4d88a356509c1a38f5049d5f7f53c. --- config.js | 1 - ui/component/fileThumbnail/view.jsx | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/config.js b/config.js index aca1591b7..f042ad2e0 100644 --- a/config.js +++ b/config.js @@ -41,7 +41,6 @@ const config = { PINNED_URI_2: process.env.PINNED_URI_2, PINNED_LABEL_2: process.env.PINNED_LABEL_2, KNOWN_APP_DOMAINS: process.env.KNOWN_APP_DOMAINS ? process.env.KNOWN_APP_DOMAINS.split(',') : [], - THUMBNAIL_FALLBACK: process.env.THUMBNAIL_FALLBACK, }; config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`; diff --git a/ui/component/fileThumbnail/view.jsx b/ui/component/fileThumbnail/view.jsx index e5fd1b18e..ad818c19c 100644 --- a/ui/component/fileThumbnail/view.jsx +++ b/ui/component/fileThumbnail/view.jsx @@ -2,7 +2,6 @@ import type { Node } from 'react'; import { getThumbnailCdnUrl } from 'util/thumbnail'; import React from 'react'; -import { THUMBNAIL_FALLBACK } from 'config'; import FreezeframeWrapper from './FreezeframeWrapper'; import Placeholder from './placeholder.png'; import classnames from 'classnames'; @@ -15,11 +14,10 @@ type Props = { claim: ?StreamClaim, doResolveUri: string => void, className?: string, - fallbackThumbnail?: string, }; function FileThumbnail(props: Props) { - const { claim, uri, doResolveUri, thumbnail: rawThumbnail, children, allowGifs = false, className, fallbackThumbnail = THUMBNAIL_FALLBACK } = props; + const { claim, uri, doResolveUri, thumbnail: rawThumbnail, children, allowGifs = false, className } = props; const passedThumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://'); const thumbnailFromClaim = uri && claim && claim.value && claim.value.thumbnail ? claim.value.thumbnail.url : undefined; @@ -48,11 +46,9 @@ function FileThumbnail(props: Props) { } // @endif - const cleanUrl = url ? url.replace(/'/g, "\\'") : ''; - return (
Date: Thu, 18 Feb 2021 17:35:26 +0200 Subject: [PATCH 10/16] Small fixes for amounts Needed amounts seemed odd, did small fix hopefully the right way --- ui/component/channelStakedIndicator/view.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/component/channelStakedIndicator/view.jsx b/ui/component/channelStakedIndicator/view.jsx index 6f0187f7b..fb548728f 100644 --- a/ui/component/channelStakedIndicator/view.jsx +++ b/ui/component/channelStakedIndicator/view.jsx @@ -23,10 +23,10 @@ function getChannelLevel(amount: number): number { case amount >= 50 && amount < 250: level = 3; break; - case amount >= 100 && amount < 1000: + case amount >= 250 && amount < 1000: level = 4; break; - case amount > 1000: + case amount >= 1000: level = 5; break; } -- 2.45.2 From c31c3a53707f5a4d6b20b943156f28d3c76bc877 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 18 Feb 2021 16:25:52 -0500 Subject: [PATCH 11/16] popcorn2 --- ui/component/common/icon-custom.jsx | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/ui/component/common/icon-custom.jsx b/ui/component/common/icon-custom.jsx index 993be921b..ef87d7e1a 100644 --- a/ui/component/common/icon-custom.jsx +++ b/ui/component/common/icon-custom.jsx @@ -1113,17 +1113,24 @@ export const icons = { strokeLinecap="round" strokeLinejoin="round" > - - - - - - - - - - - + + + + + + ), }; -- 2.45.2 From 432adce368619b029798256928a0a057584f590d Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 18 Feb 2021 17:20:53 -0500 Subject: [PATCH 12/16] popcorn3 --- ui/component/common/icon-custom.jsx | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/ui/component/common/icon-custom.jsx b/ui/component/common/icon-custom.jsx index ef87d7e1a..20fe6c0b2 100644 --- a/ui/component/common/icon-custom.jsx +++ b/ui/component/common/icon-custom.jsx @@ -1113,23 +1113,15 @@ export const icons = { strokeLinecap="round" strokeLinejoin="round" > - - - - - + + + + + + + + + ), -- 2.45.2 From b231b1a51f98cd72326ca79f2b7ec12c1a04f398 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 18 Feb 2021 16:33:55 -0500 Subject: [PATCH 13/16] use cdn for channel thumbnails --- ui/component/channelThumbnail/view.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ui/component/channelThumbnail/view.jsx b/ui/component/channelThumbnail/view.jsx index d3af5c508..129565416 100644 --- a/ui/component/channelThumbnail/view.jsx +++ b/ui/component/channelThumbnail/view.jsx @@ -5,6 +5,7 @@ import classnames from 'classnames'; import Gerbil from './gerbil.png'; import FreezeframeWrapper from 'component/fileThumbnail/FreezeframeWrapper'; import ChannelStakedIndicator from 'component/channelStakedIndicator'; +import { getThumbnailCdnUrl } from 'util/thumbnail'; type Props = { thumbnail: ?string, @@ -67,6 +68,14 @@ function ChannelThumbnail(props: Props) { ); } + let url = channelThumbnail; + // @if TARGET='web' + // Pass image urls through a compression proxy + if (thumbnail) { + url = getThumbnailCdnUrl({ thumbnail }); + } + // @endif + return (
setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. /> )} @@ -91,7 +100,7 @@ function ChannelThumbnail(props: Props) { {__('Channel setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. /> )} -- 2.45.2 From 675cb3119dd3d66c37097eac829dce517cd03793 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 18 Feb 2021 16:57:52 -0500 Subject: [PATCH 14/16] deny iframes of for non embed pages --- web/index.js | 2 ++ web/middleware/iframe-destroyer.js | 15 +++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 web/middleware/iframe-destroyer.js diff --git a/web/index.js b/web/index.js index 487c09d80..46362ccdc 100644 --- a/web/index.js +++ b/web/index.js @@ -6,6 +6,7 @@ const logger = require('koa-logger'); const router = require('./src/routes'); const redirectMiddleware = require('./middleware/redirect'); const cacheControlMiddleware = require('./middleware/cache-control'); +const iframeDestroyerMiddleware = require('./middleware/iframe-destroyer'); const app = new Koa(); const DIST_ROOT = path.resolve(__dirname, 'dist'); @@ -25,6 +26,7 @@ app.use(async (ctx, next) => { app.use(logger()); app.use(cacheControlMiddleware); app.use(redirectMiddleware); +app.use(iframeDestroyerMiddleware); app.use(serve(DIST_ROOT)); // Check if the request url matches any assets inside of /dist app.use(router.routes()); diff --git a/web/middleware/iframe-destroyer.js b/web/middleware/iframe-destroyer.js new file mode 100644 index 000000000..1737480f3 --- /dev/null +++ b/web/middleware/iframe-destroyer.js @@ -0,0 +1,15 @@ +const PAGES = require('../../ui/constants/pages'); + +async function iframeDestroyerMiddleware(ctx, next) { + const { + request: { path }, + } = ctx; + + if (!path.startsWith(`/$/${PAGES.EMBED}`)) { + ctx.set('X-Frame-Options', 'DENY'); + } + + return next(); +} + +module.exports = iframeDestroyerMiddleware; -- 2.45.2 From 05b998c0ee1d32640574f30a68e31f54e63cd455 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 18 Feb 2021 17:06:31 -0500 Subject: [PATCH 15/16] fix anonymous option showing black text in channel selector --- ui/scss/component/_channel.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/scss/component/_channel.scss b/ui/scss/component/_channel.scss index f802fce6d..4e4ac9e97 100644 --- a/ui/scss/component/_channel.scss +++ b/ui/scss/component/_channel.scss @@ -343,6 +343,7 @@ $metadata-z-index: 1; .channel__list-text { font-weight: var(--font-weight-bold); + color: var(--color-text); } .channel__selector { -- 2.45.2 From 2c4f45a9fdac4a6c0e90c7273be3fe5616970cc2 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 18 Feb 2021 17:25:27 -0500 Subject: [PATCH 16/16] popcorn to movies --- ui/component/common/icon-custom.jsx | 2 +- ui/constants/icons.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/component/common/icon-custom.jsx b/ui/component/common/icon-custom.jsx index 20fe6c0b2..5f9c9c8d1 100644 --- a/ui/component/common/icon-custom.jsx +++ b/ui/component/common/icon-custom.jsx @@ -1100,7 +1100,7 @@ export const icons = { ), - [ICONS.POPCORN]: (props: CustomProps) => ( + [ICONS.MOVIES]: (props: CustomProps) => (