mirror of
https://github.com/kuaifan/dootask.git
synced 2026-01-15 03:08:11 +00:00
perf: 优化聊天窗口样式
This commit is contained in:
parent
85a9e33de1
commit
fc5ce7c5db
35
resources/assets/js/directives/touchmouse.js
vendored
Executable file
35
resources/assets/js/directives/touchmouse.js
vendored
Executable 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__;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -40,10 +40,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</EPopover>
|
</EPopover>
|
||||||
|
|
||||||
<div class="toolbar-spacing"></div>
|
<ETooltip placement="top" :disabled="!$isDesktop" :content="$L('发送')">
|
||||||
|
<div class="chat-send" :class="[value ? '' : 'disabled']" v-touchmouse="send">
|
||||||
<Loading v-if="loading"/>
|
<Loading v-if="loading"/>
|
||||||
<ETooltip v-else placement="top" :disabled="!$isDesktop" :content="$L('发送')"><Icon :class="[value ? '' : 'disabled']" type="md-send" @click="send"/></ETooltip>
|
<Icon v-else type="md-send"/>
|
||||||
|
</div>
|
||||||
|
</ETooltip>
|
||||||
|
|
||||||
<slot name="toolbarAfter"/>
|
<slot name="toolbarAfter"/>
|
||||||
</div>
|
</div>
|
||||||
@ -51,15 +53,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters, mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
|
|
||||||
import Quill from 'quill';
|
import Quill from 'quill';
|
||||||
import "quill-mention";
|
import "quill-mention";
|
||||||
import ChatEmoji from "./emoji";
|
import ChatEmoji from "./emoji";
|
||||||
|
import touchmouse from "../../../../directives/touchmouse";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChatInput',
|
name: 'ChatInput',
|
||||||
components: {ChatEmoji},
|
components: {ChatEmoji},
|
||||||
|
directives: {touchmouse},
|
||||||
props: {
|
props: {
|
||||||
dialogId: {
|
dialogId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -87,7 +90,9 @@ export default {
|
|||||||
},
|
},
|
||||||
enterSend: {
|
enterSend: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: () => {
|
||||||
|
return $A.$isDesktop
|
||||||
|
}
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -337,14 +342,26 @@ export default {
|
|||||||
}
|
}
|
||||||
let html = this.$refs.editor.children[0].innerHTML
|
let html = this.$refs.editor.children[0].innerHTML
|
||||||
html = html.replace(/^(<p><br><\/p>)+|(<p><br><\/p>)+$/gi, '')
|
html = html.replace(/^(<p><br><\/p>)+|(<p><br><\/p>)+$/gi, '')
|
||||||
const quill = this.quill
|
|
||||||
const text = this.quill.getText()
|
|
||||||
this._content = html
|
this._content = html
|
||||||
this.$emit('input', this._content)
|
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)
|
this.$emit('on-ready', this.quill)
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -390,6 +407,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
send() {
|
send() {
|
||||||
|
if (this.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$emit('on-send')
|
this.$emit('on-send')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -72,6 +72,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Badge class="dialog-num" :count="$A.getDialogUnread(dialog)"/>
|
<Badge class="dialog-num" :count="$A.getDialogUnread(dialog)"/>
|
||||||
|
<div class="dialog-split"></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-else class="contacts">
|
<ul v-else class="contacts">
|
||||||
|
|||||||
@ -221,16 +221,6 @@
|
|||||||
width: 170px;
|
width: 170px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
padding: 0 2px;
|
padding: 0 2px;
|
||||||
.common-loading {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
.toolbar-spacing {
|
|
||||||
width: 1px;
|
|
||||||
height: 14px;
|
|
||||||
margin: 2px 7px 0;
|
|
||||||
background-color: #cccccc;
|
|
||||||
}
|
|
||||||
> i {
|
> i {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -240,8 +230,73 @@
|
|||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.5;
|
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 {
|
.el-tooltip.taskfont {
|
||||||
|
|||||||
@ -219,6 +219,9 @@
|
|||||||
left: 42px;
|
left: 42px;
|
||||||
transform: scale(0.8);
|
transform: scale(0.8);
|
||||||
}
|
}
|
||||||
|
.dialog-split {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
&.top {
|
&.top {
|
||||||
background-color: #EEEFF1;
|
background-color: #EEEFF1;
|
||||||
}
|
}
|
||||||
@ -432,8 +435,8 @@
|
|||||||
> ul {
|
> ul {
|
||||||
&.dialog {
|
&.dialog {
|
||||||
> li {
|
> li {
|
||||||
&:after {
|
.dialog-split {
|
||||||
content: "";
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@ -443,7 +446,7 @@
|
|||||||
transform: scaleY(0.5);
|
transform: scaleY(0.5);
|
||||||
}
|
}
|
||||||
&:last-child {
|
&:last-child {
|
||||||
&:after {
|
.dialog-split {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user