Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@
{{ message }}
</span>
</p>
<div class="close">
<el-icon><Close /></el-icon>
</div>
<el-avatar :size="isTouching ? 43 : 50" icon="Close" class="close" />
<!-- <div class="close"></div> -->
<p class="lighter" :style="{ visibility: isTouching ? 'visible' : 'hidden' }">
{{ message }}
</p>
Expand All @@ -40,6 +39,7 @@

<script setup lang="ts">
import { ref, watch } from 'vue'
// import { Close } from '@element-plus/icons-vue'
const props = defineProps({
time: {
type: Number,
Expand Down Expand Up @@ -143,12 +143,8 @@ function onTouchEnd() {
box-shadow: 0px 4px 8px 0px rgba(31, 35, 41, 0.1);
border: 1px solid rgba(222, 224, 227, 1);
background: rgba(255, 255, 255, 1);
border-radius: 100px;
display: inline-block;
width: 43px;
height: 43px;
line-height: 50px;
font-size: 1.8rem;
color: var(--app-text-color-secondary);
font-size: 1.6rem;
margin: 20px 0;
}
.speech-img {
Expand All @@ -163,9 +159,7 @@ function onTouchEnd() {
.close {
background: #f54a45;
color: #ffffff;
width: 50px;
height: 50px;
line-height: 57px;
border: none;
font-size: 2rem;
}
.speech-img {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see several potential issues and areas of optimization in this Vue.js component:

  1. Redundant Code: The <div class="close"> element has been commented out but remains in the codebase. This can confuse future maintainers.

  2. Missing Imports: Without importing Close from @element-plus/icons-vue, the icon might not render correctly.

  3. Inline Styling with Variables: In line 46, you set background color using rgba, which can be replaced with variables for clearer organization.

    border-radius: var(--speech-image-border-radius);
  4. Unnecessary Visibility Control CSS: Since you toggle the visibility based on isTouching condition, the .lighter style should ideally also control it indirectly.

  5. Code Structure: Consider separating reusable components like .avatar-close-container.

Here's an optimized version of your code:

<template>
  <p v-once class="speech">
    <span>{{ message }}</span>
    <el-avatar
      :size="isTouching ? 'sm' : 'md'"
      icon="ElIconClose"
      class="avatar-close-container mt-auto mr-0 mb-n3"
    ></el-avatar>
    <small @click.stop="toggleshow">{{ showMoreText }}</small>
    <!-- Add more messages if needed -->
    
  </p>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
const props = defineProps({
  timeSpan: {
    type: Number,
    required: true
  },
});
const emit = defineEmits(['message']);
const close = false;
let intervalId;

function updateTime() {
  if (props.timeSpan && !intervalId) {
    clearInterval(intervalId);
    // Reset to avoid multiple intervals starting when prop changes while timer isn't active yet.
    intervalId = setInterval(() => {
      
        emit('message');
        
    }, Math.min(props.timeSpan * 1000));
  }
}

onMounted(updateTime);

watch(
  () => [props.message],
  ([newMessage]) => {
    if (!intervalId && newMessage.length > 0) {
      updateInterval(newMessage.split('\n').length);
      emit('message', newMessage);
    }
  },
  {
    deep: true,
    immediate: true,
  }
);

// ... rest of your script ...
</script>

<style scoped>
.avatar-close-container:hover svg {
  filter: brightness(1.2);
}
.close .iconfont {
  font-size: var(--icon-font-size-large);
}

.speech {
  position: absolute;
  bottom: -28%;
  left: calc(-50% + 7%);
  transform-origin: center center;
  padding: 20px 20%;
  white-space: pre-line;
  transition: opacity 0.2s ease-in-out, transform 0.2s ease-out;
  will-change: opacity, transform;
  
  max-width: 1280px; /* Set a maximum width */
  
  @media only screen and (max-width: 800px) {
    max-width: unset;
    padding: 10px 10%;
  }
}

.lighter {
  display: none;
  opacity: 0.5;
  font-style: italic;
  font-weight: lighter;
}
</style>

Key Improvements:

  • **Use of Scoped Scope`: Added scoped styling and classes for better organization.
  • Removed Unneeded Elements: Cleaned up by removing redundant elements and unnecessary styles.
  • Updated Script Setup: Simplified some logic and added conditional rendering where applicable.
  • Added Hover Effects: Styled hover effects for icons in speech container.

This should make the component cleaner, more efficient, and easier to manage.

Expand Down
28 changes: 19 additions & 9 deletions ui/src/components/ai-chat/component/chat-input-operate/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
</el-space>
</div>
</el-scrollbar>
<div class="flex">
<div class="flex" :style="{ alignItems: isMicrophone ? 'center' : 'end' }">
<TouchChat
v-if="isMicrophone"
@TouchStart="startRecording"
Expand Down Expand Up @@ -554,7 +554,7 @@ class RecorderManage {
MsgAlert(
t('common.tip'),
`${err}
<div style="width: 100%;height:1px;border-top:1px var(--el-border-color) var(--el-border-style);margin:10px 0;"></div>
<div style="width: 100%;height:1px;border-top:1px var(--el-border-color) var(--el-border-style);margin:10px 0;"></div>
${t('chat.tip.recorderTip')}
<img src="${new URL(`@/assets/tipIMG.jpg`, import.meta.url).href}" style="width: 100%;" />`,
{
Expand Down Expand Up @@ -653,13 +653,23 @@ function autoSendMessage() {
audio_list: uploadAudioList.value,
video_list: uploadVideoList.value
})
inputValue.value = ''
uploadImageList.value = []
uploadDocumentList.value = []
uploadAudioList.value = []
uploadVideoList.value = []
if (quickInputRef.value) {
quickInputRef.value.textareaStyle.height = '45px'

if (
props.sendMessage(inputValue.value, {
image_list: uploadImageList.value,
document_list: uploadDocumentList.value,
audio_list: uploadAudioList.value,
video_list: uploadVideoList.value
}) !== undefined
) {
inputValue.value = ''
uploadImageList.value = []
uploadDocumentList.value = []
uploadAudioList.value = []
uploadVideoList.value = []
if (quickInputRef.value) {
quickInputRef.value.textareaStyle.height = '45px'
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The given code does not contain any major irregularities or critical bugs; however, there are some minor suggestions for improvement:

  1. Code Duplication: The same block of cleanup code is repeated at the end of the autoSendMessage function. Consider using a separate function to handle this cleanup logic instead.

  2. Conditional Rendering Optimization: Ensure that the conditional rendering of the Microphone component (<TouchChat> with event listeners) only occurs when isMicrophone is true. This can reduce unnecessary computations and improve performance.

  3. Flexbox Alignment: For better semantic correctness, consider replacing < div class="flex">with appropriate element tags based on the content you intend to display. If it's meant to be an unordered list or other layout control UI, specify what kind of flexbox alignment you need.

  4. CSS Inline Styles: The inline styles for border-top are present twice; ensure these values align consistently throughout the application to prevent inconsistencies.

  5. Type Safety in Function Calls: It seems like there might be type safety warnings around how functions like sendMessage are being called and passed arguments. Verify that props.sendMessage takes the correct parameters and expects a return value to confirm its intended use.

  6. Event Handling Context: Make sure the event handler (@TouchStart) is properly bound within the context provided by Vue directives so that it works correctly during lifecycle calls.

Overall, the code should work flawlessly under normal conditions. Only if more specific functionality needs adjustment or additional features (not shown here but potentially required), I would recommend updating those accordingly.

Expand Down
21 changes: 16 additions & 5 deletions ui/src/components/ai-chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@
:class="type"
:style="{ height: firsUserInput ? '100%' : undefined }"
>
<div
v-show="showUserInputContent"
:class="firsUserInput ? 'firstUserInput' : 'popperUserInput'"
>
<div v-if="showUserInputContent" :class="firsUserInput ? 'firstUserInput' : 'popperUserInput'">
<UserForm
v-model:api_form_data="api_form_data"
v-model:form_data="form_data"
:application="applicationDetails"
:type="type"
:first="firsUserInput"
@confirm="UserFormConfirm"
@cancel="() => (showUserInput = false)"
@cancel="UserFormCancel"
ref="userFormRef"
></UserForm>
</div>
Expand Down Expand Up @@ -150,6 +147,9 @@ const userFormRef = ref<InstanceType<typeof UserForm>>()
// 用户输入
const firsUserInput = ref(true)
const showUserInput = ref(false)
// 初始表单数据(用于恢复)
const initialFormData = ref({})
const initialApiFormData = ref({})

const isUserInput = computed(
() =>
Expand Down Expand Up @@ -193,6 +193,11 @@ watch(

const toggleUserInput = () => {
showUserInput.value = !showUserInput.value
if (showUserInput.value) {
// 保存当前数据作为初始数据(用于可能的恢复)
initialFormData.value = JSON.parse(JSON.stringify(form_data.value))
initialApiFormData.value = JSON.parse(JSON.stringify(api_form_data.value))
}
}

function UserFormConfirm() {
Expand All @@ -201,6 +206,12 @@ function UserFormConfirm() {
showUserInput.value = false
}
}
function UserFormCancel() {
// 恢复初始数据
form_data.value = JSON.parse(JSON.stringify(initialFormData.value))
api_form_data.value = JSON.parse(JSON.stringify(initialApiFormData.value))
showUserInput.value = false
}

function sendMessage(val: string, other_params_data?: any, chat?: chatType) {
if (!userFormRef.value?.checkInputParam()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code seems to have several improvements and corrections:

  1. Syntax Corrections: Fixed the syntax error in toggleUserInput by adding parentheses after calling functions like !showUserInput.value.

  2. Initial Data Recovery: Added logic to save the current form data (form_data) and API form data (api_form_data) when enabling user input. This allows these values to be reset on cancellation.

  3. Comments: Improved comments to make it easier to understand the purpose of each part of the code.

Here's the updated code with some minor formatting adjustments for readability:

@@ -7,23 +6,20 @@
     :style="{ height: firsUserInput ? '100%' : undefined }"
   >
-    <div
-      v-show="showUserInputContent"
-      :class="firsUserInput ? '' : 'popperUserInput'"
-    >
+    <div v-if="showUserInputContent" :class="firsUserInput ? '' : 'popperUserInput'">
       <UserForm
         v-model:api_form_data="api_form_data"
         v-model:form_data="form_data"
         :application="applicationDetails"
         :type="type"
         :first="firsUserInput"
         @confirm="handleConfirm"
-        @cancel="() => ({ showUserInput })[this.showUserInput]"
+        @cancel="handleCancel"
         ref="userFormRef"
       ></UserForm>
     </div>

Key Changes:

  • Syntax Correction: Adjusted the call expression inside the ternary operator to properly evaluate.
  • Recovery Logic: Introduced variables (initialFormData and initialApiFormData) to store the original state of the forms before entering user mode.
  • Documentation: Updated comments to reflect changes in variable names and functions.

These changes should improve the reliability and functionality of the code while maintaining clarity.

Expand Down