Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/renderer/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,17 @@ export default defineComponent({
break
}

case 'post': {
const { postId, query } = result

openInternalPath({
path: `/post/${postId}`,
query,
doCreateNewWindow
})
break
}

case 'channel': {
const { channelId, subPath, url } = result

Expand Down
26 changes: 22 additions & 4 deletions src/renderer/components/ft-community-post/ft-community-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import autolinker from 'autolinker'

import { A11y, Navigation, Pagination } from 'swiper/modules'

import { createWebURL, deepCopy, toLocalePublicationString } from '../../helpers/utils'
import { createWebURL, deepCopy, formatNumber, toLocalePublicationString } from '../../helpers/utils'
import { youtubeImageUrlToInvidious } from '../../helpers/api/invidious'

export default defineComponent({
Expand All @@ -29,17 +29,23 @@ export default defineComponent({
hideForbiddenTitles: {
type: Boolean,
default: true
}
},
singlePost: {
type: Boolean,
default: false
},
},
data: function () {
return {
postText: '',
postId: '',
authorThumbnails: null,
publishedText: '',
voteCount: '',
voteCount: 0,
formattedVoteCount: '',
postContent: '',
commentCount: '',
commentCount: null,
formattedCommentCount: '',
author: '',
authorId: '',
}
Expand All @@ -56,6 +62,16 @@ export default defineComponent({

hideVideo() {
return this.forbiddenTitles.some((text) => this.data.postContent.content.title?.toLowerCase().includes(text.toLowerCase()))
},

backendPreference: function () {
return this.$store.getters.getBackendPreference
},
backendFallback: function () {
return this.$store.getters.getBackendFallback
},
isInvidiousAllowed: function() {
return this.backendPreference === 'invidious' || this.backendFallback
}
},
created: function () {
Expand Down Expand Up @@ -127,7 +143,9 @@ export default defineComponent({
isRSS: this.data.isRSS
})
this.voteCount = this.data.voteCount
this.formattedVoteCount = formatNumber(this.voteCount)
this.commentCount = this.data.commentCount
this.formattedCommentCount = formatNumber(this.commentCount)
this.type = (this.data.postContent !== null && this.data.postContent !== undefined) ? this.data.postContent.type : 'text'
this.author = this.data.author
this.authorId = this.data.authorId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@
white-space: pre-wrap;
}

.commentsLink {
color: var(--primary-text-color);
text-decoration: none;
font-weight: bold;
}

.bottomSection {
color: var(--tertiary-text-color);
display: block;
Expand Down
41 changes: 36 additions & 5 deletions src/renderer/components/ft-community-post/ft-community-post.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,42 @@
<div
class="bottomSection"
>
<span class="likeCount"><font-awesome-icon
class="thumbs-up-icon"
:icon="['fas', 'thumbs-up']"
/> {{ voteCount }}</span>
<span class="commentCount">
<span
class="likeCount"
:title="$tc('Global.Counts.Like Count', voteCount, {count: formattedVoteCount})"
:aria-label="$tc('Global.Counts.Like Count', voteCount, {count: formattedVoteCount})"
>
<font-awesome-icon
class="thumbs-up-icon"
:icon="['fas', 'thumbs-up']"
aria-hidden="true"
/> {{ formattedVoteCount }}</span>
<router-link
v-if="isInvidiousAllowed && !singlePost"
:to="{
path: `/post/${postId}`,
query: authorId ? { authorId } : undefined
}"
class="commentsLink"
:aria-label="$t('Channel.Community.View Full Post')"
>
<span
class="commentCount"
:title="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
:aria-label="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
>
<font-awesome-icon
class="comment-count-icon"
:icon="['fas', 'comment']"
aria-hidden="true"
/> {{ formattedCommentCount }}</span>
</router-link>
<span
v-else-if="commentCount != null"
class="commentCount"
:title="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
:aria-label="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
>
<font-awesome-icon
class="comment-count-icon"
:icon="['fas', 'comment']"
Expand Down
1 change: 1 addition & 0 deletions src/renderer/components/ft-input/ft-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export default defineComponent({
case 'search':
case 'channel':
case 'hashtag':
case 'post':
isYoutubeLink = true
break

Expand Down
12 changes: 12 additions & 0 deletions src/renderer/components/top-nav/top-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ export default defineComponent({
break
}

case 'post': {
const { postId, query } = result

openInternalPath({
path: `/post/${postId}`,
query,
doCreateNewWindow,
searchQueryText: queryText,
})
break
}

case 'channel': {
const { channelId, subPath, url } = result

Expand Down
110 changes: 95 additions & 15 deletions src/renderer/components/watch-video-comments/watch-video-comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtSelect from '../../components/ft-select/ft-select.vue'
import FtTimestampCatcher from '../../components/ft-timestamp-catcher/ft-timestamp-catcher.vue'
import { copyToClipboard, showToast } from '../../helpers/utils'
import { invidiousGetCommentReplies, invidiousGetComments } from '../../helpers/api/invidious'
import { getInvidiousCommunityPostCommentReplies, getInvidiousCommunityPostComments, invidiousGetCommentReplies, invidiousGetComments } from '../../helpers/api/invidious'
import { getLocalComments, parseLocalComment } from '../../helpers/api/local'

export default defineComponent({
Expand Down Expand Up @@ -36,6 +36,18 @@ export default defineComponent({
type: String,
default: null,
},
isPostComments: {
type: Boolean,
default: false,
},
postAuthorId: {
type: String,
default: null
},
showSortBy: {
type: Boolean,
default: true,
}
},
emits: ['timestamp-event'],
setup: function () {
Expand Down Expand Up @@ -98,7 +110,7 @@ export default defineComponent({
if (!this.generalAutoLoadMorePaginatedItemsEnabled) {
return false
}
if (!this.videoPlayerReady) { return false }
if (!this.videoPlayerReady && !this.isPostComments) { return false }

return {
callback: (isVisible, _entry) => {
Expand Down Expand Up @@ -162,8 +174,12 @@ export default defineComponent({

getCommentData: function () {
this.isLoading = true
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious') {
this.getCommentDataInvidious()
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious' || this.isPostComments) {
if (!this.isPostComments) {
this.getCommentDataInvidious()
} else {
this.getPostCommentsInvidious()
}
} else {
this.getCommentDataLocal()
}
Expand All @@ -173,8 +189,12 @@ export default defineComponent({
if (this.commentData.length === 0 || this.nextPageToken === null || typeof this.nextPageToken === 'undefined') {
showToast(this.$t('Comments.There are no more comments for this video'))
} else {
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious') {
this.getCommentDataInvidious()
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious' || this.isPostComments) {
if (!this.isPostComments) {
this.getCommentDataInvidious()
} else {
this.getPostCommentsInvidious()
}
} else {
this.getCommentDataLocal(true)
}
Expand All @@ -190,17 +210,14 @@ export default defineComponent({
},

getCommentReplies: function (index) {
if (process.env.SUPPORTS_LOCAL_API) {
switch (this.commentData[index].dataType) {
case 'local':
this.getCommentRepliesLocal(index)
break
case 'invidious':
this.getCommentRepliesInvidious(index)
break
if (!process.env.SUPPORTS_LOCAL_API || this.commentData[index].dataType === 'invidious' || this.isPostComments) {
if (!this.isPostComments) {
this.getCommentRepliesInvidious(index)
} else {
this.getPostCommentRepliesInvidious(index)
}
} else {
this.getCommentRepliesInvidious(index)
this.getCommentRepliesLocal(index)
}
},

Expand Down Expand Up @@ -375,5 +392,68 @@ export default defineComponent({
this.isLoading = false
})
},

getPostCommentsInvidious: function() {
const nextPageToken = this.nextPageToken

const fetchComments = nextPageToken == null
? getInvidiousCommunityPostComments({ postId: this.id, authorId: this.postAuthorId })
: getInvidiousCommunityPostCommentReplies({ postId: this.id, replyToken: this.nextPageToken, authorId: this.postAuthorId })

fetchComments.then(({ response, commentData, continuation }) => {
commentData = commentData.map(({ replyToken, ...comment }) => {
if (comment.hasReplyToken) {
this.replyTokens.set(comment.id, replyToken)
} else {
this.replyTokens.delete(comment.id)
}

return comment
})

this.commentData = this.commentData.concat(commentData)
this.nextPageToken = response?.continuation ?? continuation
this.isLoading = false
this.showComments = true
}).catch((err) => {
console.error(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
showToast(`${errorMessage}: ${err}`, 10000, () => {
copyToClipboard(err)
})
this.isLoading = false
})
},

getPostCommentRepliesInvidious: function(index) {
showToast(this.$t('Comments.Getting comment replies, please wait'))

const comment = this.commentData[index]
const replyToken = this.replyTokens.get(comment.id)
const id = this.id

getInvidiousCommunityPostCommentReplies({ postId: id, replyToken: replyToken, authorId: this.postAuthorId })
.then(({ commentData, continuation }) => {
comment.replies = comment.replies.concat(commentData)
comment.showReplies = true

if (continuation) {
this.replyTokens.set(comment.id, continuation)
comment.hasReplyToken = true
} else {
this.replyTokens.delete(comment.id)
comment.hasReplyToken = false
}

this.isLoading = false
}).catch((error) => {
console.error(error)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
showToast(`${errorMessage}: ${error}`, 10000, () => {
copyToClipboard(error)
})
this.isLoading = false
})
}
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
{{ $t("Comments.Click to View Comments") }}
</h4>
<ft-select
v-if="commentData.length > 0 && !isLoading && showComments"
v-if="commentData.length > 0 && !isLoading && showComments && showSortBy"
class="commentSort"
:placeholder="$t('Comments.Sort by')"
:value="currentSortValue"
Expand Down Expand Up @@ -264,7 +264,16 @@
<div
v-else-if="showComments && !isLoading"
>
<h3 class="noCommentMsg">
<h3
v-if="isPostComments"
class="noCommentMsg"
>
{{ $t("Comments.There are no comments available for this post") }}
</h3>
<h3
v-else
class="noCommentMsg"
>
{{ $t("Comments.There are no comments available for this video") }}
</h3>
</div>
Expand Down
Loading