perf: 会话顶部提示剩余未读消息

This commit is contained in:
kuaifan 2023-02-07 04:30:18 +08:00
parent daa88a2cc2
commit a0e84479f2
6 changed files with 119 additions and 10 deletions

View File

@ -457,6 +457,15 @@ class DialogController extends AbstractController
->where('web_socket_dialog_msgs.id', '<', $last->id)
->orderByDesc('web_socket_dialog_msgs.id')
->value('id'));
//
if (empty($position_id)) {
$unreadBuilder = WebSocketDialogMsgRead::whereDialogId($dialog_id)->whereUserid($user->userid)->whereReadAt(null)->where('msg_id', '<', $last->id);
$unread = $unreadBuilder->count();
$data['before'] = [
'unread' => $unread,
'first_id' => $unread > 0 ? intval($unreadBuilder->orderBy('msg_id')->value('msg_id')) : 0,
];
}
}
$data['list'] = $list;
$data['time'] = Base::time();

View File

@ -97,6 +97,14 @@
</slot>
</div>
<!--顶部提示-->
<div v-if="beforeUnread" class="dialog-top" :class="{'down': tagShow}">
<div class="top-unread" @click="goBeforeUnread">
<Icon v-if="beforeLoad" type="ios-loading" class="icon-loading"></Icon>
<span>{{$L(`未读消息${beforeUnread.unread}`)}}</span>
</div>
</div>
<!--消息列表-->
<VirtualList
ref="scroller"
@ -522,6 +530,8 @@ export default {
scrollDirection: null,
scrollAction: 0,
scrollTmp: 0,
beforeLoad: false,
}
},
@ -538,6 +548,7 @@ export default {
'dialogMsgs',
'dialogTodos',
'dialogMsgTransfer',
'dialogBeforeUnreads',
'cacheDialogs',
'wsOpenNum',
'touchBackInProgress',
@ -751,6 +762,11 @@ export default {
}
}
return null
},
beforeUnread() {
const before = this.dialogBeforeUnreads.find(({id}) => id === this.dialogId)
return before || null
}
},
@ -2202,6 +2218,25 @@ export default {
}
},
goBeforeUnread() {
if (!this.beforeUnread || this.beforeLoad) {
return;
}
//
this.beforeLoad = true
const {first_id} = this.beforeUnread
this.$store.dispatch("dialogMsgMark", {
dialog_id: this.dialogId,
type: 'read'
}).then(_ => {
this.onPositionId(first_id)
}).catch(({msg}) => {
$A.modalError(msg)
}).finally(_ => {
this.beforeLoad = false
})
},
getBase64Image(url) {
return new Promise(resolve => {
let canvas = document.createElement('CANVAS'),

View File

@ -720,17 +720,12 @@ export default {
},
handleReadClick() {
this.$store.dispatch("call", {
url: 'dialog/msg/mark',
data: {
dialog_id: this.operateItem.id,
type: $A.getDialogUnread(this.operateItem, true) > 0 ? 'read' : 'unread'
},
}).then(({data}) => {
this.$store.dispatch("saveDialog", data);
this.$store.dispatch("dialogMsgMark", {
dialog_id: this.operateItem.id,
type: $A.getDialogUnread(this.operateItem, true) > 0 ? 'read' : 'unread'
}).catch(({msg}) => {
$A.modalError(msg);
});
$A.modalError(msg)
})
},
handleSilenceClick() {

View File

@ -2505,6 +2505,18 @@ export default {
dispatch("saveDialogTodo", resData.todo)
}
//
const before = Object.assign({id: data.dialog_id}, resData.before || {});
const index = state.dialogBeforeUnreads.findIndex(({id}) => id == data.dialog_id);
if (before.unread) {
if (index > -1) {
state.dialogBeforeUnreads.splice(index, 1, before);
} else {
state.dialogBeforeUnreads.push(before);
}
} else if (index > -1) {
state.dialogBeforeUnreads.splice(index, 1);
}
//
dispatch("saveDialogMsg", resData.list)
resolve(result)
}).catch(e => {
@ -2569,6 +2581,33 @@ export default {
}, 50);
},
/**
* 标记已读未读
* @param state
* @param dispatch
* @param data
* @returns {Promise<unknown>}
*/
dialogMsgMark({state, dispatch}, data) {
return new Promise((resolve, reject) => {
dispatch("call", {
url: 'dialog/msg/mark',
data,
}).then(result => {
if (data.type === 'read') {
const index = state.dialogBeforeUnreads.findIndex(({id}) => id == data.dialog_id)
if (index > -1) {
state.dialogBeforeUnreads.splice(index, 1)
}
}
dispatch("saveDialog", result.data)
resolve(result)
}).catch(e => {
reject(e)
})
})
},
/** *****************************************************************************************/
/** ************************************* loads *********************************************/
/** *****************************************************************************************/

View File

@ -82,6 +82,7 @@ export default {
dialogHistory: [],
dialogInputCache: [],
dialogMsgTransfer: {time: 0},
dialogBeforeUnreads: [],
// 文件
fileLists: [],

View File

@ -1074,6 +1074,30 @@
}
}
.dialog-top {
position: absolute;
top: 78px;
left: 0;
right: 0;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
.top-unread {
display: flex;
align-items: center;
justify-content: center;
padding: 6px 12px;
border-radius: 4px;
box-shadow: 0 2px 8px 0 rgba($primary-text-color, 0.33);
background: #fff;
cursor: pointer;
> i {
margin-right: 4px;
}
}
}
.dialog-footer {
position: relative;
padding: 0 24px;
@ -1589,6 +1613,12 @@
}
}
}
.dialog-top {
top: 68px;
&.down {
top: 98px;
}
}
.dialog-footer {
background-color: #f8f8f8;
padding: 8px 10px;