|
@@ -9,7 +9,7 @@
|
|
|
</div>
|
|
|
|
|
|
<!-- 聊天消息区域 -->
|
|
|
- <div class="chat-list">
|
|
|
+ <div class="chat-list" ref="chatListRef">
|
|
|
<div v-for="(item, index) in wsStore.messages" :key="index">
|
|
|
<div class="chat-time">{{ formatTime(item.timestamp || Date.now()) }}</div>
|
|
|
<div class="box">
|
|
@@ -48,17 +48,17 @@
|
|
|
placeholder="输入文本"
|
|
|
@keyup.enter="sendMessage"
|
|
|
/>
|
|
|
- <svg-icon class="page-icon mr12" name="emoji" @click="toggleAppBox(1)" />
|
|
|
- <svg-icon class="page-icon" name="add2" @click="toggleAppBox(2)" />
|
|
|
+ <svg-icon class="page-icon mr12 emoji-toggle" name="emoji" @click="toggleAppBox(1)" />
|
|
|
+ <svg-icon class="page-icon tools-toggle" name="add2" @click="toggleAppBox(2)" />
|
|
|
</div>
|
|
|
|
|
|
<!-- 表情面板 -->
|
|
|
- <div class="app-box" v-show="showEmoji" :style="{ height: `${appBoxHeight}px` }">
|
|
|
+ <div class="app-box" v-show="showEmoji" :style="{ height: `${appBoxHeight}px` }" ref="emojiRef">
|
|
|
😀 😃 😄 😁 😆 😅 😂 🤣 😊 😇 🙂 🙃 😉 😌 😍
|
|
|
</div>
|
|
|
|
|
|
<!-- 工具栏面板 -->
|
|
|
- <div class="app-box" v-show="showTools" :style="{ height: `${appBoxHeight}px` }">
|
|
|
+ <div class="app-box" v-show="showTools" :style="{ height: `${appBoxHeight}px` }" ref="toolsRef">
|
|
|
<div class="tool-btn">
|
|
|
<svg-icon class="tool-icon" name="tp" />
|
|
|
<div>图片</div>
|
|
@@ -73,7 +73,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, computed, onMounted, onUnmounted } from "vue";
|
|
|
+import { ref, computed, onMounted, onUnmounted,onBeforeUnmount } from "vue";
|
|
|
import { useRouter, useRoute } from "vue-router";
|
|
|
import { useWebSocketStore } from "@/stores/modules/webSocketStore.js";
|
|
|
import { useWalletStore } from "@/stores/modules/walletStore.js";
|
|
@@ -95,6 +95,19 @@ const keyboardHeight = ref(0);
|
|
|
const showEmoji = ref(false);
|
|
|
const showTools = ref(false);
|
|
|
const appBoxHeight = ref(210);
|
|
|
+const chatListRef = ref(null);
|
|
|
+const emojiRef = ref(null);
|
|
|
+const toolsRef = ref(null);
|
|
|
+
|
|
|
+// 滚动到底部
|
|
|
+const scrollToBottom = () => {
|
|
|
+ nextTick(() => {
|
|
|
+ if (chatListRef.value) {
|
|
|
+ const el = chatListRef.value;
|
|
|
+ el.scrollTop = el.scrollHeight;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
|
|
|
// 平台判断
|
|
|
const isMobile = Capacitor.getPlatform() !== "web";
|
|
@@ -128,10 +141,8 @@ const onFocus = () => {
|
|
|
// 隐藏所有面板
|
|
|
showEmoji.value = false;
|
|
|
showTools.value = false;
|
|
|
- // 判断是不是web
|
|
|
- if (Capacitor.getPlatform() != "web") {
|
|
|
- setupKeyboardListeners();
|
|
|
- }
|
|
|
+ if (isMobile) setupKeyboardListeners();
|
|
|
+ scrollToBottom();
|
|
|
};
|
|
|
|
|
|
// 键盘监听
|
|
@@ -228,6 +239,7 @@ const sendMessage = () => {
|
|
|
};
|
|
|
wsStore.sendMessage(message);
|
|
|
text.value = "";
|
|
|
+ scrollToBottom();
|
|
|
};
|
|
|
|
|
|
// 时间格式化
|
|
@@ -245,11 +257,41 @@ onMounted(() => {
|
|
|
messageType: 1,
|
|
|
friendUsername: route.query.uuid,
|
|
|
});
|
|
|
+ scrollToBottom();
|
|
|
+ document.addEventListener('click', handleClickOutside);
|
|
|
});
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
if (isMobile) Keyboard.removeAllListeners();
|
|
|
});
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ document.removeEventListener('click', handleClickOutside);
|
|
|
+});
|
|
|
+
|
|
|
+// 判断是否点击在元素外
|
|
|
+const handleClickOutside = (event) => {
|
|
|
+ const emojiEl = emojiRef.value;
|
|
|
+ const toolsEl = toolsRef.value;
|
|
|
+ const target = event.target;
|
|
|
+
|
|
|
+ if (
|
|
|
+ showEmoji.value &&
|
|
|
+ emojiEl &&
|
|
|
+ !emojiEl.contains(target) &&
|
|
|
+ !target.closest('.emoji-toggle')
|
|
|
+ ) {
|
|
|
+ showEmoji.value = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ showTools.value &&
|
|
|
+ toolsEl &&
|
|
|
+ !toolsEl.contains(target) &&
|
|
|
+ !target.closest('.tools-toggle')
|
|
|
+ ) {
|
|
|
+ showTools.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
// 页面跳转
|
|
|
const goBack = () => router.push("im");
|