mirror of
https://github.com/FreeTubeApp/FreeTube
synced 2024-11-22 18:07:13 +01:00
Migrate Popular view to composition API (#6129)
* Migrate Popular to composition API * remove comment, use shallowRef for shownResults Co-Authored-By: absidue <48293849+absidue@users.noreply.github.com> * Optimize setting shownResults Co-Authored-By: absidue <48293849+absidue@users.noreply.github.com> * Fix typo Co-authored-by: absidue <48293849+absidue@users.noreply.github.com> --------- Co-authored-by: absidue <48293849+absidue@users.noreply.github.com>
This commit is contained in:
parent
006ed4050f
commit
8ab8b4ed7f
@ -1,108 +0,0 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapMutations } from 'vuex'
|
||||
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
||||
import FtCard from '../../components/ft-card/ft-card.vue'
|
||||
import FtElementList from '../../components/FtElementList/FtElementList.vue'
|
||||
import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue'
|
||||
import FtRefreshWidget from '../../components/ft-refresh-widget/ft-refresh-widget.vue'
|
||||
|
||||
import { invidiousAPICall } from '../../helpers/api/invidious'
|
||||
import { copyToClipboard, getRelativeTimeFromDate, setPublishedTimestampsInvidious, showToast } from '../../helpers/utils'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Popular',
|
||||
components: {
|
||||
'ft-loader': FtLoader,
|
||||
'ft-card': FtCard,
|
||||
'ft-element-list': FtElementList,
|
||||
'ft-icon-button': FtIconButton,
|
||||
'ft-refresh-widget': FtRefreshWidget,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
isLoading: false,
|
||||
shownResults: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
lastPopularRefreshTimestamp: function () {
|
||||
return getRelativeTimeFromDate(this.$store.getters.getLastPopularRefreshTimestamp, true)
|
||||
},
|
||||
popularCache: function () {
|
||||
return this.$store.getters.getPopularCache
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
document.addEventListener('keydown', this.keyboardShortcutHandler)
|
||||
|
||||
this.shownResults = this.popularCache || []
|
||||
if (!this.shownResults || this.shownResults.length < 1) {
|
||||
this.fetchPopularInfo()
|
||||
}
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
document.removeEventListener('keydown', this.keyboardShortcutHandler)
|
||||
},
|
||||
methods: {
|
||||
fetchPopularInfo: async function () {
|
||||
const searchPayload = {
|
||||
resource: 'popular',
|
||||
id: '',
|
||||
params: {}
|
||||
}
|
||||
|
||||
this.isLoading = true
|
||||
const result = await invidiousAPICall(searchPayload)
|
||||
.catch((err) => {
|
||||
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
||||
showToast(`${errorMessage}: ${err}`, 10000, () => {
|
||||
copyToClipboard(err)
|
||||
})
|
||||
return undefined
|
||||
})
|
||||
|
||||
if (!result) {
|
||||
this.isLoading = false
|
||||
return
|
||||
}
|
||||
|
||||
const items = result.filter((item) => {
|
||||
return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist'
|
||||
})
|
||||
setPublishedTimestampsInvidious(items.filter(item => item.type === 'video' || item.type === 'shortVideo'))
|
||||
this.setLastPopularRefreshTimestamp(new Date())
|
||||
|
||||
this.shownResults = items
|
||||
|
||||
this.isLoading = false
|
||||
this.$store.commit('setPopularCache', items)
|
||||
},
|
||||
|
||||
/**
|
||||
* This function `keyboardShortcutHandler` should always be at the bottom of this file
|
||||
* @param {KeyboardEvent} event the keyboard event
|
||||
*/
|
||||
keyboardShortcutHandler: function (event) {
|
||||
if (event.ctrlKey || document.activeElement.classList.contains('ft-input')) {
|
||||
return
|
||||
}
|
||||
// Avoid handling events due to user holding a key (not released)
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat
|
||||
if (event.repeat) { return }
|
||||
|
||||
switch (event.key) {
|
||||
case 'r':
|
||||
case 'R':
|
||||
case 'F5':
|
||||
if (!this.isLoading) {
|
||||
this.fetchPopularInfo()
|
||||
}
|
||||
break
|
||||
}
|
||||
},
|
||||
|
||||
...mapMutations([
|
||||
'setLastPopularRefreshTimestamp'
|
||||
])
|
||||
}
|
||||
})
|
@ -22,5 +22,101 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./Popular.js" />
|
||||
<script setup>
|
||||
|
||||
import { computed, onBeforeUnmount, onMounted, ref, shallowRef } from 'vue'
|
||||
|
||||
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
||||
import FtCard from '../../components/ft-card/ft-card.vue'
|
||||
import FtElementList from '../../components/FtElementList/FtElementList.vue'
|
||||
import FtRefreshWidget from '../../components/ft-refresh-widget/ft-refresh-widget.vue'
|
||||
import store from '../../store/index'
|
||||
|
||||
import { invidiousAPICall } from '../../helpers/api/invidious'
|
||||
import { copyToClipboard, getRelativeTimeFromDate, setPublishedTimestampsInvidious, showToast } from '../../helpers/utils'
|
||||
import { useI18n } from '../../composables/use-i18n-polyfill'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const isLoading = ref(false)
|
||||
|
||||
const lastPopularRefreshTimestamp = computed(() => {
|
||||
return getRelativeTimeFromDate(store.getters.getLastPopularRefreshTimestamp, true)
|
||||
})
|
||||
|
||||
/** @type {import('vue').ComputedRef<Array | null>} */
|
||||
const popularCache = computed(() => {
|
||||
return store.getters.getPopularCache
|
||||
})
|
||||
|
||||
const shownResults = shallowRef(popularCache.value || [])
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('keydown', keyboardShortcutHandler)
|
||||
|
||||
if (shownResults.value.length === 0) {
|
||||
fetchPopularInfo()
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('keydown', keyboardShortcutHandler)
|
||||
})
|
||||
|
||||
async function fetchPopularInfo() {
|
||||
const searchPayload = {
|
||||
resource: 'popular',
|
||||
id: '',
|
||||
params: {}
|
||||
}
|
||||
|
||||
isLoading.value = true
|
||||
const result = await invidiousAPICall(searchPayload)
|
||||
.catch((err) => {
|
||||
const errorMessage = t('Invidious API Error (Click to copy)')
|
||||
showToast(`${errorMessage}: ${err}`, 10000, () => {
|
||||
copyToClipboard(err)
|
||||
})
|
||||
return undefined
|
||||
})
|
||||
|
||||
if (!result) {
|
||||
isLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
const items = result.filter((item) => {
|
||||
return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist'
|
||||
})
|
||||
|
||||
setPublishedTimestampsInvidious(items.filter(item => item.type === 'video' || item.type === 'shortVideo'))
|
||||
store.commit('setLastPopularRefreshTimestamp', new Date())
|
||||
shownResults.value = items
|
||||
isLoading.value = false
|
||||
store.commit('setPopularCache', items)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {KeyboardEvent} event the keyboard event
|
||||
*/
|
||||
function keyboardShortcutHandler(event) {
|
||||
if (event.ctrlKey || document.activeElement.classList.contains('ft-input')) {
|
||||
return
|
||||
}
|
||||
// Avoid handling events due to user holding a key (not released)
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat
|
||||
if (event.repeat) { return }
|
||||
|
||||
switch (event.key) {
|
||||
case 'r':
|
||||
case 'R':
|
||||
case 'F5':
|
||||
if (!isLoading.value) {
|
||||
fetchPopularInfo()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped src="./Popular.css" />
|
||||
|
Loading…
Reference in New Issue
Block a user