From 739dddf74cbe45827808c4ca9ee0e1352c7f12ef Mon Sep 17 00:00:00 2001 From: Mykyta Poturai Date: Thu, 13 Aug 2020 17:26:20 +0300 Subject: [PATCH 01/22] Add caching for popular videos Also add the button to refresh the cache --- src/renderer/store/modules/utils.js | 9 ++++ src/renderer/views/Popular/Popular.css | 6 +++ src/renderer/views/Popular/Popular.js | 58 ++++++++++++++++++-------- src/renderer/views/Popular/Popular.vue | 6 +++ 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/renderer/store/modules/utils.js b/src/renderer/store/modules/utils.js index c92cdba4..d839ae11 100644 --- a/src/renderer/store/modules/utils.js +++ b/src/renderer/store/modules/utils.js @@ -3,6 +3,7 @@ import FtToastEvents from '../../components/ft-toast/ft-toast-events' const state = { isSideNavOpen: false, sessionSearchHistory: [], + popularCache: undefined, searchSettings: { sortBy: 'relevance', time: '', @@ -42,6 +43,10 @@ const getters = { return state.sessionSearchHistory }, + getPopularCache () { + return state.popularCache + }, + getSearchSettings () { return state.searchSettings } @@ -113,6 +118,10 @@ const mutations = { } }, + setPopularCache (state, value) { + state.popularCache = value + }, + setSearchSortBy (state, value) { state.searchSettings.sortBy = value }, diff --git a/src/renderer/views/Popular/Popular.css b/src/renderer/views/Popular/Popular.css index c6ad6abd..4255d98b 100644 --- a/src/renderer/views/Popular/Popular.css +++ b/src/renderer/views/Popular/Popular.css @@ -4,6 +4,12 @@ margin-bottom: 60px; } +.floatingTopButton { + position: absolute; + top: 70px; + right: 10px; +} + @media only screen and (max-width: 680px) { .card { width: 90%; diff --git a/src/renderer/views/Popular/Popular.js b/src/renderer/views/Popular/Popular.js index dc8979d4..bd0f14fb 100644 --- a/src/renderer/views/Popular/Popular.js +++ b/src/renderer/views/Popular/Popular.js @@ -2,13 +2,15 @@ import Vue from 'vue' import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtCard from '../../components/ft-card/ft-card.vue' import FtElementList from '../../components/ft-element-list/ft-element-list.vue' +import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue' export default Vue.extend({ name: 'Popular', components: { 'ft-loader': FtLoader, 'ft-card': FtCard, - 'ft-element-list': FtElementList + 'ft-element-list': FtElementList, + 'ft-icon-button': FtIconButton }, data: function () { return { @@ -16,35 +18,55 @@ export default Vue.extend({ shownResults: [] } }, + computed: { + popularCache: function () { + return this.$store.getters.getPopularCache + } + }, mounted: function () { this.getTrendingInfo() }, methods: { - getTrendingInfo: function () { - this.isLoading = true - + refreshTrendingInfo: async function () { + await this.fetchTrendingInfo() + await this.getTrendingInfo() + }, + fetchTrendingInfo: async function () { const searchPayload = { resource: 'popular', id: '', params: {} } - this.$store.dispatch('invidiousAPICall', searchPayload).then((result) => { - if (!result) { - return - } - - console.log(result) - - const returnData = result.filter((item) => { - return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist' - }) - - this.shownResults = this.shownResults.concat(returnData) - this.isLoading = false - }).catch((err) => { + const result = await this.$store.dispatch('invidiousAPICall', searchPayload).catch((err) => { console.log(err) }) + + if (!result) { + return + } + + console.log(result) + + const returnData = result.filter((item) => { + return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist' + }) + this.$store.commit('setPopularCache', returnData) + return returnData + }, + + getTrendingInfo: async function () { + this.isLoading = true + let data = this.popularCache + if (!data || data.length < 1) { + data = await this.fetchTrendingInfo() + } + if (!data) { + return + } + + this.shownResults = this.shownResults.concat(data) + this.isLoading = false } } }) diff --git a/src/renderer/views/Popular/Popular.vue b/src/renderer/views/Popular/Popular.vue index c148cd79..3efba2f8 100644 --- a/src/renderer/views/Popular/Popular.vue +++ b/src/renderer/views/Popular/Popular.vue @@ -13,6 +13,12 @@ :data="shownResults" /> + From 5bc2e70e88da155eaed5ac5afdc01e6d0a988e9b Mon Sep 17 00:00:00 2001 From: Mykyta Poturai Date: Tue, 18 Aug 2020 18:51:56 +0300 Subject: [PATCH 02/22] Refactor popular page --- src/renderer/store/modules/utils.js | 2 +- src/renderer/views/Popular/Popular.js | 30 +++++++++----------------- src/renderer/views/Popular/Popular.vue | 3 ++- 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/renderer/store/modules/utils.js b/src/renderer/store/modules/utils.js index d839ae11..8cd0c57d 100644 --- a/src/renderer/store/modules/utils.js +++ b/src/renderer/store/modules/utils.js @@ -3,7 +3,7 @@ import FtToastEvents from '../../components/ft-toast/ft-toast-events' const state = { isSideNavOpen: false, sessionSearchHistory: [], - popularCache: undefined, + popularCache: null, searchSettings: { sortBy: 'relevance', time: '', diff --git a/src/renderer/views/Popular/Popular.js b/src/renderer/views/Popular/Popular.js index bd0f14fb..cd80eeab 100644 --- a/src/renderer/views/Popular/Popular.js +++ b/src/renderer/views/Popular/Popular.js @@ -24,12 +24,14 @@ export default Vue.extend({ } }, mounted: function () { - this.getTrendingInfo() + this.shownResults = this.popularCache + if (!this.shownResults || this.shownResults.length < 1) { + this.fetchTrendingInfo() + } }, methods: { - refreshTrendingInfo: async function () { - await this.fetchTrendingInfo() - await this.getTrendingInfo() + refreshTrendingInfo: function () { + this.fetchTrendingInfo() }, fetchTrendingInfo: async function () { const searchPayload = { @@ -38,35 +40,23 @@ export default Vue.extend({ params: {} } + this.isLoading = true const result = await this.$store.dispatch('invidiousAPICall', searchPayload).catch((err) => { console.log(err) }) if (!result) { + this.isLoading = false return } console.log(result) - const returnData = result.filter((item) => { + this.shownResults = result.filter((item) => { return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist' }) - this.$store.commit('setPopularCache', returnData) - return returnData - }, - - getTrendingInfo: async function () { - this.isLoading = true - let data = this.popularCache - if (!data || data.length < 1) { - data = await this.fetchTrendingInfo() - } - if (!data) { - return - } - - this.shownResults = this.shownResults.concat(data) this.isLoading = false + this.$store.commit('setPopularCache', this.shownResults) } } }) diff --git a/src/renderer/views/Popular/Popular.vue b/src/renderer/views/Popular/Popular.vue index 3efba2f8..d16346c9 100644 --- a/src/renderer/views/Popular/Popular.vue +++ b/src/renderer/views/Popular/Popular.vue @@ -16,7 +16,8 @@ From 60a315f360dd3f9a794addacb49a632eec4ff6d5 Mon Sep 17 00:00:00 2001 From: Mykyta Poturai Date: Sat, 22 Aug 2020 23:10:52 +0300 Subject: [PATCH 03/22] Refactor popular page V2 --- src/renderer/views/Popular/Popular.js | 7 ++----- src/renderer/views/Popular/Popular.vue | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/renderer/views/Popular/Popular.js b/src/renderer/views/Popular/Popular.js index cd80eeab..e45b4a9c 100644 --- a/src/renderer/views/Popular/Popular.js +++ b/src/renderer/views/Popular/Popular.js @@ -26,14 +26,11 @@ export default Vue.extend({ mounted: function () { this.shownResults = this.popularCache if (!this.shownResults || this.shownResults.length < 1) { - this.fetchTrendingInfo() + this.fetchPopularInfo() } }, methods: { - refreshTrendingInfo: function () { - this.fetchTrendingInfo() - }, - fetchTrendingInfo: async function () { + fetchPopularInfo: async function () { const searchPayload = { resource: 'popular', id: '', diff --git a/src/renderer/views/Popular/Popular.vue b/src/renderer/views/Popular/Popular.vue index d16346c9..b133588f 100644 --- a/src/renderer/views/Popular/Popular.vue +++ b/src/renderer/views/Popular/Popular.vue @@ -17,8 +17,8 @@ icon="sync" class="floatingTopButton" :size="12" - :theme="primary" - @click="refreshTrendingInfo" + theme="primary" + @click="fetchPopularInfo" /> From 69dada2df48e87140d2d5f9b2d7a27d25e6c279a Mon Sep 17 00:00:00 2001 From: Mykyta Poturai Date: Sat, 22 Aug 2020 23:37:09 +0300 Subject: [PATCH 04/22] Add caching for trending videos --- src/renderer/store/modules/utils.js | 9 ++++++ src/renderer/views/Trending/Trending.css | 6 ++++ src/renderer/views/Trending/Trending.js | 37 +++++++++++++++++------- src/renderer/views/Trending/Trending.vue | 7 +++++ 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/renderer/store/modules/utils.js b/src/renderer/store/modules/utils.js index 8cd0c57d..c543f5d8 100644 --- a/src/renderer/store/modules/utils.js +++ b/src/renderer/store/modules/utils.js @@ -4,6 +4,7 @@ const state = { isSideNavOpen: false, sessionSearchHistory: [], popularCache: null, + trendingCache: null, searchSettings: { sortBy: 'relevance', time: '', @@ -47,6 +48,10 @@ const getters = { return state.popularCache }, + getTrendingCache () { + return state.trendingCache + }, + getSearchSettings () { return state.searchSettings } @@ -122,6 +127,10 @@ const mutations = { state.popularCache = value }, + setTrendingCache (state, value) { + state.trendingCache = value + }, + setSearchSortBy (state, value) { state.searchSettings.sortBy = value }, diff --git a/src/renderer/views/Trending/Trending.css b/src/renderer/views/Trending/Trending.css index c6ad6abd..4255d98b 100644 --- a/src/renderer/views/Trending/Trending.css +++ b/src/renderer/views/Trending/Trending.css @@ -4,6 +4,12 @@ margin-bottom: 60px; } +.floatingTopButton { + position: absolute; + top: 70px; + right: 10px; +} + @media only screen and (max-width: 680px) { .card { width: 90%; diff --git a/src/renderer/views/Trending/Trending.js b/src/renderer/views/Trending/Trending.js index e576ea8c..45023c12 100644 --- a/src/renderer/views/Trending/Trending.js +++ b/src/renderer/views/Trending/Trending.js @@ -2,6 +2,7 @@ import Vue from 'vue' import FtCard from '../../components/ft-card/ft-card.vue' import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtElementList from '../../components/ft-element-list/ft-element-list.vue' +import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue' import ytrend from 'yt-trending-scraper' @@ -10,7 +11,8 @@ export default Vue.extend({ components: { 'ft-card': FtCard, 'ft-loader': FtLoader, - 'ft-element-list': FtElementList + 'ft-element-list': FtElementList, + 'ft-icon-button': FtIconButton }, data: function () { return { @@ -30,23 +32,34 @@ export default Vue.extend({ }, invidiousInstance: function () { return this.$store.getters.getInvidiousInstance + }, + trendingCache () { + return this.$store.getters.getTrendingCache } }, mounted: function () { - if (!this.usingElectron) { - this.getVideoInformationInvidious() + if (this.trendingCache && this.trendingCache.length > 0) { + this.shownResults = this.trendingCache } else { - switch (this.backendPreference) { - case 'local': - this.getTrendingInfoLocal() - break - case 'invidious': - this.getTrendingInfoInvidious() - break - } + this.getTrendingInfo() } }, methods: { + getTrendingInfo () { + if (!this.usingElectron) { + this.getVideoInformationInvidious() + } else { + switch (this.backendPreference) { + case 'local': + this.getTrendingInfoLocal() + break + case 'invidious': + this.getTrendingInfoInvidious() + break + } + } + }, + getTrendingInfoLocal: function () { this.isLoading = true @@ -59,6 +72,7 @@ export default Vue.extend({ this.shownResults = this.shownResults.concat(returnData) this.isLoading = false + this.$store.commit('setTrendingCache', this.shownResults) }).catch((err) => { console.log(err) const errorMessage = this.$t('Local API Error (Click to copy)') @@ -102,6 +116,7 @@ export default Vue.extend({ this.shownResults = this.shownResults.concat(returnData) this.isLoading = false + this.$store.commit('setTrendingCache', this.shownResults) }).catch((err) => { console.log(err) const errorMessage = this.$t('Invidious API Error (Click to copy)') diff --git a/src/renderer/views/Trending/Trending.vue b/src/renderer/views/Trending/Trending.vue index 54eef065..eed230d6 100644 --- a/src/renderer/views/Trending/Trending.vue +++ b/src/renderer/views/Trending/Trending.vue @@ -13,6 +13,13 @@ :data="shownResults" /> + From 48ff7cd2a49379e5ae32173b461302e28af1b4c8 Mon Sep 17 00:00:00 2001 From: Luca Date: Mon, 24 Aug 2020 17:01:09 +0200 Subject: [PATCH 05/22] Added Japanese, Spanish (Mexico) as languages and fixed the non displaying Subscribe translation --- src/renderer/components/watch-video-info/watch-video-info.js | 2 +- src/renderer/main.js | 2 +- static/locales/{es_MX.yaml => es-MX.yaml} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename static/locales/{es_MX.yaml => es-MX.yaml} (100%) diff --git a/src/renderer/components/watch-video-info/watch-video-info.js b/src/renderer/components/watch-video-info/watch-video-info.js index fccdd3ed..2ccb2e43 100644 --- a/src/renderer/components/watch-video-info/watch-video-info.js +++ b/src/renderer/components/watch-video-info/watch-video-info.js @@ -100,7 +100,7 @@ export default Vue.extend({ }, subscribedText: function () { - return `${this.$t('Subscribe').toUpperCase()} ${this.subscriptionCountText}` + return `${this.$t('Channel.Subscribe').toUpperCase()} ${this.subscriptionCountText}` }, dateString() { diff --git a/src/renderer/main.js b/src/renderer/main.js index 1222c3cb..a98d02be 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -23,7 +23,7 @@ Vue.component('font-awesome-icon', FontAwesomeIcon) Vue.use(VueI18n) // List of locales approved for use -const activeLocales = ['en-US', 'de-DE', 'fi', 'fr-FR', 'pt-BR', 'pt-PT', 'ru', 'vi', 'zh-CN', 'zh-TW'] +const activeLocales = ['en-US', 'de-DE', 'es-MX', 'fi', 'fr-FR', 'ja', 'pt-BR', 'pt-PT', 'ru', 'vi', 'zh-CN', 'zh-TW'] const messages = {} // Take active locales and load respective YAML file diff --git a/static/locales/es_MX.yaml b/static/locales/es-MX.yaml similarity index 100% rename from static/locales/es_MX.yaml rename to static/locales/es-MX.yaml From c1ce439399338196d42574456e176382dc8000fc Mon Sep 17 00:00:00 2001 From: Mykyta Poturai Date: Mon, 24 Aug 2020 22:50:03 +0300 Subject: [PATCH 06/22] Improve long list rendering time Speed up list rendering by wrapping list elements in a lazy container. Only the first 16 elements are loaded at first. The rest is rendered after it becomes visible. --- package-lock.json | 5 +++ package.json | 1 + src/renderer/App.js | 3 ++ .../ft-element-list/ft-element-list.js | 8 +--- .../ft-element-list/ft-element-list.vue | 27 +++----------- .../ft-list-lazy-wrapper.css | 3 ++ .../ft-list-lazy-wrapper.js | 37 +++++++++++++++++++ .../ft-list-lazy-wrapper.vue | 28 ++++++++++++++ 8 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.css create mode 100644 src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js create mode 100644 src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue diff --git a/package-lock.json b/package-lock.json index 55ff0c4e..a6618763 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18872,6 +18872,11 @@ "vue-style-loader": "^4.1.0" } }, + "vue-observe-visibility": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vue-observe-visibility/-/vue-observe-visibility-0.4.6.tgz", + "integrity": "sha512-xo0CEVdkjSjhJoDdLSvoZoQrw/H2BlzB5jrCBKGZNXN2zdZgMuZ9BKrxXDjNP2AxlcCoKc8OahI3F3r3JGLv2Q==" + }, "vue-router": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz", diff --git a/package.json b/package.json index 07ba7f3b..6d211718 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "vue": "^2.6.12", "vue-electron": "^1.0.6", "vue-i18n": "^8.21.0", + "vue-observe-visibility": "^0.4.6", "vue-router": "^3.4.3", "vuex": "^3.5.1", "xml2json": "^0.12.0", diff --git a/src/renderer/App.js b/src/renderer/App.js index c91c064d..609c375a 100644 --- a/src/renderer/App.js +++ b/src/renderer/App.js @@ -1,4 +1,5 @@ import Vue from 'vue' +import { ObserveVisibility } from 'vue-observe-visibility' import TopNav from './components/top-nav/top-nav.vue' import SideNav from './components/side-nav/side-nav.vue' import FtToast from './components/ft-toast/ft-toast.vue' @@ -7,6 +8,8 @@ import $ from 'jquery' let useElectron let shell +Vue.directive('observe-visibility', ObserveVisibility) + if (window && window.process && window.process.type === 'renderer') { /* eslint-disable-next-line */ shell = require('electron').shell diff --git a/src/renderer/components/ft-element-list/ft-element-list.js b/src/renderer/components/ft-element-list/ft-element-list.js index c9cab911..744355c1 100644 --- a/src/renderer/components/ft-element-list/ft-element-list.js +++ b/src/renderer/components/ft-element-list/ft-element-list.js @@ -1,18 +1,14 @@ import Vue from 'vue' import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' import FtAutoGrid from '../ft-auto-grid/ft-auto-grid.vue' -import FtListVideo from '../ft-list-video/ft-list-video.vue' -import FtListChannel from '../ft-list-channel/ft-list-channel.vue' -import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue' +import FtListLazyWrapper from '../ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue' export default Vue.extend({ name: 'FtElementList', components: { 'ft-flex-box': FtFlexBox, 'ft-auto-grid': FtAutoGrid, - 'ft-list-video': FtListVideo, - 'ft-list-channel': FtListChannel, - 'ft-list-playlist': FtListPlaylist + 'ft-list-lazy-wrapper': FtListLazyWrapper }, props: { data: { diff --git a/src/renderer/components/ft-element-list/ft-element-list.vue b/src/renderer/components/ft-element-list/ft-element-list.vue index 58398c57..c615b3e7 100644 --- a/src/renderer/components/ft-element-list/ft-element-list.vue +++ b/src/renderer/components/ft-element-list/ft-element-list.vue @@ -2,28 +2,13 @@ - + :key="index" + appearance="result" + :data="result" + :first-screen="index < 16" + /> diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.css b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.css new file mode 100644 index 00000000..d58d0725 --- /dev/null +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.css @@ -0,0 +1,3 @@ +.lazyWrapper { + min-height: 264px; +} diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js new file mode 100644 index 00000000..67c1fdb1 --- /dev/null +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js @@ -0,0 +1,37 @@ +import Vue from 'vue' +import FtListVideo from '../ft-list-video/ft-list-video.vue' +import FtListChannel from '../ft-list-channel/ft-list-channel.vue' +import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue' + +export default Vue.extend({ + name: 'FtListLazyWrapper', + components: { + 'ft-list-video': FtListVideo, + 'ft-list-channel': FtListChannel, + 'ft-list-playlist': FtListPlaylist + }, + props: { + data: { + type: Object, + required: true + }, + appearance: { + type: String, + required: true + }, + firstScreen: { + type: Boolean, + required: true + } + }, + data: function () { + return { + visible: this.firstScreen + } + }, + methods: { + onVisibilityChanged: function (visible) { + this.visible = visible + } + } +}) diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue new file mode 100644 index 00000000..4e83c825 --- /dev/null +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue @@ -0,0 +1,28 @@ + + +