2020-02-16 19:30:00 +01:00
|
|
|
import Vue from 'vue'
|
2020-08-13 20:21:25 +02:00
|
|
|
import { mapActions } from 'vuex'
|
2020-02-16 19:30:00 +01:00
|
|
|
import FtCard from '../../components/ft-card/ft-card.vue'
|
|
|
|
import FtButton from '../../components/ft-button/ft-button.vue'
|
|
|
|
import FtInput from '../../components/ft-input/ft-input.vue'
|
|
|
|
import FtSelect from '../../components/ft-select/ft-select.vue'
|
|
|
|
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
|
|
|
|
import FtChannelBubble from '../../components/ft-channel-bubble/ft-channel-bubble.vue'
|
|
|
|
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
|
|
|
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
|
2022-06-21 08:14:15 +02:00
|
|
|
import FtAgeRestricted from '../../components/ft-age-restricted/ft-age-restricted.vue'
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2020-06-24 04:40:34 +02:00
|
|
|
import ytch from 'yt-channel-info'
|
2020-08-13 20:21:25 +02:00
|
|
|
import autolinker from 'autolinker'
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
import { MAIN_PROFILE_ID } from '../../../constants'
|
2022-09-19 14:14:53 +02:00
|
|
|
import i18n from '../../i18n/index'
|
2020-06-24 04:40:34 +02:00
|
|
|
|
2020-02-16 19:30:00 +01:00
|
|
|
export default Vue.extend({
|
|
|
|
name: 'Search',
|
|
|
|
components: {
|
|
|
|
'ft-card': FtCard,
|
|
|
|
'ft-button': FtButton,
|
|
|
|
'ft-input': FtInput,
|
|
|
|
'ft-select': FtSelect,
|
|
|
|
'ft-flex-box': FtFlexBox,
|
|
|
|
'ft-channel-bubble': FtChannelBubble,
|
|
|
|
'ft-loader': FtLoader,
|
2022-06-21 08:14:15 +02:00
|
|
|
'ft-element-list': FtElementList,
|
|
|
|
'ft-age-restricted': FtAgeRestricted
|
2020-02-16 19:30:00 +01:00
|
|
|
},
|
|
|
|
data: function () {
|
|
|
|
return {
|
|
|
|
isLoading: false,
|
|
|
|
isElementListLoading: false,
|
|
|
|
currentTab: 'videos',
|
|
|
|
id: '',
|
2022-08-08 11:26:04 +02:00
|
|
|
idType: 0,
|
2020-02-16 19:30:00 +01:00
|
|
|
channelName: '',
|
|
|
|
bannerUrl: '',
|
|
|
|
thumbnailUrl: '',
|
|
|
|
subCount: 0,
|
|
|
|
latestVideosPage: 2,
|
|
|
|
searchPage: 2,
|
2020-06-24 04:40:34 +02:00
|
|
|
videoContinuationString: '',
|
2020-02-16 19:30:00 +01:00
|
|
|
playlistContinuationString: '',
|
2020-06-24 04:40:34 +02:00
|
|
|
searchContinuationString: '',
|
2020-02-16 19:30:00 +01:00
|
|
|
channelDescription: '',
|
|
|
|
videoSortBy: 'newest',
|
|
|
|
playlistSortBy: 'last',
|
|
|
|
lastSearchQuery: '',
|
|
|
|
relatedChannels: [],
|
|
|
|
latestVideos: [],
|
|
|
|
latestPlaylists: [],
|
|
|
|
searchResults: [],
|
|
|
|
shownElementList: [],
|
2020-06-24 04:40:34 +02:00
|
|
|
apiUsed: '',
|
2022-06-21 08:14:15 +02:00
|
|
|
isFamilyFriendly: false,
|
2022-06-03 16:04:50 +02:00
|
|
|
errorMessage: '',
|
2020-02-16 19:30:00 +01:00
|
|
|
videoSelectValues: [
|
|
|
|
'newest',
|
|
|
|
'oldest',
|
|
|
|
'popular'
|
|
|
|
],
|
|
|
|
playlistSelectValues: [
|
|
|
|
'last',
|
2021-03-04 22:51:56 +01:00
|
|
|
'newest'
|
2020-02-16 19:30:00 +01:00
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
2020-06-24 04:40:34 +02:00
|
|
|
backendPreference: function () {
|
|
|
|
return this.$store.getters.getBackendPreference
|
|
|
|
},
|
|
|
|
|
|
|
|
backendFallback: function () {
|
|
|
|
return this.$store.getters.getBackendFallback
|
|
|
|
},
|
|
|
|
|
2022-06-21 08:14:15 +02:00
|
|
|
hideUnsubscribeButton: function() {
|
|
|
|
return this.$store.getters.getHideUnsubscribeButton
|
|
|
|
},
|
|
|
|
|
|
|
|
showFamilyFriendlyOnly: function() {
|
|
|
|
return this.$store.getters.getShowFamilyFriendlyOnly
|
|
|
|
},
|
|
|
|
|
2021-07-03 03:55:56 +02:00
|
|
|
currentInvidiousInstance: function () {
|
|
|
|
return this.$store.getters.getCurrentInvidiousInstance
|
2020-10-13 17:06:04 +02:00
|
|
|
},
|
|
|
|
|
2020-02-16 19:30:00 +01:00
|
|
|
sessionSearchHistory: function () {
|
|
|
|
return this.$store.getters.getSessionSearchHistory
|
|
|
|
},
|
|
|
|
|
2020-08-31 23:35:22 +02:00
|
|
|
profileList: function () {
|
|
|
|
return this.$store.getters.getProfileList
|
|
|
|
},
|
|
|
|
|
|
|
|
activeProfile: function () {
|
|
|
|
return this.$store.getters.getActiveProfile
|
|
|
|
},
|
|
|
|
|
2022-06-03 16:04:50 +02:00
|
|
|
subscriptionInfo: function () {
|
|
|
|
return this.activeProfile.subscriptions.find((channel) => {
|
2020-08-31 23:35:22 +02:00
|
|
|
return channel.id === this.id
|
2022-06-03 16:04:50 +02:00
|
|
|
}) ?? null
|
|
|
|
},
|
2020-08-31 23:35:22 +02:00
|
|
|
|
2022-06-03 16:04:50 +02:00
|
|
|
isSubscribed: function () {
|
|
|
|
return this.subscriptionInfo !== null
|
2020-08-31 23:35:22 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
subscribedText: function () {
|
|
|
|
if (this.isSubscribed) {
|
|
|
|
return this.$t('Channel.Unsubscribe').toUpperCase()
|
|
|
|
} else {
|
|
|
|
return this.$t('Channel.Subscribe').toUpperCase()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2020-08-09 05:15:00 +02:00
|
|
|
videoSelectNames: function () {
|
|
|
|
return [
|
|
|
|
this.$t('Channel.Videos.Sort Types.Newest'),
|
|
|
|
this.$t('Channel.Videos.Sort Types.Oldest'),
|
|
|
|
this.$t('Channel.Videos.Sort Types.Most Popular')
|
|
|
|
]
|
|
|
|
},
|
|
|
|
|
|
|
|
playlistSelectNames: function () {
|
|
|
|
return [
|
|
|
|
this.$t('Channel.Playlists.Sort Types.Last Video Added'),
|
2021-03-04 22:51:56 +01:00
|
|
|
this.$t('Channel.Playlists.Sort Types.Newest')
|
2020-08-09 05:15:00 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
|
2022-09-19 14:14:53 +02:00
|
|
|
currentLocale: function () {
|
|
|
|
return i18n.locale.replace('_', '-')
|
|
|
|
},
|
|
|
|
|
2020-02-16 19:30:00 +01:00
|
|
|
formattedSubCount: function () {
|
2020-10-06 04:27:32 +02:00
|
|
|
if (this.hideChannelSubscriptions) {
|
|
|
|
return null
|
|
|
|
}
|
2022-09-19 14:14:53 +02:00
|
|
|
return Intl.NumberFormat(this.currentLocale).format(this.subCount)
|
2020-07-12 00:36:42 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
showFetchMoreButton: function () {
|
|
|
|
switch (this.currentTab) {
|
|
|
|
case 'videos':
|
2021-02-15 15:59:35 +01:00
|
|
|
if (this.apiUsed === 'invidious' || (this.videoContinuationString !== '' && this.videoContinuationString !== null)) {
|
2020-07-12 00:36:42 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'playlists':
|
|
|
|
if (this.playlistContinuationString !== '' && this.playlistContinuationString !== null) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'search':
|
|
|
|
if (this.searchContinuationString !== '' && this.searchContinuationString !== null) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
2020-10-06 04:27:32 +02:00
|
|
|
},
|
|
|
|
hideChannelSubscriptions: function () {
|
|
|
|
return this.$store.getters.getHideChannelSubscriptions
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
watch: {
|
2020-09-03 03:06:49 +02:00
|
|
|
$route() {
|
|
|
|
// react to route changes...
|
2022-08-08 11:26:04 +02:00
|
|
|
this.originalId = this.$route.params.id
|
2020-09-03 03:06:49 +02:00
|
|
|
this.id = this.$route.params.id
|
2022-08-08 11:26:04 +02:00
|
|
|
this.idType = this.$route.query.idType ? Number(this.$route.query.idType) : 0
|
2021-11-02 12:45:50 +01:00
|
|
|
this.currentTab = this.$route.params.currentTab ?? 'videos'
|
2020-09-21 04:20:40 +02:00
|
|
|
this.latestVideosPage = 2
|
|
|
|
this.searchPage = 2
|
|
|
|
this.relatedChannels = []
|
|
|
|
this.latestVideos = []
|
|
|
|
this.latestPlaylists = []
|
|
|
|
this.searchResults = []
|
|
|
|
this.shownElementList = []
|
|
|
|
this.apiUsed = ''
|
2020-09-03 03:06:49 +02:00
|
|
|
this.isLoading = true
|
|
|
|
|
2022-09-17 10:19:31 +02:00
|
|
|
if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') {
|
|
|
|
this.getChannelInfoInvidious()
|
|
|
|
this.getPlaylistsInvidious()
|
2020-09-03 03:06:49 +02:00
|
|
|
} else {
|
2022-09-17 10:19:31 +02:00
|
|
|
this.getChannelInfoLocal()
|
|
|
|
this.getChannelVideosLocal()
|
|
|
|
this.getPlaylistsLocal()
|
2020-09-03 03:06:49 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2020-02-16 19:30:00 +01:00
|
|
|
videoSortBy () {
|
|
|
|
this.isElementListLoading = true
|
|
|
|
this.latestVideos = []
|
2020-06-24 04:40:34 +02:00
|
|
|
switch (this.apiUsed) {
|
|
|
|
case 'local':
|
|
|
|
this.getChannelVideosLocal()
|
|
|
|
break
|
|
|
|
case 'invidious':
|
|
|
|
this.latestVideosPage = 1
|
|
|
|
this.channelInvidiousNextPage()
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
this.getChannelVideosLocal()
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
playlistSortBy () {
|
|
|
|
this.isElementListLoading = true
|
|
|
|
this.latestPlaylists = []
|
|
|
|
this.playlistContinuationString = ''
|
2020-06-24 04:40:34 +02:00
|
|
|
switch (this.apiUsed) {
|
|
|
|
case 'local':
|
|
|
|
this.getPlaylistsLocal()
|
|
|
|
break
|
|
|
|
case 'invidious':
|
|
|
|
this.channelInvidiousNextPage()
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
this.getPlaylistsLocal()
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted: function () {
|
2022-08-08 11:26:04 +02:00
|
|
|
this.originalId = this.$route.params.id
|
2020-02-16 19:30:00 +01:00
|
|
|
this.id = this.$route.params.id
|
2022-08-08 11:26:04 +02:00
|
|
|
this.idType = this.$route.query.idType ? Number(this.$route.query.idType) : 0
|
2021-11-02 12:45:50 +01:00
|
|
|
this.currentTab = this.$route.params.currentTab ?? 'videos'
|
2020-06-24 04:40:34 +02:00
|
|
|
this.isLoading = true
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2022-09-17 10:19:31 +02:00
|
|
|
if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') {
|
|
|
|
this.getChannelInfoInvidious()
|
|
|
|
this.getPlaylistsInvidious()
|
2020-06-24 04:40:34 +02:00
|
|
|
} else {
|
2022-09-17 10:19:31 +02:00
|
|
|
this.getChannelInfoLocal()
|
|
|
|
this.getChannelVideosLocal()
|
|
|
|
this.getPlaylistsLocal()
|
2020-06-24 04:40:34 +02:00
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
},
|
|
|
|
methods: {
|
2020-09-16 04:07:54 +02:00
|
|
|
goToChannel: function (id) {
|
|
|
|
this.$router.push({ path: `/channel/${id}` })
|
|
|
|
},
|
|
|
|
|
2020-06-24 04:40:34 +02:00
|
|
|
getChannelInfoLocal: function () {
|
2020-07-30 04:58:07 +02:00
|
|
|
this.apiUsed = 'local'
|
2022-08-08 11:26:04 +02:00
|
|
|
const expectedId = this.originalId
|
|
|
|
ytch.getChannelInfo({ channelId: this.id, channelIdType: this.idType }).then((response) => {
|
2022-06-03 16:04:50 +02:00
|
|
|
if (response.alertMessage) {
|
|
|
|
this.setErrorMessage(response.alertMessage)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this.errorMessage = ''
|
2022-08-08 11:26:04 +02:00
|
|
|
if (expectedId !== this.originalId) {
|
2022-05-25 11:32:19 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-06-03 14:52:35 +02:00
|
|
|
const channelId = response.authorId
|
|
|
|
const channelName = response.author
|
|
|
|
const channelThumbnailUrl = response.authorThumbnails[2].url
|
|
|
|
this.id = channelId
|
2022-08-08 11:26:04 +02:00
|
|
|
// set the id type to 1 so that searching and sorting work
|
|
|
|
this.idType = 1
|
2022-06-03 14:52:35 +02:00
|
|
|
this.channelName = channelName
|
2022-06-21 08:14:15 +02:00
|
|
|
this.isFamilyFriendly = response.isFamilyFriendly
|
2021-07-21 17:45:02 +02:00
|
|
|
document.title = `${this.channelName} - ${process.env.PRODUCT_NAME}`
|
2020-10-06 23:45:30 +02:00
|
|
|
if (this.hideChannelSubscriptions || response.subscriberCount === 0) {
|
2020-10-06 04:27:32 +02:00
|
|
|
this.subCount = null
|
|
|
|
} else {
|
|
|
|
this.subCount = response.subscriberCount.toFixed(0)
|
|
|
|
}
|
2022-06-03 14:52:35 +02:00
|
|
|
this.thumbnailUrl = channelThumbnailUrl
|
|
|
|
this.updateSubscriptionDetails({ channelThumbnailUrl, channelName, channelId })
|
2020-08-13 20:21:25 +02:00
|
|
|
this.channelDescription = autolinker.link(response.description)
|
2021-04-30 23:18:45 +02:00
|
|
|
this.relatedChannels = response.relatedChannels.items
|
2021-08-20 20:45:00 +02:00
|
|
|
this.relatedChannels.forEach(relatedChannel => {
|
2022-04-06 05:05:15 +02:00
|
|
|
relatedChannel.thumbnail.map(thumbnail => {
|
2021-08-20 20:45:00 +02:00
|
|
|
if (!thumbnail.url.includes('https')) {
|
|
|
|
thumbnail.url = `https:${thumbnail.url}`
|
|
|
|
}
|
|
|
|
return thumbnail
|
|
|
|
})
|
2022-04-06 05:05:15 +02:00
|
|
|
relatedChannel.authorThumbnails = relatedChannel.thumbnail
|
2021-08-20 20:45:00 +02:00
|
|
|
})
|
2020-07-12 00:36:42 +02:00
|
|
|
|
|
|
|
if (response.authorBanners !== null) {
|
2020-07-17 05:14:26 +02:00
|
|
|
const bannerUrl = response.authorBanners[response.authorBanners.length - 1].url
|
|
|
|
|
|
|
|
if (!bannerUrl.includes('https')) {
|
|
|
|
this.bannerUrl = `https://${bannerUrl}`
|
|
|
|
} else {
|
|
|
|
this.bannerUrl = bannerUrl
|
|
|
|
}
|
2020-07-12 00:36:42 +02:00
|
|
|
} else {
|
|
|
|
this.bannerUrl = null
|
|
|
|
}
|
|
|
|
|
2020-06-24 04:40:34 +02:00
|
|
|
this.isLoading = false
|
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
if (this.backendPreference === 'local' && this.backendFallback) {
|
2020-08-09 05:15:00 +02:00
|
|
|
this.showToast({
|
|
|
|
message: this.$t('Falling back to Invidious API')
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
this.getChannelInfoInvidious()
|
|
|
|
} else {
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
2020-06-24 04:40:34 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
getChannelVideosLocal: function () {
|
|
|
|
this.isElementListLoading = true
|
2022-08-08 11:26:04 +02:00
|
|
|
const expectedId = this.originalId
|
|
|
|
ytch.getChannelVideos({ channelId: this.id, channelIdType: this.idType, sortBy: this.videoSortBy }).then((response) => {
|
|
|
|
if (expectedId !== this.originalId) {
|
2022-05-25 11:32:19 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-24 04:40:34 +02:00
|
|
|
this.latestVideos = response.items
|
|
|
|
this.videoContinuationString = response.continuation
|
|
|
|
this.isElementListLoading = false
|
2020-07-12 00:36:42 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
if (this.backendPreference === 'local' && this.backendFallback) {
|
2020-08-09 05:15:00 +02:00
|
|
|
this.showToast({
|
|
|
|
message: this.$t('Falling back to Invidious API')
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
this.getChannelInfoInvidious()
|
|
|
|
} else {
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
2020-06-24 04:40:34 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
channelLocalNextPage: function () {
|
2022-04-06 05:05:15 +02:00
|
|
|
ytch.getChannelVideosMore({ continuation: this.videoContinuationString }).then((response) => {
|
2020-06-24 04:40:34 +02:00
|
|
|
this.latestVideos = this.latestVideos.concat(response.items)
|
|
|
|
this.videoContinuationString = response.continuation
|
2020-07-12 00:36:42 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-06-24 04:40:34 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
getChannelInfoInvidious: function () {
|
2020-02-16 19:30:00 +01:00
|
|
|
this.isLoading = true
|
2020-07-30 04:58:07 +02:00
|
|
|
this.apiUsed = 'invidious'
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2022-08-08 11:26:04 +02:00
|
|
|
const expectedId = this.originalId
|
|
|
|
this.invidiousGetChannelInfo(this.id).then((response) => {
|
|
|
|
if (expectedId !== this.originalId) {
|
2022-05-25 11:32:19 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-06-03 14:52:35 +02:00
|
|
|
const channelName = response.author
|
|
|
|
const channelId = response.authorId
|
|
|
|
this.channelName = channelName
|
2021-07-21 17:45:02 +02:00
|
|
|
document.title = `${this.channelName} - ${process.env.PRODUCT_NAME}`
|
2022-06-03 14:52:35 +02:00
|
|
|
this.id = channelId
|
2022-06-21 08:14:15 +02:00
|
|
|
this.isFamilyFriendly = response.isFamilyFriendly
|
2020-10-06 04:27:32 +02:00
|
|
|
if (this.hideChannelSubscriptions) {
|
|
|
|
this.subCount = null
|
|
|
|
} else {
|
|
|
|
this.subCount = response.subCount
|
|
|
|
}
|
2022-06-03 14:52:35 +02:00
|
|
|
const thumbnail = response.authorThumbnails[3].url
|
|
|
|
this.thumbnailUrl = thumbnail.replace('https://yt3.ggpht.com', `${this.currentInvidiousInstance}/ggpht/`)
|
|
|
|
this.updateSubscriptionDetails({ channelThumbnailUrl: thumbnail, channelName: channelName, channelId: channelId })
|
2020-08-13 20:21:25 +02:00
|
|
|
this.channelDescription = autolinker.link(response.description)
|
2020-10-13 17:06:04 +02:00
|
|
|
this.relatedChannels = response.relatedChannels.map((channel) => {
|
2021-07-03 03:55:56 +02:00
|
|
|
channel.authorThumbnails[channel.authorThumbnails.length - 1].url = channel.authorThumbnails[channel.authorThumbnails.length - 1].url.replace('https://yt3.ggpht.com', `${this.currentInvidiousInstance}/ggpht/`)
|
2022-08-16 01:14:59 +02:00
|
|
|
channel.channelId = channel.authorId
|
2020-10-13 17:06:04 +02:00
|
|
|
return channel
|
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
this.latestVideos = response.latestVideos
|
2020-07-12 00:36:42 +02:00
|
|
|
|
2022-05-12 11:37:25 +02:00
|
|
|
if (response.authorBanners instanceof Array && response.authorBanners.length > 0) {
|
2021-07-03 03:55:56 +02:00
|
|
|
this.bannerUrl = response.authorBanners[0].url.replace('https://yt3.ggpht.com', `${this.currentInvidiousInstance}/ggpht/`)
|
2022-05-12 11:37:25 +02:00
|
|
|
} else {
|
|
|
|
this.bannerUrl = null
|
2020-07-12 00:36:42 +02:00
|
|
|
}
|
|
|
|
|
2022-06-03 16:04:50 +02:00
|
|
|
this.errorMessage = ''
|
2020-02-16 19:30:00 +01:00
|
|
|
this.isLoading = false
|
2020-08-09 05:15:00 +02:00
|
|
|
}).catch((err) => {
|
2022-06-03 16:04:50 +02:00
|
|
|
this.setErrorMessage(err.responseJSON.error)
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
|
|
|
this.showToast({
|
2021-02-15 15:59:35 +01:00
|
|
|
message: `${errorMessage}: ${err.responseJSON.error}`,
|
2020-08-09 05:15:00 +02:00
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err.responseJSON.error })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
this.isLoading = false
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
2020-06-24 04:40:34 +02:00
|
|
|
channelInvidiousNextPage: function () {
|
2020-02-16 19:30:00 +01:00
|
|
|
const payload = {
|
|
|
|
resource: 'channels/videos',
|
|
|
|
id: this.id,
|
|
|
|
params: {
|
|
|
|
sort_by: this.videoSortBy,
|
|
|
|
page: this.latestVideosPage
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-22 01:56:32 +02:00
|
|
|
this.invidiousAPICall(payload).then((response) => {
|
2020-02-16 19:30:00 +01:00
|
|
|
this.latestVideos = this.latestVideos.concat(response)
|
|
|
|
this.latestVideosPage++
|
|
|
|
this.isElementListLoading = false
|
2020-08-09 05:15:00 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
2020-06-24 04:40:34 +02:00
|
|
|
getPlaylistsLocal: function () {
|
2022-08-08 11:26:04 +02:00
|
|
|
const expectedId = this.originalId
|
|
|
|
ytch.getChannelPlaylistInfo({ channelId: this.id, channelIdType: this.idType, sortBy: this.playlistSortBy }).then((response) => {
|
|
|
|
if (expectedId !== this.originalId) {
|
2022-05-25 11:32:19 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-01-11 17:26:14 +01:00
|
|
|
this.latestPlaylists = response.items.map((item) => {
|
|
|
|
item.proxyThumbnail = false
|
|
|
|
return item
|
|
|
|
})
|
2020-06-24 04:40:34 +02:00
|
|
|
this.playlistContinuationString = response.continuation
|
|
|
|
this.isElementListLoading = false
|
2020-07-12 00:36:42 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
if (this.backendPreference === 'local' && this.backendFallback) {
|
2020-08-09 05:15:00 +02:00
|
|
|
this.showToast({
|
|
|
|
message: this.$t('Falling back to Invidious API')
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
this.getPlaylistsInvidious()
|
|
|
|
} else {
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
2020-06-24 04:40:34 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
getPlaylistsLocalMore: function () {
|
2022-04-06 05:05:15 +02:00
|
|
|
ytch.getChannelPlaylistsMore({ continuation: this.playlistContinuationString }).then((response) => {
|
2020-06-24 04:40:34 +02:00
|
|
|
this.latestPlaylists = this.latestPlaylists.concat(response.items)
|
|
|
|
this.playlistContinuationString = response.continuation
|
2020-07-12 00:36:42 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-06-24 04:40:34 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
getPlaylistsInvidious: function () {
|
2022-05-12 11:37:25 +02:00
|
|
|
const payload = {
|
|
|
|
resource: 'channels/playlists',
|
|
|
|
id: this.id,
|
|
|
|
params: {
|
|
|
|
sort_by: this.playlistSortBy
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.invidiousAPICall(payload).then((response) => {
|
|
|
|
this.playlistContinuationString = response.continuation
|
|
|
|
this.latestPlaylists = response.playlists
|
|
|
|
this.isElementListLoading = false
|
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2022-05-12 11:37:25 +02:00
|
|
|
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err.responseJSON.error}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err.responseJSON.error })
|
2022-05-12 11:37:25 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
if (this.backendPreference === 'invidious' && this.backendFallback) {
|
|
|
|
this.showToast({
|
|
|
|
message: this.$t('Falling back to Local API')
|
|
|
|
})
|
|
|
|
this.getPlaylistsLocal()
|
|
|
|
} else {
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
getPlaylistsInvidiousMore: function () {
|
2020-02-16 19:30:00 +01:00
|
|
|
if (this.playlistContinuationString === null) {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.warn('There are no more playlists available for this channel')
|
2020-02-16 19:30:00 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
resource: 'channels/playlists',
|
|
|
|
id: this.id,
|
|
|
|
params: {
|
2021-02-15 15:59:35 +01:00
|
|
|
sort_by: this.playlistSortBy
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-15 15:59:35 +01:00
|
|
|
if (this.playlistContinuationString) {
|
|
|
|
payload.params.continuation = this.playlistContinuationString
|
|
|
|
}
|
|
|
|
|
2021-05-22 01:56:32 +02:00
|
|
|
this.invidiousAPICall(payload).then((response) => {
|
2020-02-16 19:30:00 +01:00
|
|
|
this.playlistContinuationString = response.continuation
|
|
|
|
this.latestPlaylists = this.latestPlaylists.concat(response.playlists)
|
|
|
|
this.isElementListLoading = false
|
2020-07-30 04:58:07 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
|
|
|
this.showToast({
|
2021-02-15 15:59:35 +01:00
|
|
|
message: `${errorMessage}: ${err.responseJSON.error}`,
|
2020-08-09 05:15:00 +02:00
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err.responseJSON.error })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
if (this.backendPreference === 'invidious' && this.backendFallback) {
|
2020-08-09 05:15:00 +02:00
|
|
|
this.showToast({
|
|
|
|
message: this.$t('Falling back to Local API')
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
this.getPlaylistsLocal()
|
|
|
|
} else {
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
handleSubscription: function () {
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
const currentProfile = JSON.parse(JSON.stringify(this.activeProfile))
|
2020-08-31 23:35:22 +02:00
|
|
|
const primaryProfile = JSON.parse(JSON.stringify(this.profileList[0]))
|
|
|
|
|
|
|
|
if (this.isSubscribed) {
|
|
|
|
currentProfile.subscriptions = currentProfile.subscriptions.filter((channel) => {
|
|
|
|
return channel.id !== this.id
|
|
|
|
})
|
|
|
|
|
|
|
|
this.updateProfile(currentProfile)
|
|
|
|
this.showToast({
|
2020-09-16 14:51:24 +02:00
|
|
|
message: this.$t('Channel.Channel has been removed from your subscriptions')
|
2020-08-31 23:35:22 +02:00
|
|
|
})
|
|
|
|
|
2022-08-16 11:45:39 +02:00
|
|
|
if (this.activeProfile._id === MAIN_PROFILE_ID) {
|
2020-08-31 23:35:22 +02:00
|
|
|
// Check if a subscription exists in a different profile.
|
|
|
|
// Remove from there as well.
|
|
|
|
let duplicateSubscriptions = 0
|
|
|
|
|
|
|
|
this.profileList.forEach((profile) => {
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
if (profile._id === MAIN_PROFILE_ID) {
|
2020-08-31 23:35:22 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
const parsedProfile = JSON.parse(JSON.stringify(profile))
|
|
|
|
const index = parsedProfile.subscriptions.findIndex((channel) => {
|
|
|
|
return channel.id === this.id
|
|
|
|
})
|
|
|
|
|
|
|
|
if (index !== -1) {
|
|
|
|
duplicateSubscriptions++
|
|
|
|
|
|
|
|
parsedProfile.subscriptions = parsedProfile.subscriptions.filter((x) => {
|
2020-09-16 14:51:24 +02:00
|
|
|
return x.id !== this.id
|
2020-08-31 23:35:22 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
this.updateProfile(parsedProfile)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
if (duplicateSubscriptions > 0) {
|
|
|
|
this.showToast({
|
2022-10-13 13:51:15 +02:00
|
|
|
message: this.$t('Channel.Removed subscription from {count} other channel(s)', { count: duplicateSubscriptions })
|
2020-08-31 23:35:22 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const subscription = {
|
|
|
|
id: this.id,
|
|
|
|
name: this.channelName,
|
|
|
|
thumbnail: this.thumbnailUrl
|
|
|
|
}
|
|
|
|
currentProfile.subscriptions.push(subscription)
|
|
|
|
|
|
|
|
this.updateProfile(currentProfile)
|
|
|
|
this.showToast({
|
2020-09-16 14:51:24 +02:00
|
|
|
message: this.$t('Channel.Added channel to your subscriptions')
|
2020-08-31 23:35:22 +02:00
|
|
|
})
|
|
|
|
|
2022-08-16 11:45:39 +02:00
|
|
|
if (this.activeProfile._id !== MAIN_PROFILE_ID) {
|
2020-08-31 23:35:22 +02:00
|
|
|
const index = primaryProfile.subscriptions.findIndex((channel) => {
|
|
|
|
return channel.id === this.id
|
|
|
|
})
|
|
|
|
|
|
|
|
if (index === -1) {
|
|
|
|
primaryProfile.subscriptions.push(subscription)
|
|
|
|
this.updateProfile(primaryProfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
},
|
|
|
|
|
2022-06-03 16:04:50 +02:00
|
|
|
setErrorMessage: function (errorMessage) {
|
|
|
|
this.isLoading = false
|
|
|
|
this.errorMessage = errorMessage
|
|
|
|
this.id = this.subscriptionInfo.id
|
|
|
|
this.channelName = this.subscriptionInfo.name
|
|
|
|
this.thumbnailUrl = this.subscriptionInfo.thumbnail
|
|
|
|
this.bannerUrl = null
|
|
|
|
this.subCount = null
|
|
|
|
},
|
|
|
|
|
2020-02-16 19:30:00 +01:00
|
|
|
handleFetchMore: function () {
|
|
|
|
switch (this.currentTab) {
|
|
|
|
case 'videos':
|
2020-06-24 04:40:34 +02:00
|
|
|
switch (this.apiUsed) {
|
|
|
|
case 'local':
|
|
|
|
this.channelLocalNextPage()
|
|
|
|
break
|
|
|
|
case 'invidious':
|
|
|
|
this.channelInvidiousNextPage()
|
|
|
|
break
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
break
|
|
|
|
case 'playlists':
|
2020-06-24 04:40:34 +02:00
|
|
|
switch (this.apiUsed) {
|
|
|
|
case 'local':
|
|
|
|
this.getPlaylistsLocalMore()
|
|
|
|
break
|
|
|
|
case 'invidious':
|
2022-05-12 11:37:25 +02:00
|
|
|
this.getPlaylistsInvidiousMore()
|
2020-06-24 04:40:34 +02:00
|
|
|
break
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
break
|
|
|
|
case 'search':
|
2020-06-24 04:40:34 +02:00
|
|
|
switch (this.apiUsed) {
|
|
|
|
case 'local':
|
|
|
|
this.searchChannelLocal()
|
|
|
|
break
|
|
|
|
case 'invidious':
|
|
|
|
this.searchChannelInvidious()
|
|
|
|
break
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
break
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
changeTab: function (tab) {
|
|
|
|
this.currentTab = tab
|
|
|
|
},
|
|
|
|
|
|
|
|
newSearch: function (query) {
|
|
|
|
this.lastSearchQuery = query
|
2020-06-24 04:40:34 +02:00
|
|
|
this.searchContinuationString = ''
|
2020-02-16 19:30:00 +01:00
|
|
|
this.isElementListLoading = true
|
|
|
|
this.searchPage = 1
|
|
|
|
this.searchResults = []
|
|
|
|
this.changeTab('search')
|
2020-06-24 04:40:34 +02:00
|
|
|
switch (this.apiUsed) {
|
|
|
|
case 'local':
|
|
|
|
this.searchChannelLocal()
|
|
|
|
break
|
|
|
|
case 'invidious':
|
|
|
|
this.searchChannelInvidious()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
searchChannelLocal: function () {
|
|
|
|
if (this.searchContinuationString === '') {
|
2022-08-08 11:26:04 +02:00
|
|
|
ytch.searchChannel({ channelId: this.id, channelIdType: this.idType, query: this.lastSearchQuery }).then((response) => {
|
2020-06-24 04:40:34 +02:00
|
|
|
this.searchResults = response.items
|
|
|
|
this.isElementListLoading = false
|
|
|
|
this.searchContinuationString = response.continuation
|
2020-07-12 00:36:42 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
if (this.backendPreference === 'local' && this.backendFallback) {
|
2020-08-09 05:15:00 +02:00
|
|
|
this.showToast({
|
|
|
|
message: this.$t('Falling back to Invidious API')
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
this.searchChannelInvidious()
|
|
|
|
} else {
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
2020-06-24 04:40:34 +02:00
|
|
|
})
|
|
|
|
} else {
|
2022-04-06 05:05:15 +02:00
|
|
|
ytch.searchChannelMore({ continuation: this.searchContinuationString }).then((response) => {
|
2020-06-24 04:40:34 +02:00
|
|
|
this.searchResults = this.searchResults.concat(response.items)
|
|
|
|
this.isElementListLoading = false
|
|
|
|
this.searchContinuationString = response.continuation
|
2020-07-12 00:36:42 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Local API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-06-24 04:40:34 +02:00
|
|
|
})
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
},
|
|
|
|
|
2020-06-24 04:40:34 +02:00
|
|
|
searchChannelInvidious: function () {
|
2020-02-16 19:30:00 +01:00
|
|
|
const payload = {
|
|
|
|
resource: 'channels/search',
|
|
|
|
id: this.id,
|
|
|
|
params: {
|
|
|
|
q: this.lastSearchQuery,
|
|
|
|
page: this.searchPage
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-22 01:56:32 +02:00
|
|
|
this.invidiousAPICall(payload).then((response) => {
|
2020-02-16 19:30:00 +01:00
|
|
|
this.searchResults = this.searchResults.concat(response)
|
|
|
|
this.isElementListLoading = false
|
|
|
|
this.searchPage++
|
2020-07-30 04:58:07 +02:00
|
|
|
}).catch((err) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2020-08-09 05:15:00 +02:00
|
|
|
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
|
|
|
this.showToast({
|
|
|
|
message: `${errorMessage}: ${err}`,
|
|
|
|
time: 10000,
|
|
|
|
action: () => {
|
2022-09-21 09:00:21 +02:00
|
|
|
this.copyToClipboard({ content: err })
|
2020-08-09 05:15:00 +02:00
|
|
|
}
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
if (this.backendPreference === 'invidious' && this.backendFallback) {
|
2020-08-09 05:15:00 +02:00
|
|
|
this.showToast({
|
|
|
|
message: this.$t('Falling back to Local API')
|
|
|
|
})
|
2020-07-30 04:58:07 +02:00
|
|
|
this.searchChannelLocal()
|
|
|
|
} else {
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
})
|
2020-08-13 20:21:25 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
...mapActions([
|
2020-08-31 23:35:22 +02:00
|
|
|
'showToast',
|
2021-05-22 01:56:32 +02:00
|
|
|
'updateProfile',
|
|
|
|
'invidiousGetChannelInfo',
|
2022-06-03 14:52:35 +02:00
|
|
|
'invidiousAPICall',
|
2022-09-21 09:00:21 +02:00
|
|
|
'updateSubscriptionDetails',
|
|
|
|
'copyToClipboard'
|
2020-08-13 20:21:25 +02:00
|
|
|
])
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|
|
|
|
})
|