154 lines
4.8 KiB
Vue
154 lines
4.8 KiB
Vue
<template>
|
||
<div class="moment-card card-item">
|
||
<el-avatar :src="avatarUrl" :size="35" fit="contain" @click="viewProfileClick"/>
|
||
|
||
<div class="moment-content">
|
||
<span class="username">{{ props.item.username }}</span>
|
||
<p>{{ props.item.content }}</p>
|
||
|
||
<div class="moment-image-list">
|
||
<el-image v-for="(item, index) in props.item.imageList" :key="index"
|
||
:src="serviceFileRootPath + item" fit="cover"
|
||
:initial-index="index"
|
||
:preview-src-list=previewList />
|
||
</div>
|
||
|
||
<p>{{ formatTimeAgo(props.item.date) }}</p>
|
||
|
||
<div class="button-container">
|
||
<el-button v-if="isCurrentUser"
|
||
:icon="Edit" circle size="small" @click="editClick()"/>
|
||
<el-badge :value="props.item.likeList.length" :max="9">
|
||
<el-button :type="isLike ? 'danger' : 'default'"
|
||
circle size="small" @click="handleLikeClick()">
|
||
<i class="fa-regular fa-thumbs-up"></i>
|
||
</el-button>
|
||
</el-badge>
|
||
<el-badge :value="props.item.commentList.length" :max="9">
|
||
<el-button circle size="small"
|
||
@click="momentInfo.isShowComment = !momentInfo.isShowComment">
|
||
<i class="fa-regular fa-comment"></i>
|
||
</el-button>
|
||
</el-badge>
|
||
</div>
|
||
|
||
<div v-if="momentInfo.isShowComment" class="moment-comment">
|
||
<el-input
|
||
v-model="momentInfo.comment"
|
||
maxlength="100" placeholder="平等表达 友善交流"
|
||
show-word-limit type="textarea" :rows="3"
|
||
/>
|
||
|
||
<el-popover ref="emojiPopoverRef" placement="bottom" :width="300" trigger="click">
|
||
<template #default>
|
||
<div class="emoji-panel">
|
||
<EmojiPicker :native="true" @select="onSelectEmoji" />
|
||
</div>
|
||
</template>
|
||
<template #reference>
|
||
<el-button circle>
|
||
<i class="fa-regular fa-face-smile"></i>
|
||
</el-button>
|
||
</template>
|
||
</el-popover>
|
||
|
||
<el-button type="primary"
|
||
:disabled="momentInfo.comment.length === 0"
|
||
@click="sendCommentClick()"
|
||
class="send-button">发送</el-button>
|
||
</div>
|
||
|
||
<div v-if="props.item.commentList.length > 0" class="moment-comment-list">
|
||
<div v-for="(comment, index) in props.item.commentList" :key="index"
|
||
class="moment-comment-item">
|
||
<span class="name">{{ comment.username }}:</span>
|
||
<span>{{ comment.content }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import EmojiPicker from 'vue3-emoji-picker'
|
||
import 'vue3-emoji-picker/css'
|
||
import { Edit } from '@element-plus/icons-vue'
|
||
import { computed, defineProps, reactive } from 'vue'
|
||
import type { PropType } from 'vue'
|
||
import type { IMoment } from '@/types/food'
|
||
import { serviceFileRootPath } from '@/utils'
|
||
import { formatTimeAgo } from '@/utils/dateUtils'
|
||
import { useFoodStore } from '@/store/food'
|
||
import { useUserStore } from '@/store/user'
|
||
import { useAppStore } from '@/store/app'
|
||
import { useRouter } from 'vue-router'
|
||
|
||
const router = useRouter()
|
||
const userStore = useUserStore()
|
||
const appStore = useAppStore()
|
||
|
||
const props = defineProps({
|
||
item: {
|
||
required: true,
|
||
type: Object as PropType<IMoment>
|
||
}
|
||
})
|
||
|
||
const foodStore = useFoodStore()
|
||
|
||
const momentInfo = reactive({
|
||
isShowComment: false,
|
||
isLike: false,
|
||
comment: ''
|
||
})
|
||
|
||
const avatarUrl = computed(() => {
|
||
if (props.item?.avatar) {
|
||
return serviceFileRootPath + props.item.avatar
|
||
} else {
|
||
return 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
|
||
}
|
||
})
|
||
|
||
const isCurrentUser = computed(() => props.item?.userId === userStore.getUserId())
|
||
const isLike = computed(() => props.item?.likeList.includes(userStore.getUserId()))
|
||
|
||
const previewList = computed(() => {
|
||
return props.item?.imageList.map((item) => serviceFileRootPath + item)
|
||
})
|
||
|
||
const editClick = () => {
|
||
foodStore.momentApiType = 'UPDATE'
|
||
foodStore.currentMoment = props.item as IMoment
|
||
router.push('/moment/form')
|
||
}
|
||
|
||
const handleLikeClick = () => {
|
||
if (isLike.value) {
|
||
foodStore.deleteMomentLike(props.item?.id as number)
|
||
} else {
|
||
foodStore.addMomentLike(props.item?.id as number)
|
||
}
|
||
}
|
||
|
||
const onSelectEmoji = (emoji) => {
|
||
momentInfo.comment += emoji.i
|
||
}
|
||
|
||
const sendCommentClick = async () => {
|
||
await foodStore.addMomentComment(props.item?.id as number, momentInfo.comment)
|
||
|
||
momentInfo.comment = ''
|
||
momentInfo.isShowComment = false
|
||
}
|
||
|
||
const viewProfileClick = async () => {
|
||
if (!isCurrentUser.value) {
|
||
appStore.isShowMobileBack = true
|
||
foodStore.currentMomentUserId = props.item?.userId as number
|
||
await userStore.queryUser(foodStore.currentMomentUserId)
|
||
await router.push('/moment/profile')
|
||
}
|
||
}
|
||
</script>
|