mirror of https://github.com/VueTubeApp/VueTube
Merge pull request #254 from 404-Program-not-found/main
Additional comment features
This commit is contained in:
commit
a75fa1ec86
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="author-comment-badge-renderer"
|
||||||
|
v-if="metadata && iconTypeMap.hasOwnProperty(metadata.icon.iconType)"
|
||||||
|
>
|
||||||
|
<v-tooltip top>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-icon v-bind="attrs" v-on="on" class="author-badge" small>{{
|
||||||
|
iconTypeMap[metadata.icon.iconType]
|
||||||
|
}}</v-icon>
|
||||||
|
</template>
|
||||||
|
<span>{{ metadata.iconTooltip }}</span>
|
||||||
|
</v-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
metadata: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
iconTypeMap: {
|
||||||
|
CHECK: "mdi-check-circle",
|
||||||
|
CHECK_CIRCLE_THICK: "mdi-check-circle",
|
||||||
|
OFFICIAL_ARTIST_BADGE: "mdi-music-note",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.author-comment-badge-renderer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -18,23 +18,45 @@
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<div class="comment-content">
|
<div class="comment-content">
|
||||||
<div class="comment-content--header">
|
<div class="comment-content--header subtitle-2">
|
||||||
<h3 class="author-name--wrapper">
|
<div
|
||||||
<span class="font-weight-bold subtitle-2 pr-1 author-name" emoji>
|
class="author-badge-name mr-1"
|
||||||
{{ commentRenderer.authorText.runs[0].text }}
|
:class="{ owner: commentRenderer.authorIsChannelOwner }"
|
||||||
|
>
|
||||||
|
<div class="author-name--wrapper">
|
||||||
|
<span class="font-weight-bold author-name" v-emoji>
|
||||||
|
{{ commentRenderer.authorText.simpleText }}
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</div>
|
||||||
|
<template
|
||||||
|
v-for="(badge, index) in commentRenderer.authorCommentBadge"
|
||||||
|
>
|
||||||
|
<author-comment-badge-renderer
|
||||||
|
:metadata="badge"
|
||||||
|
:key="index"
|
||||||
|
class="ml-1"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
v-for="(badge, index) in commentRenderer.sponsorCommentBadge"
|
||||||
|
>
|
||||||
|
<sponsor-comment-badge-renderer
|
||||||
|
:metadata="badge"
|
||||||
|
:key="index"
|
||||||
|
class="ml-1"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
<span
|
<span
|
||||||
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
|
||||||
class="background--text subtitle-2 comment-timestamp"
|
class="background--text comment-timestamp"
|
||||||
>
|
>
|
||||||
{{ commentRenderer.publishedTimeText.runs[0].text }}
|
{{ commentRenderer.publishedTimeText.runs[0].text }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<collapsable-text :lines="4">
|
<collapsable-text :lines="4">
|
||||||
<template v-for="text in commentRenderer.contentText.runs">{{
|
<yt-text-formatter :textRuns="commentRenderer.contentText.runs">
|
||||||
text.text
|
</yt-text-formatter>
|
||||||
}}</template>
|
|
||||||
</collapsable-text>
|
</collapsable-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,25 +93,51 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
|
|
||||||
.author-name--wrapper {
|
|
||||||
min-width: 0;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment-timestamp {
|
.comment-timestamp {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.author-badge-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
.author-name--wrapper {
|
||||||
|
min-width: 0;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.owner {
|
||||||
|
padding: 0 0.6em;
|
||||||
|
background-color: #888888;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 1em;
|
||||||
|
|
||||||
|
&::v-deep .author-badge {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import collapsableText from "~/components/UtilRenderers/collapsableText.vue";
|
import collapsableText from "~/components/UtilRenderers/collapsableText.vue";
|
||||||
|
import YtTextFormatter from "~/components/UtilRenderers/YtTextFormatter.vue";
|
||||||
|
import AuthorCommentBadgeRenderer from "~/components/Comments/authorCommentBadgeRenderer.vue";
|
||||||
|
import SponsorCommentBadgeRenderer from "~/components/Comments/sponsorCommentBadgeRenderer.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { collapsableText },
|
components: {
|
||||||
|
collapsableText,
|
||||||
|
YtTextFormatter,
|
||||||
|
AuthorCommentBadgeRenderer,
|
||||||
|
SponsorCommentBadgeRenderer,
|
||||||
|
},
|
||||||
props: ["comment"],
|
props: ["comment"],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
</v-toolbar-title>
|
</v-toolbar-title>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn icon dark @click="$emit('changeState', false)">
|
<v-btn icon @click="$emit('changeState', false)">
|
||||||
<v-icon>mdi-close</v-icon>
|
<v-icon>mdi-close</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
|
@ -48,7 +48,7 @@ import commentThreadRenderer from "~/components/Comments/commentThreadRenderer.v
|
||||||
import continuationItemRenderer from "~/components/observer.vue";
|
import continuationItemRenderer from "~/components/observer.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["continuation", "commentData", "showComments"],
|
props: ["defaultContinuation", "commentData", "showComments"],
|
||||||
|
|
||||||
model: {
|
model: {
|
||||||
prop: "showComments",
|
prop: "showComments",
|
||||||
|
@ -65,9 +65,11 @@ export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
loading: true,
|
loading: true,
|
||||||
comments: [],
|
comments: [],
|
||||||
|
continuation: null,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
if (!this.continuation) this.continuation = this.defaultContinuation;
|
||||||
this.paginate();
|
this.paginate();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -77,6 +79,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
paginate() {
|
paginate() {
|
||||||
|
if (this.continuation) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
const watcherIndex = this.comments.findIndex(
|
const watcherIndex = this.comments.findIndex(
|
||||||
(comment) => comment.continuationItemRenderer
|
(comment) => comment.continuationItemRenderer
|
||||||
|
@ -107,6 +110,7 @@ export default {
|
||||||
console.log("comments", this.comments);
|
console.log("comments", this.comments);
|
||||||
if (this.comments) this.loading = false;
|
if (this.comments) this.loading = false;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
findContinuation(newResponses) {
|
findContinuation(newResponses) {
|
||||||
|
@ -115,7 +119,7 @@ export default {
|
||||||
);
|
);
|
||||||
|
|
||||||
const newContinuation =
|
const newContinuation =
|
||||||
continuationItemParent.continuationItemRenderer.continuationEndpoint
|
continuationItemParent?.continuationItemRenderer.continuationEndpoint
|
||||||
.continuationCommand.token;
|
.continuationCommand.token;
|
||||||
|
|
||||||
return newContinuation;
|
return newContinuation;
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="author-comment-badge-renderer"
|
||||||
|
v-if="metadata && metadata.customBadge"
|
||||||
|
>
|
||||||
|
<v-tooltip top>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<img
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
class="badge"
|
||||||
|
:src="metadata.customBadge.thumbnails[0].url"
|
||||||
|
:alt="metadata.tooltip"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<span>{{ metadata.tooltip }}</span>
|
||||||
|
</v-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
metadata: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.author-comment-badge-renderer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1.25em;
|
||||||
|
height: 1.25em;
|
||||||
|
vertical-align: -0.1em;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<div class="yt-text-formatter" v-emoji>
|
||||||
|
<template v-for="(text, index) in textRuns">
|
||||||
|
<template v-if="$rendererUtils.checkInternal(text)">
|
||||||
|
<a
|
||||||
|
@click="openInternal($rendererUtils.getNavigationEndpoints(text))"
|
||||||
|
:key="index"
|
||||||
|
>{{ text.text }}</a
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
v-else-if="
|
||||||
|
text.navigationEndpoint && text.navigationEndpoint.urlEndpoint
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
@click="openExternal($rendererUtils.getNavigationEndpoints(text))"
|
||||||
|
:key="index"
|
||||||
|
>{{ text.text }}</a
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="text.emoji && text.emoji.isCustomEmoji">
|
||||||
|
<img
|
||||||
|
:src="
|
||||||
|
text.emoji.image.thumbnails[text.emoji.image.thumbnails.length - 1]
|
||||||
|
.url
|
||||||
|
"
|
||||||
|
:alt="text.text"
|
||||||
|
:key="index"
|
||||||
|
class="emoji"
|
||||||
|
draggable="false"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else> {{ text.text }} </template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
textRuns: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,26 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="description" v-if="render.descriptionBodyText">
|
<div class="description" v-if="render.descriptionBodyText">
|
||||||
<template v-for="(text, index) in render.descriptionBodyText.runs">
|
<yt-text-formatter :textRuns="render.descriptionBodyText.runs">
|
||||||
<template v-if="$rendererUtils.checkInternal(text)">
|
</yt-text-formatter>
|
||||||
<a
|
|
||||||
@click="openInternal($rendererUtils.getNavigationEndpoints(text))"
|
|
||||||
:key="index"
|
|
||||||
>{{ text.text }}</a
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
v-else-if="
|
|
||||||
text.navigationEndpoint && text.navigationEndpoint.urlEndpoint
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
@click="openExternal($rendererUtils.getNavigationEndpoints(text))"
|
|
||||||
:key="index"
|
|
||||||
>{{ text.text }}</a
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
<template v-else> {{ text.text }} </template>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -32,9 +13,15 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Browser } from "@capacitor/browser";
|
import { Browser } from "@capacitor/browser";
|
||||||
|
import YtTextFormatter from "~/components/UtilRenderers/YtTextFormatter.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["render"],
|
props: ["render"],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
YtTextFormatter,
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async openExternal(url) {
|
async openExternal(url) {
|
||||||
await Browser.open({ url: url });
|
await Browser.open({ url: url });
|
||||||
|
|
|
@ -172,7 +172,7 @@
|
||||||
v-if="loaded && video.commentData"
|
v-if="loaded && video.commentData"
|
||||||
>
|
>
|
||||||
<mainCommentRenderer
|
<mainCommentRenderer
|
||||||
:continuation="video.commentContinuation"
|
:defaultContinuation="video.commentContinuation"
|
||||||
:commentData="video.commentData"
|
:commentData="video.commentData"
|
||||||
v-model="showComments"
|
v-model="showComments"
|
||||||
></mainCommentRenderer>
|
></mainCommentRenderer>
|
||||||
|
|
|
@ -13,7 +13,8 @@ const ytApiVal = {
|
||||||
VERSION: "16.25",
|
VERSION: "16.25",
|
||||||
CLIENTNAME: "ANDROID",
|
CLIENTNAME: "ANDROID",
|
||||||
VERSION_WEB: "2.20220411.09.00",
|
VERSION_WEB: "2.20220411.09.00",
|
||||||
CLIENT_WEB: 2,
|
CLIENT_WEB_M: 2,
|
||||||
|
CLIENT_WEB_D: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const filesystem = {
|
const filesystem = {
|
||||||
|
|
|
@ -159,7 +159,7 @@ class Innertube {
|
||||||
...{
|
...{
|
||||||
context: {
|
context: {
|
||||||
client: {
|
client: {
|
||||||
clientName: constants.YT_API_VALUES.CLIENT_WEB,
|
clientName: constants.YT_API_VALUES.CLIENT_WEB_M,
|
||||||
clientVersion: constants.YT_API_VALUES.VERSION_WEB,
|
clientVersion: constants.YT_API_VALUES.VERSION_WEB,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -152,7 +152,7 @@ const innertubeModule = {
|
||||||
...contextAdditional,
|
...contextAdditional,
|
||||||
...{
|
...{
|
||||||
client: {
|
client: {
|
||||||
clientName: constants.YT_API_VALUES.CLIENT_WEB,
|
clientName: constants.YT_API_VALUES.CLIENT_WEB_D,
|
||||||
clientVersion: constants.YT_API_VALUES.VERSION_WEB,
|
clientVersion: constants.YT_API_VALUES.VERSION_WEB,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue