liming 1 week ago
parent
commit
c7dd921d9f
3 changed files with 258 additions and 202 deletions
  1. 1 0
      android/app/capacitor.build.gradle
  2. 1 0
      package.json
  3. 256 202
      src/views/im/chat/index.vue

+ 1 - 0
android/app/capacitor.build.gradle

@@ -16,6 +16,7 @@ dependencies {
     implementation project(':capacitor-browser')
     implementation project(':capacitor-device')
     implementation project(':capacitor-inappbrowser')
+    implementation project(':capacitor-keyboard')
     implementation project(':capacitor-local-notifications')
     implementation project(':capacitor-push-notifications')
     implementation project(':capacitor-status-bar')

+ 1 - 0
package.json

@@ -30,6 +30,7 @@
     "@capacitor/device": "^7.0.1",
     "@capacitor/inappbrowser": "^2.2.0",
     "@capacitor/ios": "^7.2.0",
+    "@capacitor/keyboard": "^7.0.1",
     "@capacitor/local-notifications": "^7.0.1",
     "@capacitor/push-notifications": "^7.0.1",
     "@capacitor/status-bar": "^7.0.1",

+ 256 - 202
src/views/im/chat/index.vue

@@ -1,232 +1,286 @@
 <template>
-    <div class="container">
-        <div class="chat-bg"></div>
-        <div class="header-chat">
-            <svg-icon class="page-icon" name="lf-arrow" @click="goBack"/>
-            <div class="header-title">群聊(8)</div>
-            <svg-icon class="page-icon" name="more"  @click="goDetail"/>
-        </div>
-        <div class="chat-list">
-            <div v-for="(item,index) in 2">
-                <div class="chat-time">23:{{ 20+index }}</div>
-                <div class="box" v-for="(text,i) in 10">
-                    <div class="list-item" :class="i % 2 === 0 ? '' : 'flex-reverse'">
-                        <van-image 
-                            class="list-img" 
-                            :class="i % 2 === 0 ? 'mr12' : 'ml12'" 
-                            round src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
-                            @click="router.push('personal')"/>
-                        <div class="list-cont">
-                            <div :class="i % 2 === 0 ? '' : 'text-right'">苏苏编号</div>
-                            <!-- 名片 -->
-                            <div class="business-card" v-if="i % 2 === 0">
-                                <div class="business-card-cont">
-                                    <van-image class="list-img mr12" round src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"/>
-                                    <div>名字名字</div>
-                                </div>
-                                <div class="line"></div>
-                                <div class="business-card-text">个人名片</div>
-                            </div>
-                            <!-- 文本信息 -->
-                            <div class="content" v-if="i % 2 !== 0">文本信息文本信息文本信息文本信息文本信息文本信息文本信息文本信息</div>
-                        </div>
-                    </div>
-                     <!--消息撤回 -->
-                     <div class="withdrawal">
-                        <div class="withdrawal-text">哈哈哈撤回了一条消息</div>
-                    </div>
+  <div class="container"  :style="{height: `calc(100% - ${keyboardHeight}px)` }"> 
+    <div class="chat-bg"></div>
+    <div class="header-chat">
+      <svg-icon class="page-icon" name="lf-arrow" @click="goBack" />
+      <div class="header-title">群聊2(8) </div>
+      <svg-icon class="page-icon" name="more" @click="goDetail" />
+    </div>
+    <div class="chat-list">
+      <div v-for="(item, index) in 2">
+        <div class="chat-time">23:{{ 20 + index }}</div>
+        <div class="box" v-for="(text, i) in 10">
+          <div class="list-item" :class="i % 2 === 0 ? '' : 'flex-reverse'">
+            <van-image
+              class="list-img"
+              :class="i % 2 === 0 ? 'mr12' : 'ml12'"
+              round
+              src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
+              @click="router.push('personal')"
+            />
+            <div class="list-cont">
+              <div :class="i % 2 === 0 ? '' : 'text-right'">苏苏编号</div>
+              <!-- 名片 -->
+              <div class="business-card" v-if="i % 2 === 0">
+                <div class="business-card-cont">
+                  <van-image
+                    class="list-img mr12"
+                    round
+                    src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
+                  />
+                  <div>名字名字</div>
                 </div>
+                <div class="line"></div>
+                <div class="business-card-text">个人名片</div>
+              </div>
+              <!-- 文本信息 -->
+              <div class="content" v-if="i % 2 !== 0">
+                文本信息文本信息文本信息文本信息文本信息文本信息文本信息文本信息
+              </div>
             </div>
+          </div>
+          <!--消息撤回 -->
+          <div class="withdrawal">
+            <div class="withdrawal-text">哈哈哈撤回了一条消息</div>
+          </div>
         </div>
-        <!-- 输入框 -->
-        <div class="page-foot">
-            <div class="flex-box">
-                <svg-icon class="page-icon" name="voice" />
-                <van-field 
-                    rows="1" 
-                    type="textarea" 
-                    :border="false" 
-                    autosize class="input" v-model="text" placeholder="输入文本"
-                />
-                <svg-icon class="page-icon mr12" name="emoji" />
-                <svg-icon class="page-icon" name="add2" />
-            </div>
-        </div>
+      </div>
     </div>
+    <!-- 输入框 -->
+    <div class="page-foot">
+      <div class="flex-box">
+        <svg-icon class="page-icon" name="voice" />
+        <van-field
+          rows="1"
+          type="textarea"
+          :border="false"
+          autosize
+          class="input"
+          v-model="text"
+          @focus="onFocus"
+          placeholder="输入文本" 
+        />
+        <svg-icon class="page-icon mr12" name="emoji" />
+        <svg-icon class="page-icon" name="add2" />
+      </div>
+    </div>
+  </div>
 </template>
 
-<script setup>
-import { useRouter } from 'vue-router'
-const router = useRouter();
+<script setup> 
+import { useRouter } from "vue-router";
+import { Keyboard } from '@capacitor/keyboard';
 
+const router = useRouter();
 
-const text = ref('')
+const text = ref("");
+const keyboardHeight = ref(10);
+  
 const goBack = () => {
-    router.push('im')
-}
+  router.push("im");
+};
 const goDetail = () => {
-    router.push('detail')
+  router.push("detail");
+};  
+
+const onFocus = () => { 
+  // 初始化
+  setupKeyboardListeners();
 }
+
+// 监听键盘事件
+const setupKeyboardListeners = async () => {
+  // 获取键盘高度(仅在键盘显示时有效)
+  Keyboard.addListener('keyboardWillShow', (info) => {
+    keyboardHeight.value = info.keyboardHeight
+  });
+  Keyboard.addListener('keyboardWillHide', () => {
+    console.log('键盘已隐藏'); 
+    keyboardHeight.value = 10;
+  });
+};
+
+
+onUnmounted(() => {
+  Keyboard.removeAllListeners();
+});
+
+
 </script>
 
 <style lang="less" scoped>
-.mr12{
-    margin-right: 12px;
+.mr12 {
+  margin-right: 12px;
 }
-.ml12{
-    margin-left: 12px;
+.ml12 {
+  margin-left: 12px;
 }
-.text-right{
-    text-align: right;
+.text-right {
+  text-align: right;
 }
-.page-icon{
-    width: 24px;
-    height: 24px;
-    flex-shrink: 0;
+.page-icon {
+  width: 24px;
+  height: 24px;
+  flex-shrink: 0;
 }
-.container{
-    height: 100%;
+.container {
+  // :style="{height: handleFocus }"
+  // height:   calc(100% - 10px); 
+  display: flex;
+  flex-direction: column;
+  .chat-bg {
+    height: 126px;
+    background: linear-gradient(90deg, @theme-color1 0%, #40a4fb 100%);
+    position: absolute;
+    left: 0;
+    right: 0;
+    z-index: -1;
+  }
+  .header-chat {
+    padding-top: 56px;
+    margin: 0 16px;
     display: flex;
-    flex-direction: column;
-    .chat-bg{
-        height: 126px;
-        background: linear-gradient( 90deg, @theme-color1 0%, #40A4FB 100%);
-        position: absolute;
-        left: 0;
-        right: 0;
-        z-index: -1;
+    align-items: center;
+    color: @theme-color1;
+    .header-title {
+      flex: 1;
+      font-family:
+        PingFang SC,
+        PingFang SC;
+      font-weight: 500;
+      font-size: 19px;
+      color: #ffffff;
+      text-align: center;
     }
-    .header-chat{
-        padding-top: 56px;
-        margin: 0 16px;
-        display: flex;
-        align-items: center;
-        color: @theme-color1;
-        .header-title{
-            flex: 1;
-            font-family: PingFang SC, PingFang SC;
-            font-weight: 500;
-            font-size: 19px;
-            color: #FFFFFF;
-            text-align: center;
-        }
+  }
+  .chat-list {
+    background: #f7f8fa;
+    border-radius: 30px 30px 0 0;
+    flex: 1;
+    overflow: auto;
+    margin-top: 20px;
+    padding: 0 16px 24px;
+    .chat-time {
+      font-family:
+        PingFang SC,
+        PingFang SC;
+      font-weight: 400;
+      font-size: 12px;
+      color: #8d8d8d;
+      text-align: center;
+      margin: 20px 0;
     }
-    .chat-list{
-        background: #F7F8FA;
-        border-radius: 30px 30px 0 0;
-        flex: 1;
-        overflow: auto;
-        margin-top: 20px;
-        padding:0 16px 24px;
-        .chat-time{
-            font-family: PingFang SC, PingFang SC;
-            font-weight: 400;
-            font-size: 12px;
-            color: #8D8D8D;
-            text-align: center;
-            margin: 20px 0;
+    .box {
+      .list-item {
+        display: flex;
+        margin-bottom: 24px;
+        .list-img {
+          width: 44px;
+          height: 44px;
+          flex-shrink: 0;
         }
-        .box{
-            .list-item{
-                display: flex;
-                margin-bottom: 24px;
-                .list-img{
-                    width: 44px;
-                    height: 44px;
-                    flex-shrink: 0;
-                }
-                .list-cont{
-                    font-family: PingFang SC, PingFang SC;
-                    font-weight: 400;
-                    font-size: 12px;
-                    color: #8D8D8D;
-                    .business-card{
-                        width: 199px;
-                        height: 93px;
-                        background: #FFFFFF;
-                        border-radius: 10px;
-                        margin-top: 8px;
-                        padding: 10px;
-                        box-sizing: border-box;
-                        .business-card-cont{
-                            display: flex;
-                            align-items: center;
-                            font-family: PingFang SC, PingFang SC;
-                            font-weight: 400;
-                            font-size: 15px;
-                            color: #000000;
-                        }
-                        .line{
-                            height: 1px;
-                            background: #F2F2F2;
-                            margin: 10px 0 6px;
-                        }
-                        .business-card-text{
-                            font-family: PingFang SC, PingFang SC;
-                            font-weight: 400;
-                            font-size: 10px;
-                            color: #8D8D8D;
-                        }
-                    }
-                    .content{
-                        max-width: 230px;
-                        background: #4D71FF;
-                        border-radius: 10px;
-                        margin-top: 8px;
-                        padding: 8px 17px;
-                        font-family: PingFang SC, PingFang SC;
-                        font-weight: 400;
-                        font-size: 15px;
-                        color: #FFFFFF;
-                    }
-                } 
+        .list-cont {
+          font-family:
+            PingFang SC,
+            PingFang SC;
+          font-weight: 400;
+          font-size: 12px;
+          color: #8d8d8d;
+          .business-card {
+            width: 199px;
+            height: 93px;
+            background: #ffffff;
+            border-radius: 10px;
+            margin-top: 8px;
+            padding: 10px;
+            box-sizing: border-box;
+            .business-card-cont {
+              display: flex;
+              align-items: center;
+              font-family:
+                PingFang SC,
+                PingFang SC;
+              font-weight: 400;
+              font-size: 15px;
+              color: #000000;
             }
-            .withdrawal{
-                display: flex;
-                justify-content: center;
-                margin-bottom: 24px;
-                .withdrawal-text{
-                    width: 142px;
-                    height: 29px;
-                    line-height: 29px;
-                    box-sizing: border-box;
-                    background: #F2F2F2;
-                    border-radius: 4px;
-                    font-family: PingFang SC, PingFang SC;
-                    font-weight: 400;
-                    font-size: 12px;
-                    color: #8D8D8D;
-                    text-align: center;
-                }
+            .line {
+              height: 1px;
+              background: #f2f2f2;
+              margin: 10px 0 6px;
             }
-            .flex-reverse{
-                flex-direction: row-reverse;
+            .business-card-text {
+              font-family:
+                PingFang SC,
+                PingFang SC;
+              font-weight: 400;
+              font-size: 10px;
+              color: #8d8d8d;
             }
+          }
+          .content {
+            max-width: 230px;
+            background: #4d71ff;
+            border-radius: 10px;
+            margin-top: 8px;
+            padding: 8px 17px;
+            font-family:
+              PingFang SC,
+              PingFang SC;
+            font-weight: 400;
+            font-size: 15px;
+            color: #ffffff;
+          }
         }
-    }
-    .chat-list::-webkit-scrollbar{
-        width: 0;
-    }
-    .page-foot{
-        position: relative;
-		background-color: #fff;
-        .flex-box {
-            padding: 8px 16px;
-			display: flex;
-			align-items: center;
-            box-sizing: border-box;
-            .input{
-                flex: 1;
-                background: #F2F2F2;
-                border-radius: 17px;
-                border: 1px solid #D8D8D8;
-                padding: 6px 16px;
-                font-weight: 500;
-                font-size: 15px;
-                margin: 0 12px;
-                overflow-y: auto;
-            }
+      }
+      .withdrawal {
+        display: flex;
+        justify-content: center;
+        margin-bottom: 24px;
+        .withdrawal-text {
+          width: 142px;
+          height: 29px;
+          line-height: 29px;
+          box-sizing: border-box;
+          background: #f2f2f2;
+          border-radius: 4px;
+          font-family:
+            PingFang SC,
+            PingFang SC;
+          font-weight: 400;
+          font-size: 12px;
+          color: #8d8d8d;
+          text-align: center;
         }
+      }
+      .flex-reverse {
+        flex-direction: row-reverse;
+      }
+    }
+  }
+  .chat-list::-webkit-scrollbar {
+    width: 0;
+  }
+  .page-foot {
+    position: relative;
+    background-color: #fff;
+    .flex-box {
+      padding: 8px 16px;
+      display: flex;
+      align-items: center;
+      box-sizing: border-box;
+      .input {
+        flex: 1;
+        background: #f2f2f2;
+        border-radius: 17px;
+        border: 1px solid #d8d8d8;
+        padding: 6px 16px;
+        font-weight: 500;
+        font-size: 15px;
+        margin: 0 12px;
+        overflow-y: auto;
+      }
     }
+  }
 }
-</style>
+</style>