mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-07 14:25:40 +00:00
perf: 消息输入框支持全屏输入
This commit is contained in:
parent
c2715f9b5e
commit
4957f32d06
@ -93,6 +93,10 @@
|
||||
<i class="taskfont"></i>
|
||||
{{$L('上传文件')}}
|
||||
</div>
|
||||
<div class="chat-input-popover-item" @click="onToolbar('full')">
|
||||
<i class="taskfont"></i>
|
||||
{{$L('全屏输入')}}
|
||||
</div>
|
||||
<div v-if="canAnon" class="chat-input-popover-item" @click="onToolbar('anon')">
|
||||
<i class="taskfont"></i>
|
||||
{{$L('匿名消息')}}
|
||||
@ -165,6 +169,22 @@
|
||||
<div class="record-cancel" @click.stop="stopRecord(true)">{{$L(touchLimitY ? '松开取消' : '向上滑动取消')}}</div>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<Modal
|
||||
v-model="fullInput"
|
||||
:value="true"
|
||||
:mask-closable="false"
|
||||
:beforeClose="onFullBeforeClose"
|
||||
class-name="chat-input-full-input"
|
||||
footer-hide
|
||||
fullscreen>
|
||||
<div class="chat-input-box">
|
||||
<div class="chat-input-wrapper">
|
||||
<div ref="editorFull" class="no-dark-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
<i slot="close" class="taskfont"></i>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -278,6 +298,9 @@ export default {
|
||||
isSpecVersion: this.checkIOSVersion(),
|
||||
|
||||
timer: null,
|
||||
|
||||
fullInput: false,
|
||||
fullQuill: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@ -641,61 +664,7 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
mention: {
|
||||
allowedChars: /^\S*$/,
|
||||
mentionDenotationChars: ["@", "#", "~"],
|
||||
defaultMenuOrientation: this.defaultMenuOrientation,
|
||||
isolateCharacter: true,
|
||||
positioningStrategy: 'fixed',
|
||||
renderItem: (data) => {
|
||||
if (data.disabled === true) {
|
||||
return `<div class="mention-item-disabled">${data.value}</div>`;
|
||||
}
|
||||
if (data.id === 0) {
|
||||
return `<div class="mention-item-at">@</div><div class="mention-item-name">${data.value}</div><div class="mention-item-tip">${data.tip}</div>`;
|
||||
}
|
||||
if (data.avatar) {
|
||||
const botHtml = data.bot ? `<div class="taskfont mention-item-bot"></div>` : ''
|
||||
return `<div class="mention-item-img${data.online ? ' online' : ''}"><img src="${data.avatar}"/><em></em></div>${botHtml}<div class="mention-item-name">${data.value}</div>`;
|
||||
}
|
||||
if (data.tip) {
|
||||
return `<div class="mention-item-name" title="${data.value}">${data.value}</div><div class="mention-item-tip">${data.tip}</div>`;
|
||||
}
|
||||
return `<div class="mention-item-name" title="${data.value}">${data.value}</div>`;
|
||||
},
|
||||
renderLoading: () => {
|
||||
return "Loading...";
|
||||
},
|
||||
source: (searchTerm, renderList, mentionChar) => {
|
||||
const mentionName = mentionChar == "@" ? 'user-mention' : (mentionChar == "#" ? 'task-mention' : 'file-mention');
|
||||
const containers = document.getElementsByClassName("ql-mention-list-container");
|
||||
for (let i = 0; i < containers.length; i++) {
|
||||
containers[i].classList.remove("user-mention");
|
||||
containers[i].classList.remove("task-mention");
|
||||
containers[i].classList.remove("file-mention");
|
||||
containers[i].classList.add(mentionName);
|
||||
$A.scrollPreventThrough(containers[i]);
|
||||
}
|
||||
let mentionSourceCache = null;
|
||||
this.getMentionSource(mentionChar, searchTerm, array => {
|
||||
const values = [];
|
||||
array.some(item => {
|
||||
let list = item.list;
|
||||
if (searchTerm) {
|
||||
list = list.filter(({value}) => $A.strExists(value, searchTerm));
|
||||
}
|
||||
if (list.length > 0) {
|
||||
item.label && values.push(...item.label)
|
||||
values.push(...list)
|
||||
}
|
||||
})
|
||||
if ($A.jsonStringify(values.map(({id}) => id)) !== mentionSourceCache) {
|
||||
mentionSourceCache = $A.jsonStringify(values.map(({id}) => id))
|
||||
renderList(values, searchTerm);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
mention: this.quillMention()
|
||||
}
|
||||
}, this.options)
|
||||
|
||||
@ -730,7 +699,7 @@ export default {
|
||||
if (this.maxlength > 0 && this.quill.getLength() > this.maxlength) {
|
||||
this.quill.deleteText(this.maxlength, this.quill.getLength());
|
||||
}
|
||||
let html = this.$refs.editor.children[0].innerHTML
|
||||
let html = this.$refs.editor.firstChild.innerHTML
|
||||
html = html.replace(/^(<p>\s*<\/p>)+|(<p>\s*<\/p>)+$/gi, '')
|
||||
html = html.replace(/^(<p><br\/*><\/p>)+|(<p><br\/*><\/p>)+$/gi, '')
|
||||
this.updateEmojiQuick(html)
|
||||
@ -808,6 +777,64 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
quillMention() {
|
||||
return {
|
||||
allowedChars: /^\S*$/,
|
||||
mentionDenotationChars: ["@", "#", "~"],
|
||||
defaultMenuOrientation: this.defaultMenuOrientation,
|
||||
isolateCharacter: true,
|
||||
positioningStrategy: 'fixed',
|
||||
renderItem: (data) => {
|
||||
if (data.disabled === true) {
|
||||
return `<div class="mention-item-disabled">${data.value}</div>`;
|
||||
}
|
||||
if (data.id === 0) {
|
||||
return `<div class="mention-item-at">@</div><div class="mention-item-name">${data.value}</div><div class="mention-item-tip">${data.tip}</div>`;
|
||||
}
|
||||
if (data.avatar) {
|
||||
const botHtml = data.bot ? `<div class="taskfont mention-item-bot"></div>` : ''
|
||||
return `<div class="mention-item-img${data.online ? ' online' : ''}"><img src="${data.avatar}"/><em></em></div>${botHtml}<div class="mention-item-name">${data.value}</div>`;
|
||||
}
|
||||
if (data.tip) {
|
||||
return `<div class="mention-item-name" title="${data.value}">${data.value}</div><div class="mention-item-tip">${data.tip}</div>`;
|
||||
}
|
||||
return `<div class="mention-item-name" title="${data.value}">${data.value}</div>`;
|
||||
},
|
||||
renderLoading: () => {
|
||||
return "Loading...";
|
||||
},
|
||||
source: (searchTerm, renderList, mentionChar) => {
|
||||
const mentionName = mentionChar == "@" ? 'user-mention' : (mentionChar == "#" ? 'task-mention' : 'file-mention');
|
||||
const containers = document.getElementsByClassName("ql-mention-list-container");
|
||||
for (let i = 0; i < containers.length; i++) {
|
||||
containers[i].classList.remove("user-mention");
|
||||
containers[i].classList.remove("task-mention");
|
||||
containers[i].classList.remove("file-mention");
|
||||
containers[i].classList.add(mentionName);
|
||||
$A.scrollPreventThrough(containers[i]);
|
||||
}
|
||||
let mentionSourceCache = null;
|
||||
this.getMentionSource(mentionChar, searchTerm, array => {
|
||||
const values = [];
|
||||
array.some(item => {
|
||||
let list = item.list;
|
||||
if (searchTerm) {
|
||||
list = list.filter(({value}) => $A.strExists(value, searchTerm));
|
||||
}
|
||||
if (list.length > 0) {
|
||||
item.label && values.push(...item.label)
|
||||
values.push(...list)
|
||||
}
|
||||
})
|
||||
if ($A.jsonStringify(values.map(({id}) => id)) !== mentionSourceCache) {
|
||||
mentionSourceCache = $A.jsonStringify(values.map(({id}) => id))
|
||||
renderList(values, searchTerm);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateEmojiQuick(text) {
|
||||
if (!this.isFocus || !text) {
|
||||
this.emojiQuickShow = false
|
||||
@ -1099,6 +1126,10 @@ export default {
|
||||
});
|
||||
break;
|
||||
|
||||
case 'full':
|
||||
this.onFullInput()
|
||||
break;
|
||||
|
||||
case 'image':
|
||||
case 'file':
|
||||
case 'call':
|
||||
@ -1108,6 +1139,38 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onFullInput() {
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
this.fullInput = !this.fullInput;
|
||||
//
|
||||
if (this.fullInput) {
|
||||
this.$nextTick(_ => {
|
||||
this.fullQuill = new Quill(this.$refs.editorFull, Object.assign({
|
||||
theme: 'bubble',
|
||||
readOnly: false,
|
||||
placeholder: this.placeholder,
|
||||
modules: {
|
||||
toolbar: [
|
||||
['bold', 'strike', 'italic', 'underline', {'list': 'ordered'}, {'list': 'bullet'}, 'blockquote', 'code-block']
|
||||
],
|
||||
mention: this.quillMention()
|
||||
}
|
||||
}, this.options))
|
||||
this.fullQuill.enable(true)
|
||||
this.$refs.editorFull.firstChild.innerHTML = this.$refs.editor.firstChild.innerHTML
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onFullBeforeClose() {
|
||||
return new Promise(resolve => {
|
||||
this.$refs.editor.firstChild.innerHTML = this.$refs.editorFull.firstChild.innerHTML
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
|
||||
onMoreVisibleChange(v) {
|
||||
this.showMore = v;
|
||||
},
|
||||
|
||||
@ -605,6 +605,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
.chat-input-full-input {
|
||||
.ivu-modal {
|
||||
.ivu-modal-content {
|
||||
margin-top: 46px;
|
||||
border-top-left-radius: 18px !important;
|
||||
border-top-right-radius: 18px !important;
|
||||
.ivu-modal-body {
|
||||
overflow: visible;
|
||||
padding: 24px !important;
|
||||
}
|
||||
.ivu-modal-close {
|
||||
> i {
|
||||
top: 3px;
|
||||
right: 2px;
|
||||
font-size: 24px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #ffffff;
|
||||
border-radius: 50%;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-input-box {
|
||||
height: 100%;
|
||||
|
||||
.chat-input-wrapper {
|
||||
height: 100%;
|
||||
|
||||
.ql-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.ql-editor {
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ql-mention-list-container {
|
||||
width: auto;
|
||||
min-width: 220px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user