0
0
Fork 0
mirror of https://github.com/VueTubeApp/VueTube synced 2024-11-22 19:25:16 +00:00

Merge pull request #256 from Frontesque/dev

Merge branch "dev" to branch "main"
This commit is contained in:
Kenny 2022-04-21 23:12:05 -04:00 committed by GitHub
commit 6b0c0669f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 248 additions and 76 deletions

View file

@ -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>

View file

@ -18,23 +18,45 @@
/>
</a>
<div class="comment-content">
<div class="comment-content--header">
<h3 class="author-name--wrapper">
<span class="font-weight-bold subtitle-2 pr-1 author-name" emoji>
{{ commentRenderer.authorText.runs[0].text }}
</span>
</h3>
<div class="comment-content--header subtitle-2">
<div
class="author-badge-name mr-1"
:class="{ owner: commentRenderer.authorIsChannelOwner }"
>
<div class="author-name--wrapper">
<span class="font-weight-bold author-name" v-emoji>
{{ commentRenderer.authorText.simpleText }}
</span>
</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
: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 }}
</span>
</div>
<collapsable-text :lines="4">
<template v-for="text in commentRenderer.contentText.runs">{{
text.text
}}</template>
<yt-text-formatter :textRuns="commentRenderer.contentText.runs">
</yt-text-formatter>
</collapsable-text>
</div>
</div>
@ -71,25 +93,51 @@
display: flex;
align-items: baseline;
.author-name--wrapper {
min-width: 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.comment-timestamp {
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>
<script>
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 {
components: { collapsableText },
components: {
collapsableText,
YtTextFormatter,
AuthorCommentBadgeRenderer,
SponsorCommentBadgeRenderer,
},
props: ["comment"],
data() {

View file

@ -10,7 +10,7 @@
</template>
</v-toolbar-title>
<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-btn>
</template>
@ -48,7 +48,7 @@ import commentThreadRenderer from "~/components/Comments/commentThreadRenderer.v
import continuationItemRenderer from "~/components/observer.vue";
export default {
props: ["continuation", "commentData", "showComments"],
props: ["defaultContinuation", "commentData", "showComments"],
model: {
prop: "showComments",
@ -65,9 +65,11 @@ export default {
data: () => ({
loading: true,
comments: [],
continuation: null,
}),
mounted() {
if (!this.continuation) this.continuation = this.defaultContinuation;
this.paginate();
},
@ -77,36 +79,38 @@ export default {
},
paginate() {
this.loading = true;
const watcherIndex = this.comments.findIndex(
(comment) => comment.continuationItemRenderer
);
if (watcherIndex) this.comments.splice(watcherIndex, 1);
this.$youtube
.getContinuation(this.continuation, "next", "web")
.then((result) => {
let processed;
if (
result.data.onResponseReceivedEndpoints.find(
(endpoints) => endpoints.reloadContinuationItemsCommand
)
) {
processed = result.data.onResponseReceivedEndpoints.map(
(endpoints) =>
endpoints.reloadContinuationItemsCommand.continuationItems
);
} else {
processed = result.data.onResponseReceivedEndpoints.map(
(endpoints) =>
endpoints.appendContinuationItemsAction.continuationItems
);
}
processed = processed.flat(1);
this.comments = this.comments.concat(processed);
this.continuation = this.findContinuation(processed);
console.log("comments", this.comments);
if (this.comments) this.loading = false;
});
if (this.continuation) {
this.loading = true;
const watcherIndex = this.comments.findIndex(
(comment) => comment.continuationItemRenderer
);
if (watcherIndex) this.comments.splice(watcherIndex, 1);
this.$youtube
.getContinuation(this.continuation, "next", "web")
.then((result) => {
let processed;
if (
result.data.onResponseReceivedEndpoints.find(
(endpoints) => endpoints.reloadContinuationItemsCommand
)
) {
processed = result.data.onResponseReceivedEndpoints.map(
(endpoints) =>
endpoints.reloadContinuationItemsCommand.continuationItems
);
} else {
processed = result.data.onResponseReceivedEndpoints.map(
(endpoints) =>
endpoints.appendContinuationItemsAction.continuationItems
);
}
processed = processed.flat(1);
this.comments = this.comments.concat(processed);
this.continuation = this.findContinuation(processed);
console.log("comments", this.comments);
if (this.comments) this.loading = false;
});
}
},
findContinuation(newResponses) {
@ -115,7 +119,7 @@ export default {
);
const newContinuation =
continuationItemParent.continuationItemRenderer.continuationEndpoint
continuationItemParent?.continuationItemRenderer.continuationEndpoint
.continuationCommand.token;
return newContinuation;

View file

@ -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>

View file

@ -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>

View file

@ -1,26 +1,7 @@
<template>
<div class="description" v-if="render.descriptionBodyText">
<template v-for="(text, index) in render.descriptionBodyText.runs">
<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> {{ text.text }} </template>
</template>
<yt-text-formatter :textRuns="render.descriptionBodyText.runs">
</yt-text-formatter>
</div>
</template>
@ -32,9 +13,15 @@
<script>
import { Browser } from "@capacitor/browser";
import YtTextFormatter from "~/components/UtilRenderers/YtTextFormatter.vue";
export default {
props: ["render"],
components: {
YtTextFormatter,
},
methods: {
async openExternal(url) {
await Browser.open({ url: url });

View file

@ -172,7 +172,7 @@
v-if="loaded && video.commentData"
>
<mainCommentRenderer
:continuation="video.commentContinuation"
:defaultContinuation="video.commentContinuation"
:commentData="video.commentData"
v-model="showComments"
></mainCommentRenderer>

View file

@ -13,7 +13,8 @@ const ytApiVal = {
VERSION: "16.25",
CLIENTNAME: "ANDROID",
VERSION_WEB: "2.20220411.09.00",
CLIENT_WEB: 2,
CLIENT_WEB_M: 2,
CLIENT_WEB_D: 1,
};
const filesystem = {

View file

@ -159,7 +159,7 @@ class Innertube {
...{
context: {
client: {
clientName: constants.YT_API_VALUES.CLIENT_WEB,
clientName: constants.YT_API_VALUES.CLIENT_WEB_M,
clientVersion: constants.YT_API_VALUES.VERSION_WEB,
},
},

View file

@ -152,7 +152,7 @@ const innertubeModule = {
...contextAdditional,
...{
client: {
clientName: constants.YT_API_VALUES.CLIENT_WEB,
clientName: constants.YT_API_VALUES.CLIENT_WEB_D,
clientVersion: constants.YT_API_VALUES.VERSION_WEB,
},
},