wkw 1 сар өмнө
parent
commit
e0f9611e97
1 өөрчлөгдсөн 176 нэмэгдсэн , 36 устгасан
  1. 176 36
      src/views/im/chat/index.vue

+ 176 - 36
src/views/im/chat/index.vue

@@ -82,6 +82,27 @@
               <!-- 语音消息 -->
               <div class="content" v-if="item.contentType === Constant.REJECT_AUDIO_ONLINE || item.contentType === Constant.REJECT_VIDEO_ONLINE">[对方拒绝]</div>
               <div class="content" v-if="item.contentType === Constant.CANCELL_AUDIO_ONLINE || item.contentType === Constant.CANCELL_VIDEO_ONLINE">[通话结束]</div>
+              <div class="quotation">引用消息</div>
+              <!-- 阅后即焚消息 -->
+              <div
+                class="burn-message"
+                @click="openBurnMessage(item)"
+              >
+                <!-- 未查看 -->
+                <div v-if="!item.viewed && !item.destroyed" class="burn-mask">
+                  🔒 阅后即焚,点击查看
+                </div>
+
+                <!-- 已查看但未销毁 -->
+                <div v-else-if="item.viewed && !item.destroyed" class="burn-content">
+                  {{ item.content }}
+                  <span class="burn-countdown">{{ item.countdown }}s</span>
+                </div>
+
+                <!-- 已焚毁 -->
+                <div v-else class="burn-destroyed">🔥 该消息已焚毁</div>
+              </div>
+
             </div>
           </div>
         </div>
@@ -101,7 +122,11 @@
       cancel-text="取消"
       @select="onActionSelect"
     />
-
+    <!-- 引用消息展示 -->
+    <div v-if="quoteMsg" class="quote-box">
+      <div class="quote-content">{{ quoteMsg.fromUsername}}:{{ renderQuoteContent(quoteMsg) }}</div>
+      <span class="quote-close" @click="cancelQuote">✕</span>
+    </div>
     <!-- 输入框 -->
     <div class="page-foot">
       <div class="flex-box">
@@ -114,32 +139,34 @@
         />
 
         <!-- 文字输入框 或 按住说话按钮 -->
-        <template v-if="!voiceMode">
-          <van-field
-            rows="1"
-            type="textarea"
-            :border="false"
-            autosize
-            class="input"
-            v-model="text"
-            @focus="onFocus"
-            placeholder="输入文本"
-            @keypress="handleKeyPress"
-            @keyup.enter="sendMessage"
-          />
-          <!-- :disabled="deletefriend.includes(wsStore.toUserInfo.uuid)" -->
-        </template>
+        <div class="box-input">
+          <template v-if="!voiceMode">
+            <van-field
+              rows="1"
+              type="textarea"
+              :border="false"
+              autosize
+              class="input"
+              v-model="text"
+              @focus="onFocus"
+              placeholder="输入文本"
+              @keypress="handleKeyPress"
+              @keyup.enter="sendMessage"
+            />
+            <!-- :disabled="deletefriend.includes(wsStore.toUserInfo.uuid)" -->
+          </template>
 
-        <template v-else>
-          <div
-            class="hold-talk-btn"
-            @touchstart.prevent.stop="handleTouchStart"
-            @touchmove.prevent.stop="handleTouchMove"
-            @touchend.prevent.stop="handleTouchEnd"
-          >
-            {{ cancelRecording ? "松开手指,取消发送" : "按住说话" }}
-          </div>
-        </template>
+          <template v-else>
+            <div
+              class="hold-talk-btn"
+              @touchstart.prevent.stop="handleTouchStart"
+              @touchmove.prevent.stop="handleTouchMove"
+              @touchend.prevent.stop="handleTouchEnd"
+            >
+            按住说话
+            </div>
+          </template>
+        </div>
         <svg-icon
           class="page-icon mr12 emoji-toggle"
           name="emoji"
@@ -151,18 +178,12 @@
           @click="toggleAppBox(2)"
         />
       </div>
-
       <!-- 录音状态浮层 -->
-      <!-- <div v-if="recording" class="recording-toast">
-        <div v-if="cancelRecording" class="cancel-msg">松开手指,取消发送</div>
-        <div v-else class="send-msg">松开发送,上滑取消</div>
-      </div> -->
       <div v-if="recording" class="recording-toast">
         <div class="mic-icon"></div>
         <div v-if="cancelRecording" class="cancel-msg">松开手指,取消发送</div>
         <div v-else class="send-msg">手指上滑,取消发送</div>
       </div>
-
       <!-- 表情面板 -->
       <div
         class="app-box"
@@ -219,6 +240,10 @@
           <svg-icon class="tool-icon" name="mp" />
           <div>名片</div>
         </div> -->
+        <div class="tool-btn">
+          <svg-icon class="tool-icon" name="mp" />
+          <div>阅后即焚</div>
+        </div>
       </div>
     </div>
 
@@ -258,7 +283,8 @@ const appBoxHeight = ref(210);
 const chatListRef = ref(null);
 const emojiRef = ref(null);
 const toolsRef = ref(null);
-const deletefriend = ref([])
+const deletefriend = ref([]);
+const quoteMsg = ref(null);// 当前引用的消息
 // 表情数组
 const emojis = [
   "😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣",
@@ -320,6 +346,7 @@ const toggleAppBox = async (type) => {
     showToast(`${wsStore.toUserInfo.type == 'user' ? '对方已删除' : '您已不在群聊里面'}`);
     return;
   }
+  voiceMode.value = false;
   if (isMobile) await Keyboard.hide();
   keyboardHeight.value = 0;
   if (type === 1) {
@@ -478,6 +505,7 @@ const showActionSheet = ref(false)
 const actions = [
   { name: "复制", key: "copy" },
   { name: "撤回", key: "revoke" },
+  { name: "引用", key: "quote" }
 ];
 const onLongPress = (msg) => {
   currentMsg.value = msg;
@@ -500,9 +528,29 @@ const onActionSelect = (action) => {
     };
     wsStore.sendMessage(message);
     currentMsg.value.revoked = true;
+  }else if(action.key === "quote"){
+    // 引用
+    quoteMsg.value = currentMsg.value; // 设置引用
+    console.log(quoteMsg.value)
   }
   showActionSheet.value = false;
 };
+// 取消引用
+const cancelQuote = () => {
+  quoteMsg.value = null;
+};
+// 渲染引用的内容(文字/图片等)
+const renderQuoteContent = (msg) => {
+  if (msg.contentType === MSG_TYPE.TEXT) {
+    return msg.content;
+  } else if (msg.contentType === MSG_TYPE.IMAGE) {
+    return "[图片]";
+  } else if (msg.contentType === MSG_TYPE.AUDIO) {
+    return "[语音]";
+  } else {
+    return "[消息]";
+  }
+};
 
 // 发送消息
 const sendMessage = () => {
@@ -857,10 +905,14 @@ const goNoticePage = () => {
     position: relative;
     background-color: #fff;
     .flex-box {
-      padding: 8px 16px 20px;
+      padding: 8px 16px 16px;
       display: flex;
       align-items: center;
       box-sizing: border-box;
+      .box-input{
+        flex: 1;
+        margin: 0 12px;
+      }
       .input {
         flex: 1;
         background: #f2f2f2;
@@ -869,7 +921,7 @@ const goNoticePage = () => {
         padding: 6px 16px;
         font-weight: 500;
         font-size: 15px;
-        margin: 0 12px;
+        // margin: 0 12px;
         overflow-y: auto;
       }
     }
@@ -952,7 +1004,7 @@ const goNoticePage = () => {
   user-select: none;
   -webkit-user-select: none;
   -webkit-touch-callout: none;
-  margin: 0 12px;
+  // margin: 0 12px;
   line-height: 24px;
   border: 1px solid #f5f5f5;
 }
@@ -1031,4 +1083,92 @@ const goNoticePage = () => {
   color: red;
   margin-left: 6px;
 }
+// 引用样式
+.quote-box {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  background: #f2f2f2;
+  border-radius: 6px;
+  padding: 4px 16px;
+  // margin-bottom: 6px;
+  font-size: 14px;
+  color: #969696;
+  font-size: 12px;
+}
+.quote-content {
+  margin-bottom: 2px;
+}
+.quotation{
+  background: #f2f2f2;
+  border-radius: 5px;
+  padding: 5px 10px;
+  margin-top: 5px;
+}
+// 阅后即焚样式
+.burn-message {
+  background: #fff;
+  color: #000;
+  border-radius: 10px;
+  margin-top: 8px;
+  padding: 8px 14px;
+  max-width: 100%;
+  font-size: 15px;
+  position: relative;
+  cursor: pointer;
+  word-break: break-word;
+  white-space: pre-wrap;
+  transition: all 0.3s ease;
+
+  &.self {
+    background: #4d71ff;
+    color: #fff;
+  }
+
+  .burn-mask {
+    text-align: center;
+    color: #999;
+    font-size: 14px;
+    filter: blur(0px);
+  }
+
+  .burn-content {
+    animation: fadeIn 0.3s ease-in;
+    position: relative;
+
+    .burn-countdown {
+      font-size: 12px;
+      color: #ff5b5b;
+      margin-left: 6px;
+    }
+  }
+
+  .burn-destroyed {
+    color: #999;
+    font-size: 13px;
+    text-align: center;
+    animation: fadeOut 1s forwards;
+  }
+}
+
+@keyframes fadeIn {
+  from {
+    opacity: 0;
+    transform: scale(0.95);
+  }
+  to {
+    opacity: 1;
+    transform: scale(1);
+  }
+}
+
+@keyframes fadeOut {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+    height: 0;
+  }
+}
 </style>