auto resize the input element rows, when use inputed more than one line

This commit is contained in:
RockYang 2024-05-21 17:36:47 +08:00
parent bee19392c1
commit 7f1ec90748
3 changed files with 125 additions and 82 deletions

View File

@ -1,6 +1,7 @@
# 更新日志 # 更新日志
## v4.0.8 ## v4.0.8
* 功能优化:当数据库更新失败的时候记录错误日志 * 功能优化:当数据库更新失败的时候记录错误日志
* 功能优化:聊天输入框会随着输入内容的增多自动调整高度
## v4.0.7 ## v4.0.7

View File

@ -129,7 +129,7 @@ $borderColor = #4676d0;
--el-main-padding: 0; --el-main-padding: 0;
margin: 0; margin: 0;
.chat-box { .chat-container {
min-width: 0; min-width: 0;
flex: 1; flex: 1;
background-color: var(--el-bg-color) background-color: var(--el-bg-color)
@ -138,6 +138,7 @@ $borderColor = #4676d0;
#container { #container {
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
position relative
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 0; width: 0;
@ -165,8 +166,13 @@ $borderColor = #4676d0;
} }
.input-box { .input-box {
position absolute
bottom 0
width 100%
.input-box-inner {
display flex
background-color: #ffffff background-color: #ffffff
display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
@ -192,7 +198,7 @@ $borderColor = #4676d0;
} }
} }
.input-container { .input-body {
width 100% width 100%
margin: 0; margin: 0;
border: none; border: none;
@ -201,24 +207,42 @@ $borderColor = #4676d0;
justify-content center justify-content center
position relative position relative
.el-textarea { .hide-div {
.el-textarea__inner::-webkit-scrollbar { white-space: pre-wrap; /* */
visibility: hidden; /* div */
position: absolute; /* */
line-height: 24px
font-size 14px
word-wrap: break-word; /* */
overflow-wrap: break-word; /* */
}
.input-border {
display flex
width 100%
overflow hidden
border: 2px solid #21AA93
border-radius 10px
padding 10px
.prompt-input::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;
} }
}
.select-file { .prompt-input {
position absolute; width 100%
right 48px; line-height: 24px
top 20px; border none
font-size 14px
background none
resize: none
} }
.send-btn { .send-btn {
position absolute; width 32px
right 12px; margin-left 10px
top 20px;
.el-button { .el-button {
padding 8px 5px; padding 8px 5px;
border-radius 6px; border-radius 6px;
@ -230,6 +254,9 @@ $borderColor = #4676d0;
} }
} }
}
}
#container::-webkit-scrollbar { #container::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;

View File

@ -65,9 +65,9 @@
</div> </div>
</el-aside> </el-aside>
<el-main v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.3)"> <el-main v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.3)">
<div class="chat-box" :style="{height: mainWinHeight+'px'}"> <div class="chat-container">
<div> <div>
<div id="container"> <div id="container" :style="{height: mainWinHeight+'px'}">
<div class="chat-box" id="chat-box" :style="{height: chatBoxHeight+'px'}"> <div class="chat-box" id="chat-box" :style="{height: chatBoxHeight+'px'}">
<div v-if="showHello"> <div v-if="showHello">
<welcome @send="autofillPrompt"/> <welcome @send="autofillPrompt"/>
@ -84,8 +84,8 @@
</div> </div>
</div><!-- end chat box --> </div><!-- end chat box -->
<el-affix position="bottom" :offset="0">
<div class="input-box"> <div class="input-box">
<div class="input-box-inner">
<span class="tool-item"> <span class="tool-item">
<el-popover <el-popover
:width="300" :width="300"
@ -151,19 +151,19 @@
</el-tooltip> </el-tooltip>
</span> </span>
<div class="input-container"> <div class="input-body">
<el-input <div ref="textHeightRef" class="hide-div">{{prompt}}</div>
ref="textInput" <div class="input-border">
<textarea
ref="inputRef"
class="prompt-input"
:rows="row"
v-model="prompt" v-model="prompt"
v-on:keydown="inputKeyDown" @keydown="onInput"
autofocus @input="onInput"
type="textarea"
:rows="2"
style="--el-input-focus-border-color:#21AA93;
border: 1px solid #21AA93;--el-input-border-color:#21AA93;
border-radius: 5px; --el-input-hover-border-color:#21AA93;"
placeholder="按 Enter 键发送消息,使用 Ctrl + Enter 换行" placeholder="按 Enter 键发送消息,使用 Ctrl + Enter 换行"
/> autofocus>
</textarea>
<span class="send-btn"> <span class="send-btn">
<el-button type="info" v-if="showStopGenerate" @click="stopGenerate" plain> <el-button type="info" v-if="showStopGenerate" @click="stopGenerate" plain>
<el-icon> <el-icon>
@ -175,8 +175,10 @@
</el-button> </el-button>
</span> </span>
</div> </div>
</div>
</div><!-- end input box --> </div><!-- end input box -->
</el-affix> </div>
</div><!-- end container --> </div><!-- end container -->
</div><!-- end loading --> </div><!-- end loading -->
</div> </div>
@ -237,11 +239,13 @@ const roleId = ref(0)
const newChatItem = ref(null); const newChatItem = ref(null);
const isLogin = ref(false) const isLogin = ref(false)
const showHello = ref(true) const showHello = ref(true)
const textInput = ref(null) const inputRef = ref(null)
const textHeightRef = ref(null)
const showNotice = ref(false) const showNotice = ref(false)
const notice = ref("") const notice = ref("")
const noticeKey = ref("SYSTEM_NOTICE") const noticeKey = ref("SYSTEM_NOTICE")
const store = useSharedStore(); const store = useSharedStore();
const row = ref(1)
if (isMobile()) { if (isMobile()) {
router.replace("/mobile/chat") router.replace("/mobile/chat")
@ -705,8 +709,19 @@ const enableInput = () => {
showStopGenerate.value = false; showStopGenerate.value = false;
} }
// const onInput = (e) => {
const inputKeyDown = function (e) { //
const lineHeight = parseFloat(window.getComputedStyle(inputRef.value).lineHeight)
textHeightRef.value.style.width = inputRef.value.clientWidth + 'px'; // textarea
const lines = Math.floor(textHeightRef.value.clientHeight / lineHeight);
inputRef.value.scrollTo(0, inputRef.value.scrollHeight)
if (prompt.value.length === 0) {
row.value = 1
} else if (row.value <= 7) {
row.value = lines
}
//
if (e.keyCode === 13) { if (e.keyCode === 13) {
if (e.ctrlKey) { // Ctrl + Enter if (e.ctrlKey) { // Ctrl + Enter
prompt.value += "\n"; prompt.value += "\n";
@ -720,7 +735,7 @@ const inputKeyDown = function (e) {
// prompt // prompt
const autofillPrompt = (text) => { const autofillPrompt = (text) => {
prompt.value = text prompt.value = text
textInput.value.focus() inputRef.value.focus()
// sendMessage() // sendMessage()
} }
// //