mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2026-09-12 16:40:40 +08:00
refactor: 抽离点赞hook并统一点赞逻辑,优化评论列表组件
1. 新增useUpvote点赞hook,统一文章、瞬间的点赞逻辑与本地缓存 2. 重构文章详情、瞬间详情页的点赞代码,移除重复实现 3. 为评论列表组件添加kind参数支持动态类型,新增refresh暴露方法与全局刷新监听 4. 优化瞬间列表页的点赞、评论交互与样式
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue'
|
import { onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { getPostCommentList } from '@/api/halo'
|
import { getPostCommentList } from '@/api/halo'
|
||||||
import { checkAvatarUrl } from '@/utils/url'
|
import { checkAvatarUrl } from '@/utils/url'
|
||||||
import type { IComment, ICommentListRes } from '@/api/types/halo'
|
import type { IComment, ICommentListRes } from '@/api/types/halo'
|
||||||
@@ -8,8 +8,11 @@
|
|||||||
disallowComment ?: boolean
|
disallowComment ?: boolean
|
||||||
postName : string
|
postName : string
|
||||||
post : { metadata : { name : string } }
|
post : { metadata : { name : string } }
|
||||||
|
/** 评论目标 kind(文章 Post / 瞬间 Moment) */
|
||||||
|
kind ?: string
|
||||||
}>(), {
|
}>(), {
|
||||||
disallowComment: false,
|
disallowComment: false,
|
||||||
|
kind: 'Post',
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -21,7 +24,7 @@
|
|||||||
const loading = ref<'loading' | 'success' | 'error'>('loading')
|
const loading = ref<'loading' | 'success' | 'error'>('loading')
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
group: 'content.halo.run',
|
group: 'content.halo.run',
|
||||||
kind: 'Post',
|
kind: props.kind,
|
||||||
version: 'v1alpha1',
|
version: 'v1alpha1',
|
||||||
name: props.postName,
|
name: props.postName,
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -91,6 +94,22 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 外部刷新(评论成功后由宿主调用) */
|
||||||
|
function refresh() {
|
||||||
|
handleGetData()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 兼容旧广播链路(article-detail 评论成功后 uni.$emit('comment_list_refresh')) */
|
||||||
|
onMounted(() => {
|
||||||
|
uni.$on('comment_list_refresh', handleGetData)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
uni.$off('comment_list_refresh', handleGetData)
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({ refresh })
|
||||||
|
|
||||||
handleGetData()
|
handleGetData()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -135,7 +154,7 @@
|
|||||||
<view v-if="dataList.length === 0" class="empty py-12">
|
<view v-if="dataList.length === 0" class="empty py-12">
|
||||||
<view class="empty-box flex flex-col items-center">
|
<view class="empty-box flex flex-col items-center">
|
||||||
<wd-icon class-prefix="uhemoji-icon" name="-confused" size="100rpx" class="text-primary" />
|
<wd-icon class-prefix="uhemoji-icon" name="-confused" size="100rpx" class="text-primary" />
|
||||||
<text class="mt-2 text-sm text-gray-500">{{disallowComment ? '暂无评论' : '暂无评论'}}</text>
|
<text class="mt-2 text-sm text-gray-500">暂无评论</text>
|
||||||
<view v-if="disallowComment" class="mt-2 text-xs text-red-400">
|
<view v-if="disallowComment" class="mt-2 text-xs text-red-400">
|
||||||
文章已开启禁止评论
|
文章已开启禁止评论
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* 点赞交互(文章详情 / 瞬间详情 / 瞬间列表共用)
|
||||||
|
* 已点赞名单本地持久化(刷新/重进后仍防重复);支持单目标(详情页)与多目标(列表页)。
|
||||||
|
*/
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { submitUpvote } from '@/api/halo'
|
||||||
|
import { getCache, setCache } from '@/utils/storage'
|
||||||
|
|
||||||
|
const UPVOTE_CACHE_KEY = 'uh_upvoted_names'
|
||||||
|
|
||||||
|
function readUpvotedNames(): string[] {
|
||||||
|
const list = getCache<string[]>(UPVOTE_CACHE_KEY)
|
||||||
|
return Array.isArray(list) ? list : []
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useUpvote(plural: 'posts' | 'moments', getName: () => string | undefined) {
|
||||||
|
const upvotedNames = ref<string[]>(readUpvotedNames())
|
||||||
|
|
||||||
|
/** 判断是否已点赞(可指定 name;缺省用单目标 getName) */
|
||||||
|
function hasUpvoted(name?: string): boolean {
|
||||||
|
const n = name ?? getName()
|
||||||
|
return !!n && upvotedNames.value.includes(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 按 name 点赞(列表多目标场景;成功后持久化 + 回调) */
|
||||||
|
async function likeByName(name: string, onSuccess?: (name: string) => void) {
|
||||||
|
if (!name)
|
||||||
|
return
|
||||||
|
if (upvotedNames.value.includes(name)) {
|
||||||
|
uni.showToast({ icon: 'none', title: '已经点过赞啦!' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await submitUpvote({ group: 'content.halo.run', plural, name })
|
||||||
|
uni.showToast({ icon: 'none', title: '点赞成功!' })
|
||||||
|
upvotedNames.value.push(name)
|
||||||
|
setCache(UPVOTE_CACHE_KEY, upvotedNames.value)
|
||||||
|
onSuccess?.(name)
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error('点赞失败', err)
|
||||||
|
uni.showToast({ icon: 'none', title: '点赞失败' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 点赞当前目标(详情页单目标场景) */
|
||||||
|
async function handleDoLikes(onSuccess?: (name: string) => void) {
|
||||||
|
const name = getName()
|
||||||
|
if (!name)
|
||||||
|
return
|
||||||
|
await likeByName(name, onSuccess)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
upvotedNames,
|
||||||
|
hasUpvoted,
|
||||||
|
handleDoLikes,
|
||||||
|
likeByName,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { onLoad, onPullDownRefresh, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
import { onLoad, onPullDownRefresh, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
||||||
import { getPostByName, getPostCommentReplyList, postTrackersCounter, submitUpvote } from '@/api/halo'
|
import { getPostByName, getPostCommentReplyList, postTrackersCounter } from '@/api/halo'
|
||||||
|
import { useUpvote } from '@/hooks/useUpvote'
|
||||||
import { createVerificationCode, requestRestrictReadCheck } from '@/api/uni-halo'
|
import { createVerificationCode, requestRestrictReadCheck } from '@/api/uni-halo'
|
||||||
import { formatTime } from '@/utils/formatTime'
|
import { formatTime } from '@/utils/formatTime'
|
||||||
import { useAppConfigStore } from '@/store/appConfig'
|
import { useAppConfigStore } from '@/store/appConfig'
|
||||||
@@ -188,36 +189,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------- 点赞 ---------------- */
|
/* ---------------- 点赞 ---------------- */
|
||||||
const upvotedNames = ref<string[]>([])
|
const { hasUpvoted, handleDoLikes } = useUpvote('posts', () => result.value?.metadata.name)
|
||||||
|
|
||||||
function hasUpvoted() : boolean {
|
function handleDoLikesClick() {
|
||||||
return upvotedNames.value.includes(result.value?.metadata.name || '')
|
handleDoLikes((name) => {
|
||||||
}
|
if (result.value?.stats) {
|
||||||
|
|
||||||
async function handleDoLikes() {
|
|
||||||
if (!result.value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (hasUpvoted()) {
|
|
||||||
uni.showToast({ icon: 'none', title: '已经点过赞啦!' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await submitUpvote({
|
|
||||||
group: 'content.halo.run',
|
|
||||||
plural: 'posts',
|
|
||||||
name: result.value.metadata.name,
|
|
||||||
})
|
|
||||||
uni.showToast({ icon: 'none', title: '点赞成功!' })
|
|
||||||
upvotedNames.value.push(result.value.metadata.name)
|
|
||||||
if (result.value.stats) {
|
|
||||||
result.value.stats.upvote = (result.value.stats.upvote || 0) + 1
|
result.value.stats.upvote = (result.value.stats.upvote || 0) + 1
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
catch (err) {
|
|
||||||
console.error('点赞失败', err)
|
|
||||||
uni.showToast({ icon: 'none', title: '点赞失败' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------- 收藏 ---------------- */
|
/* ---------------- 收藏 ---------------- */
|
||||||
@@ -358,6 +337,13 @@
|
|||||||
commentModal.value.show = false
|
commentModal.value.show = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 评论列表加载完成:同步评论计数(统计区展示) */
|
||||||
|
function handleCommentLoaded(list : IComment[]) {
|
||||||
|
if (result.value?.stats) {
|
||||||
|
result.value.stats.comment = list.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleOnShowCommentDetail(data : { postName : string, comment : IComment }) {
|
function handleOnShowCommentDetail(data : { postName : string, comment : IComment }) {
|
||||||
commentDetail.value = {
|
commentDetail.value = {
|
||||||
show: true,
|
show: true,
|
||||||
@@ -595,8 +581,8 @@
|
|||||||
|
|
||||||
<!-- 评论区域 -->
|
<!-- 评论区域 -->
|
||||||
<uh-comment-list v-if="calcIsShowComment && result" :disallow-comment="!result.spec.allowComment"
|
<uh-comment-list v-if="calcIsShowComment && result" :disallow-comment="!result.spec.allowComment"
|
||||||
:post-name="result.metadata.name" :post="result" @on-comment="handleOnComment"
|
:post-name="result.metadata.name" :post="result" @on-comment="handleOnComment"
|
||||||
@on-comment-detail="handleOnShowCommentDetail" />
|
@on-comment-detail="handleOnShowCommentDetail" @on-loaded="handleCommentLoaded" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -607,7 +593,7 @@
|
|||||||
class="uh-global-card-glass box-border flex items-center justify-center gap-2 border rounded-full p-1 text-primary">
|
class="uh-global-card-glass box-border flex items-center justify-center gap-2 border rounded-full p-1 text-primary">
|
||||||
<view
|
<view
|
||||||
class="uh-global-card-glass box-border h-[72rpx] flex flex-1 items-center justify-center gap-x-1 border rounded-full px-4 shadow-none"
|
class="uh-global-card-glass box-border h-[72rpx] flex flex-1 items-center justify-center gap-x-1 border rounded-full px-4 shadow-none"
|
||||||
:class="{ active: hasUpvoted() }" @click="handleDoLikes">
|
:class="{ active: hasUpvoted() }" @click="handleDoLikesClick">
|
||||||
<wd-icon class-prefix="uhemoji-icon" name="-kiss-" size="36rpx" />
|
<wd-icon class-prefix="uhemoji-icon" name="-kiss-" size="36rpx" />
|
||||||
<text class="shrink-0 text-sm text-gray-900 font-semibold">点赞</text>
|
<text class="shrink-0 text-sm text-gray-900 font-semibold">点赞</text>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { onLoad, onPullDownRefresh, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
import { onLoad, onPullDownRefresh, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
||||||
import { getMomentByName, submitUpvote } from '@/api/halo'
|
import { getMomentByName } from '@/api/halo'
|
||||||
|
import { useUpvote } from '@/hooks/useUpvote'
|
||||||
import { useAppConfigStore } from '@/store/appConfig'
|
import { useAppConfigStore } from '@/store/appConfig'
|
||||||
import { useFavoritesStore } from '@/store/favorites'
|
import { useFavoritesStore } from '@/store/favorites'
|
||||||
import { checkAvatarUrl, checkThumbnailUrl } from '@/utils/url'
|
import { checkAvatarUrl, checkThumbnailUrl } from '@/utils/url'
|
||||||
@@ -138,35 +139,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------- 点赞 ---------------- */
|
/* ---------------- 点赞 ---------------- */
|
||||||
const upvotedNames = ref<string[]>([])
|
const { hasUpvoted, handleDoLikes } = useUpvote('moments', () => moment.value?.metadata.name)
|
||||||
|
|
||||||
function hasUpvoted() : boolean {
|
function handleDoLikesClick() {
|
||||||
return upvotedNames.value.includes(moment.value?.metadata.name || '')
|
handleDoLikes((name) => {
|
||||||
}
|
const current = moment.value
|
||||||
|
if (current?.stats) {
|
||||||
async function handleDoLikes() {
|
|
||||||
const current = moment.value
|
|
||||||
if (!current) { return }
|
|
||||||
if (hasUpvoted()) {
|
|
||||||
uni.showToast({ icon: 'none', title: '已经点过赞啦!' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await submitUpvote({
|
|
||||||
group: 'content.halo.run',
|
|
||||||
plural: 'moments',
|
|
||||||
name: current.metadata.name,
|
|
||||||
})
|
|
||||||
uni.showToast({ icon: 'none', title: '点赞成功!' })
|
|
||||||
upvotedNames.value.push(current.metadata.name)
|
|
||||||
if (current.stats) {
|
|
||||||
current.stats.upvote = (current.stats.upvote || 0) + 1
|
current.stats.upvote = (current.stats.upvote || 0) + 1
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
catch (err) {
|
|
||||||
console.error('点赞失败', err)
|
|
||||||
uni.showToast({ icon: 'none', title: '点赞失败' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------- 评论 ---------------- */
|
/* ---------------- 评论 ---------------- */
|
||||||
@@ -176,6 +157,8 @@
|
|||||||
postName: '',
|
postName: '',
|
||||||
title: '',
|
title: '',
|
||||||
})
|
})
|
||||||
|
/** 评论列表组件实例(评论成功后刷新) */
|
||||||
|
const commentListRef = ref<{ refresh : () => void } | null>(null)
|
||||||
|
|
||||||
function handleToComment() {
|
function handleToComment() {
|
||||||
const current = moment.value
|
const current = moment.value
|
||||||
@@ -193,8 +176,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 评论列表触发(回复某条评论/新增) */
|
||||||
|
function handleOnComment(data : { isComment : boolean, postName : string, title : string }) {
|
||||||
|
commentModal.value = {
|
||||||
|
show: true,
|
||||||
|
isComment: data.isComment,
|
||||||
|
postName: data.postName,
|
||||||
|
title: data.title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleOnCommentModalClose(data : { refresh : boolean, isSubmit : boolean }) {
|
function handleOnCommentModalClose(data : { refresh : boolean, isSubmit : boolean }) {
|
||||||
commentModal.value.show = false
|
commentModal.value.show = false
|
||||||
|
if (data.isSubmit) {
|
||||||
|
// 评论成功后刷新评论列表与计数
|
||||||
|
commentListRef.value?.refresh()
|
||||||
|
loadMoment()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------- 视频互斥 ---------------- */
|
/* ---------------- 视频互斥 ---------------- */
|
||||||
@@ -358,6 +356,10 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 评论列表(瞬间评论,kind=Moment) -->
|
||||||
|
<uh-comment-list v-if="moment" ref="commentListRef" :post-name="moment.metadata.name" :post="moment"
|
||||||
|
kind="Moment" :disallow-comment="!moment.spec.allowComment" @on-comment="handleOnComment" />
|
||||||
</view>
|
</view>
|
||||||
<!-- 悬浮操作(与文章详情一致:点赞/评论/收藏) -->
|
<!-- 悬浮操作(与文章详情一致:点赞/评论/收藏) -->
|
||||||
<view class="fixed bottom-8 left-1/2 z-10 flex items-center justify-center pb-safe -translate-x-1/2">
|
<view class="fixed bottom-8 left-1/2 z-10 flex items-center justify-center pb-safe -translate-x-1/2">
|
||||||
@@ -366,12 +368,12 @@
|
|||||||
<!-- 点赞 -->
|
<!-- 点赞 -->
|
||||||
<view
|
<view
|
||||||
class="uh-global-card-glass box-border h-[72rpx] flex flex-1 items-center justify-center gap-x-1 border rounded-full px-4 shadow-none"
|
class="uh-global-card-glass box-border h-[72rpx] flex flex-1 items-center justify-center gap-x-1 border rounded-full px-4 shadow-none"
|
||||||
:class="{ active: hasUpvoted() }" @click="handleDoLikes">
|
:class="{ active: hasUpvoted() }" @click="handleDoLikesClick">
|
||||||
<wd-icon class-prefix="uhemoji-icon" name="-kiss-" size="36rpx" />
|
<wd-icon class-prefix="uhemoji-icon" name="-kiss-" size="36rpx" />
|
||||||
<text class="shrink-0 text-sm text-gray-900 font-semibold">点赞</text>
|
<text class="shrink-0 text-sm text-gray-900 font-semibold">点赞</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- 评论 -->
|
<!-- 评论 -->
|
||||||
<view
|
<view v-if="moment.spec.allowComment"
|
||||||
class="uh-global-card-glass box-border h-[72rpx] flex flex-1 items-center justify-center gap-x-1 border rounded-full px-4 shadow-none"
|
class="uh-global-card-glass box-border h-[72rpx] flex flex-1 items-center justify-center gap-x-1 border rounded-full px-4 shadow-none"
|
||||||
@click="handleToComment()">
|
@click="handleToComment()">
|
||||||
<wd-icon class-prefix="uhemoji-icon" name="-thinking" size="36rpx" />
|
<wd-icon class-prefix="uhemoji-icon" name="-thinking" size="36rpx" />
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
import { formatTime } from '@/utils/formatTime'
|
import { formatTime } from '@/utils/formatTime'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
|
import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
|
||||||
|
import { useUpvote } from '@/hooks/useUpvote'
|
||||||
import { markdownConfig } from '@/config/markdown'
|
import { markdownConfig } from '@/config/markdown'
|
||||||
import type { IMoment } from '@/api/types/halo'
|
import type { IMoment } from '@/api/types/halo'
|
||||||
|
|
||||||
@@ -204,6 +205,52 @@
|
|||||||
uni.showToast({ icon: 'none', title: favorited ? '收藏成功' : '已取消收藏' })
|
uni.showToast({ icon: 'none', title: favorited ? '收藏成功' : '已取消收藏' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------- 点赞(useUpvote 持久化防重复) ---------------- */
|
||||||
|
const { hasUpvoted, likeByName } = useUpvote('moments', () => '')
|
||||||
|
|
||||||
|
function handleMomentLike(moment : MomentCard) {
|
||||||
|
if (!moment) { return }
|
||||||
|
likeByName(moment.metadata.name, (name) => {
|
||||||
|
if (moment.stats) {
|
||||||
|
moment.stats.upvote = (moment.stats.upvote || 0) + 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------- 评论(列表内直接弹评论窗) ---------------- */
|
||||||
|
const commentModal = ref({
|
||||||
|
show: false,
|
||||||
|
isComment: true,
|
||||||
|
postName: '',
|
||||||
|
title: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleMomentComment(moment : MomentCard) {
|
||||||
|
if (!moment) { return }
|
||||||
|
if (!moment.spec.allowComment) {
|
||||||
|
uni.showToast({ icon: 'none', title: '瞬间已开启禁止评论!' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
commentModal.value = {
|
||||||
|
show: true,
|
||||||
|
isComment: true,
|
||||||
|
postName: moment.metadata.name,
|
||||||
|
title: '新增评论',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOnCommentModalClose(data : { refresh : boolean, isSubmit : boolean }) {
|
||||||
|
const postName = commentModal.value.postName
|
||||||
|
commentModal.value.show = false
|
||||||
|
if (data.isSubmit) {
|
||||||
|
// 评论成功后列表计数 +1
|
||||||
|
const target = dataList.value.find(item => item.metadata.name === postName)
|
||||||
|
if (target?.stats) {
|
||||||
|
target.stats.totalComment = (target.stats.totalComment || 0) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleToTopPage(duration = 500) {
|
function handleToTopPage(duration = 500) {
|
||||||
uni.pageScrollTo({
|
uni.pageScrollTo({
|
||||||
scrollTop: 0,
|
scrollTop: 0,
|
||||||
@@ -311,7 +358,7 @@
|
|||||||
|
|
||||||
<!-- 正文 -->
|
<!-- 正文 -->
|
||||||
<view class="box-border px-4 pt-3">
|
<view class="box-border px-4 pt-3">
|
||||||
<view class="relative box-border rounded-lg bg-page p-3">
|
<view class="relative box-border rounded-lg bg-page p-3 text-gray-900 text-sm">
|
||||||
<mp-html lazy-load :domain="markdownConfig.domain ?? ''"
|
<mp-html lazy-load :domain="markdownConfig.domain ?? ''"
|
||||||
:loading-img="markdownConfig.loadingGif" scroll-table selectable
|
:loading-img="markdownConfig.loadingGif" scroll-table selectable
|
||||||
:tag-style="markdownConfig.tagStyle" :container-style="markdownConfig.containStyle"
|
:tag-style="markdownConfig.tagStyle" :container-style="markdownConfig.containStyle"
|
||||||
@@ -342,18 +389,22 @@
|
|||||||
<!-- (点赞/评论) -->
|
<!-- (点赞/评论) -->
|
||||||
<view
|
<view
|
||||||
class="mb-1 mt-2 box-border w-full flex items-center justify-between border-t border-black/5 px-4 py-3 text-xs text-gray-400">
|
class="mb-1 mt-2 box-border w-full flex items-center justify-between border-t border-black/5 px-4 py-3 text-xs text-gray-400">
|
||||||
<view class="flex items-center gap-x-1">
|
<view class="flex items-center gap-x-1" @click.stop="handleMomentLike(moment)">
|
||||||
<wd-icon class-prefix="uhemoji-icon" name="-kiss-" size="32rpx" />
|
<wd-icon class-prefix="uhemoji-icon" name="-kiss-" size="32rpx" />
|
||||||
<text class="text-sm text-gray-600">点赞 {{ moment.stats.upvote || 0 }}</text>
|
<text class="text-sm"
|
||||||
|
:class="hasUpvoted(moment.metadata.name) ? 'text-primary' : 'text-gray-600'">
|
||||||
|
点赞 {{ moment.stats.upvote || 0 }}
|
||||||
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center gap-x-1">
|
<view v-if="moment.spec.allowComment" class="flex items-center gap-x-1"
|
||||||
|
@click.stop="handleMomentComment(moment)">
|
||||||
<wd-icon class-prefix="uhemoji-icon" name="-thinking" size="32rpx" />
|
<wd-icon class-prefix="uhemoji-icon" name="-thinking" size="32rpx" />
|
||||||
<text class="text-sm text-gray-600">评论 {{ moment.stats.totalComment || 0 }}</text>
|
<text class="text-sm text-gray-600">评论 {{ moment.stats.totalComment || 0 }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center gap-x-1" @click.stop="handleToggleMomentFavorite(moment)">
|
<view class="flex items-center gap-x-1" @click.stop="handleToggleMomentFavorite(moment)">
|
||||||
<wd-icon class-prefix="uhemoji-icon" name="-smile-" size="32rpx" />
|
<wd-icon class-prefix="uhemoji-icon" name="-smile-" size="32rpx" />
|
||||||
<text class="text-sm text-gray-600"
|
<text class="text-sm"
|
||||||
:style="isMomentFavorite(moment) ? { color: '#ffb300' } : ''">
|
:class="isMomentFavorite(moment) ? 'text-primary' : 'text-gray-600'">
|
||||||
{{ isMomentFavorite(moment) ? '已收藏' : '收藏' }}
|
{{ isMomentFavorite(moment) ? '已收藏' : '收藏' }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -366,4 +417,9 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 评论弹窗(瞬间评论,subjectKind=Moment) -->
|
||||||
|
<uh-comment-modal v-if="commentModal.show" :show="commentModal.show" :is-comment="commentModal.isComment"
|
||||||
|
:title="commentModal.title" :post-name="commentModal.postName" subject-kind="Moment"
|
||||||
|
@on-close="handleOnCommentModalClose" />
|
||||||
</template>
|
</template>
|
||||||
Reference in New Issue
Block a user