feat: add mobile comment editor

This commit is contained in:
Tim
2025-07-18 17:45:02 +08:00
parent 8e0a672b8d
commit 75a100c8c2
3 changed files with 98 additions and 5 deletions

View File

@@ -33,7 +33,8 @@
</ReactionsGroup>
</div>
<div class="comment-editor-wrapper">
<CommentEditor v-if="showEditor" @submit="submitReply" :loading="isWaitingForReply" :disabled="!loggedIn" :show-login-overlay="!loggedIn" />
<CommentEditor v-if="showEditor && !isMobile" @submit="submitReply" :loading="isWaitingForReply" :disabled="!loggedIn" :show-login-overlay="!loggedIn" />
<SimpleCommentEditor v-if="showEditor && isMobile" @submit="submitReply" :loading="isWaitingForReply" :disabled="!loggedIn" :show-login-overlay="!loggedIn" />
</div>
<div v-if="comment.reply && comment.reply.length" class="reply-toggle" @click="toggleReplies">
<i v-if="showReplies" class="fas fa-chevron-up reply-toggle-icon"></i>
@@ -69,6 +70,7 @@ import { ref, watch, computed } from 'vue'
import VueEasyLightbox from 'vue-easy-lightbox'
import { useRouter } from 'vue-router'
import CommentEditor from './CommentEditor.vue'
import SimpleCommentEditor from './SimpleCommentEditor.vue'
import { renderMarkdown } from '../utils/markdown'
import TimeManager from '../utils/time'
import BaseTimeline from './BaseTimeline.vue'
@@ -77,6 +79,7 @@ import { getToken, authState } from '../utils/auth'
import ReactionsGroup from './ReactionsGroup.vue'
import DropdownMenu from './DropdownMenu.vue'
import LoginOverlay from './LoginOverlay.vue'
import { isMobile } from '../utils/screen'
const CommentItem = {
name: 'CommentItem',
@@ -205,11 +208,11 @@ const CommentItem = {
lightboxVisible.value = true
}
}
return { showReplies, toggleReplies, showEditor, toggleEditor, submitReply, copyCommentLink, renderMarkdown, isWaitingForReply, commentMenuItems, deleteComment, lightboxVisible, lightboxIndex, lightboxImgs, handleImageClick, loggedIn }
return { showReplies, toggleReplies, showEditor, toggleEditor, submitReply, copyCommentLink, renderMarkdown, isWaitingForReply, commentMenuItems, deleteComment, lightboxVisible, lightboxIndex, lightboxImgs, handleImageClick, loggedIn, isMobile }
}
}
CommentItem.components = { CommentItem, CommentEditor, BaseTimeline, ReactionsGroup, DropdownMenu, VueEasyLightbox, LoginOverlay }
CommentItem.components = { CommentItem, CommentEditor, SimpleCommentEditor, BaseTimeline, ReactionsGroup, DropdownMenu, VueEasyLightbox, LoginOverlay }
export default CommentItem
</script>

View File

@@ -0,0 +1,87 @@
<template>
<div class="comment-editor-container">
<div class="comment-editor-wrapper">
<BaseInput textarea rows="3" v-model="text" placeholder="说点什么..." />
<LoginOverlay v-if="showLoginOverlay" />
</div>
<div class="comment-bottom-container">
<div class="comment-submit" :class="{ disabled: isDisabled }" @click="submit">
<template v-if="!loading">
确认
</template>
<template v-else>
<i class="fa-solid fa-spinner fa-spin"></i> 发布中...
</template>
</div>
</div>
</div>
</template>
<script>
import { ref, computed } from 'vue'
import BaseInput from './BaseInput.vue'
import LoginOverlay from './LoginOverlay.vue'
export default {
name: 'SimpleCommentEditor',
components: { BaseInput, LoginOverlay },
emits: ['submit'],
props: {
loading: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
showLoginOverlay: { type: Boolean, default: false }
},
setup(props, { emit }) {
const text = ref('')
const isDisabled = computed(() => props.loading || props.disabled || !text.value.trim())
const submit = () => {
if (isDisabled.value) return
emit('submit', text.value)
text.value = ''
}
return { text, submit, isDisabled }
}
}
</script>
<style scoped>
.comment-editor-container {
margin-top: 20px;
margin-bottom: 50px;
}
.comment-editor-wrapper {
position: relative;
}
.comment-bottom-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
padding-top: 10px;
}
.comment-submit {
background-color: var(--primary-color);
color: #fff;
padding: 10px 20px;
border-radius: 10px;
font-size: 14px;
cursor: pointer;
}
.comment-submit.disabled {
background-color: var(--primary-color-disabled);
opacity: 0.5;
cursor: not-allowed;
}
.comment-submit.disabled:hover {
background-color: var(--primary-color-disabled);
}
.comment-submit:hover {
background-color: var(--primary-color-hover);
}
</style>

View File

@@ -63,7 +63,9 @@
</div>
</div>
<CommentEditor @submit="postComment" :loading="isWaitingPostingComment" :disabled="!loggedIn"
<CommentEditor v-if="!isMobile" @submit="postComment" :loading="isWaitingPostingComment" :disabled="!loggedIn"
:show-login-overlay="!loggedIn" />
<SimpleCommentEditor v-else @submit="postComment" :loading="isWaitingPostingComment" :disabled="!loggedIn"
:show-login-overlay="!loggedIn" />
<div class="comments-container">
@@ -108,6 +110,7 @@ import VueEasyLightbox from 'vue-easy-lightbox'
import { useRoute } from 'vue-router'
import CommentItem from '../components/CommentItem.vue'
import CommentEditor from '../components/CommentEditor.vue'
import SimpleCommentEditor from '../components/SimpleCommentEditor.vue'
import BaseTimeline from '../components/BaseTimeline.vue'
import ArticleTags from '../components/ArticleTags.vue'
import ArticleCategory from '../components/ArticleCategory.vue'
@@ -124,7 +127,7 @@ hatch.register()
export default {
name: 'PostPageView',
components: { CommentItem, CommentEditor, BaseTimeline, ArticleTags, ArticleCategory, ReactionsGroup, DropdownMenu, VueEasyLightbox },
components: { CommentItem, CommentEditor, SimpleCommentEditor, BaseTimeline, ArticleTags, ArticleCategory, ReactionsGroup, DropdownMenu, VueEasyLightbox },
setup() {
const route = useRoute()
const postId = route.params.id