mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-18 04:50:57 +08:00
Compare commits
1 Commits
codex/add-
...
codex/upda
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
615832f112 |
33
frontend_nuxt/components/NewMessageContainer.vue
Normal file
33
frontend_nuxt/components/NewMessageContainer.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<div class="new-message-container" :style="{ bottom: bottom + 'px' }" @click="$emit('click')">
|
||||||
|
{{ count }} 条新消息,点击查看
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
count: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.new-message-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: #fff;
|
||||||
|
padding: 6px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -62,7 +62,14 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="message-input-area">
|
<NewMessageContainer
|
||||||
|
v-if="showNewMessageContainer"
|
||||||
|
:count="newMessagesCount"
|
||||||
|
:bottom="inputAreaHeight + 20"
|
||||||
|
@click="handleNewMessagesClick"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="message-input-area" ref="messageInputAreaEl">
|
||||||
<div v-if="replyTo" class="active-reply">
|
<div v-if="replyTo" class="active-reply">
|
||||||
正在回复 {{ replyTo.sender.username }}:
|
正在回复 {{ replyTo.sender.username }}:
|
||||||
{{ stripMarkdownLength(replyTo.content, 50) }}
|
{{ stripMarkdownLength(replyTo.content, 50) }}
|
||||||
@@ -96,6 +103,7 @@ import { useChannelsUnreadCount } from '~/composables/useChannelsUnreadCount'
|
|||||||
import TimeManager from '~/utils/time'
|
import TimeManager from '~/utils/time'
|
||||||
import BaseTimeline from '~/components/BaseTimeline.vue'
|
import BaseTimeline from '~/components/BaseTimeline.vue'
|
||||||
import BasePlaceholder from '~/components/BasePlaceholder.vue'
|
import BasePlaceholder from '~/components/BasePlaceholder.vue'
|
||||||
|
import NewMessageContainer from '~/components/NewMessageContainer.vue'
|
||||||
|
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -112,6 +120,7 @@ const error = ref(null)
|
|||||||
const conversationId = route.params.id
|
const conversationId = route.params.id
|
||||||
const currentUser = ref(null)
|
const currentUser = ref(null)
|
||||||
const messagesListEl = ref(null)
|
const messagesListEl = ref(null)
|
||||||
|
const messageInputAreaEl = ref(null)
|
||||||
const currentPage = ref(0)
|
const currentPage = ref(0)
|
||||||
const totalPages = ref(0)
|
const totalPages = ref(0)
|
||||||
const loadingMore = ref(false)
|
const loadingMore = ref(false)
|
||||||
@@ -120,6 +129,21 @@ const isChannel = ref(false)
|
|||||||
const isFloatMode = computed(() => route.query.float !== undefined)
|
const isFloatMode = computed(() => route.query.float !== undefined)
|
||||||
const floatRoute = useState('messageFloatRoute')
|
const floatRoute = useState('messageFloatRoute')
|
||||||
const replyTo = ref(null)
|
const replyTo = ref(null)
|
||||||
|
const newMessagesCount = ref(0)
|
||||||
|
const inputAreaHeight = ref(0)
|
||||||
|
const showNewMessageContainer = computed(
|
||||||
|
() => newMessagesCount.value > 0 && !isUserNearBottom.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
function updateInputAreaHeight() {
|
||||||
|
if (!messageInputAreaEl.value) return
|
||||||
|
inputAreaHeight.value = messageInputAreaEl.value.offsetHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleNewMessagesClick() {
|
||||||
|
scrollToBottomSmooth()
|
||||||
|
newMessagesCount.value = 0
|
||||||
|
}
|
||||||
|
|
||||||
const isUserNearBottom = ref(true)
|
const isUserNearBottom = ref(true)
|
||||||
function updateNearBottom() {
|
function updateNearBottom() {
|
||||||
@@ -329,6 +353,10 @@ onMounted(async () => {
|
|||||||
messagesListEl.value.addEventListener('scroll', updateNearBottom, { passive: true })
|
messagesListEl.value.addEventListener('scroll', updateNearBottom, { passive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', updateInputAreaHeight)
|
||||||
|
await nextTick()
|
||||||
|
updateInputAreaHeight()
|
||||||
|
|
||||||
currentUser.value = await fetchCurrentUser()
|
currentUser.value = await fetchCurrentUser()
|
||||||
if (currentUser.value) {
|
if (currentUser.value) {
|
||||||
await fetchMessages(0)
|
await fetchMessages(0)
|
||||||
@@ -370,9 +398,10 @@ const subscribeToConversation = () => {
|
|||||||
|
|
||||||
await markConversationAsRead()
|
await markConversationAsRead()
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
if (isUserNearBottom.value) {
|
if (isUserNearBottom.value) {
|
||||||
scrollToBottomSmooth()
|
scrollToBottomSmooth()
|
||||||
|
} else {
|
||||||
|
newMessagesCount.value += 1
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to parse websocket message', e)
|
console.error('Failed to parse websocket message', e)
|
||||||
@@ -386,6 +415,14 @@ watch(isConnected, (newValue) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(isUserNearBottom, (val) => {
|
||||||
|
if (val) newMessagesCount.value = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(replyTo, () => {
|
||||||
|
nextTick(updateInputAreaHeight)
|
||||||
|
})
|
||||||
|
|
||||||
onActivated(async () => {
|
onActivated(async () => {
|
||||||
// 返回页面时:刷新数据与已读,并滚动到底部
|
// 返回页面时:刷新数据与已读,并滚动到底部
|
||||||
if (currentUser.value) {
|
if (currentUser.value) {
|
||||||
@@ -418,6 +455,7 @@ onUnmounted(() => {
|
|||||||
if (messagesListEl.value) {
|
if (messagesListEl.value) {
|
||||||
messagesListEl.value.removeEventListener('scroll', updateNearBottom)
|
messagesListEl.value.removeEventListener('scroll', updateNearBottom)
|
||||||
}
|
}
|
||||||
|
window.removeEventListener('resize', updateInputAreaHeight)
|
||||||
})
|
})
|
||||||
|
|
||||||
function minimize() {
|
function minimize() {
|
||||||
|
|||||||
Reference in New Issue
Block a user