koishi-plugin-chat-patch 1.0.11 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -164,7 +164,7 @@
164
164
  </div>
165
165
 
166
166
  <input v-model="inputMessage" type="text" :placeholder="inputPlaceholder" @keyup.enter="sendMessage"
167
- :disabled="!canInputMessage" ref="messageInput" @paste="handlePaste" />
167
+ :disabled="!canInputMessage" ref="messageInput" @paste="handlePaste" @focus="handleInputFocus" />
168
168
  <button @click="sendMessage" :disabled="!canSendMessage" :class="{ 'is-sending': isSending }">
169
169
  {{ isSending ? '发送中...' : '发送' }}
170
170
  </button>
@@ -445,7 +445,7 @@ const ImageComponent = defineComponent({
445
445
  ref: imgRef,
446
446
  draggable: false,
447
447
  style: {
448
- 'max-width': '400px',
448
+ 'max-width': 'min(400px, 66.67vw)',
449
449
  'max-height': '200px',
450
450
  'width': 'auto',
451
451
  'height': 'auto',
@@ -1102,15 +1102,9 @@ const inputPlaceholder = computed(() => {
1102
1102
  }
1103
1103
  })
1104
1104
 
1105
+ // 简化的容器样式,现在主要由CSS处理
1105
1106
  const chatContainerStyle = computed(() => {
1106
- if (isMobile.value) {
1107
- const height = pluginConfig.value.chatContainerHeight || 80; // 默认80
1108
- const marginTop = 100 - height - 19; // 19vh 是输入框高度,100是总高度
1109
- return {
1110
- height: `${height}vh`,
1111
- marginTop: `${marginTop}vh`
1112
- };
1113
- }
1107
+ // 移除复杂的高度计算,让CSS的dvh单位自动处理
1114
1108
  return {};
1115
1109
  });
1116
1110
 
@@ -1546,11 +1540,11 @@ function checkScrollPosition() {
1546
1540
 
1547
1541
  showScrollButton.value = shouldShowButton
1548
1542
 
1549
- // 检测用户是否在主动滚动(向上滚动查看历史消息)
1543
+ // 检测是否在主动滚动(向上滚动查看历史消息)
1550
1544
  if (!isAtBottom) {
1551
1545
  isUserScrolling.value = true
1552
1546
  } else {
1553
- // 用户滚动到底部时,重置滚动状态
1547
+ // 滚动到底部时,重置滚动状态
1554
1548
  isUserScrolling.value = false
1555
1549
  }
1556
1550
  }
@@ -2646,10 +2640,10 @@ function handleMessageEvent(messageEvent: any) {
2646
2640
  // 更新频道消息数量缓存
2647
2641
  channelMessageCounts.value[channelKey] = messages.length
2648
2642
 
2649
- // 在添加新消息前检查用户是否在底部附近
2643
+ // 在添加新消息前检查是否在底部附近
2650
2644
  const wasNearBottom = isNearBottom()
2651
2645
 
2652
- // 智能滚动:基于添加消息前的位置状态来决定是否滚动
2646
+ // 基于添加消息前的位置状态来决定是否滚动
2653
2647
  nextTick(() => {
2654
2648
  // 再次等待,确保新消息的DOM已经渲染
2655
2649
  setTimeout(() => {
@@ -2730,7 +2724,7 @@ function handleBotMessageSentEvent(sentEvent: any) {
2730
2724
  // 更新频道消息数量缓存
2731
2725
  channelMessageCounts.value[channelKey] = messages.length
2732
2726
 
2733
- // 在添加新消息前检查用户是否在底部附近
2727
+ // 在添加新消息前检查是否在底部附近
2734
2728
  const wasNearBottom = isNearBottom()
2735
2729
 
2736
2730
  // 智能滚动:基于添加消息前的位置状态来决定是否滚动
@@ -2839,10 +2833,9 @@ function handleBotMessageEvent(botMessageEvent: any) {
2839
2833
  // 更新频道消息数量缓存
2840
2834
  channelMessageCounts.value[channelKey] = messages.length
2841
2835
 
2842
- // 在添加新消息前检查用户是否在底部附近
2836
+ // 在添加新消息前检查是否在底部附近
2843
2837
  const wasNearBottom = isNearBottom()
2844
2838
 
2845
- // 智能滚动:基于添加消息前的位置状态来决定是否滚动
2846
2839
  nextTick(() => {
2847
2840
  // 再次等待,确保新消息的DOM已经渲染
2848
2841
  setTimeout(() => {
@@ -3129,12 +3122,47 @@ function checkMobile() {
3129
3122
  isMobile.value = window.innerWidth <= 768
3130
3123
  }
3131
3124
 
3125
+ // 判断是否应该自动滚动
3126
+ function shouldAutoScroll(): boolean {
3127
+ // 如果没有主动滚动,或者已经在底部附近,则应该自动滚动
3128
+ return !isUserScrolling.value || isNearBottom()
3129
+ }
3130
+
3131
+ // 简单的视口高度管理
3132
+ const handleViewportChange = () => {
3133
+ if (isMobile.value && messageHistory.value) {
3134
+ // 当视口变化时,确保消息区域滚动到底部
3135
+ nextTick(() => {
3136
+ if (shouldAutoScroll()) {
3137
+ scrollToBottom()
3138
+ }
3139
+ })
3140
+ }
3141
+ }
3142
+
3143
+ // 输入框焦点处理
3144
+ const handleInputFocus = () => {
3145
+ if (isMobile.value) {
3146
+ // 延迟滚动,等待键盘完全出现
3147
+ setTimeout(() => {
3148
+ if (messageHistory.value && shouldAutoScroll()) {
3149
+ scrollToBottom()
3150
+ }
3151
+ }, 300)
3152
+ }
3153
+ }
3154
+
3132
3155
  // 生命周期
3133
3156
  onMounted(async () => {
3134
3157
  // 检测手机端
3135
3158
  checkMobile()
3136
3159
  window.addEventListener('resize', checkMobile)
3137
3160
 
3161
+ // 添加视口变化监听(处理键盘弹出)
3162
+ if (window.visualViewport) {
3163
+ window.visualViewport.addEventListener('resize', handleViewportChange)
3164
+ }
3165
+
3138
3166
  // 添加点击外部关闭菜单的监听器
3139
3167
  document.addEventListener('click', handleClickOutside)
3140
3168
 
@@ -3192,6 +3220,9 @@ onMounted(async () => {
3192
3220
  // 在组件卸载时清理监听器
3193
3221
  onUnmounted(() => {
3194
3222
  window.removeEventListener('resize', checkMobile)
3223
+ if (window.visualViewport) {
3224
+ window.visualViewport.removeEventListener('resize', handleViewportChange)
3225
+ }
3195
3226
  document.removeEventListener('click', handleClickOutside)
3196
3227
 
3197
3228
  if (dispose1 && typeof dispose1 === 'function') {