mirror of https://github.com/FreeTubeApp/FreeTube
218 lines
6.3 KiB
JavaScript
218 lines
6.3 KiB
JavaScript
import { defineComponent } from 'vue'
|
|
|
|
import { mapActions } from 'vuex'
|
|
|
|
import FtButton from '../../components/ft-button/ft-button.vue'
|
|
|
|
import { MAIN_PROFILE_ID } from '../../../constants'
|
|
import { deepCopy, showToast } from '../../helpers/utils'
|
|
import { getFirstCharacter } from '../../helpers/strings'
|
|
|
|
export default defineComponent({
|
|
name: 'FtSubscribeButton',
|
|
components: {
|
|
'ft-button': FtButton
|
|
},
|
|
props: {
|
|
channelId: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
channelName: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
channelThumbnail: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
hideProfileDropdownToggle: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
openDropdownOnSubscribe: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
subscriptionCountText: {
|
|
default: '',
|
|
type: String,
|
|
required: false
|
|
}
|
|
},
|
|
data: function () {
|
|
return {
|
|
isProfileDropdownOpen: false
|
|
}
|
|
},
|
|
computed: {
|
|
locale: function () {
|
|
return this.$i18n.locale.replace('_', '-')
|
|
},
|
|
profileInitials: function () {
|
|
return this.profileDisplayList.map((profile) => {
|
|
return profile.name
|
|
? getFirstCharacter(profile.name, this.locale).toUpperCase()
|
|
: ''
|
|
})
|
|
},
|
|
|
|
profileList: function () {
|
|
return this.$store.getters.getProfileList
|
|
},
|
|
|
|
/* sort by 'All Channels' -> active profile -> unsubscribed channels -> subscribed channels */
|
|
profileDisplayList: function () {
|
|
const mainProfileAndActiveProfile = [this.profileList[0]]
|
|
if (this.activeProfile._id !== MAIN_PROFILE_ID) {
|
|
mainProfileAndActiveProfile.push(this.activeProfile)
|
|
}
|
|
|
|
return [
|
|
...mainProfileAndActiveProfile,
|
|
...this.profileList.filter((profile, i) =>
|
|
i !== 0 && !this.isActiveProfile(profile) && !this.isProfileSubscribed(profile)),
|
|
...this.profileList.filter((profile, i) =>
|
|
i !== 0 && !this.isActiveProfile(profile) && this.isProfileSubscribed(profile))
|
|
]
|
|
},
|
|
|
|
activeProfile: function () {
|
|
return this.$store.getters.getActiveProfile
|
|
},
|
|
|
|
subscriptionInfo: function () {
|
|
return this.subscriptionInfoForProfile(this.activeProfile)
|
|
},
|
|
|
|
hideChannelSubscriptions: function () {
|
|
return this.$store.getters.getHideChannelSubscriptions
|
|
},
|
|
|
|
subscribedText: function () {
|
|
let subscribedValue = (this.isProfileSubscribed(this.activeProfile) ? this.$t('Channel.Unsubscribe') : this.$t('Channel.Subscribe')).toUpperCase()
|
|
if (this.subscriptionCountText !== '' && !this.hideChannelSubscriptions) {
|
|
subscribedValue += ' ' + this.subscriptionCountText
|
|
}
|
|
return subscribedValue
|
|
},
|
|
|
|
isProfileDropdownEnabled: function () {
|
|
return !this.hideProfileDropdownToggle && this.profileList.length > 1
|
|
}
|
|
|
|
},
|
|
methods: {
|
|
handleSubscription: function (profile = this.activeProfile) {
|
|
if (this.channelId === '') {
|
|
return
|
|
}
|
|
|
|
const currentProfile = deepCopy(profile)
|
|
|
|
if (this.isProfileSubscribed(profile)) {
|
|
currentProfile.subscriptions = currentProfile.subscriptions.filter((channel) => {
|
|
return channel.id !== this.channelId
|
|
})
|
|
|
|
this.updateProfile(currentProfile)
|
|
showToast(this.$t('Channel.Channel has been removed from your subscriptions'))
|
|
|
|
if (profile._id === MAIN_PROFILE_ID) {
|
|
// Check if a subscription exists in a different profile.
|
|
// Remove from there as well.
|
|
let duplicateSubscriptions = 0
|
|
|
|
this.profileList.forEach((profileInList) => {
|
|
if (profileInList._id === MAIN_PROFILE_ID) {
|
|
return
|
|
}
|
|
duplicateSubscriptions += this.unsubscribe(profileInList, this.channelId)
|
|
})
|
|
|
|
if (duplicateSubscriptions > 0) {
|
|
const message = this.$t('Channel.Removed subscription from {count} other channel(s)', { count: duplicateSubscriptions })
|
|
showToast(message)
|
|
}
|
|
}
|
|
} else {
|
|
const subscription = {
|
|
id: this.channelId,
|
|
name: this.channelName,
|
|
thumbnail: this.channelThumbnail
|
|
}
|
|
currentProfile.subscriptions.push(subscription)
|
|
|
|
this.updateProfile(currentProfile)
|
|
showToast(this.$t('Channel.Added channel to your subscriptions'))
|
|
|
|
if (profile._id !== MAIN_PROFILE_ID) {
|
|
const primaryProfile = deepCopy(this.profileList.find(prof => {
|
|
return prof._id === MAIN_PROFILE_ID
|
|
}))
|
|
|
|
const index = primaryProfile.subscriptions.findIndex((channel) => {
|
|
return channel.id === this.channelId
|
|
})
|
|
|
|
if (index === -1) {
|
|
primaryProfile.subscriptions.push(subscription)
|
|
this.updateProfile(primaryProfile)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.isProfileDropdownEnabled && this.openDropdownOnSubscribe && !this.isProfileDropdownOpen) {
|
|
this.toggleProfileDropdown()
|
|
}
|
|
},
|
|
|
|
handleProfileDropdownFocusOut: function () {
|
|
if (!this.$refs.subscribeButton.matches(':focus-within')) {
|
|
this.isProfileDropdownOpen = false
|
|
}
|
|
},
|
|
|
|
toggleProfileDropdown: function() {
|
|
this.isProfileDropdownOpen = !this.isProfileDropdownOpen
|
|
},
|
|
|
|
isActiveProfile: function (profile) {
|
|
return profile._id === this.activeProfile._id
|
|
},
|
|
|
|
subscriptionInfoForProfile: function (profile) {
|
|
return profile.subscriptions.find((channel) => {
|
|
return channel.id === this.channelId
|
|
}) ?? null
|
|
},
|
|
|
|
isProfileSubscribed: function (profile) {
|
|
return this.subscriptionInfoForProfile(profile) !== null
|
|
},
|
|
|
|
unsubscribe: function(profile, channelId) {
|
|
const parsedProfile = deepCopy(profile)
|
|
const index = parsedProfile.subscriptions.findIndex((channel) => {
|
|
return channel.id === channelId
|
|
})
|
|
|
|
if (index !== -1) {
|
|
// use filter instead of splice in case the subscription appears multiple times
|
|
// https://github.com/FreeTubeApp/FreeTube/pull/3468#discussion_r1179290877
|
|
parsedProfile.subscriptions = parsedProfile.subscriptions.filter((x) => {
|
|
return x.id !== channelId
|
|
})
|
|
|
|
this.updateProfile(parsedProfile)
|
|
return 1
|
|
}
|
|
return 0
|
|
},
|
|
|
|
...mapActions([
|
|
'updateProfile'
|
|
])
|
|
}
|
|
})
|