2021-07-21 10:19:51 +00:00
|
|
|
<template>
|
2023-08-13 17:31:57 +00:00
|
|
|
<div class="comment mt-1.5 flex">
|
2021-10-08 18:52:51 +00:00
|
|
|
<img
|
|
|
|
:src="comment.thumbnail"
|
2023-08-13 17:31:57 +00:00
|
|
|
class="comment-avatar h-12 w-12 rounded-full"
|
2021-11-01 20:23:04 +00:00
|
|
|
height="48"
|
|
|
|
width="48"
|
2021-10-08 18:52:51 +00:00
|
|
|
loading="lazy"
|
|
|
|
alt="Avatar"
|
|
|
|
/>
|
2021-07-21 10:19:51 +00:00
|
|
|
|
2021-12-27 14:46:36 +00:00
|
|
|
<div class="comment-content pl-2">
|
2021-10-08 18:52:51 +00:00
|
|
|
<div class="comment-header">
|
2022-01-12 11:27:08 +00:00
|
|
|
<div v-if="comment.pinned" class="comment-pinned">
|
2021-12-27 22:33:55 +00:00
|
|
|
<font-awesome-icon icon="thumbtack" />
|
2022-10-17 00:43:01 +00:00
|
|
|
<span
|
|
|
|
v-t="{
|
|
|
|
path: 'comment.pinned_by',
|
|
|
|
args: { author: uploader },
|
|
|
|
}"
|
2023-07-27 11:46:05 +00:00
|
|
|
class="ml-1.5"
|
2022-10-17 00:43:01 +00:00
|
|
|
/>
|
2021-10-08 18:52:51 +00:00
|
|
|
</div>
|
2021-07-21 10:19:51 +00:00
|
|
|
|
2021-10-08 18:52:51 +00:00
|
|
|
<div class="comment-author">
|
2023-08-13 17:31:57 +00:00
|
|
|
<router-link class="link font-bold" :to="comment.commentorUrl">{{ comment.author }}</router-link>
|
2023-07-27 11:46:05 +00:00
|
|
|
<font-awesome-icon v-if="comment.verified" class="ml-1.5" icon="check" />
|
2021-10-08 18:52:51 +00:00
|
|
|
</div>
|
2023-08-13 17:31:57 +00:00
|
|
|
<div class="comment-meta mb-1.5 text-sm" v-text="comment.commentedTime" />
|
2021-10-08 18:52:51 +00:00
|
|
|
</div>
|
2023-07-27 11:46:05 +00:00
|
|
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
2023-07-22 16:22:57 +00:00
|
|
|
<div class="whitespace-pre-wrap" v-html="purifiedText" />
|
2022-10-21 19:51:32 +00:00
|
|
|
<div class="comment-footer mt-1 flex items-center">
|
2023-05-09 10:25:01 +00:00
|
|
|
<div class="i-fa6-solid:thumbs-up" />
|
2021-12-27 16:29:25 +00:00
|
|
|
<span class="ml-1" v-text="numberFormat(comment.likeCount)" />
|
2023-07-27 11:46:05 +00:00
|
|
|
<font-awesome-icon v-if="comment.hearted" class="ml-1" icon="heart" />
|
2021-10-08 18:52:51 +00:00
|
|
|
</div>
|
2021-11-04 10:52:28 +00:00
|
|
|
<template v-if="comment.repliesPage && (!loadingReplies || !showingReplies)">
|
2023-07-27 11:46:05 +00:00
|
|
|
<div class="cursor-pointer" @click="loadReplies">
|
2022-10-17 16:13:43 +00:00
|
|
|
<a v-text="`${$t('actions.reply_count', comment.replyCount)}`" />
|
2021-12-27 14:46:39 +00:00
|
|
|
<font-awesome-icon class="ml-1.5" icon="level-down-alt" />
|
2021-11-01 20:23:04 +00:00
|
|
|
</div>
|
2021-11-04 10:52:28 +00:00
|
|
|
</template>
|
|
|
|
<template v-if="showingReplies">
|
2023-07-27 11:46:05 +00:00
|
|
|
<div class="cursor-pointer" @click="hideReplies">
|
2022-01-12 11:27:08 +00:00
|
|
|
<a v-t="'actions.hide_replies'" />
|
2021-12-27 14:46:39 +00:00
|
|
|
<font-awesome-icon class="ml-1.5" icon="level-up-alt" />
|
2021-11-04 10:52:28 +00:00
|
|
|
</div>
|
|
|
|
</template>
|
2021-12-27 14:46:36 +00:00
|
|
|
<div v-show="showingReplies" v-if="replies" class="replies">
|
|
|
|
<div v-for="reply in replies" :key="reply.commentId" class="w-full">
|
2022-01-13 05:12:06 +00:00
|
|
|
<CommentItem :comment="reply" :uploader="uploader" :video-id="videoId" />
|
2021-11-01 20:23:04 +00:00
|
|
|
</div>
|
2023-07-27 11:46:05 +00:00
|
|
|
<div v-if="nextpage" class="cursor-pointer" @click="loadReplies">
|
2022-01-12 11:27:08 +00:00
|
|
|
<a v-t="'actions.load_more_replies'" />
|
2021-12-27 14:46:39 +00:00
|
|
|
<font-awesome-icon class="ml-1.5" icon="level-down-alt" />
|
2021-11-01 20:23:04 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2021-07-21 10:19:51 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2023-07-22 16:22:57 +00:00
|
|
|
import { purifyHTML } from "@/utils/HtmlUtils";
|
|
|
|
|
2021-10-08 18:52:51 +00:00
|
|
|
export default {
|
2021-07-21 10:19:51 +00:00
|
|
|
props: {
|
2021-10-08 18:52:51 +00:00
|
|
|
comment: {
|
|
|
|
type: Object,
|
|
|
|
default: () => {
|
|
|
|
return {};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
uploader: { type: String, default: null },
|
2021-11-01 20:23:04 +00:00
|
|
|
videoId: { type: String, default: null },
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
2021-11-04 10:52:28 +00:00
|
|
|
loadingReplies: false,
|
|
|
|
showingReplies: false,
|
2021-11-01 20:23:04 +00:00
|
|
|
replies: [],
|
|
|
|
nextpage: null,
|
|
|
|
};
|
|
|
|
},
|
2023-07-22 16:22:57 +00:00
|
|
|
computed: {
|
|
|
|
purifiedText() {
|
|
|
|
return purifyHTML(this.comment.commentText);
|
|
|
|
},
|
|
|
|
},
|
2021-11-01 20:23:04 +00:00
|
|
|
methods: {
|
2021-11-04 10:52:28 +00:00
|
|
|
async loadReplies() {
|
|
|
|
if (!this.showingReplies && this.loadingReplies) {
|
|
|
|
this.showingReplies = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.loadingReplies = true;
|
|
|
|
this.showingReplies = true;
|
2021-11-01 20:23:04 +00:00
|
|
|
this.fetchJson(this.apiUrl() + "/nextpage/comments/" + this.videoId, {
|
|
|
|
nextpage: this.nextpage || this.comment.repliesPage,
|
|
|
|
}).then(json => {
|
|
|
|
this.replies = this.replies.concat(json.comments);
|
|
|
|
this.nextpage = json.nextpage;
|
|
|
|
});
|
|
|
|
},
|
2021-11-04 10:52:28 +00:00
|
|
|
async hideReplies() {
|
|
|
|
this.showingReplies = false;
|
|
|
|
},
|
2021-10-08 18:52:51 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|