Files
timi-tdesign-pc/src/components/comment/list/reply/index.vue
T
2025-07-08 16:28:40 +08:00

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>&nbsp;回复&nbsp;</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>