180 lines
3.8 KiB
Vue
180 lines
3.8 KiB
Vue
<template>
|
|
<div class="tui-comment-reply-list">
|
|
<div v-if="comment && comment.replies" class="reply" v-for="reply in comment.replies" :key="reply.id">
|
|
<div class="header">
|
|
<!-- 发送者头像 -->
|
|
<div class="sender-avatar">
|
|
<a
|
|
v-if="reply.sender"
|
|
:href="`/user/space/${reply.senderId}`"
|
|
v-popup:config="popupUserStore.config"
|
|
@mouseenter="popupUserStore.user.value = reply.sender"
|
|
>
|
|
<img
|
|
:class="(<any>ImageType)[reply.sender.profile.avatarType]"
|
|
:src="UserAPI.getAvatarURL(reply.sender.profile)"
|
|
alt="回复发送者头像"
|
|
/>
|
|
</a>
|
|
<img v-else class="ir-pixelated" :src="defAvatarURL" alt="回复发送者头像" />
|
|
</div>
|
|
<!-- 被回复用户 -->
|
|
<a
|
|
v-if="reply.sender"
|
|
class="pink bold selectable"
|
|
:href="`/user/space/${reply.senderId}`"
|
|
target="_blank"
|
|
v-text="reply.sender.name"
|
|
v-popup:config="popupUserStore.config"
|
|
@mouseenter="popupUserStore.user.value = reply.sender"
|
|
></a>
|
|
<span
|
|
v-else
|
|
class="gray selectable"
|
|
v-text="reply.senderNick"
|
|
></span>
|
|
<!-- 非回复层主时才显示被回复用户 -->
|
|
<template v-if="!!reply.replyId">
|
|
<span> 回复 </span>
|
|
<!-- 被回复用户 -->
|
|
<a
|
|
v-if="reply.receiver"
|
|
class="pink bold selectable"
|
|
:href="`/user/space/${reply.receiverId}`"
|
|
target="_blank"
|
|
v-text="reply.receiver.name"
|
|
v-popup:config="popupUserStore.config"
|
|
@mouseenter="popupUserStore.user.value = reply.receiver"
|
|
></a>
|
|
<span
|
|
v-else
|
|
class="gray selectable"
|
|
v-text="reply.receiverNick"
|
|
></span>
|
|
</template>
|
|
</div>
|
|
<!-- 回复内容 -->
|
|
<markdown-view class="content" :content="reply.content" />
|
|
<!-- 其他回复信息 -->
|
|
<div class="reply-to">
|
|
<a href="javascript:" @click="onReply(comment, reply)">回复</a>
|
|
<span
|
|
class="light-gray"
|
|
v-text="Time.toPassedDate(reply.createdAt)"
|
|
v-popup:text="Time.toDateTime(reply.createdAt)"
|
|
></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import {
|
|
CommentView,
|
|
CommonAPI,
|
|
ImageType,
|
|
MarkdownView,
|
|
PublicResources,
|
|
SettingKey,
|
|
SettingMapper,
|
|
Time,
|
|
UserAPI
|
|
} from "timi-web";
|
|
import { Emits, useHandler } from "~/components/comment/list/reply/emits";
|
|
import { popupUserStore } from "~/store/popupUser";
|
|
|
|
defineOptions({
|
|
name: "CommentReplyList"
|
|
});
|
|
|
|
const props = withDefaults(defineProps<{
|
|
comment: CommentView,
|
|
}>(), {});
|
|
const { comment } = toRefs(props);
|
|
|
|
const emits = defineEmits<Emits>();
|
|
const { onReply } = useHandler(emits);
|
|
|
|
// 默认头像
|
|
const defAvatarURL = ref();
|
|
onMounted(async () => {
|
|
const res = JSON.parse(SettingMapper.getValue(SettingKey.PUBLIC_RESOURCES) as string) as PublicResources;
|
|
defAvatarURL.value = CommonAPI.getAttachmentReadAPI(res.user.avatar);
|
|
});
|
|
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.tui-comment-reply-list {
|
|
|
|
.reply {
|
|
padding: 6px;
|
|
|
|
&:nth-child(n + 2) {
|
|
border-top: 1px #d7d7d7 dotted;
|
|
}
|
|
|
|
&:first-child {
|
|
border-top: 2px solid #E4EFFA;
|
|
}
|
|
|
|
.header {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.sender-avatar {
|
|
border: 1px solid #FBC7D4;
|
|
padding: 1px;
|
|
margin-right: .5rem;
|
|
|
|
img {
|
|
width: 32px;
|
|
height: 32px;
|
|
transition: .5s var(--tui-bezier);
|
|
}
|
|
}
|
|
}
|
|
|
|
.content {
|
|
width: 100%;
|
|
margin-top: .5rem;
|
|
}
|
|
|
|
.reply-to {
|
|
display: flex;
|
|
padding-right: 0;
|
|
justify-content: end;
|
|
|
|
> a {
|
|
margin-right: .5rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@media screen and (max-width: 650px) {
|
|
.tui-comment-reply-list {
|
|
|
|
.reply {
|
|
padding: 3px;
|
|
transition: .5s var(--tui-bezier);
|
|
|
|
.header {
|
|
|
|
.sender-avatar {
|
|
|
|
img {
|
|
width: 16px;
|
|
height: 16px;
|
|
transition: .5s var(--tui-bezier);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|