perf: 优化搜索

This commit is contained in:
kuaifan 2023-03-08 21:13:51 +08:00
parent c30c6114d5
commit e564be3fb5
2 changed files with 66 additions and 81 deletions

View File

@ -5,16 +5,16 @@
<div class="messenger-select"> <div class="messenger-select">
<div class="messenger-search"> <div class="messenger-search">
<div class="search-wrapper"> <div class="search-wrapper">
<Input v-if="tabActive==='dialog'" v-model="dialogKey" :placeholder="$L(loadDialogs ? '更新中...' : '搜索消息')" clearable > <Input v-if="tabActive==='dialog'" v-model="dialogSearchKey" :placeholder="$L(loadDialogs ? '更新中...' : '搜索消息')" clearable >
<div class="search-pre" slot="prefix"> <div class="search-pre" slot="prefix">
<Loading v-if="loadDialogs"/> <Loading v-if="loadDialogs || dialogSearchLoad > 0"/>
<Icon v-else type="ios-search" /> <Icon v-else type="ios-search" />
</div> </div>
</Input> </Input>
<Input v-else prefix="ios-search" v-model="contactsKey" :placeholder="$L('搜索联系人')" clearable /> <Input v-else prefix="ios-search" v-model="contactsKey" :placeholder="$L('搜索联系人')" clearable />
</div> </div>
</div> </div>
<div v-if="tabActive==='dialog' && !dialogKey" class="messenger-nav"> <div v-if="tabActive==='dialog' && !dialogSearchKey" class="messenger-nav">
<EDropdown <EDropdown
trigger="click" trigger="click"
placement="bottom-start" placement="bottom-start"
@ -53,14 +53,8 @@
<ul <ul
v-if="tabActive==='dialog'" v-if="tabActive==='dialog'"
class="dialog"> class="dialog">
<template v-if="dialogList.length === 0">
<li v-if="dialogLoad > 0" class="loading"><Loading/></li>
<li v-else class="nothing">
{{$L(dialogKey ? `没有任何与"${dialogKey}"相关的会话` : `没有任何会话`)}}
</li>
</template>
<li <li
v-else v-if="dialogList.length > 0"
v-for="(dialog, key) in dialogList" v-for="(dialog, key) in dialogList"
:ref="`dialog_${dialog.id}`" :ref="`dialog_${dialog.id}`"
:key="key" :key="key"
@ -107,6 +101,9 @@
<Badge class="dialog-num" :type="dialog.silence ? 'normal' : 'error'" :overflow-count="999" :count="$A.getDialogUnread(dialog, true)"/> <Badge class="dialog-num" :type="dialog.silence ? 'normal' : 'error'" :overflow-count="999" :count="$A.getDialogUnread(dialog, true)"/>
<div class="dialog-line"></div> <div class="dialog-line"></div>
</li> </li>
<li v-else-if="dialogSearchLoad === 0" class="nothing">
{{$L(dialogSearchKey ? `没有任何与"${dialogSearchKey}"相关的会话` : `没有任何会话`)}}
</li>
</ul> </ul>
<ul v-else class="contacts"> <ul v-else class="contacts">
<template v-if="contactsFilter.length === 0"> <template v-if="contactsFilter.length === 0">
@ -193,9 +190,9 @@ export default {
activeNum: 0, activeNum: 0,
tabActive: 'dialog', tabActive: 'dialog',
dialogLoad: 0, dialogSearchLoad: 0,
dialogKey: '', dialogSearchKey: '',
dialogSearch: [], dialogSearchList: [],
dialogActive: '', dialogActive: '',
dialogMenus: [ dialogMenus: [
@ -296,8 +293,14 @@ export default {
}, },
dialogList() { dialogList() {
const {dialogActive, dialogKey, dialogSearch} = this; const {dialogActive, dialogSearchKey, dialogSearchList} = this
if (dialogActive == '' && dialogKey == '') { if (dialogSearchList.length > 0) {
return dialogSearchList.sort((a, b) => {
//
return (a.is_search === true ? 1 : 0) - (b.is_search === true ? 1 : 0)
})
}
if (dialogActive == '' && dialogSearchKey == '') {
return this.cacheDialogs.filter(dialog => this.filterDialog(dialog)).sort((a, b) => { return this.cacheDialogs.filter(dialog => this.filterDialog(dialog)).sort((a, b) => {
if (a.top_at || b.top_at) { if (a.top_at || b.top_at) {
return $A.Date(b.top_at) - $A.Date(a.top_at); return $A.Date(b.top_at) - $A.Date(a.top_at);
@ -312,7 +315,7 @@ export default {
if (!this.filterDialog(dialog)) { if (!this.filterDialog(dialog)) {
return false; return false;
} }
if (dialogKey) { if (dialogSearchKey) {
const {name, pinyin, last_msg} = dialog; const {name, pinyin, last_msg} = dialog;
let searchString = `${name} ${pinyin}` let searchString = `${name} ${pinyin}`
if (last_msg) { if (last_msg) {
@ -326,7 +329,7 @@ export default {
break break
} }
} }
if (!$A.strExists(searchString, dialogKey)) { if (!$A.strExists(searchString, dialogSearchKey)) {
return false; return false;
} }
} else if (dialogActive) { } else if (dialogActive) {
@ -358,36 +361,7 @@ export default {
} }
return true; return true;
}) })
if (dialogSearch.length > 0) {
const msgIds = [];
const userIds = [];
list.forEach(item => {
if (item.last_msg && !msgIds.includes(item.last_msg.id)) {
msgIds.push(item.last_msg.id)
}
if (item.dialog_user && !userIds.includes(item.dialog_user.userid)) {
userIds.push(item.dialog_user.userid)
}
})
dialogSearch.forEach(item => {
if ($A.leftExists(item.id, "u:")) {
if (!userIds.includes(item.dialog_user.userid)) {
list.push(Object.assign(item, {is_search: true}))
}
} else {
if (!item.last_msg || !msgIds.includes(item.last_msg.id)) {
list.push(Object.assign(item, {is_search: true}))
}
}
})
}
return list.sort((a, b) => { return list.sort((a, b) => {
//
a._by_search = a.is_search === true ? 1 : 0
b._by_search = b.is_search === true ? 1 : 0
if (a._by_search || b._by_search) {
return a._by_search - b._by_search
}
// //
if (a.top_at || b.top_at) { if (a.top_at || b.top_at) {
return $A.Date(b.top_at) - $A.Date(a.top_at); return $A.Date(b.top_at) - $A.Date(a.top_at);
@ -482,31 +456,24 @@ export default {
immediate: true immediate: true
}, },
dialogKey(val) { dialogSearchKey(val) {
switch (val) { switch (val) {
case 'log.open': case 'log.o':
case 'log:open':
case 'eruda:open':
$A.IDBSet("logOpen", "open").then(_ => $A.reloadUrl()); $A.IDBSet("logOpen", "open").then(_ => $A.reloadUrl());
break; break;
case 'log.close': case 'log.c':
case 'log:close':
case 'eruda:close':
$A.IDBSet("logOpen", "close").then(_ => $A.reloadUrl()); $A.IDBSet("logOpen", "close").then(_ => $A.reloadUrl());
break; break;
} }
// //
this.dialogSearch = []; this.dialogSearchList = [];
if (val == '') { if (val == '') {
return; return
} }
this.dialogLoad++; this.__searchTimer && clearTimeout(this.__searchTimer)
setTimeout(() => { this.__searchTimer = setTimeout(this.searchDialog, 600)
if (this.dialogKey == val) { this.dialogSearchLoad++
this.searchDialog(val); setTimeout(_ => this.dialogSearchLoad--, 600)
}
this.dialogLoad--;
}, 600);
}, },
contactsKey(val) { contactsKey(val) {
@ -604,7 +571,7 @@ export default {
}, },
dialogClass(dialog) { dialogClass(dialog) {
if (this.dialogKey) { if (this.dialogSearchKey) {
return null return null
} }
return { return {
@ -619,7 +586,6 @@ export default {
if (this.operateVisible) { if (this.operateVisible) {
return return
} }
this.dialogKey = "";
// //
if ($A.isJson(dialogId) && $A.leftExists(dialogId.dialog_id, "u:")) { if ($A.isJson(dialogId) && $A.leftExists(dialogId.dialog_id, "u:")) {
this.$store.dispatch("openDialogUserid", $A.leftDelete(dialogId.dialog_id, "u:")).catch(({msg}) => { this.$store.dispatch("openDialogUserid", $A.leftDelete(dialogId.dialog_id, "u:")).catch(({msg}) => {
@ -684,15 +650,45 @@ export default {
return true; return true;
}, },
searchDialog(key) { searchDialog() {
this.dialogLoad++; const key = this.dialogSearchKey
if (key == '') {
return
}
//
this.dialogSearchLoad++;
this.$store.dispatch("call", { this.$store.dispatch("call", {
url: 'dialog/search', url: 'dialog/search',
data: {key}, data: {key},
}).then(({data}) => { }).then(({data}) => {
this.dialogSearch = data; if (key !== this.dialogSearchKey) {
return
}
const list = $A.cloneJSON(this.dialogList)
const msgIds = [];
const userIds = [];
list.forEach(item => {
if (item.last_msg && !msgIds.includes(item.last_msg.id)) {
msgIds.push(item.last_msg.id)
}
if (item.dialog_user && !userIds.includes(item.dialog_user.userid)) {
userIds.push(item.dialog_user.userid)
}
})
data.some(item => {
if ($A.leftExists(item.id, "u:")) {
if (!userIds.includes(item.dialog_user.userid)) {
list.push(Object.assign(item, {is_search: true}))
}
} else {
if (!item.last_msg || !msgIds.includes(item.last_msg.id)) {
list.push(Object.assign(item, {is_search: true}))
}
}
})
this.dialogSearchList = list;
}).finally(_ => { }).finally(_ => {
this.dialogLoad--; this.dialogSearchLoad--;
}); });
}, },
@ -801,7 +797,7 @@ export default {
}, },
handleLongpress(event, el) { handleLongpress(event, el) {
if (this.dialogKey) { if (this.dialogSearchKey) {
return; return;
} }
const dialogId = $A.getAttr(el, 'data-id') const dialogId = $A.getAttr(el, 'data-id')

View File

@ -350,8 +350,7 @@
} }
} }
} }
&.nothing, &.nothing {
&.loading {
justify-content: center; justify-content: center;
padding: 24px; padding: 24px;
margin: 0; margin: 0;
@ -360,16 +359,6 @@
cursor: default; cursor: default;
word-break: break-all; word-break: break-all;
} }
&.loading {
display: flex;
align-items: flex-start;
justify-content: center;
.common-loading {
width: 20px;
height: 20px;
margin: 1px;
}
}
} }
} }
&.contacts { &.contacts {