perf: 优化输入草稿

This commit is contained in:
kuaifan 2023-03-19 20:26:45 +08:00
parent dba6f70dbb
commit abbd0e097c
4 changed files with 93 additions and 54 deletions

View File

@ -435,14 +435,14 @@ export default {
this.userCache = null; this.userCache = null;
this.taskList = null; this.taskList = null;
this.fileList = {}; this.fileList = {};
this.$emit('input', this.getInputCache()) this.loadInputCache()
}, },
taskId() { taskId() {
this.userList = null; this.userList = null;
this.userCache = null; this.userCache = null;
this.taskList = null; this.taskList = null;
this.fileList = {}; this.fileList = {};
this.$emit('input', this.getInputCache()) this.loadInputCache()
}, },
showEmoji(val) { showEmoji(val) {
@ -516,7 +516,7 @@ export default {
if (this.isFocus) { if (this.isFocus) {
return return
} }
this.$emit('input', this.getInputCache()) this.loadInputCache()
}, },
wrapperHeight(newVal, oldVal) { wrapperHeight(newVal, oldVal) {
@ -637,7 +637,7 @@ export default {
if (this.value) { if (this.value) {
this.setContent(this.value) this.setContent(this.value)
} else { } else {
this.$emit('input', this.getInputCache()) this.loadInputCache()
} }
// Mark model as touched if editor lost focus // Mark model as touched if editor lost focus
@ -806,9 +806,15 @@ export default {
this.pasteClean = bool this.pasteClean = bool
}, },
getInputCache() { loadInputCache() {
const item = this.dialogInputCache.find(item => item.key == this.cacheKey); const item = this.dialogInputCache.find(item => item.key == this.cacheKey);
return item ? item.cache : ''; if (item) {
this.pasteClean = false
this.$emit('input', item.cache)
this.$nextTick(_ => this.pasteClean = true)
} else {
this.$emit('input', '')
}
}, },
onClickEditor() { onClickEditor() {

View File

@ -89,6 +89,11 @@
<em v-if="dialog.last_at">{{$A.formatTime(dialog.last_at)}}</em> <em v-if="dialog.last_at">{{$A.formatTime(dialog.last_at)}}</em>
</div> </div>
<div class="dialog-text no-dark-content"> <div class="dialog-text no-dark-content">
<template v-if="dialog.draft && dialog.id != dialogId">
<div class="last-draft">[{{$L('草稿')}}]</div>
<div class="last-text"><span>{{dialog.draft}}</span></div>
</template>
<template v-else>
<template v-if="dialog.type=='group' && dialog.last_msg && dialog.last_msg.userid"> <template v-if="dialog.type=='group' && dialog.last_msg && dialog.last_msg.userid">
<div v-if="dialog.last_msg.userid == userId" class="last-self">{{$L('')}}</div> <div v-if="dialog.last_msg.userid == userId" class="last-self">{{$L('')}}</div>
<UserAvatar v-else :userid="dialog.last_msg.userid" :show-name="true" :show-icon="false" tooltip-disabled/> <UserAvatar v-else :userid="dialog.last_msg.userid" :show-name="true" :show-icon="false" tooltip-disabled/>
@ -97,6 +102,7 @@
<em v-if="formatMsgEmojiDesc(dialog.last_msg)">{{formatMsgEmojiDesc(dialog.last_msg)}}</em> <em v-if="formatMsgEmojiDesc(dialog.last_msg)">{{formatMsgEmojiDesc(dialog.last_msg)}}</em>
<span>{{$A.getMsgSimpleDesc(dialog.last_msg)}}</span> <span>{{$A.getMsgSimpleDesc(dialog.last_msg)}}</span>
</div> </div>
</template>
<div v-if="dialog.silence" class="taskfont last-silence">&#xe7d7;</div> <div v-if="dialog.silence" class="taskfont last-silence">&#xe7d7;</div>
</div> </div>
</div> </div>
@ -309,15 +315,7 @@ export default {
}) })
} }
if (dialogActive == '' && dialogSearchKey == '') { if (dialogActive == '' && dialogSearchKey == '') {
return this.cacheDialogs.filter(dialog => this.filterDialog(dialog)).sort((a, b) => { return this.cacheDialogs.filter(dialog => this.filterDialog(dialog)).sort(this.dialogSort);
if (a.top_at || b.top_at) {
return $A.Date(b.top_at) - $A.Date(a.top_at);
}
if (a.todo_num > 0 || b.todo_num > 0) {
return b.todo_num - a.todo_num;
}
return $A.Date(b.last_at) - $A.Date(a.last_at);
});
} }
const list = this.cacheDialogs.filter(dialog => { const list = this.cacheDialogs.filter(dialog => {
if (!this.filterDialog(dialog)) { if (!this.filterDialog(dialog)) {
@ -369,18 +367,7 @@ export default {
} }
return true; return true;
}) })
return list.sort((a, b) => { return list.sort(this.dialogSort)
//
if (a.top_at || b.top_at) {
return $A.Date(b.top_at) - $A.Date(a.top_at);
}
//
if (a.todo_num > 0 || b.todo_num > 0) {
return b.todo_num - a.todo_num;
}
//
return $A.Date(b.last_at) - $A.Date(a.last_at);
})
}, },
contactsFilter() { contactsFilter() {
@ -598,6 +585,23 @@ export default {
} }
}, },
dialogSort(a, b) {
//
if (a.top_at || b.top_at) {
return $A.Date(b.top_at) - $A.Date(a.top_at);
}
//
if (a.todo_num > 0 || b.todo_num > 0) {
return b.todo_num - a.todo_num;
}
// 稿
if (a.draft || b.draft) {
return (b.draft ? 1 : 0) - (a.draft ? 1 : 0);
}
//
return $A.Date(b.last_at) - $A.Date(a.last_at);
},
openDialog(dialogId) { openDialog(dialogId) {
if (this.operateVisible) { if (this.operateVisible) {
return return
@ -925,18 +929,6 @@ export default {
const {type, group_type} = data const {type, group_type} = data
return type === 'group' && group_type !== 'user' return type === 'group' && group_type !== 'user'
}, },
userTag({identity, department_name}) {
const array = []
const deps = department_name?.split(",").find(item => /\(M\)$/.test(item))
if (deps) {
array.push(deps.replace(/\(M\)$/, '') + ' ' + this.$L('负责人'))
}
if (identity?.includes('temp')) {
array.push(this.$L('临时'))
}
return array.join(', ')
}
} }
} }
</script> </script>

View File

@ -26,7 +26,7 @@ export default {
// 读取缓存 // 读取缓存
state.cacheServerUrl = await $A.IDBString("cacheServerUrl") state.cacheServerUrl = await $A.IDBString("cacheServerUrl")
state.cacheUserBasic = await $A.IDBArray("cacheUserBasic") state.cacheUserBasic = await $A.IDBArray("cacheUserBasic")
state.cacheDialogs = (await $A.IDBArray("cacheDialogs")).map(item => Object.assign(item, {loading: false})) state.cacheDialogs = (await $A.IDBArray("cacheDialogs")).map(item => Object.assign(item, {loading: false, draft: null}))
state.cacheProjects = await $A.IDBArray("cacheProjects") state.cacheProjects = await $A.IDBArray("cacheProjects")
state.cacheColumns = await $A.IDBArray("cacheColumns") state.cacheColumns = await $A.IDBArray("cacheColumns")
state.cacheTasks = await $A.IDBArray("cacheTasks") state.cacheTasks = await $A.IDBArray("cacheTasks")
@ -38,6 +38,11 @@ export default {
state.userInfo = await $A.IDBJson("userInfo") state.userInfo = await $A.IDBJson("userInfo")
state.callAt = await $A.IDBArray("callAt") state.callAt = await $A.IDBArray("callAt")
// 聊天草稿
state.dialogInputCache.some(item => {
dispatch("saveDialogDraft", item)
})
// 会员信息 // 会员信息
if (state.userInfo.userid) { if (state.userInfo.userid) {
state.userId = state.userInfo.userid = $A.runNum(state.userInfo.userid) state.userId = state.userInfo.userid = $A.runNum(state.userInfo.userid)
@ -2202,6 +2207,7 @@ export default {
search_msg_id = dialog_id.search_msg_id; search_msg_id = dialog_id.search_msg_id;
dialog_id = dialog_id.dialog_id; dialog_id = dialog_id.dialog_id;
} }
//
requestAnimationFrame(_ => { requestAnimationFrame(_ => {
state.dialogSearchMsgId = /^\d+$/.test(search_msg_id) ? search_msg_id : 0; state.dialogSearchMsgId = /^\d+$/.test(search_msg_id) ? search_msg_id : 0;
state.dialogId = /^\d+$/.test(dialog_id) ? dialog_id : 0; state.dialogId = /^\d+$/.test(dialog_id) ? dialog_id : 0;
@ -2338,6 +2344,9 @@ export default {
if (!/^\d+$/.test(dialog_id)) { if (!/^\d+$/.test(dialog_id)) {
return return
} }
// 保存聊天草稿
const item = state.dialogInputCache.find(item => item.key == dialog_id) || {key: dialog_id, cache: null};
dispatch("saveDialogDraft", item)
// 关闭会话后只保留会话最后50条数据 // 关闭会话后只保留会话最后50条数据
const retain = 50 const retain = 50
const msgs = state.dialogMsgs.filter(item => item.dialog_id == dialog_id) const msgs = state.dialogMsgs.filter(item => item.dialog_id == dialog_id)
@ -2389,21 +2398,39 @@ export default {
}, },
/** /**
* 保存聊天草稿 * 保存输入缓存
* @param state * @param state
* @param data {key, cache} * @param key
* @param cache
*/ */
saveDialogInputCache({state}, data) { saveDialogInputCache({state}, {key, cache}) {
const index = state.dialogInputCache.findIndex(item => item.key == data.key); const index = state.dialogInputCache.findIndex(item => item.key == key);
if (index > -1) { if (index > -1) {
state.dialogInputCache.splice(index, 1, data) if (cache) {
state.dialogInputCache.splice(index, 1, {key, cache})
} else { } else {
state.dialogInputCache.push(data) state.dialogInputCache.splice(index, 1)
}
} else if (cache) {
state.dialogInputCache.push({key, cache})
} }
// //
$A.IDBSave("dialogInputCache", state.dialogInputCache, 600); $A.IDBSave("dialogInputCache", state.dialogInputCache, 600);
}, },
/**
* 保存聊天草稿
* @param state
* @param key
* @param cache
*/
saveDialogDraft({state}, {key, cache}) {
const dialogs = state.cacheDialogs.find(item => item.id == key);
if (dialogs) {
dialogs.draft = cache?.replace(/<img[^>]*>/gi, `[${$A.L('图片')}]`).replace(/<[^>]*>/g, '') || null;
}
},
/** *****************************************************************************************/ /** *****************************************************************************************/
/** ************************************** 消息 **********************************************/ /** ************************************** 消息 **********************************************/
/** *****************************************************************************************/ /** *****************************************************************************************/

View File

@ -247,12 +247,14 @@
align-items: center; align-items: center;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
.last-draft,
.common-avatar, .common-avatar,
.last-self { .last-self {
flex-shrink: 0; flex-shrink: 0;
padding-right: 4px; padding-right: 4px;
margin-right: 4px; margin-right: 4px;
position: relative; position: relative;
overflow: hidden;
&:after { &:after {
content: ":"; content: ":";
position: absolute; position: absolute;
@ -261,6 +263,18 @@
right: 0; right: 0;
} }
} }
.last-draft {
color: #ff0000;
&:after {
color: $primary-desc-color;
}
}
.common-avatar {
flex-shrink: 1;
.avatar-name {
max-width: 100%;
}
}
.last-text { .last-text {
flex: 1; flex: 1;
display: flex; display: flex;