+
-
-
+
+
+
-
+
@@ -45,6 +47,7 @@ import { mdiCheckCircleOutline } from '@mdi/js'
import ExpandableNumber from '@/components/ExpandableNumber'
import NGErrorHandler from '@/components/NGErrorHandler'
import VideoItem from '@/components/Video/VideoItem.vue'
+import GenericDisplayItem from '@/components/GenericDisplayItem'
import SubscriptionButton from '@/components/SubscriptionButton'
import GridRow from '@/components/Grid/GridRow'
import GridCol from '@/components/Grid/GridCol'
@@ -58,6 +61,10 @@ export default {
channel: null,
error: null,
+ loading: true,
+ currentlySelectedTab: 0,
+ tabs: [],
+
mdiCheckCircleOutline
}
},
@@ -111,7 +118,8 @@ export default {
this.fetchChannel()
},
watch: {
- '$route.params.channelId': 'fetchChannel'
+ '$route.params.channelId': 'fetchChannel',
+ currentlySelectedTab: 'onTabChange'
},
methods: {
async fetchChannel () {
@@ -119,6 +127,28 @@ export default {
this.channel = await this.$store.dispatch('auth/makeRequest', {
path: '/' + this.$route.params.path + '/' + this.$route.params.channelId
})
+ this.tabs.push({
+ originalName: '',
+ name: this.$t('channel_tabs.videos')
+ })
+ for (const tab of this.channel.tabs) {
+ tab.originalName = tab.name
+ switch (tab.name) {
+ case 'Livestreams':
+ tab.name = this.$t('channel_tabs.livestreams')
+ break
+ case 'Playlists':
+ tab.name = this.$t('channel_tabs.playlists')
+ break
+ case 'Channels':
+ tab.name = this.$t('channel_tabs.channels')
+ break
+ case 'Shorts':
+ tab.name = this.$t('channel_tabs.shorts')
+ break
+ }
+ this.tabs.push(tab)
+ }
this.error = null
} catch (e) {
if (e.isAxiosError) {
@@ -126,6 +156,8 @@ export default {
} else {
throw e
}
+ } finally {
+ this.loading = false
}
},
@@ -135,16 +167,53 @@ export default {
}
},
- fetchMoreVideos () {
- this.$store.dispatch('auth/makeRequest', {
- path: '/nextpage/channel/' + this.channel.id,
- params: {
- nextpage: this.channel.nextpage
+ async onTabChange (newTab) {
+ this.loading = true
+ try {
+ if (newTab === 0) {
+ this.channelVideos = this.channel.relatedStreams
+ return
}
- }).then(j => {
- this.channel.relatedStreams = this.channel.relatedStreams.concat(j.relatedStreams)
- this.channel.nextpage = j.nextpage
- })
+ const t = this.tabs[this.currentlySelectedTab]
+
+ const { content, nextpage } = await this.$store.dispatch('auth/makeRequest', {
+ method: 'GET',
+ path: '/channels/tabs',
+ params: {
+ data: t.data
+ }
+ })
+ t.videos = content
+ t.nextpage = nextpage
+ } finally {
+ this.loading = false
+ }
+ },
+
+ async fetchMoreVideos () {
+ if (this.currentlySelectedTab === 0) {
+ this.$store.dispatch('auth/makeRequest', {
+ path: '/nextpage/channel/' + this.channel.id,
+ params: {
+ nextpage: this.channel.nextpage
+ }
+ }).then(j => {
+ this.channel.relatedStreams = this.channel.relatedStreams.concat(j.relatedStreams)
+ this.channel.nextpage = j.nextpage
+ })
+ } else {
+ const t = this.tabs[this.currentlySelectedTab]
+ this.$store.dispatch('auth/makeRequest', {
+ path: '/channels/tabs',
+ params: {
+ data: t.data,
+ nextpage: t.nextpage
+ }
+ }).then(j => {
+ t.videos = t.videos.concat(j.relatedStreams)
+ t.nextpage = j.nextpage
+ })
+ }
}
},
computed: {
@@ -152,9 +221,25 @@ export default {
return LibPiped.purifyHTML(marked.parseInline(this.channel.description, {
breaks: true
}))
+ },
+
+ view () {
+ if (this.currentlySelectedTab === 0) {
+ return {
+ videos: this.channel.relatedStreams,
+ hasNextPage: this.channel.nextpage != null
+ }
+ } else {
+ const t = this.tabs[this.currentlySelectedTab]
+ return {
+ videos: t.videos,
+ hasNextPage: t.nextpage != null
+ }
+ }
}
},
components: {
+ GenericDisplayItem,
ChannelSharingPanel,
ExpandableNumber,
GridRow,
diff --git a/src/translations/en.json b/src/translations/en.json
index b04d4af..a8ab7a6 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -31,6 +31,13 @@
"lastWatchedTill": "Last watched till {t}",
"watchedAgo": "Watched {t} till {p}"
},
+ "channel_tabs": {
+ "videos": "Videos",
+ "livestreams": "Livestreams",
+ "playlists": "Playlists",
+ "channels": "Channels",
+ "shorts": "Shorts"
+ },
"search_results": {
"filterLabel": "Filter results by type",
"result_types": {