diff --git a/src/renderer/components/CommentSection/CommentSection.vue b/src/renderer/components/CommentSection/CommentSection.vue index c9e7d2033d416..f1c348f39e0ad 100644 --- a/src/renderer/components/CommentSection/CommentSection.vue +++ b/src/renderer/components/CommentSection/CommentSection.vue @@ -314,7 +314,7 @@ import FtTimestampCatcher from '../FtTimestampCatcher.vue' import store from '../../store/index' import { copyToClipboard, showToast } from '../../helpers/utils' -import { getLocalComments, parseLocalComment } from '../../helpers/api/local' +import { getLocalCommunityPostComments, getLocalComments, parseLocalComment } from '../../helpers/api/local' import { getInvidiousCommunityPostCommentReplies, getInvidiousCommunityPostComments, @@ -476,7 +476,7 @@ function isSubscribedToChannel(channelId) { function getCommentData() { isLoading.value = true - if (!process.env.SUPPORTS_LOCAL_API || backendPreference.value === 'invidious' || props.isPostComments) { + if (!process.env.SUPPORTS_LOCAL_API || backendPreference.value === 'invidious') { if (!props.isPostComments) { getCommentDataInvidious() } else { @@ -491,7 +491,7 @@ function getMoreComments() { if (commentData.value.length === 0 || nextPageToken.value == null) { showToast(t('Comments.There are no more comments for this video')) } else { - if (!process.env.SUPPORTS_LOCAL_API || backendPreference.value === 'invidious' || props.isPostComments) { + if (!process.env.SUPPORTS_LOCAL_API || backendPreference.value === 'invidious') { if (!props.isPostComments) { getCommentDataInvidious() } else { @@ -518,7 +518,7 @@ function toggleCommentReplies(index) { * @param {number} index */ function getCommentReplies(index) { - if (!process.env.SUPPORTS_LOCAL_API || commentData.value[index].dataType === 'invidious' || props.isPostComments) { + if (!process.env.SUPPORTS_LOCAL_API || commentData.value[index].dataType === 'invidious') { if (!props.isPostComments) { getCommentRepliesInvidious(index) } else { @@ -545,9 +545,15 @@ async function getCommentDataLocal(more = false) { comments = await localCommentsInstance.applySort(sortNewest.value ? 'NEWEST_FIRST' : 'TOP_COMMENTS') localCommentsInstance = comments } else { - comments = await getLocalComments(props.id) - sortNewest.value = comments.header?.sort_menu?.sub_menu_items?.[1].selected ?? false - localCommentsInstance = comments + if (props.isPostComments) { + comments = await getLocalCommunityPostComments(props.id, props.postAuthorId) + sortNewest.value = comments.header?.sort_menu?.sub_menu_items?.[1].selected ?? false + localCommentsInstance = comments + } else { + comments = await getLocalComments(props.id) + sortNewest.value = comments.header?.sort_menu?.sub_menu_items?.[1].selected ?? false + localCommentsInstance = comments + } } const parsedComments = comments.contents @@ -596,7 +602,11 @@ async function getCommentDataLocal(more = false) { if (backendFallback.value && backendPreference.value === 'local') { localCommentsInstance = undefined showToast(t('Falling back to Invidious API')) - getCommentDataInvidious() + if (props.isPostComments) { + getPostCommentsInvidious() + } else { + getCommentDataInvidious() + } } else { isLoading.value = false } @@ -763,7 +773,13 @@ function getPostCommentsInvidious() { showToast(`${errorMessage}: ${err}`, 10000, () => { copyToClipboard(err) }) - isLoading.value = false + + if (process.env.SUPPORTS_LOCAL_API && backendFallback.value && backendPreference.value === 'invidious') { + showToast(t('Falling back to Local API')) + getCommentDataLocal() + } else { + isLoading.value = false + } }) } diff --git a/src/renderer/components/FtCommunityPost/FtCommunityPost.vue b/src/renderer/components/FtCommunityPost/FtCommunityPost.vue index 69cb119a31065..e3e2f555a5334 100644 --- a/src/renderer/components/FtCommunityPost/FtCommunityPost.vue +++ b/src/renderer/components/FtCommunityPost/FtCommunityPost.vue @@ -126,7 +126,7 @@ aria-hidden="true" /> {{ formattedVoteCount }} - {{ $t('Channel.Posts.Viewing Posts Only Supported By Invidious') }} - - + @@ -32,6 +29,7 @@ import { computed, onMounted, ref, shallowRef, watch } from 'vue' import { useRoute, useRouter } from 'vue-router/composables' import packageDetails from '../../../package.json' +import { useI18n } from '../composables/use-i18n-polyfill' import FtCard from '../components/ft-card/ft-card.vue' import FtCommunityPost from '../components/FtCommunityPost/FtCommunityPost.vue' @@ -41,6 +39,10 @@ import CommentSection from '../components/CommentSection/CommentSection.vue' import store from '../store/index' import { getInvidiousCommunityPost } from '../helpers/api/invidious' +import { getLocalCommunityPost } from '../helpers/api/local' +import { copyToClipboard, showToast } from '../helpers/utils' + +const { t } = useI18n() const router = useRouter() const route = useRoute() @@ -60,22 +62,18 @@ const backendFallback = computed(() => { return store.getters.getBackendFallback }) -const isInvidiousAllowed = computed(() => { - return backendPreference.value === 'invidious' || backendFallback.value -}) - onMounted(async () => { - if (isInvidiousAllowed.value) { - id.value = route.params.id - authorId.value = route.query.authorId + id.value = route.params.id + authorId.value = route.query.authorId + + if (!process.env.SUPPORTS_LOCAL_API || backendPreference.value === 'invidious') { await loadDataInvidiousAsync() + } else { + await loadDataLocalAsync() } }) -async function loadDataInvidiousAsync() { - post.value = await getInvidiousCommunityPost(id.value, authorId.value) - authorId.value = post.value.authorId - +function updateTitleAndRoute() { store.commit('setAppTitle', `${post.value.author} - ${packageDetails.productName}`) isLoading.value = false @@ -92,13 +90,56 @@ async function loadDataInvidiousAsync() { } } +async function loadDataLocalAsync() { + try { + post.value = await getLocalCommunityPost(id.value, authorId.value) + authorId.value = post.value.authorId + updateTitleAndRoute() + } catch (error) { + console.error(error) + const errorMessage = t('Local API Error (Click to copy)') + showToast(`${errorMessage}: ${error}`, 10000, () => { + copyToClipboard(error) + }) + if (backendPreference.value === 'local' && backendFallback.value) { + showToast(t('Falling back to Invidious API')) + await loadDataInvidiousAsync() + } else { + isLoading.value = false + } + } +} + +async function loadDataInvidiousAsync() { + try { + post.value = await getInvidiousCommunityPost(id.value, authorId.value) + authorId.value = post.value.authorId + updateTitleAndRoute() + } catch (error) { + console.error(error) + const errorMessage = t('Invidious API Error (Click to copy)') + showToast(`${errorMessage}: ${error}`, 10000, () => { + copyToClipboard(error) + }) + + if (process.env.SUPPORTS_LOCAL_API && backendPreference.value === 'invidious' && backendFallback.value) { + showToast(t('Falling back to Local API')) + await loadDataLocalAsync() + } else { + isLoading.value = false + } + } +} + watch(() => route.params.id, async () => { // react to route changes... isLoading.value = true - if (isInvidiousAllowed.value) { - id.value = route.params.id - authorId.value = route.query.authorId + id.value = route.params.id + authorId.value = route.query.authorId + if (!process.env.SUPPORTS_LOCAL_API || backendPreference.value === 'invidious') { await loadDataInvidiousAsync() + } else { + await loadDataLocalAsync() } }) diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index d9443406c04d5..fb2c4f4a0ddd4 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -830,7 +830,6 @@ Channel: Reveal Answers: Reveal Answers Hide Answers: Hide Answers Video hidden by FreeTube: Video hidden by FreeTube - Viewing Posts Only Supported By Invidious: Viewing Posts is only supported by Invidious. Head to a channel's community tab to view content there without Invidious. Video: IP block: 'YouTube has blocked your IP address from watching videos. Please try switching to a different VPN or proxy.' MembersOnly: Members-only videos cannot be watched with FreeTube as they require Google login and paid membership to the uploader's channel.