import Vue from 'vue' import { mapActions } from 'vuex' import FtButton from '../../components/ft-button/ft-button.vue' import FtCard from '../../components/ft-card/ft-card.vue' import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue' import FtInput from '../../components/ft-input/ft-input.vue' import FtPrompt from '../../components/ft-prompt/ft-prompt.vue' import ytch from 'yt-channel-info' export default Vue.extend({ name: 'SubscribedChannels', components: { 'ft-button': FtButton, 'ft-card': FtCard, 'ft-flex-box': FtFlexBox, 'ft-input': FtInput, 'ft-prompt': FtPrompt }, data: function () { return { query: '', subscribedChannels: [], filteredChannels: [], re: { url: /(.+=\w{1})\d+(.+)/, ivToIv: /^.+(ggpht.+)/, ivToYt: /^.+ggpht\/(.+)/, ytToIv: /^.+ggpht\.com\/(.+)/ }, thumbnailSize: 176, ytBaseURL: 'https://yt3.ggpht.com', showUnsubscribePrompt: false, unsubscribePromptValues: [ 'yes', 'no' ], channelToUnsubscribe: null, errorCount: 0 } }, computed: { activeProfile: function () { return this.$store.getters.getActiveProfile }, activeProfileId: function () { return this.activeProfile._id }, activeSubscriptionList: function () { return this.activeProfile.subscriptions }, channelList: function () { if (this.query !== '') { return this.filteredChannels } else { return this.subscribedChannels } }, locale: function () { return this.$i18n.locale.replace('_', '-') }, backendPreference: function () { return this.$store.getters.getBackendPreference }, currentInvidiousInstance: function () { return this.$store.getters.getCurrentInvidiousInstance }, unsubscribePromptNames: function () { return [ this.$t('Yes'), this.$t('No') ] } }, watch: { activeProfileId: function() { this.query = '' this.getSubscription() }, activeSubscriptionList: function() { this.getSubscription() this.filterChannels() } }, mounted: function () { this.getSubscription() }, methods: { getSubscription: function () { this.subscribedChannels = this.activeSubscriptionList.slice().sort((a, b) => { return a.name.localeCompare(b.name, this.locale) }) }, handleInput: function(input) { this.query = input this.filterChannels() }, filterChannels: function () { if (this.query === '') { this.filteredChannels = [] return } const escapedQuery = this.query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') const re = new RegExp(escapedQuery, 'i') this.filteredChannels = this.subscribedChannels.filter(channel => { return re.test(channel.name) }) }, handleUnsubscribeButtonClick: function(channel) { this.channelToUnsubscribe = channel this.showUnsubscribePrompt = true }, handleUnsubscribePromptClick: function(value) { this.showUnsubscribePrompt = false if (value !== 'yes') { this.channelToUnsubscribe = null return } this.unsubscribeChannel() }, unsubscribeChannel: function () { const currentProfile = JSON.parse(JSON.stringify(this.activeProfile)) let index = currentProfile.subscriptions.findIndex(channel => { return channel.id === this.channelToUnsubscribe.id }) currentProfile.subscriptions.splice(index, 1) this.updateProfile(currentProfile) this.showToast({ message: this.$t('Channels.Unsubscribed', { channelName: this.channelToUnsubscribe.name }) }) index = this.subscribedChannels.findIndex(channel => { return channel.id === this.channelToUnsubscribe.id }) this.subscribedChannels.splice(index, 1) index = this.filteredChannels.findIndex(channel => { return channel.id === this.channelToUnsubscribe.id }) if (index !== -1) { this.filteredChannels.splice(index, 1) } this.channelToUnsubscribe = null }, thumbnailURL: function(originalURL) { let newURL = originalURL if (new URL(originalURL).hostname === 'yt3.ggpht.com') { if (this.backendPreference === 'invidious') { // YT to IV newURL = originalURL.replace(this.re.ytToIv, `${this.currentInvidiousInstance}/ggpht/$1`) } } else { if (this.backendPreference === 'local') { // IV to YT newURL = originalURL.replace(this.re.ivToYt, `${this.ytBaseURL}/$1`) } else { // IV to IV newURL = originalURL.replace(this.re.ivToIv, `${this.currentInvidiousInstance}/$1`) } } return newURL.replace(this.re.url, `$1${this.thumbnailSize}$2`) }, updateThumbnail: function(channel) { this.errorCount += 1 if (this.backendPreference === 'local') { // avoid too many concurrent requests setTimeout(() => { ytch.getChannelInfo({ channelId: channel.id }).then(response => { this.updateSubscriptionDetails({ channelThumbnailUrl: this.thumbnailURL(response.authorThumbnails[0].url), channelName: channel.name, channelId: channel.id }) }) }, this.errorCount * 500) } else { setTimeout(() => { this.invidiousGetChannelInfo(channel.id).then(response => { this.updateSubscriptionDetails({ channelThumbnailUrl: this.thumbnailURL(response.authorThumbnails[0].url), channelName: channel.name, channelId: channel.id }) }) }, this.errorCount * 500) } }, goToChannel: function (id) { this.$router.push({ path: `/channel/${id}` }) }, ...mapActions([ 'showToast', 'updateProfile', 'updateSubscriptionDetails', 'invidiousGetChannelInfo' ]) } })