diff --git a/src/renderer/store/modules/subscriptions.js b/src/renderer/store/modules/subscriptions.js
index 486a2e10..37be7815 100644
--- a/src/renderer/store/modules/subscriptions.js
+++ b/src/renderer/store/modules/subscriptions.js
@@ -4,7 +4,8 @@ const state = {
allSubscriptionsList: [],
profileSubscriptions: {
activeProfile: MAIN_PROFILE_ID,
- videoList: []
+ videoList: [],
+ errorChannels: []
}
}
diff --git a/src/renderer/views/Channel/Channel.js b/src/renderer/views/Channel/Channel.js
index 1fd79744..6c9197d2 100644
--- a/src/renderer/views/Channel/Channel.js
+++ b/src/renderer/views/Channel/Channel.js
@@ -50,6 +50,7 @@ export default Vue.extend({
searchResults: [],
shownElementList: [],
apiUsed: '',
+ errorMessage: '',
videoSelectValues: [
'newest',
'oldest',
@@ -90,16 +91,14 @@ export default Vue.extend({
return this.$store.getters.getActiveProfile
},
- isSubscribed: function () {
- const subIndex = this.activeProfile.subscriptions.findIndex((channel) => {
+ subscriptionInfo: function () {
+ return this.activeProfile.subscriptions.find((channel) => {
return channel.id === this.id
- })
+ }) ?? null
+ },
- if (subIndex === -1) {
- return false
- } else {
- return true
- }
+ isSubscribed: function () {
+ return this.subscriptionInfo !== null
},
subscribedText: function () {
@@ -251,6 +250,11 @@ export default Vue.extend({
this.apiUsed = 'local'
const expectedId = this.id
ytch.getChannelInfo({ channelId: expectedId }).then((response) => {
+ if (response.alertMessage) {
+ this.setErrorMessage(response.alertMessage)
+ return
+ }
+ this.errorMessage = ''
if (expectedId !== this.id) {
return
}
@@ -401,8 +405,10 @@ export default Vue.extend({
this.bannerUrl = null
}
+ this.errorMessage = ''
this.isLoading = false
}).catch((err) => {
+ this.setErrorMessage(err.responseJSON.error)
console.log(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
this.showToast({
@@ -645,6 +651,16 @@ export default Vue.extend({
}
},
+ 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
+ },
+
handleFetchMore: function () {
switch (this.currentTab) {
case 'videos':
diff --git a/src/renderer/views/Channel/Channel.vue b/src/renderer/views/Channel/Channel.vue
index d48ed797..50765254 100644
--- a/src/renderer/views/Channel/Channel.vue
+++ b/src/renderer/views/Channel/Channel.vue
@@ -3,7 +3,7 @@
ref="search"
>
+
+
+ {{ errorMessage }}
+
+
diff --git a/src/renderer/views/Subscriptions/Subscriptions.css b/src/renderer/views/Subscriptions/Subscriptions.css
index 8c2f6196..452a03b7 100644
--- a/src/renderer/views/Subscriptions/Subscriptions.css
+++ b/src/renderer/views/Subscriptions/Subscriptions.css
@@ -14,6 +14,10 @@
right: 10px;
}
+.channelBubble {
+ display: inline-block;
+}
+
@media only screen and (max-width: 350px) {
.floatingTopButton {
position: absolute
diff --git a/src/renderer/views/Subscriptions/Subscriptions.js b/src/renderer/views/Subscriptions/Subscriptions.js
index 9e449541..7400ba56 100644
--- a/src/renderer/views/Subscriptions/Subscriptions.js
+++ b/src/renderer/views/Subscriptions/Subscriptions.js
@@ -6,6 +6,7 @@ import FtButton from '../../components/ft-button/ft-button.vue'
import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
+import FtChannelBubble from '../../components/ft-channel-bubble/ft-channel-bubble.vue'
import ytch from 'yt-channel-info'
import Parser from 'rss-parser'
@@ -19,13 +20,15 @@ export default Vue.extend({
'ft-button': FtButton,
'ft-icon-button': FtIconButton,
'ft-flex-box': FtFlexBox,
- 'ft-element-list': FtElementList
+ 'ft-element-list': FtElementList,
+ 'ft-channel-bubble': FtChannelBubble
},
data: function () {
return {
isLoading: false,
dataLimit: 100,
- videoList: []
+ videoList: [],
+ errorChannels: []
}
},
computed: {
@@ -110,6 +113,7 @@ export default Vue.extend({
}))
} else {
this.videoList = subscriptionList.videoList
+ this.errorChannels = subscriptionList.errorChannels
}
} else {
this.getProfileSubscriptions()
@@ -123,6 +127,10 @@ export default Vue.extend({
}
},
methods: {
+ goToChannel: function (id) {
+ this.$router.push({ path: `/channel/${id}` })
+ },
+
getSubscriptions: function () {
if (this.activeSubscriptionList.length === 0) {
this.isLoading = false
@@ -144,10 +152,9 @@ export default Vue.extend({
let videoList = []
let channelCount = 0
-
+ this.errorChannels = []
this.activeSubscriptionList.forEach(async (channel) => {
let videos = []
-
if (!this.usingElectron || this.backendPreference === 'invidious') {
if (useRss) {
videos = await this.getChannelVideosInvidiousRSS(channel)
@@ -174,7 +181,8 @@ export default Vue.extend({
const profileSubscriptions = {
activeProfile: this.activeProfile._id,
- videoList: videoList
+ videoList: videoList,
+ errorChannels: this.errorChannels
}
this.videoList = await Promise.all(videoList.filter((video) => {
@@ -226,6 +234,11 @@ export default Vue.extend({
getChannelVideosLocalScraper: function (channel, failedAttempts = 0) {
return new Promise((resolve, reject) => {
ytch.getChannelVideos({ channelId: channel.id, sortBy: 'latest' }).then(async (response) => {
+ if (response.alertMessage) {
+ this.errorChannels.push(channel)
+ resolve([])
+ return
+ }
const videos = await Promise.all(response.items.map(async (video) => {
if (video.liveNow) {
video.publishedDate = new Date().getTime()
@@ -297,33 +310,38 @@ export default Vue.extend({
resolve(items)
}).catch((err) => {
console.log(err)
- const errorMessage = this.$t('Local API Error (Click to copy)')
- this.showToast({
- message: `${errorMessage}: ${err}`,
- time: 10000,
- action: () => {
- navigator.clipboard.writeText(err)
- }
- })
- switch (failedAttempts) {
- case 0:
- resolve(this.getChannelVideosLocalScraper(channel, failedAttempts + 1))
- break
- case 1:
- if (this.backendFallback) {
- this.showToast({
- message: this.$t('Falling back to Invidious API')
- })
- resolve(this.getChannelVideosInvidiousRSS(channel, failedAttempts + 1))
- } else {
- resolve([])
+ if (err.toString().match(/404/)) {
+ this.errorChannels.push(channel)
+ resolve([])
+ } else {
+ const errorMessage = this.$t('Local API Error (Click to copy)')
+ this.showToast({
+ message: `${errorMessage}: ${err}`,
+ time: 10000,
+ action: () => {
+ navigator.clipboard.writeText(err)
}
- break
- case 2:
- resolve(this.getChannelVideosLocalScraper(channel, failedAttempts + 1))
- break
- default:
- resolve([])
+ })
+ switch (failedAttempts) {
+ case 0:
+ resolve(this.getChannelVideosLocalScraper(channel, failedAttempts + 1))
+ break
+ case 1:
+ if (this.backendFallback) {
+ this.showToast({
+ message: this.$t('Falling back to Invidious API')
+ })
+ resolve(this.getChannelVideosInvidiousRSS(channel, failedAttempts + 1))
+ } else {
+ resolve([])
+ }
+ break
+ case 2:
+ resolve(this.getChannelVideosLocalScraper(channel, failedAttempts + 1))
+ break
+ default:
+ resolve([])
+ }
}
})
})
@@ -403,25 +421,30 @@ export default Vue.extend({
navigator.clipboard.writeText(err)
}
})
- switch (failedAttempts) {
- case 0:
- resolve(this.getChannelVideosInvidiousScraper(channel, failedAttempts + 1))
- break
- case 1:
- if (this.backendFallback) {
- this.showToast({
- message: this.$t('Falling back to the local API')
- })
- resolve(this.getChannelVideosLocalRSS(channel, failedAttempts + 1))
- } else {
+ if (err.toString().match(/500/)) {
+ this.errorChannels.push(channel)
+ resolve([])
+ } else {
+ switch (failedAttempts) {
+ case 0:
+ resolve(this.getChannelVideosInvidiousScraper(channel, failedAttempts + 1))
+ break
+ case 1:
+ if (this.backendFallback) {
+ this.showToast({
+ message: this.$t('Falling back to the local API')
+ })
+ resolve(this.getChannelVideosLocalRSS(channel, failedAttempts + 1))
+ } else {
+ resolve([])
+ }
+ break
+ case 2:
+ resolve(this.getChannelVideosInvidiousScraper(channel, failedAttempts + 1))
+ break
+ default:
resolve([])
- }
- break
- case 2:
- resolve(this.getChannelVideosInvidiousScraper(channel, failedAttempts + 1))
- break
- default:
- resolve([])
+ }
}
})
})
diff --git a/src/renderer/views/Subscriptions/Subscriptions.vue b/src/renderer/views/Subscriptions/Subscriptions.vue
index ba817618..f2a1245f 100644
--- a/src/renderer/views/Subscriptions/Subscriptions.vue
+++ b/src/renderer/views/Subscriptions/Subscriptions.vue
@@ -8,6 +8,22 @@
v-else
class="card"
>
+
+
{{ $t("Subscriptions.Error Channels") }}
+
+
+
+
{{ $t("Subscriptions.Subscriptions") }}