pref: topic reactivity

This commit is contained in:
KUN1007 2023-10-07 21:16:02 +08:00
parent 30502722ef
commit 3f5a6158b0
9 changed files with 163 additions and 138 deletions

View file

@ -3,7 +3,7 @@
*/
// 读取本地存储中的语言配置
const localStorageString = localStorage.getItem('KUNGalgame-settings')
const localStorageString = localStorage.getItem('KUNGalgameSettings')
// 这里是为了兼容各种浏览器,某些浏览器的 navigator.language 值为 'zh-CN',会导致报错
const getInitLanguage = () => {

View file

@ -1,6 +1,6 @@
<!-- 话题的底部区域推话题回复点赞等 -->
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { watch, ref } from 'vue'
import { Icon } from '@iconify/vue'
//
import message from '@/components/alert/Message'
@ -19,8 +19,18 @@ const props = defineProps<{
toUid: number
}>()
const dislikesArray = ref(props.dislikes)
const isDisliked = ref(false)
const isDisliked = ref(props.dislikes.includes(props.uid))
const dislikesCount = ref(props.dislikes.length)
//
watch(
() => props.dislikes,
(newLikes) => {
// isLiked likesCount
isDisliked.value = newLikes.includes(props.uid)
dislikesCount.value = newLikes.length
}
)
// throttle
const throttleCallback = () => {
@ -56,34 +66,32 @@ const dislikeOperation = async (
}
}
// throttle 1007
const handleClickDislikeThrottled = throttle(
async () => {
// /
const toggleDislike = async () => {
//
if (props.uid === props.toUid) {
message('You cannot dislike yourself', '您不可以给自己点踩', 'warn')
return
}
//
isDisliked.value = !isDisliked.value
const { tid, rid, toUid } = props
const isPush = !isDisliked.value //
const res = await dislikeOperation(
props.tid,
props.rid,
props.toUid,
isDisliked.value
)
//
const res = await dislikeOperation(tid, rid, toUid, isPush)
if (res.code === 200) {
//
dislikesArray.value.length = isDisliked.value
? dislikesArray.value.length + 1
: dislikesArray.value.length - 1
isDisliked.value = isPush
dislikesCount.value += isPush ? 1 : -1
message('Dislike successfully!', '点踩成功', 'success')
} else {
message('Dislike failed!', '点踩失败', 'error')
}
},
}
// throttle 1007
const handleClickDislikeThrottled = throttle(
toggleDislike,
1007,
throttleCallback
)
@ -92,14 +100,6 @@ const handleClickDislikeThrottled = throttle(
const handleClickDislike = () => {
handleClickDislikeThrottled()
}
//
onMounted(() => {
//
if (props.dislikes.includes(props.uid)) {
isDisliked.value = true
}
})
</script>
<template>
@ -112,7 +112,7 @@ onMounted(() => {
>
<Icon icon="line-md:thumbs-down-twotone" />
</span>
{{ dislikes.length }}
{{ dislikesCount }}
</li>
</template>

View file

@ -15,6 +15,7 @@ import { useKUNGalgameTopicStore } from '@/store/modules/topic'
// store
import { useKUNGalgameUserStore } from '@/store/modules/kungalgamer'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
// 使 store
const { isEdit, replyDraft } = storeToRefs(useKUNGalgameTopicStore())
@ -38,6 +39,10 @@ const props = defineProps<{
toUid: number
}>()
const info = computed(() => props.info)
const content = computed(() => props.content)
const toUid = computed(() => props.toUid)
/**
* 这里只是简单起见不显示重新编辑
* 实际上如果用户自己修改了 localStorage 中保存的信息这个验证就失效了
@ -45,15 +50,13 @@ const props = defineProps<{
*/
// uid
const currUserUid = useKUNGalgameUserStore().uid
// / uid
const masterUid = props.toUid
//
const handleClickReply = async () => {
const handleClickReply = () => {
// 便
replyDraft.value.tid = props.info.tid
replyDraft.value.tid = info.value.tid
// uid
replyDraft.value.to_uid = masterUid
replyDraft.value.to_uid = toUid.value
// floor 0
replyDraft.value.to_floor = 0
//
@ -70,14 +73,14 @@ const handleClickReply = async () => {
<!-- 推话题 -->
<Upvote
:uid="currUserUid"
:tid="props.info.tid"
:rid="props.info.rid"
:upvotes="props.info.upvotes"
:to-uid="masterUid"
:tid="info.tid"
:rid="info.rid"
:upvotes="info.upvotes"
:to-uid="toUid"
/>
<!-- 浏览数楼主才会显示 -->
<li v-if="props.info.views > 0">
<li v-if="info.views > 0">
<span class="icon"><Icon icon="ic:outline-remove-red-eye" /></span>
{{ info.views }}
</li>
@ -85,19 +88,19 @@ const handleClickReply = async () => {
<!-- 点赞 -->
<Like
:uid="currUserUid"
:tid="props.info.tid"
:rid="props.info.rid"
:likes="props.info.likes"
:to-uid="masterUid"
:tid="info.tid"
:rid="info.rid"
:likes="info.likes"
:to-uid="toUid"
/>
<!-- -->
<Dislike
:uid="currUserUid"
:tid="props.info.tid"
:rid="props.info.rid"
:dislikes="props.info.dislikes"
:to-uid="masterUid"
:tid="info.tid"
:rid="info.rid"
:dislikes="info.dislikes"
:to-uid="toUid"
/>
</ul>
</div>
@ -116,14 +119,14 @@ const handleClickReply = async () => {
<!-- 编辑 -->
<Rewrite
:tid="props.info.tid"
:rid="props.info.rid"
:tid="info.tid"
:rid="info.rid"
:uid="currUserUid"
:title="props.content.title"
:content="props.content.content"
:tags="props.content.tags"
:category="props.content.category"
:to-uid="masterUid"
:title="content.title"
:content="content.content"
:tags="content.tags"
:category="content.category"
:to-uid="toUid"
/>
<!-- 回复的插槽 -->

View file

@ -1,6 +1,6 @@
<!-- 话题的底部区域推话题回复点赞等 -->
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { watch, ref } from 'vue'
import { Icon } from '@iconify/vue'
//
import message from '@/components/alert/Message'
@ -19,8 +19,18 @@ const props = defineProps<{
toUid: number
}>()
const likesArray = ref(props.likes)
const isLiked = ref(false)
const isLiked = ref(props.likes.includes(props.uid))
const likesCount = ref(props.likes.length)
//
watch(
() => props.likes,
(newLikes) => {
// isLiked likesCount
isLiked.value = newLikes.includes(props.uid)
likesCount.value = newLikes.length
}
)
// throttle
const throttleCallback = () => {
@ -52,50 +62,36 @@ const likeOperation = async (
}
}
// throttle 1007
const handleClickLikeThrottled = throttle(
async () => {
// /
const toggleLike = async () => {
//
if (props.uid === props.toUid) {
message('You cannot like yourself', '您不可以给自己点赞', 'warn')
return
}
//
isLiked.value = !isLiked.value
const { tid, rid, toUid } = props
const isPush = !isLiked.value //
const res = await likeOperation(
props.tid,
props.rid,
props.toUid,
isLiked.value
)
//
const res = await likeOperation(tid, rid, toUid, isPush)
if (res.code === 200) {
//
likesArray.value.length = isLiked.value
? likesArray.value.length + 1
: likesArray.value.length - 1
isLiked.value = isPush
likesCount.value += isPush ? 1 : -1
message('Like successfully!', '点赞成功', 'success')
} else {
message('Like failed!', '点赞失败', 'error')
}
},
1007,
throttleCallback
)
}
// throttle 1007
const handleClickLikeThrottled = throttle(toggleLike, 1007, throttleCallback)
//
const handleClickLike = () => {
handleClickLikeThrottled()
}
//
onMounted(() => {
//
if (props.likes.includes(props.uid)) {
isLiked.value = true
}
})
</script>
<template>
@ -108,7 +104,7 @@ onMounted(() => {
>
<Icon icon="line-md:thumbs-up-twotone" />
</span>
{{ likesArray.length }}
{{ likesCount }}
</li>
</template>

View file

@ -1,5 +1,6 @@
<!-- 话题的底部区域推话题回复点赞等 -->
<script setup lang="ts">
import { watch, ref } from 'vue'
import { Icon } from '@iconify/vue'
import { useRouter } from 'vue-router'
// store
@ -28,7 +29,19 @@ const props = defineProps<{
}>()
//
const isShowRewrite = props.uid === props.toUid
const isShowRewrite = ref(props.uid === props.toUid)
//
watch(
() => props.toUid,
() => {
if (props.uid === props.toUid) {
isShowRewrite.value = true
} else {
isShowRewrite.value = false
}
}
)
//
const rewriteTopic = () => {

View file

@ -1,6 +1,6 @@
<!-- 话题的底部区域推话题回复点赞等 -->
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { watch, ref } from 'vue'
import { Icon } from '@iconify/vue'
//
import { useKUNGalgameMessageStore } from '@/store/modules/message'
@ -18,8 +18,17 @@ const props = defineProps<{
toUid: number
}>()
const upvotesArray = ref(props.upvotes)
const isUpvote = ref(false)
const isUpvote = ref(props.upvotes.includes(props.uid))
const upvoteCount = ref(props.upvotes.length)
//
watch(
() => props.upvotes,
(newUpvote) => {
isUpvote.value = props.upvotes.includes(props.uid)
upvoteCount.value = newUpvote.length
}
)
//
const upvoteTopic = async () => {
@ -31,15 +40,14 @@ const upvoteTopic = async () => {
//
if (res) {
const { tid, toUid } = props
//
const res = await useKUNGalgameTopicStore().updateTopicUpvote(
props.tid,
props.toUid
)
const res = await useKUNGalgameTopicStore().updateTopicUpvote(tid, toUid)
if (res.code === 200) {
//
upvotesArray.value.length++
upvoteCount.value++
isUpvote.value = true
message('Topic upvote successfully', '推话题成功', 'success')
} else {
@ -58,16 +66,18 @@ const upvoteReply = async () => {
//
if (res) {
const { tid, toUid, rid } = props
//
const res = await useKUNGalgameTopicStore().updateReplyUpvote(
props.tid,
props.toUid,
props.rid
tid,
toUid,
rid
)
if (res.code === 200) {
//
upvotesArray.value.length++
upvoteCount.value++
isUpvote.value = true
message('Reply upvote successfully', '推回复成功', 'success')
} else {
@ -91,14 +101,6 @@ const handleClickUpvote = async () => {
upvoteReply()
}
}
//
onMounted(() => {
//
if (props.upvotes.includes(props.uid)) {
isUpvote.value = true
}
})
</script>
<template>
@ -111,7 +113,7 @@ onMounted(() => {
>
<Icon icon="bi:rocket" />
</span>
{{ upvotes.length }}
{{ upvoteCount }}
</li>
</template>
@ -141,6 +143,6 @@ li {
/* 激活后的样式 */
.active {
color: var(--kungalgame-blue-4);
color: var(--kungalgame-blue-4) !important;
}
</style>

View file

@ -4,8 +4,10 @@
这个区域包含所有人回复给楼主的话题其中每个人的话题将会被拆分成为单独的组件
-->
<script setup lang="ts">
import { onMounted, onUnmounted, onUpdated, ref } from 'vue'
import { computed, onMounted, onUnmounted, onUpdated, ref } from 'vue'
import { Icon } from '@iconify/vue'
//
import Content from '../Content.vue'
//
import Comments from '../comment/Comments.vue'
// Footer
@ -30,10 +32,13 @@ import { storeToRefs } from 'pinia'
const { scrollToReplyId, commentDraft } = storeToRefs(useKUNGalgameTopicStore())
defineProps<{
const props = defineProps<{
repliesData: TopicReply[]
}>()
// props
const replies = computed(() => props.repliesData)
//
const isCommentPanelOpen = ref(false)
//
@ -58,14 +63,14 @@ const handleClickComment = (rid: number) => {
<!-- 被推 10 小时内样式改变 -->
<div
class="other-topic-container"
v-for="(reply, index) in repliesData"
v-for="(reply, index) in replies"
:class="hourDiff(reply.upvote_time, 10) ? 'active-upvote' : ''"
:key="`${index}`"
:id="`kungalgame-reply-${reply.floor}`"
>
<!-- 每个人的单个话题 -->
<!-- 楼层标志 -->
<div class="floor">
<div class="floor" :class="reply.edited ? 'rewrite' : ''">
<span>K{{ reply.floor }}</span>
</div>
<!-- 其他人话题内容区的容器 -->
@ -91,8 +96,9 @@ const handleClickComment = (rid: number) => {
<!-- 上部区域的右边 -->
<Rewrite v-if="reply.edited" :time="reply.edited" />
</div>
<!-- 右侧部分分文本 -->
<div class="text" v-html="reply.content"></div>
<!-- 富文本内容展示区域 -->
<Content :content="reply.content" />
</div>
</div>
<!-- 其他人回复的下部 -->
@ -164,6 +170,7 @@ const handleClickComment = (rid: number) => {
border-bottom: none;
/* 这里的阴影只能这么绘制 */
filter: drop-shadow(1px 2px 2px var(--kungalgame-trans-blue-4));
margin: 5px 0;
span {
transform: rotate(10deg) translateY(40px);
padding: 0 30px;
@ -253,6 +260,13 @@ const handleClickComment = (rid: number) => {
margin-right: 17px;
}
/* 被重新编辑后的楼层标志样式 */
.rewrite {
span {
transform: rotate(0) translateY(0) translateX(-7px);
}
}
/* 回复被推的样式 */
.active-upvote .container {
border: 2px solid var(--kungalgame-pink-3);

View file

@ -21,8 +21,6 @@ import ReplyPanelBtn from './ReplyPanelBtn.vue'
//
import { useKUNGalgameMessageStore } from '@/store/modules/message'
//
import message from '@/components/alert/Message'
// store
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
import { storeToRefs } from 'pinia'

View file

@ -10,7 +10,6 @@ import { useTempReplyStore } from '@/store/temp/reply'
import { storeToRefs } from 'pinia'
//
import { useTempReplyRewriteStore } from '@/store/temp/replyRewrite'
import { timeEnd } from 'console'
const { rid, replyContent, tags, edited } = storeToRefs(
useTempReplyRewriteStore()