From cd73747164be2b46236e519baaf0340f964fafdd Mon Sep 17 00:00:00 2001
From: Tim <135014430+nagisa77@users.noreply.github.com>
Date: Mon, 25 Aug 2025 15:42:09 +0800
Subject: [PATCH 1/5] feat: support floating message box
---
frontend_nuxt/app.vue | 2 +
frontend_nuxt/components/ChatFloating.vue | 56 +++++++++++++++++++++++
frontend_nuxt/pages/message-box/[id].vue | 38 +++++++++++++++
frontend_nuxt/pages/message-box/index.vue | 44 +++++++++++++++++-
4 files changed, 138 insertions(+), 2 deletions(-)
create mode 100644 frontend_nuxt/components/ChatFloating.vue
diff --git a/frontend_nuxt/app.vue b/frontend_nuxt/app.vue
index 8eab548cf..a79f1c6d2 100644
--- a/frontend_nuxt/app.vue
+++ b/frontend_nuxt/app.vue
@@ -22,6 +22,7 @@
+
@@ -30,6 +31,7 @@ import HeaderComponent from '~/components/HeaderComponent.vue'
import MenuComponent from '~/components/MenuComponent.vue'
import GlobalPopups from '~/components/GlobalPopups.vue'
import ConfirmDialog from '~/components/ConfirmDialog.vue'
+import ChatFloating from '~/components/ChatFloating.vue'
import { useIsMobile } from '~/utils/screen'
const isMobile = useIsMobile()
diff --git a/frontend_nuxt/components/ChatFloating.vue b/frontend_nuxt/components/ChatFloating.vue
new file mode 100644
index 000000000..d1202bfba
--- /dev/null
+++ b/frontend_nuxt/components/ChatFloating.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend_nuxt/pages/message-box/[id].vue b/frontend_nuxt/pages/message-box/[id].vue
index fee571f53..5f049289e 100644
--- a/frontend_nuxt/pages/message-box/[id].vue
+++ b/frontend_nuxt/pages/message-box/[id].vue
@@ -7,6 +7,10 @@
{{ isChannel ? conversationName : otherParticipant?.username }}
+
+
+
+
@@ -82,6 +86,10 @@ const { fetchUnreadCount: refreshGlobalUnreadCount } = useUnreadCount()
const { fetchChannelUnread: refreshChannelUnread } = useChannelsUnreadCount()
let subscription = null
+const chatFloating = useState('chatFloating', () => false)
+const chatPath = useState('chatPath', () => '/message-box')
+const isFloat = computed(() => route.query.float === '1')
+
const messages = ref([])
const participants = ref([])
const loading = ref(true)
@@ -115,6 +123,24 @@ function handleAvatarError(event) {
event.target.src = '/default-avatar.svg'
}
+function minimizeChat() {
+ chatPath.value = route.fullPath
+ chatFloating.value = true
+ navigateTo('/')
+}
+
+function maximizeChat() {
+ if (window.parent) {
+ window.parent.postMessage(
+ {
+ type: 'maximize-chat',
+ path: route.fullPath.replace('?float=1', '').replace('&float=1', ''),
+ },
+ '*',
+ )
+ }
+}
+
// No changes needed here, as renderMarkdown is now imported.
// The old function is removed.
@@ -411,6 +437,7 @@ onUnmounted(() => {
font-size: 18px;
font-weight: 600;
margin: 0;
+ flex: 1;
}
.messages-list {
@@ -524,4 +551,15 @@ onUnmounted(() => {
margin-left: 10px;
margin-right: 10px;
}
+
+.chat-controls {
+ margin-left: auto;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+}
+
+.control-icon {
+ font-size: 16px;
+}
diff --git a/frontend_nuxt/pages/message-box/index.vue b/frontend_nuxt/pages/message-box/index.vue
index d2af0f6af..73abdde2c 100644
--- a/frontend_nuxt/pages/message-box/index.vue
+++ b/frontend_nuxt/pages/message-box/index.vue
@@ -1,5 +1,9 @@
+
+
+
+
站内信
@@ -114,8 +118,8 @@
diff --git a/frontend_nuxt/pages/posts/[id]/index.vue b/frontend_nuxt/pages/posts/[id]/index.vue
index 33ecd8f61..7777cb2a0 100644
--- a/frontend_nuxt/pages/posts/[id]/index.vue
+++ b/frontend_nuxt/pages/posts/[id]/index.vue
@@ -260,7 +260,6 @@ import { getMedalTitle } from '~/utils/medal'
import { toast } from '~/main'
import { getToken, authState } from '~/utils/auth'
import TimeManager from '~/utils/time'
-import { useRouter } from 'vue-router'
import { useIsMobile } from '~/utils/screen'
import Dropdown from '~/components/Dropdown.vue'
import { ClientOnly } from '#components'
@@ -272,7 +271,6 @@ const API_BASE_URL = config.public.apiBaseUrl
const route = useRoute()
const postId = route.params.id
-const router = useRouter()
const title = ref('')
const author = ref('')
diff --git a/frontend_nuxt/pages/users/[id].vue b/frontend_nuxt/pages/users/[id].vue
index 521e445ea..973a95b68 100644
--- a/frontend_nuxt/pages/users/[id].vue
+++ b/frontend_nuxt/pages/users/[id].vue
@@ -328,7 +328,7 @@
-
-
diff --git a/frontend_nuxt/pages/message-box/[id].vue b/frontend_nuxt/pages/message-box/[id].vue
index 5f049289e..fee571f53 100644
--- a/frontend_nuxt/pages/message-box/[id].vue
+++ b/frontend_nuxt/pages/message-box/[id].vue
@@ -7,10 +7,6 @@
{{ isChannel ? conversationName : otherParticipant?.username }}
-
-
-
-
@@ -86,10 +82,6 @@ const { fetchUnreadCount: refreshGlobalUnreadCount } = useUnreadCount()
const { fetchChannelUnread: refreshChannelUnread } = useChannelsUnreadCount()
let subscription = null
-const chatFloating = useState('chatFloating', () => false)
-const chatPath = useState('chatPath', () => '/message-box')
-const isFloat = computed(() => route.query.float === '1')
-
const messages = ref([])
const participants = ref([])
const loading = ref(true)
@@ -123,24 +115,6 @@ function handleAvatarError(event) {
event.target.src = '/default-avatar.svg'
}
-function minimizeChat() {
- chatPath.value = route.fullPath
- chatFloating.value = true
- navigateTo('/')
-}
-
-function maximizeChat() {
- if (window.parent) {
- window.parent.postMessage(
- {
- type: 'maximize-chat',
- path: route.fullPath.replace('?float=1', '').replace('&float=1', ''),
- },
- '*',
- )
- }
-}
-
// No changes needed here, as renderMarkdown is now imported.
// The old function is removed.
@@ -437,7 +411,6 @@ onUnmounted(() => {
font-size: 18px;
font-weight: 600;
margin: 0;
- flex: 1;
}
.messages-list {
@@ -551,15 +524,4 @@ onUnmounted(() => {
margin-left: 10px;
margin-right: 10px;
}
-
-.chat-controls {
- margin-left: auto;
- cursor: pointer;
- display: flex;
- align-items: center;
-}
-
-.control-icon {
- font-size: 16px;
-}
diff --git a/frontend_nuxt/pages/message-box/index.vue b/frontend_nuxt/pages/message-box/index.vue
index 0f95ffa73..17f14587c 100644
--- a/frontend_nuxt/pages/message-box/index.vue
+++ b/frontend_nuxt/pages/message-box/index.vue
@@ -1,9 +1,5 @@