perf: 优化聊天窗口样式

This commit is contained in:
kuaifan 2022-05-25 09:20:47 +08:00
parent 85a9e33de1
commit fc5ce7c5db
5 changed files with 140 additions and 26 deletions

35
resources/assets/js/directives/touchmouse.js vendored Executable file
View File

@ -0,0 +1,35 @@
const isSupportTouch = "ontouchend" in document;
export default {
bind (el, binding) {
let isMove = false;
el.__touchMouseDown__ = e => {
isMove = false;
e.preventDefault();
};
el.__touchMouseMove__ = _ => {
isMove = true;
};
el.__touchMouseUp__ = e => {
if (isMove) {
return;
}
if (binding.expression) {
binding.value(e);
}
};
el.addEventListener(isSupportTouch ? 'touchstart' : 'mousedown', el.__touchMouseDown__);
el.addEventListener(isSupportTouch ? 'touchmove' : 'mousemove', el.__touchMouseMove__);
el.addEventListener(isSupportTouch ? 'touchend' : 'mouseup', el.__touchMouseUp__);
},
update () {
},
unbind (el) {
el.removeEventListener(isSupportTouch ? 'touchstart' : 'mousedown', el.__touchMouseDown__);
el.removeEventListener(isSupportTouch ? 'touchmove' : 'mousemove', el.__touchMouseMove__);
el.removeEventListener(isSupportTouch ? 'touchend' : 'mouseup', el.__touchMouseUp__);
delete el.__touchMouseDown__;
delete el.__touchMouseMove__;
delete el.__touchMouseUp__;
}
};

View File

@ -40,10 +40,12 @@
</div>
</EPopover>
<div class="toolbar-spacing"></div>
<Loading v-if="loading"/>
<ETooltip v-else placement="top" :disabled="!$isDesktop" :content="$L('发送')"><Icon :class="[value ? '' : 'disabled']" type="md-send" @click="send"/></ETooltip>
<ETooltip placement="top" :disabled="!$isDesktop" :content="$L('发送')">
<div class="chat-send" :class="[value ? '' : 'disabled']" v-touchmouse="send">
<Loading v-if="loading"/>
<Icon v-else type="md-send"/>
</div>
</ETooltip>
<slot name="toolbarAfter"/>
</div>
@ -51,15 +53,16 @@
</template>
<script>
import {mapGetters, mapState} from "vuex";
import {mapState} from "vuex";
import Quill from 'quill';
import "quill-mention";
import ChatEmoji from "./emoji";
import touchmouse from "../../../../directives/touchmouse";
export default {
name: 'ChatInput',
components: {ChatEmoji},
directives: {touchmouse},
props: {
dialogId: {
type: Number,
@ -87,7 +90,9 @@ export default {
},
enterSend: {
type: Boolean,
default: true
default: () => {
return $A.$isDesktop
}
},
options: {
type: Object,
@ -337,14 +342,26 @@ export default {
}
let html = this.$refs.editor.children[0].innerHTML
html = html.replace(/^(<p><br><\/p>)+|(<p><br><\/p>)+$/gi, '')
const quill = this.quill
const text = this.quill.getText()
this._content = html
this.$emit('input', this._content)
this.$emit('on-change', { html, text, quill })
this.$nextTick(_ => {
const range = this.quill.getSelection();
if (range) {
const endText = this.quill.getText(range.index);
/\n\n/.test(endText) && this.quill.deleteText(range.index, 1);
}
})
})
// Emit ready event
// Clipboard Matcher ()
this.quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
delta.ops = delta.ops.map(op => ({
insert: op.insert
}))
return delta
})
// Ready event
this.$emit('on-ready', this.quill)
},
@ -390,6 +407,9 @@ export default {
},
send() {
if (this.loading) {
return;
}
this.$emit('on-send')
},

View File

@ -72,6 +72,7 @@
</div>
</div>
<Badge class="dialog-num" :count="$A.getDialogUnread(dialog)"/>
<div class="dialog-split"></div>
</li>
</ul>
<ul v-else class="contacts">

View File

@ -221,16 +221,6 @@
width: 170px;
height: 28px;
padding: 0 2px;
.common-loading {
width: 18px;
height: 18px;
}
.toolbar-spacing {
width: 1px;
height: 14px;
margin: 2px 7px 0;
background-color: #cccccc;
}
> i {
display: inline-block;
cursor: pointer;
@ -240,8 +230,73 @@
&.disabled {
opacity: 0.5;
}
&:last-child {
margin-right: -5px;
}
.chat-send {
display: flex;
align-items: center;
justify-content: flex-end;
cursor: pointer;
font-size: 20px;
padding-right: 16px;
margin: 0 -16px 0 7px;
height: 48px;
width: 48px;
position: relative;
.common-loading {
width: 18px;
height: 18px;
padding: 0;
margin: 0 1px;
}
> i {
position: static;
z-index: 2;
display: flex;
align-items: center;
height: 100%;
color: #ffffff;
transition: all 0.3s;
}
&:after {
position: absolute;
content: "";
left: 0;
z-index: 1;
width: 1px;
height: 14px;
background-color: #cccccc;
transition: all 0.3s ease;
transform: scale(0);
opacity: 0;
}
&:before {
position: absolute;
content: "";
left: 2px;
z-index: 1;
border-radius: 50%;
background-color: #8bcf70;
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
transition: all 0.3s ease;
transform: scale(1);
opacity: 1;
}
&.disabled {
> i {
color: rgba($primary-text-color, 0.5);
}
&:after {
transform: scale(1);
opacity: 1;
}
&:before {
transform: scale(0);
opacity: 0;
}
}
}
.el-tooltip.taskfont {

View File

@ -219,6 +219,9 @@
left: 42px;
transform: scale(0.8);
}
.dialog-split {
display: none;
}
&.top {
background-color: #EEEFF1;
}
@ -432,8 +435,8 @@
> ul {
&.dialog {
> li {
&:after {
content: "";
.dialog-split {
display: block;
position: absolute;
bottom: 0;
right: 0;
@ -443,7 +446,7 @@
transform: scaleY(0.5);
}
&:last-child {
&:after {
.dialog-split {
display: none;
}
}