mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-14 04:32:49 +00:00
perf: 优化聊天输入框
This commit is contained in:
parent
6823d87198
commit
cc125cc292
@ -47,8 +47,8 @@
|
|||||||
"openpgp_hi": "^5.7.0-1",
|
"openpgp_hi": "^5.7.0-1",
|
||||||
"photoswipe": "^5.2.8",
|
"photoswipe": "^5.2.8",
|
||||||
"postcss": "^8.4.5",
|
"postcss": "^8.4.5",
|
||||||
"quill": "^2.0.0-rc.5",
|
"quill-hitosea": "^2.0.0-rc.5.1",
|
||||||
"quill-mention-hi": "^4.0.0-2",
|
"quill-mention-hitosea": "^4.0.0-6",
|
||||||
"resolve-url-loader": "^4.0.0",
|
"resolve-url-loader": "^4.0.0",
|
||||||
"sass": "^1.71.1",
|
"sass": "^1.71.1",
|
||||||
"sass-loader": "^14.1.1",
|
"sass-loader": "^14.1.1",
|
||||||
|
|||||||
@ -40,7 +40,9 @@
|
|||||||
@paste="handlePaste"></div>
|
@paste="handlePaste"></div>
|
||||||
|
|
||||||
<!-- 工具栏占位 -->
|
<!-- 工具栏占位 -->
|
||||||
<div class="chat-space"></div>
|
<div class="chat-space">
|
||||||
|
<input class="space-input" @focus="onSpaceInputFocus"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 工具栏 -->
|
<!-- 工具栏 -->
|
||||||
<ul class="chat-toolbar" @click.stop>
|
<ul class="chat-toolbar" @click.stop>
|
||||||
@ -211,8 +213,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import Quill from 'quill';
|
import Quill from 'quill-hitosea';
|
||||||
import "quill-mention-hi";
|
import "quill-mention-hitosea";
|
||||||
import ChatEmoji from "./emoji";
|
import ChatEmoji from "./emoji";
|
||||||
import touchmouse from "../../../../directives/touchmouse";
|
import touchmouse from "../../../../directives/touchmouse";
|
||||||
import touchclick from "../../../../directives/touchclick";
|
import touchclick from "../../../../directives/touchclick";
|
||||||
@ -324,10 +326,11 @@ export default {
|
|||||||
|
|
||||||
emojiTimer: null,
|
emojiTimer: null,
|
||||||
scrollTimer: null,
|
scrollTimer: null,
|
||||||
selectTimer: null,
|
|
||||||
textTimer: null,
|
textTimer: null,
|
||||||
fileTimer: null,
|
fileTimer: null,
|
||||||
moreTimer: null,
|
moreTimer: null,
|
||||||
|
selectTimer: null,
|
||||||
|
selectRange: null,
|
||||||
|
|
||||||
fullInput: false,
|
fullInput: false,
|
||||||
fullQuill: null,
|
fullQuill: null,
|
||||||
@ -640,7 +643,7 @@ export default {
|
|||||||
keyboard: {
|
keyboard: {
|
||||||
bindings: {
|
bindings: {
|
||||||
'short enter': {
|
'short enter': {
|
||||||
key: 13,
|
key: "Enter",
|
||||||
shortKey: true,
|
shortKey: true,
|
||||||
handler: _ => {
|
handler: _ => {
|
||||||
if (!this.isEnterSend) {
|
if (!this.isEnterSend) {
|
||||||
@ -651,7 +654,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
'enter': {
|
'enter': {
|
||||||
key: 13,
|
key: "Enter",
|
||||||
shiftKey: false,
|
shiftKey: false,
|
||||||
handler: _ => {
|
handler: _ => {
|
||||||
if (this.isEnterSend) {
|
if (this.isEnterSend) {
|
||||||
@ -662,7 +665,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
'esc': {
|
'esc': {
|
||||||
key: 27,
|
key: "Escape",
|
||||||
shiftKey: false,
|
shiftKey: false,
|
||||||
handler: _ => {
|
handler: _ => {
|
||||||
if (this.emojiQuickShow) {
|
if (this.emojiQuickShow) {
|
||||||
@ -691,15 +694,15 @@ export default {
|
|||||||
|
|
||||||
// Mark model as touched if editor lost focus
|
// Mark model as touched if editor lost focus
|
||||||
this.quill.on('selection-change', range => {
|
this.quill.on('selection-change', range => {
|
||||||
if (!range && document.activeElement) {
|
if (range) {
|
||||||
// 修复光标会超出的问题
|
this.selectRange = range
|
||||||
if (['ql-editor', 'ql-clipboard'].includes(document.activeElement.className)) {
|
} else if (this.selectRange && document.activeElement && /(ql-editor|ql-clipboard)/.test(document.activeElement.className)) {
|
||||||
this.selectTimer && clearTimeout(this.selectTimer)
|
// 修复iOS光标会超出的问题
|
||||||
this.selectTimer = setTimeout(_ => {
|
this.selectTimer && clearTimeout(this.selectTimer)
|
||||||
this.quill.setSelection(document.activeElement.className === 'ql-editor' ? 0 : this.quill.getLength())
|
this.selectTimer = setTimeout(_ => {
|
||||||
}, 100)
|
this.quill.setSelection(this.selectRange.index, this.selectRange.length)
|
||||||
return
|
}, 100)
|
||||||
}
|
return
|
||||||
}
|
}
|
||||||
this.isFocus = !!range;
|
this.isFocus = !!range;
|
||||||
})
|
})
|
||||||
@ -765,8 +768,8 @@ export default {
|
|||||||
this.$nextTick(_ => {
|
this.$nextTick(_ => {
|
||||||
this.quill.root.addEventListener('keydown', e => {
|
this.quill.root.addEventListener('keydown', e => {
|
||||||
if (e.key === '\r\r' && e.keyCode === 229) {
|
if (e.key === '\r\r' && e.keyCode === 229) {
|
||||||
const length = this.quill.getSelection(true).index;
|
const {index} = this.quill.getSelection(true);
|
||||||
this.quill.insertText(length, "\r\n");
|
this.quill.insertText(index, "\r\n");
|
||||||
//
|
//
|
||||||
this.keyTimer && clearTimeout(this.keyTimer)
|
this.keyTimer && clearTimeout(this.keyTimer)
|
||||||
this.keyTimer = setTimeout(_ => {
|
this.keyTimer = setTimeout(_ => {
|
||||||
@ -950,7 +953,7 @@ export default {
|
|||||||
|
|
||||||
setContent(value) {
|
setContent(value) {
|
||||||
if (this.quill) {
|
if (this.quill) {
|
||||||
this.quill.setContents(this.quill.clipboard.convert(value))
|
this.quill.setContents(this.quill.clipboard.convert({html: value}))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1310,6 +1313,13 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onSpaceInputFocus() {
|
||||||
|
if (this.selectRange) {
|
||||||
|
// 修复Android光标会超出的问题
|
||||||
|
this.quill?.setSelection(this.selectRange.index, this.selectRange.length)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
openMenu(char) {
|
openMenu(char) {
|
||||||
if (!this.quill) {
|
if (!this.quill) {
|
||||||
return;
|
return;
|
||||||
@ -1330,7 +1340,10 @@ export default {
|
|||||||
if (!this.quill) {
|
if (!this.quill) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.quill.getModule("mention").insertItem(data, true);
|
const {index} = this.quill.getSelection(true);
|
||||||
|
this.quill.insertEmbed(index, "mention", data, Quill.sources.USER);
|
||||||
|
this.quill.insertText(index + 1, " ", Quill.sources.USER);
|
||||||
|
this.quill.setSelection(index + 2, Quill.sources.USER);
|
||||||
},
|
},
|
||||||
|
|
||||||
getProjectId() {
|
getProjectId() {
|
||||||
@ -1665,9 +1678,9 @@ export default {
|
|||||||
array.forEach(image => {
|
array.forEach(image => {
|
||||||
const t = new FileReader;
|
const t = new FileReader;
|
||||||
t.onload = ({target}) => {
|
t.onload = ({target}) => {
|
||||||
const length = this.quill.getSelection(true).index;
|
const {index} = this.quill.getSelection(true);
|
||||||
this.quill.insertEmbed(length, "image", target.result);
|
this.quill.insertEmbed(index, "image", target.result);
|
||||||
this.quill.setSelection(length + 1)
|
this.quill.setSelection(index + 1)
|
||||||
};
|
};
|
||||||
t.readAsDataURL(image)
|
t.readAsDataURL(image)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -501,7 +501,7 @@ export default {
|
|||||||
|
|
||||||
recordStyle(info) {
|
recordStyle(info) {
|
||||||
const {duration} = info;
|
const {duration} = info;
|
||||||
const width = 50 + Math.min(180, Math.floor(duration / 150));
|
const width = 50 + Math.min(180, Math.floor(duration / 200));
|
||||||
return {
|
return {
|
||||||
width: width + 'px',
|
width: width + 'px',
|
||||||
};
|
};
|
||||||
|
|||||||
12
resources/assets/sass/dark.scss
vendored
12
resources/assets/sass/dark.scss
vendored
@ -194,6 +194,12 @@ body.dark-mode-reverse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-position {
|
||||||
|
.position-label {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dialog-scroller {
|
.dialog-scroller {
|
||||||
.dialog-item {
|
.dialog-item {
|
||||||
.dialog-view {
|
.dialog-view {
|
||||||
@ -541,6 +547,12 @@ body.dark-mode-reverse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-input-record-transfer {
|
||||||
|
&.cancel {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ql-mention-list-container {
|
.ql-mention-list-container {
|
||||||
.ql-mention-list-item {
|
.ql-mention-list-item {
|
||||||
.mention-item-at {
|
.mention-item-at {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
@import "~quill/dist/quill.bubble.css";
|
@import "~quill-hitosea/dist/quill.bubble.css";
|
||||||
@import "~quill-mention-hi/dist/quill.mention.min.css";
|
@import "~quill-mention-hitosea/dist/quill.mention.min.css";
|
||||||
|
|
||||||
.chat-input-box {
|
.chat-input-box {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -224,6 +224,21 @@
|
|||||||
float: right;
|
float: right;
|
||||||
width: 170px;
|
width: 170px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
|
.space-input {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
background: transparent;
|
||||||
|
height: 1px;
|
||||||
|
width: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-toolbar {
|
.chat-toolbar {
|
||||||
|
|||||||
4
vite.config.js
vendored
4
vite.config.js
vendored
@ -49,8 +49,8 @@ export default defineConfig(({command, mode}) => {
|
|||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'~element-sea': resolve(__dirname, 'node_modules/element-sea'),
|
'~element-sea': resolve(__dirname, 'node_modules/element-sea'),
|
||||||
'~quill': resolve(__dirname, 'node_modules/quill'),
|
'~quill-hitosea': resolve(__dirname, 'node_modules/quill-hitosea'),
|
||||||
'~quill-mention-hi': resolve(__dirname, 'node_modules/quill-mention-hi'),
|
'~quill-mention-hitosea': resolve(__dirname, 'node_modules/quill-mention-hitosea'),
|
||||||
'../images': resolve(__dirname, command === 'serve' ? '/images' : 'resources/assets/statics/public/images'),
|
'../images': resolve(__dirname, command === 'serve' ? '/images' : 'resources/assets/statics/public/images'),
|
||||||
'../css': resolve(__dirname, command === 'serve' ? '/css' : 'resources/assets/statics/public/css')
|
'../css': resolve(__dirname, command === 'serve' ? '/css' : 'resources/assets/statics/public/css')
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user