diff --git a/README.md b/README.md index f789d284..b08eb882 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Enough of the rewrite has been done to hopefully provide code examples of what w ## What Needs to be Done? -Like I mentioned above, there are a lot of things that need to be done. I have created some issues over at the [issues](#) page to give a quick rundown on what needs to be done as well as what the requirements are in order for those issues to be considered complete. I will make more issues with more requirements as progress is made. +Like I mentioned above, there are a lot of things that need to be done. I have created some issues over at the [issues](https://github.com/FreeTubeApp/FreeTube-Vue/issues) page to give a quick rundown on what needs to be done as well as what the requirements are in order for those issues to be considered complete. I will make more issues with more requirements as progress is made. At this time, here is the list of things to do/need to do: @@ -26,7 +26,7 @@ At this time, here is the list of things to do/need to do: - [x] Basic App Structure and Layout - [x] Video Layout (Along with Channel and Playlist Layout) - [x] Search / Search View (Along with Filters) -- [ ] Search Suggestions +- [x] Search Suggestions - [x] Channel View - [x] Channel Search - [x] Trending Page @@ -42,7 +42,7 @@ At this time, here is the list of things to do/need to do: - [ ] History Page and Logic - [ ] Profile Page and Logic - [ ] Misc. Adjustments and Settings -- [ ] Packagaing and Testing +- [ ] Packaging and Testing This list is somewhat in order of when I plan on working on each thing. Obviously things can change and anyone is welcome to work on whatever they like. diff --git a/package-lock.json b/package-lock.json index 0660f6f6..056ade5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4092,50 +4092,19 @@ } }, "@videojs/http-streaming": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-1.13.2.tgz", - "integrity": "sha512-U4Xhh+HxGpRBx9Gm0LlEadq85k9BwckzFgZmyhacauhK/27Mz0goKKFAt+BpxBNp2oHVdAdk8NHfneinsqni3Q==", + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-1.10.6.tgz", + "integrity": "sha512-uPBuunHnxWeFRYxRX0j6h1IIWv3+QKvSkZGmW9TvqxWBqeNGSrQymR6tm1nVjQ2HhMVxVphQTUhUTTPDVWqmQg==", "requires": { "aes-decrypter": "3.0.0", "global": "^4.3.0", "m3u8-parser": "4.4.0", - "mpd-parser": "0.10.0", - "mux.js": "5.5.1", + "mpd-parser": "0.8.1", + "mux.js": "5.2.1", "url-toolkit": "^2.1.3", "video.js": "^6.8.0 || ^7.0.0" } }, - "@videojs/vhs-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-1.3.0.tgz", - "integrity": "sha512-oiqXDtHQqDPun7JseWkirUHGrgdYdeF12goUut5z7vwAj4DmUufEPFJ4xK5hYGXGFDyDhk2rSFOR122Ze6qXyQ==", - "requires": { - "@babel/runtime": "^7.5.5", - "global": "^4.3.2", - "url-toolkit": "^2.1.6" - } - }, - "@videojs/xhr": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.5.1.tgz", - "integrity": "sha512-wV9nGESHseSK+S9ePEru2+OJZ1jq/ZbbzniGQ4weAmTIepuBMSYPx5zrxxQA0E786T5ykpO8ts+LayV+3/oI2w==", - "requires": { - "@babel/runtime": "^7.5.5", - "global": "~4.4.0", - "is-function": "^1.0.1" - }, - "dependencies": { - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - } - } - }, "@vue/component-compiler-utils": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz", @@ -9850,23 +9819,6 @@ "debug": "^2.6.9", "mkdirp": "^0.5.4", "yauzl": "^2.10.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } } }, "extsprintf": { @@ -11102,19 +11054,19 @@ } }, "global-agent": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz", - "integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==", + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz", + "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==", "dev": true, "optional": true, "requires": { - "boolean": "^3.0.0", - "core-js": "^3.6.4", + "boolean": "^3.0.1", + "core-js": "^3.6.5", "es6-error": "^4.1.1", - "matcher": "^2.1.0", - "roarr": "^2.15.2", - "semver": "^7.1.2", - "serialize-error": "^5.0.0" + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" }, "dependencies": { "semver": { @@ -14699,19 +14651,19 @@ } }, "matcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz", - "integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, "optional": true, "requires": { - "escape-string-regexp": "^2.0.0" + "escape-string-regexp": "^4.0.0" }, "dependencies": { "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "optional": true } @@ -15108,14 +15060,12 @@ } }, "mpd-parser": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.10.0.tgz", - "integrity": "sha512-eIqkH/2osPr7tIIjhRmDWqm2wdJ7Q8oPfWvdjealzsLV2D2oNe0a0ae2gyYYs1sw5e5hdssDA2V6Sz8MW+Uvvw==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.8.1.tgz", + "integrity": "sha512-WBTJ1bKk8OLUIxBh6s1ju1e2yz/5CzhPbgi6P3F3kJHKhGy1Z+ElvEnuzEbtC/dnbRcJtMXazE3f93N5LLdp9Q==", "requires": { - "@babel/runtime": "^7.5.5", - "@videojs/vhs-utils": "^1.1.0", "global": "^4.3.2", - "xmldom": "^0.1.27" + "url-toolkit": "^2.1.1" } }, "ms": { @@ -15146,9 +15096,9 @@ "dev": true }, "mux.js": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.5.1.tgz", - "integrity": "sha512-5VmmjADBqS4++8pTI6poSRJ+chHdaoI4XErcQPM5w4QfwaDl+FQlSI0iOgWbYDn6CBCbDRKaSCcEiN2K5aHNGQ==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.2.1.tgz", + "integrity": "sha512-1t2payD3Y8izfZRq7tfUQlhL2fKzjeLr9v1/2qNCTkEQnd9Abtn1JgzsBgGZubEXh6lM5L8B0iLGoWQiukjtbQ==" }, "nan": { "version": "2.12.0", @@ -16753,7 +16703,8 @@ "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true }, "process-nextick-args": { "version": "2.0.0", @@ -17934,13 +17885,22 @@ } }, "serialize-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", - "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", "dev": true, "optional": true, "requires": { - "type-fest": "^0.8.0" + "type-fest": "^0.13.1" + }, + "dependencies": { + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true + } } }, "serialize-javascript": { @@ -19700,9 +19660,9 @@ } }, "url-toolkit": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.6.tgz", - "integrity": "sha512-UaZ2+50am4HwrV2crR/JAf63Q4VvPYphe63WGeoJxeu8gmOm0qxPt+KsukfakPNrX9aymGNEkkaoICwn+OuvBw==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.2.0.tgz", + "integrity": "sha512-Rde0c9S4fJK3FaHim3DSgdQ8IFrSXcZCpAJo9T7/FA+BoQGhK0ow3mpwGQLJCPYsNn6TstpW7/7DzMpSpz9F9w==" }, "use": { "version": "3.1.1", @@ -19809,18 +19769,18 @@ } }, "video.js": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.8.2.tgz", - "integrity": "sha512-NIxRWCpq5N9QFnwPtemgdBf3IE3GAqLUR6R/12+qv6Flc/o2hRvPw3aFQwytRvBAqgc6Wg2whrHCh8ltQ3RiRA==", + "version": "7.6.6", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.6.6.tgz", + "integrity": "sha512-AXzHwymhvMpS7c7rF29u0j0/3tSs+v2gIk5UY8OkiDHSEHL7T0+t3hid4JHW7aGvTruUUgwyf4C74cX2RDL1Pw==", "requires": { - "@babel/runtime": "^7.9.2", - "@videojs/http-streaming": "1.13.2", - "@videojs/xhr": "2.5.1", + "@babel/runtime": "^7.4.5", + "@videojs/http-streaming": "1.10.6", "global": "4.3.2", "keycode": "^2.2.0", "safe-json-parse": "4.0.0", "videojs-font": "3.2.0", - "videojs-vtt.js": "^0.15.2" + "videojs-vtt.js": "^0.14.1", + "xhr": "2.4.0" } }, "videojs-abloop": { @@ -19956,9 +19916,9 @@ } }, "videojs-vtt.js": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.2.tgz", - "integrity": "sha512-kEo4hNMvu+6KhPvVYPKwESruwhHC3oFis133LwhXHO9U7nRnx0RiJYMiqbgwjgazDEXHR6t8oGJiHM6wq5XlAw==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.14.1.tgz", + "integrity": "sha512-YxOiywx6N9t3J5nqsE5WN2Sw4CSqVe3zV+AZm2T4syOc2buNJaD6ZoexSdeszx2sHLU/RRo2r4BJAXFDQ7Qo2Q==", "requires": { "global": "^4.3.1" } @@ -20991,6 +20951,17 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, + "xhr": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.0.tgz", + "integrity": "sha1-4W5mpF+GmGHu76tBbV7/ci3ECZM=", + "requires": { + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -21013,11 +20984,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index eb925209..4f85aa90 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "mediaelement": "^4.2.16", "nedb": "^1.8.0", "opml-to-json": "0.0.3", - "video.js": "^7.8.2", + "video.js": "7.6.6", "videojs-abloop": "^1.1.2", "videojs-contrib-quality-levels": "^2.0.9", "videojs-http-source-selector": "^1.1.6", diff --git a/src/main/index.js b/src/main/index.js index 442043f5..78a0a299 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -62,7 +62,8 @@ function createWindow () { webPreferences: { nodeIntegration: true, nodeIntegrationInWorker: false, - webSecurity: false + webSecurity: false, + backgroundThrottling: false }, show: false }) diff --git a/src/renderer/components/ft-icon-button/ft-icon-button.css b/src/renderer/components/ft-icon-button/ft-icon-button.css index 1dd1eadf..89e3fb62 100644 --- a/src/renderer/components/ft-icon-button/ft-icon-button.css +++ b/src/renderer/components/ft-icon-button/ft-icon-button.css @@ -11,13 +11,16 @@ padding: 10px; font-size: 20px; border-radius: 50%; - box-shadow: 0 1px 2px rgba(0,0,0,.5); cursor: pointer; -moz-transition: background 0.2s ease-out; -o-transition: background 0.2s ease-out; transition: background 0.2s ease-out; } +.shadow { + box-shadow: 0 1px 2px rgba(0,0,0,.5); +} + .iconButton:hover { -moz-transition: background 0.2s ease-in; -o-transition: background 0.2s ease-in; @@ -105,9 +108,9 @@ } .left { - right: 100%; + right: 50%; } .right { - left: 100%; + left: 50%; } diff --git a/src/renderer/components/ft-icon-button/ft-icon-button.js b/src/renderer/components/ft-icon-button/ft-icon-button.js index 8fe06aca..9e4f7f79 100644 --- a/src/renderer/components/ft-icon-button/ft-icon-button.js +++ b/src/renderer/components/ft-icon-button/ft-icon-button.js @@ -15,6 +15,10 @@ export default Vue.extend({ type: String, default: 'base' }, + useShadow: { + type: Boolean, + default: true + }, dropdownPosition: { type: String, default: 'center' diff --git a/src/renderer/components/ft-icon-button/ft-icon-button.vue b/src/renderer/components/ft-icon-button/ft-icon-button.vue index a0432bf4..098e4398 100644 --- a/src/renderer/components/ft-icon-button/ft-icon-button.vue +++ b/src/renderer/components/ft-icon-button/ft-icon-button.vue @@ -7,7 +7,8 @@ :class="{ base: theme === 'base', primary: theme === 'primary', - secondary: theme === 'secondary' + secondary: theme === 'secondary', + shadow: useShadow }" @click="handleIconClick" /> diff --git a/src/renderer/components/ft-list-video/ft-list-video.css b/src/renderer/components/ft-list-video/ft-list-video.css index 8266ad91..52c13222 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.css +++ b/src/renderer/components/ft-list-video/ft-list-video.css @@ -83,6 +83,15 @@ cursor: pointer; } +/deep/ .iconButton { + font-size: 15px; + padding: 8px; +} + +/deep/ .iconDropdown { + margin-top: 30px; +} + .grid { width: 240px; height: 250px; @@ -105,8 +114,15 @@ height: 110px; } +.grid .optionsButton { + margin-top: 10px; + margin-left: 210px; + position: absolute; +} + .grid .videoTitle { max-height: 55px; + width: 210px; overflow-y: hidden; margin-bottom: -15px; } @@ -144,6 +160,10 @@ height: 130px; } +.list .optionsButton { + float: right; +} + .list .videoTitle { margin-left: 250px; margin-top: 5px; diff --git a/src/renderer/components/ft-list-video/ft-list-video.js b/src/renderer/components/ft-list-video/ft-list-video.js index bed3de09..fa63d7da 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.js +++ b/src/renderer/components/ft-list-video/ft-list-video.js @@ -1,7 +1,11 @@ import Vue from 'vue' +import FtIconButton from '../ft-icon-button/ft-icon-button.vue' export default Vue.extend({ name: 'FtListVideo', + components: { + 'ft-icon-button': FtIconButton + }, props: { data: { type: Object, @@ -30,10 +34,30 @@ export default Vue.extend({ progressPercentage: 0, isLive: false, isFavorited: false, - hideViews: false + hideViews: false, + optionsNames: [ + 'Open in YouTube', + 'Copy YouTube Link', + 'Open YouTube Embedded Player', + 'Copy YouTube Embedded Player Link', + 'Open in Invidious', + 'Copy Invidious Link' + ], + optionsValues: [ + 'openYoutube', + 'copyYoutube', + 'openYoutubeEmbed', + 'copyYoutubeEmbed', + 'openInvidious', + 'copyInvidious' + ] } }, computed: { + usingElectron: function () { + return this.$store.getters.getUsingElectron + }, + listType: function () { return this.$store.getters.getListType }, @@ -50,6 +74,18 @@ export default Vue.extend({ return this.$store.getters.getInvidiousInstance }, + invidiousUrl: function () { + return `${this.invidiousInstance}/watch?v=${this.id}` + }, + + youtubeUrl: function () { + return `https://www.youtube.com/watch?v=${this.id}` + }, + + youtubeEmbedUrl: function () { + return `https://www.youtube-nocookie.com/embed/${this.id}` + }, + thumbnail: function () { let baseUrl if (this.backendPreference === 'invidious') { @@ -113,6 +149,42 @@ export default Vue.extend({ console.log('TODO: ft-list-video method toggleSave') }, + handleOptionsClick: function (option) { + console.log('Handling share') + console.log(option) + + switch (option) { + case 'copyYoutube': + navigator.clipboard.writeText(this.youtubeUrl) + break + case 'openYoutube': + if (this.usingElectron) { + const shell = require('electron').shell + shell.openExternal(this.youtubeUrl) + } + break + case 'copyYoutubeEmbed': + navigator.clipboard.writeText(this.youtubeEmbedUrl) + break + case 'openYoutubeEmbed': + if (this.usingElectron) { + const shell = require('electron').shell + shell.openExternal(this.youtubeEmbedUrl) + } + break + case 'copyInvidious': + navigator.clipboard.writeText(this.invidiousUrl) + break + case 'openInvidious': + if (this.usingElectron) { + console.log('using electron') + const shell = require('electron').shell + shell.openExternal(this.invidiousUrl) + } + break + } + }, + // For Invidious data, as duration is sent in seconds calculateVideoDuration: function (lengthSeconds) { let durationText = '' diff --git a/src/renderer/components/ft-list-video/ft-list-video.vue b/src/renderer/components/ft-list-video/ft-list-video.vue index d5c64185..09503a05 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.vue +++ b/src/renderer/components/ft-list-video/ft-list-video.vue @@ -37,6 +37,16 @@ :style="{width: progressPercentage + '%'}" /> +