perf: 优化草稿消息

This commit is contained in:
kuaifan 2025-03-13 20:18:34 +08:00
parent 82afb5b150
commit 4061ae4275
7 changed files with 105 additions and 50 deletions

View File

@ -285,7 +285,7 @@
</template> </template>
<script> <script>
import {mapState} from "vuex"; import {mapGetters, mapState} from "vuex";
import Quill from 'quill-hi'; import Quill from 'quill-hi';
import "quill-mention-hi"; import "quill-mention-hi";
import ChatEmoji from "./emoji"; import ChatEmoji from "./emoji";
@ -548,6 +548,8 @@ export default {
'isModKey', 'isModKey',
]), ]),
...mapGetters(['getDraft']),
isEnterSend({cacheKeyboard}) { isEnterSend({cacheKeyboard}) {
if (this.$isEEUiApp) { if (this.$isEEUiApp) {
return cacheKeyboard.send_button_app === 'enter'; return cacheKeyboard.send_button_app === 'enter';
@ -704,6 +706,10 @@ export default {
} }
return style return style
}, },
inputDraft() {
return this.getDraft(this.dialogId)
}
}, },
watch: { watch: {
// Watch content change // Watch content change
@ -717,7 +723,10 @@ export default {
} }
} }
if (!this.simpleMode) { if (!this.simpleMode) {
this.$store.dispatch("saveDialogDraft", {id: this.dialogId, extra_draft_content: val}) this.$store.dispatch("saveDraft", {
dialogId: this.dialogId,
content: val
})
} }
}, },
@ -744,7 +753,7 @@ export default {
this.loadInputDraft() this.loadInputDraft()
}, },
'dialogData.extra_draft_content'() { inputDraft() {
if (this.isFocus) { if (this.isFocus) {
return return
} }
@ -1208,13 +1217,12 @@ export default {
}, },
loadInputDraft() { loadInputDraft() {
const {extra_draft_content} = this.dialogData; if (this.simpleMode || !this.inputDraft) {
if (this.simpleMode || !extra_draft_content) {
this.$emit('input', '') this.$emit('input', '')
return return
} }
this.pasteClean = false this.pasteClean = false
this.$emit('input', extra_draft_content) this.$emit('input', this.inputDraft)
this.$nextTick(_ => this.pasteClean = true) this.$nextTick(_ => this.pasteClean = true)
}, },

View File

@ -1688,9 +1688,9 @@ export default {
if (!this.msgText) { if (!this.msgText) {
return; return;
} }
this.$store.dispatch("saveDialogDraft", { this.$store.dispatch("saveDraft", {
id: this.taskDetail.dialog_id, dialogId: this.taskDetail.dialog_id,
extra_draft_content: this.msgText content: this.msgText
}) })
}, },

View File

@ -107,9 +107,9 @@
<em v-if="dialog.last_at">{{$A.timeFormat(dialog.last_at)}}</em> <em v-if="dialog.last_at">{{$A.timeFormat(dialog.last_at)}}</em>
</div> </div>
<div class="dialog-text no-dark-content"> <div class="dialog-text no-dark-content">
<template v-if="dialog.extra_draft_has && dialog.id != dialogId"> <template v-if="dialog.id != dialogId && tagDraft(dialog.id)">
<div class="last-draft">[{{$L('草稿')}}]</div> <div class="last-draft">[{{$L('草稿')}}]</div>
<div class="last-text"><span>{{formatDraft(dialog.extra_draft_content)}}</span></div> <div class="last-text"><span>{{formatDraft(getDraft(dialog.id))}}</span></div>
</template> </template>
<template v-else> <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">
@ -260,7 +260,7 @@
</template> </template>
<script> <script>
import {mapState} from "vuex"; import {mapGetters, mapState} from "vuex";
import DialogWrapper from "./components/DialogWrapper"; import DialogWrapper from "./components/DialogWrapper";
import longpress from "../../directives/longpress"; import longpress from "../../directives/longpress";
import emitter from "../../store/events"; import emitter from "../../store/events";
@ -363,6 +363,8 @@ export default {
'taskColorList' 'taskColorList'
]), ]),
...mapGetters(['getDraft', 'tagDraft']),
routeName() { routeName() {
return this.$route.name return this.$route.name
}, },
@ -738,8 +740,9 @@ export default {
return $A.sortFloat(b.todo_num, a.todo_num); return $A.sortFloat(b.todo_num, a.todo_num);
} }
// 稿 // 稿
if (a.extra_draft_has || b.extra_draft_has) { const drafts = [this.tagDraft(a.id) ? 1 : 0, this.tagDraft(b.id) ? 1 : 0];
return $A.sortFloat(b.extra_draft_has, a.extra_draft_has); if (drafts[0] || drafts[1]) {
return $A.sortFloat(drafts[1], drafts[0]);
} }
// //
return $A.sortDay(b.last_at, a.last_at); return $A.sortDay(b.last_at, a.last_at);

View File

@ -1,4 +1,5 @@
import * as openpgp from 'openpgp_hi/lightweight'; import * as openpgp from 'openpgp_hi/lightweight';
import {debounce} from "lodash";
import {initLanguage, languageList, languageName} from "../language"; import {initLanguage, languageList, languageName} from "../language";
import {$callData, $urlSafe, SSEClient} from './utils' import {$callData, $urlSafe, SSEClient} from './utils'
import emitter from "./events"; import emitter from "./events";
@ -973,7 +974,8 @@ export default {
'fileLists', 'fileLists',
'callAt', 'callAt',
'cacheEmojis', 'cacheEmojis',
'cacheDialogs' 'cacheDialogs',
'cacheDrafts',
], ],
json: [ json: [
'userInfo' 'userInfo'
@ -996,7 +998,6 @@ export default {
state.cacheDialogs = state.cacheDialogs.map(item => ({ state.cacheDialogs = state.cacheDialogs.map(item => ({
...item, ...item,
loading: false, loading: false,
extra_draft_has: item.extra_draft_content ? 1 : 0
})); }));
// TranslationLanguage检查 // TranslationLanguage检查
@ -1027,11 +1028,11 @@ export default {
/** /**
* Electron 页面卸载触发 * Electron 页面卸载触发
* @param dispatch * @param commit
*/ */
onBeforeUnload({dispatch}) { onBeforeUnload({commit}) {
if ($A.isSubElectron && $A.isJson(window.__dialogDraft)) { if ($A.isSubElectron && $A.isJson(window.__dialogDraft)) {
dispatch("saveDialog", window.__dialogDraft) commit('SET_DRAFT', window.__dialogDraft)
window.__dialogDraft = null; window.__dialogDraft = null;
} }
}, },
@ -3073,20 +3074,19 @@ export default {
/** /**
* 关闭对话 * 关闭对话
* @param state * @param state
* @param commit
* @param dispatch * @param dispatch
* @param dialog_id * @param dialog_id
*/ */
closeDialog({state, dispatch}, dialog_id) { closeDialog({state, commit, dispatch}, dialog_id) {
if (!/^\d+$/.test(dialog_id)) { if (!/^\d+$/.test(dialog_id)) {
return return
} }
$A.execMainDispatch("closeDialog", dialog_id) $A.execMainDispatch("closeDialog", dialog_id)
//
// 更新草稿状态 // 更新草稿标签
const dialog = state.cacheDialogs.find(item => item.id == dialog_id); commit('TAG_DRAFT', dialog_id)
if (dialog) {
dialog.extra_draft_has = dialog.extra_draft_content ? 1 : 0
}
// 关闭会话后删除会话超限消息 // 关闭会话后删除会话超限消息
const msgs = state.dialogMsgs.filter(item => item.dialog_id == dialog_id) const msgs = state.dialogMsgs.filter(item => item.dialog_id == dialog_id)
if (msgs.length > state.dialogMsgKeep) { if (msgs.length > state.dialogMsgKeep) {
@ -3176,24 +3176,17 @@ export default {
}, },
/** /**
* 保存聊天草稿 * 保存草稿
* @param state * @param commit
* @param dispatch * @param dialogId
* @param data {id, extra_draft_content} * @param content
*/ */
saveDialogDraft({state, dispatch}, data) { saveDraft({commit}, {dialogId, content}) {
data.extra_draft_content = $A.filterInvalidLine(data.extra_draft_content)
if ($A.isSubElectron) { if ($A.isSubElectron) {
window.__dialogDraft = data window.__dialogDraft = {dialogId, content}
return return
} }
state.dialogDraftTimer[data.id] && clearTimeout(state.dialogDraftTimer[data.id]) commit('SET_DRAFT', {dialogId, content})
state.dialogDraftTimer[data.id] = setTimeout(_ => {
if (state.dialogId != data.id) {
data.extra_draft_has = data.extra_draft_content ? 1 : 0
}
dispatch("saveDialog", data)
}, data.extra_draft_content ? 600 : 0)
}, },
/** *****************************************************************************************/ /** *****************************************************************************************/
@ -4428,6 +4421,5 @@ export default {
},10) },10)
} }
} }
}, },
} }

View File

@ -124,7 +124,7 @@ export default {
const todayStart = $A.daytz().startOf('day'), const todayStart = $A.daytz().startOf('day'),
todayEnd = $A.daytz().endOf('day'), todayEnd = $A.daytz().endOf('day'),
todayNow = $A.daytz(); todayNow = $A.daytz();
const filterTask = (task, checkCompleted = true) => { const filterTask = (task, checkCompleted = true) => {
if (task.archived_at) { if (task.archived_at) {
return false; return false;
@ -137,10 +137,10 @@ export default {
} }
return task.owner == 1; return task.owner == 1;
} }
// 获取所有未完成的任务 // 获取所有未完成的任务
let array = state.cacheTasks.filter(task => filterTask(task)); let array = state.cacheTasks.filter(task => filterTask(task));
// 处理临时完成的任务 // 处理临时完成的任务
let tmpCount = 0; let tmpCount = 0;
if (state.taskCompleteTemps.length > 0) { if (state.taskCompleteTemps.length > 0) {
@ -165,7 +165,7 @@ export default {
// 遍历任务进行分类 // 遍历任务进行分类
array.forEach(task => { array.forEach(task => {
const isTemp = state.taskCompleteTemps.includes(task.id); const isTemp = state.taskCompleteTemps.includes(task.id);
if (task.end_at && $A.dayjs(task.end_at) <= todayNow) { if (task.end_at && $A.dayjs(task.end_at) <= todayNow) {
// 超期任务 // 超期任务
result.overdue.push(task); result.overdue.push(task);
@ -217,14 +217,14 @@ export default {
// 获取所有未完成的协助任务 // 获取所有未完成的协助任务
let array = state.cacheTasks.filter(task => filterTask(task)); let array = state.cacheTasks.filter(task => filterTask(task));
// 处理临时完成的任务 // 处理临时完成的任务
if (state.taskCompleteTemps.length > 0) { if (state.taskCompleteTemps.length > 0) {
const tmps = state.cacheTasks.filter(task => const tmps = state.cacheTasks.filter(task =>
state.taskCompleteTemps.includes(task.id) && state.taskCompleteTemps.includes(task.id) &&
filterTask(task, false) filterTask(task, false)
); );
if (tmps.length > 0) { if (tmps.length > 0) {
array = $A.cloneJSON(array); array = $A.cloneJSON(array);
array.push(...tmps); array.push(...tmps);
@ -238,4 +238,24 @@ export default {
return timeA - timeB; return timeA - timeB;
}); });
}, },
/**
* 获取草稿
* @param state
* @returns {function(*): *|string}
*/
getDraft: (state) => (dialogId) => {
const draft = state.cacheDrafts.find(item => item.dialogId === dialogId)
return draft ? draft.content : ''
},
/**
* 是否显示草稿标签
* @param state
* @returns {function(*): boolean}
*/
tagDraft: (state) => (dialogId) => {
const draft = state.cacheDrafts.find(item => item.dialogId === dialogId)
return !!draft?.tag
},
} }

View File

@ -1,3 +1,33 @@
export default { export default {
// 设置草稿
SET_DRAFT(state, {dialogId, content}) {
const index = state.cacheDrafts.findIndex(item => item.dialogId === dialogId)
const item = {
dialogId,
content: $A.filterInvalidLine(content),
time: new Date().getTime()
}
if (index !== -1) {
// 更新已存在的草稿
item.tag = state.cacheDrafts[index].tag
state.cacheDrafts.splice(index, 1, item)
} else {
// 添加新草稿
item.tag = state.dialogId != dialogId
state.cacheDrafts.push(item)
}
// 保存到 IndexedDB
$A.IDBSave("cacheDrafts", state.cacheDrafts)
},
// 显示草稿标签
TAG_DRAFT(state, dialogId) {
const index = state.cacheDrafts.findIndex(item => item.dialogId === dialogId)
if (index !== -1) {
state.cacheDrafts[index].tag = !!state.cacheDrafts[index].content
$A.IDBSave("cacheDrafts", state.cacheDrafts)
}
},
} }

View File

@ -78,6 +78,9 @@ export default {
// Dialog // Dialog
cacheDialogs: [], cacheDialogs: [],
// Draft
cacheDrafts: [],
// Project // Project
cacheProjects: [], cacheProjects: [],
cacheColumns: [], cacheColumns: [],
@ -123,7 +126,6 @@ export default {
dialogTodos: [], dialogTodos: [],
dialogMsgTops: [], dialogMsgTops: [],
dialogHistory: [], dialogHistory: [],
dialogDraftTimer: {},
dialogMsgTransfer: {time: 0}, dialogMsgTransfer: {time: 0},
dialogSseList: [], dialogSseList: [],
dialogDroupWordChain: {}, dialogDroupWordChain: {},