From ef5aee357639d9143d0d3ac9cc81e1236675b278 Mon Sep 17 00:00:00 2001 From: Preston Date: Mon, 15 Feb 2021 09:59:35 -0500 Subject: [PATCH] Update local API comment module and fix Invidious logic on channel page --- package-lock.json | 18 +- package.json | 2 +- .../watch-video-comments.css | 7 + .../watch-video-comments.js | 183 +++++++++++------- .../watch-video-comments.vue | 9 +- src/renderer/views/Channel/Channel.js | 15 +- 6 files changed, 149 insertions(+), 85 deletions(-) diff --git a/package-lock.json b/package-lock.json index dbfdf8a4..d45c8684 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12605,9 +12605,9 @@ } }, "node-html-parser": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-2.0.2.tgz", - "integrity": "sha512-N2000Ho9dkabvRZcyiwm6zOpdiAzxAxcJ0Z0WNoh/yXHG0YCuiK2WpNQfN+9vheLNY/h/It11Gk7uwT4QTfk9Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-2.1.0.tgz", + "integrity": "sha512-kbCNfqjrwHAbG+mevL8aqjwVtF0Qv66XurWHoGLOc5G9rPR1L3k602jfeczAUUBldLNnCrdsDmO5G5nqAoMW+g==", "requires": { "he": "1.2.0" } @@ -19235,9 +19235,9 @@ } }, "yt-comment-scraper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yt-comment-scraper/-/yt-comment-scraper-2.0.0.tgz", - "integrity": "sha512-goa9Z5REPXRKddKO6MJUzaa/cBgdQPj/akIGbyb1R5KnOgl4bLy6d4nD1pVUhLkP0Z8aEqwJAMmYpPBjeXTOIg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/yt-comment-scraper/-/yt-comment-scraper-3.0.1.tgz", + "integrity": "sha512-tRWMve+V09Tw2FpZ9dg1Nkh23uVniQGeAKzAOLfKSHmAHZF/f+4bJ/LK/oYnAj26oH034gu9Lmyy+tapAYTjiQ==", "requires": { "axios": "^0.21.1", "node-html-parser": "^2.0.2" @@ -19252,9 +19252,9 @@ } }, "follow-redirects": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", - "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==" } } }, diff --git a/package.json b/package.json index 39afaa53..e5b28adf 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "youtube-chat": "^1.1.0", "youtube-suggest": "^1.1.0", "yt-channel-info": "^1.2.1", - "yt-comment-scraper": "^2.0.0", + "yt-comment-scraper": "^3.0.0", "yt-dash-manifest-generator": "1.1.0", "yt-trending-scraper": "1.1.0", "yt-xml2vtt": "^1.2.0", diff --git a/src/renderer/components/watch-video-comments/watch-video-comments.css b/src/renderer/components/watch-video-comments/watch-video-comments.css index a94f5a17..3e1fe750 100644 --- a/src/renderer/components/watch-video-comments/watch-video-comments.css +++ b/src/renderer/components/watch-video-comments/watch-video-comments.css @@ -110,6 +110,13 @@ margin-left: 30px; } +.showMoreReplies { + margin-left: 30px; + font-size: 15px; + cursor: pointer; + text-decoration: underline; +} + .getMoreComments { height: 10px; margin-top: 5px; diff --git a/src/renderer/components/watch-video-comments/watch-video-comments.js b/src/renderer/components/watch-video-comments/watch-video-comments.js index da403115..e31ae917 100644 --- a/src/renderer/components/watch-video-comments/watch-video-comments.js +++ b/src/renderer/components/watch-video-comments/watch-video-comments.js @@ -93,12 +93,24 @@ export default Vue.extend({ this.isLoading = true this.commentData = [] this.nextPageToken = undefined - this.getCommentDataLocal() + this.getCommentDataLocal({ + videoId: this.id, + setCookie: false, + sortByNewest: this.sortNewest, + continuation: this.nextPageToken ? this.nextPageToken : undefined + }) break case 'invidious': this.isLoading = true this.commentData = [] - this.getCommentDataInvidious(null) + this.getCommentDataInvidious({ + resource: 'comments', + id: this.id, + params: { + continuation: this.nextPageToken, + sort_by: this.sortNewest ? 'new' : 'top' + } + }) break } }, @@ -107,10 +119,22 @@ export default Vue.extend({ this.isLoading = true switch (this.backendPreference) { case 'local': - this.getCommentDataLocal() + this.getCommentDataLocal({ + videoId: this.id, + setCookie: false, + sortByNewest: this.sortNewest, + continuation: this.nextPageToken ? this.nextPageToken : undefined + }) break case 'invidious': - this.getCommentDataInvidious(this.nextPageToken) + this.getCommentDataInvidious({ + resource: 'comments', + id: this.id, + params: { + continuation: this.nextPageToken, + sort_by: this.sortNewest ? 'new' : 'top' + } + }) break } }, @@ -125,69 +149,34 @@ export default Vue.extend({ } }, + toggleCommentReplies: function (index) { + if (this.commentData[index].showReplies || this.commentData[index].replies.length > 0) { + this.commentData[index].showReplies = !this.commentData[index].showReplies + } else { + this.getCommentReplies(index) + } + }, + getCommentReplies: function (index) { switch (this.commentData[index].dataType) { case 'local': - this.commentData[index].showReplies = !this.commentData[index].showReplies + this.getCommentRepliesLocal({ + videoId: this.id, + setCookie: false, + sortByNewest: this.sortNewest, + continuation: this.commentData[index].replyToken, + index: index + }) break case 'invidious': - if (this.commentData[index].showReplies || this.commentData[index].replies.length > 0) { - this.commentData[index].showReplies = !this.commentData[index].showReplies - } else { - this.getCommentRepliesInvidious(index) - } + this.getCommentRepliesInvidious(index) break } }, - getCommentDataLocal: function () { - const payload = { - videoId: this.id, - setCookie: false, - sortByNewest: this.sortNewest, - continuation: this.nextPageToken ? this.nextPageToken : undefined - } - + getCommentDataLocal: function (payload) { ytcm.getComments(payload).then((response) => { - console.log(response) - const commentData = response.comments.map((comment) => { - comment.showReplies = false - comment.dataType = 'local' - this.toLocalePublicationString({ - publishText: (comment.time + ' ago'), - templateString: this.$t('Video.Publicationtemplate'), - timeStrings: this.$t('Video.Published'), - liveStreamString: this.$t('Video.Watching'), - upcomingString: this.$t('Video.Published.Upcoming'), - isLive: false, - isUpcoming: false, - isRSS: false - }).then((data) => { - comment.time = data - }).catch((error) => { - console.error(error) - }) - if (this.hideCommentLikes) { - comment.likes = null - } - comment.text = autolinker.link(comment.text) - - if (comment.numReplies > 0) { - comment.replies.forEach((reply) => { - reply.text = autolinker.link(reply.text) - }) - } - - return comment - }) - if (this.sortingChanged) { - this.commentData = [] - this.sortingChanged = false - } - this.commentData = this.commentData.concat(commentData) - this.isLoading = false - this.showComments = true - this.nextPageToken = response.continuation + this.parseLocalCommentData(response, null) }).catch((err) => { console.log(err) const errorMessage = this.$t('Local API Error (Click to copy)') @@ -209,19 +198,79 @@ export default Vue.extend({ }) }, - getCommentDataInvidious: function () { - const payload = { - resource: 'comments', - id: this.id, - params: { - continuation: this.nextPageToken, - sort_by: this.sortNewest ? 'new' : 'top' + getCommentRepliesLocal: function (payload) { + this.showToast({ + message: this.$t('Comments.Getting comment replies, please wait') + }) + ytcm.getCommentReplies(payload.videoId, payload.continuation).then((response) => { + this.parseLocalCommentData(response, payload.index) + }).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) + } + }) + if (this.backendFallback && this.backendPreference === 'local') { + this.showToast({ + message: this.$t('Falling back to Invidious API') + }) + this.getCommentDataInvidious() + } else { + this.isLoading = false } + }) + }, + + parseLocalCommentData: function (response, index = null) { + const commentData = response.comments.map((comment) => { + comment.showReplies = false + comment.authorThumb = comment.authorThumb[0].url + comment.replies = [] + comment.dataType = 'local' + this.toLocalePublicationString({ + publishText: (comment.time + ' ago'), + templateString: this.$t('Video.Publicationtemplate'), + timeStrings: this.$t('Video.Published'), + liveStreamString: this.$t('Video.Watching'), + upcomingString: this.$t('Video.Published.Upcoming'), + isLive: false, + isUpcoming: false, + isRSS: false + }).then((data) => { + comment.time = data + }).catch((error) => { + console.error(error) + }) + if (this.hideCommentLikes) { + comment.likes = null + } + comment.text = autolinker.link(comment.text) + + return comment + }) + + if (index !== null) { + this.commentData[index].replies = this.commentData[index].replies.concat(commentData) + this.commentData[index].replyToken = response.continuation + this.commentData[index].showReplies = true + } else { + if (this.sortingChanged) { + this.commentData = [] + this.sortingChanged = false + } + this.commentData = this.commentData.concat(commentData) + this.isLoading = false + this.showComments = true + this.nextPageToken = response.continuation } + }, + getCommentDataInvidious: function (payload) { this.invidiousAPICall(payload).then((response) => { - console.log(response) - const commentData = response.comments.map((comment) => { comment.showReplies = false comment.authorThumb = comment.authorThumbnails[1].url.replace('https://yt3.ggpht.com', `${this.invidiousInstance}/ggpht/`) @@ -287,8 +336,6 @@ export default Vue.extend({ } this.$store.dispatch('invidiousAPICall', payload).then((response) => { - console.log(response) - const commentData = response.comments.map((comment) => { comment.showReplies = false comment.authorThumb = comment.authorThumbnails[1].url.replace('https://yt3.ggpht.com', `${this.invidiousInstance}/ggpht/`) diff --git a/src/renderer/components/watch-video-comments/watch-video-comments.vue b/src/renderer/components/watch-video-comments/watch-video-comments.vue index 5c490d71..4b32e51c 100644 --- a/src/renderer/components/watch-video-comments/watch-video-comments.vue +++ b/src/renderer/components/watch-video-comments/watch-video-comments.vue @@ -82,7 +82,7 @@ {{ $t("Comments.View") }} {{ $t("Comments.Hide") }} @@ -128,6 +128,13 @@ View {{ reply.numReplies }} replies

+
+ Show More Replies +
diff --git a/src/renderer/views/Channel/Channel.js b/src/renderer/views/Channel/Channel.js index 0f7aff4e..441f6440 100644 --- a/src/renderer/views/Channel/Channel.js +++ b/src/renderer/views/Channel/Channel.js @@ -136,7 +136,7 @@ export default Vue.extend({ showFetchMoreButton: function () { switch (this.currentTab) { case 'videos': - if (this.videoContinuationString !== '' && this.videoContinuationString !== null) { + if (this.apiUsed === 'invidious' || (this.videoContinuationString !== '' && this.videoContinuationString !== null)) { return true } break @@ -370,7 +370,7 @@ export default Vue.extend({ console.log(err) const errorMessage = this.$t('Invidious API Error (Click to copy)') this.showToast({ - message: `${errorMessage}: ${err}`, + message: `${errorMessage}: ${err.responseJSON.error}`, time: 10000, action: () => { navigator.clipboard.writeText(err) @@ -465,11 +465,14 @@ export default Vue.extend({ resource: 'channels/playlists', id: this.id, params: { - sort_by: this.playlistSortBy, - continuation: this.playlistContinuationString + sort_by: this.playlistSortBy } } + if (this.playlistContinuationString) { + payload.params.continuation = this.playlistContinuationString + } + this.$store.dispatch('invidiousAPICall', payload).then((response) => { this.playlistContinuationString = response.continuation this.latestPlaylists = this.latestPlaylists.concat(response.playlists) @@ -478,10 +481,10 @@ export default Vue.extend({ console.log(err) const errorMessage = this.$t('Invidious API Error (Click to copy)') this.showToast({ - message: `${errorMessage}: ${err}`, + message: `${errorMessage}: ${err.responseJSON.error}`, time: 10000, action: () => { - navigator.clipboard.writeText(err) + navigator.clipboard.writeText(err.responseJSON.error) } }) if (this.backendPreference === 'invidious' && this.backendFallback) {