mirror of
https://github.com/kuaifan/dootask.git
synced 2026-01-25 03:48:17 +00:00
perf: 消息置顶滚动恢复
This commit is contained in:
parent
3a74cdc98b
commit
7714c53085
@ -2296,13 +2296,14 @@ class DialogController extends AbstractController
|
|||||||
$dialog->save();
|
$dialog->save();
|
||||||
//
|
//
|
||||||
$data = [
|
$data = [
|
||||||
|
'add' => null,
|
||||||
'update' => [
|
'update' => [
|
||||||
'dialog_id' => $dialog->id,
|
'dialog_id' => $dialog->id,
|
||||||
'top_msg_id' => $dialog->top_msg_id,
|
'top_msg_id' => $dialog->top_msg_id,
|
||||||
'top_userid' => $dialog->top_userid,
|
'top_userid' => $dialog->top_userid,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$res = $msg->sendMsg(null, $dialog->id, 'top', [
|
$res = WebSocketDialogMsg::sendMsg(null, $dialog->id, 'top', [
|
||||||
'action' => $dialog->top_msg_id ? 'add' : 'remove',
|
'action' => $dialog->top_msg_id ? 'add' : 'remove',
|
||||||
'data' => [
|
'data' => [
|
||||||
'id' => $msg->id,
|
'id' => $msg->id,
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
<!--顶部导航-->
|
<!--顶部导航-->
|
||||||
<div ref="nav" class="dialog-nav">
|
<div ref="nav" class="dialog-nav">
|
||||||
<slot name="head">
|
<slot name="head">
|
||||||
<div class="nav-wrapper" :class="{completed: $A.dialogCompleted(dialogData)}">
|
<div class="nav-wrapper" :class="navClass">
|
||||||
<div class="dialog-back" @click="onBack">
|
<div class="dialog-back" @click="onBack">
|
||||||
<i class="taskfont"></i>
|
<i class="taskfont"></i>
|
||||||
<div v-if="msgUnreadOnly" class="back-num">{{msgUnreadOnly}}</div>
|
<div v-if="msgUnreadOnly" class="back-num">{{msgUnreadOnly}}</div>
|
||||||
@ -137,7 +137,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--置顶消息-->
|
<!--置顶消息-->
|
||||||
<div v-if="topMessageInfo" class="dialog-top-message" :class="topMessageClass" @click="onPosTop">
|
<div v-if="topShow" class="dialog-top-message" @click="onPosTop">
|
||||||
<div class="dialog-top-message-warp">
|
<div class="dialog-top-message-warp">
|
||||||
<div class="dialog-top-message-font">
|
<div class="dialog-top-message-font">
|
||||||
<i class="taskfont"></i>
|
<i class="taskfont"></i>
|
||||||
@ -147,7 +147,10 @@
|
|||||||
<UserAvatar :userid="topMessageInfo.userid" showName :showIcon="false"/>:
|
<UserAvatar :userid="topMessageInfo.userid" showName :showIcon="false"/>:
|
||||||
<span>{{$A.getMsgSimpleDesc(topMessageInfo)}}</span>
|
<span>{{$A.getMsgSimpleDesc(topMessageInfo)}}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="personnel">{{$L('置顶人员')}} <UserAvatar :userid="dialogData.top_userid" showName :showIcon="false"/> </p>
|
<p class="personnel">
|
||||||
|
{{ $L('置顶人员') }}
|
||||||
|
<UserAvatar :userid="dialogData.top_userid" showName :showIcon="false"/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-top-message-btn">
|
<div class="dialog-top-message-btn">
|
||||||
<Loading v-if="topViewPosLoad" type="pure"/>
|
<Loading v-if="topViewPosLoad" type="pure"/>
|
||||||
@ -158,7 +161,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--跳转提示-->
|
<!--跳转提示-->
|
||||||
<div v-if="positionShow && positionMsg" class="dialog-position" :class="{'down': tagShow}">
|
<div v-if="positionShow && positionMsg" class="dialog-position">
|
||||||
<div class="position-label" @click="onPositionMark(positionMsg.msg_id)">
|
<div class="position-label" @click="onPositionMark(positionMsg.msg_id)">
|
||||||
<Icon v-if="positionLoad > 0" type="ios-loading" class="icon-loading"></Icon>
|
<Icon v-if="positionLoad > 0" type="ios-loading" class="icon-loading"></Icon>
|
||||||
<i v-else class="taskfont"></i>
|
<i v-else class="taskfont"></i>
|
||||||
@ -171,7 +174,6 @@
|
|||||||
ref="scroller"
|
ref="scroller"
|
||||||
class="dialog-scroller scrollbar-virtual"
|
class="dialog-scroller scrollbar-virtual"
|
||||||
active-prefix="item"
|
active-prefix="item"
|
||||||
:class="scrollerClass"
|
|
||||||
:data-key="'id'"
|
:data-key="'id'"
|
||||||
:data-sources="allMsgs"
|
:data-sources="allMsgs"
|
||||||
:data-component="msgItem"
|
:data-component="msgItem"
|
||||||
@ -949,6 +951,14 @@ export default {
|
|||||||
return this.todoList.length > 0 && this.windowScrollY === 0 && this.quoteId === 0
|
return this.todoList.length > 0 && this.windowScrollY === 0 && this.quoteId === 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tagShow() {
|
||||||
|
return this.msgTags.length > 1 && this.windowScrollY === 0 && !this.searchShow
|
||||||
|
},
|
||||||
|
|
||||||
|
topShow() {
|
||||||
|
return this.topMessageInfo && this.windowScrollY === 0 && !this.searchShow
|
||||||
|
},
|
||||||
|
|
||||||
wrapperClass() {
|
wrapperClass() {
|
||||||
if (['ready', 'ing'].includes(this.recordState)) {
|
if (['ready', 'ing'].includes(this.recordState)) {
|
||||||
return ['record-ready']
|
return ['record-ready']
|
||||||
@ -956,12 +966,11 @@ export default {
|
|||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
|
|
||||||
tagShow() {
|
navClass() {
|
||||||
return this.msgTags.length > 1 && this.windowScrollY === 0 && !this.searchShow
|
return {
|
||||||
},
|
'completed': $A.dialogCompleted(this.dialogData),
|
||||||
|
'tagged': this.tagShow
|
||||||
scrollerClass() {
|
}
|
||||||
return !this.$slots.head && !this.topMessageInfo && this.tagShow ? 'default-header' : null
|
|
||||||
},
|
},
|
||||||
|
|
||||||
pasteWrapperClass() {
|
pasteWrapperClass() {
|
||||||
@ -1104,10 +1113,6 @@ export default {
|
|||||||
|
|
||||||
topMessageInfo() {
|
topMessageInfo() {
|
||||||
return this.dialogData.top_msg_id && this.dialogMsgTops.find(({id}) => id == this.dialogData.top_msg_id)
|
return this.dialogData.top_msg_id && this.dialogMsgTops.find(({id}) => id == this.dialogData.top_msg_id)
|
||||||
},
|
|
||||||
|
|
||||||
topMessageClass() {
|
|
||||||
return !this.$slots.head && this.tagShow ? 'default-header' : null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -3383,11 +3388,10 @@ export default {
|
|||||||
data: {
|
data: {
|
||||||
msg_id: data.id
|
msg_id: data.id
|
||||||
},
|
},
|
||||||
}).then(async ({ data, msg }) => {
|
}).then(({ data, msg }) => {
|
||||||
resolve(msg)
|
resolve(msg)
|
||||||
this.onMarkOffset(false)
|
|
||||||
// 取消置顶
|
// 取消置顶
|
||||||
await this.$store.dispatch("saveDialog", {
|
this.$store.dispatch("saveDialog", {
|
||||||
'id' : this.dialogId,
|
'id' : this.dialogId,
|
||||||
'top_msg_id' : data.update?.top_msg_id || 0,
|
'top_msg_id' : data.update?.top_msg_id || 0,
|
||||||
'top_userid' : data.update?.top_userid || 0
|
'top_userid' : data.update?.top_userid || 0
|
||||||
@ -3396,10 +3400,15 @@ export default {
|
|||||||
if (data.update?.top_msg_id) {
|
if (data.update?.top_msg_id) {
|
||||||
const index = this.dialogMsgs.findIndex(({ id }) => id == data.update.top_msg_id);
|
const index = this.dialogMsgs.findIndex(({ id }) => id == data.update.top_msg_id);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
await this.$store.dispatch("saveDialogMsgTop", Object.assign({}, this.dialogMsgs[index]))
|
this.$store.dispatch("saveDialogMsgTop", Object.assign({}, this.dialogMsgs[index]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.onMarkOffset(true)
|
// 添加消息
|
||||||
|
if (data.add) {
|
||||||
|
this.$store.dispatch("saveDialogMsg", data.add);
|
||||||
|
this.$store.dispatch("updateDialogLastMsg", data.add);
|
||||||
|
this.onActive();
|
||||||
|
}
|
||||||
}).catch(({ msg }) => {
|
}).catch(({ msg }) => {
|
||||||
reject(msg);
|
reject(msg);
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
|
|||||||
@ -437,8 +437,8 @@
|
|||||||
.dialog-top-message {
|
.dialog-top-message {
|
||||||
background: white;
|
background: white;
|
||||||
|
|
||||||
.dialog-top-message-warp{
|
.dialog-top-message-warp {
|
||||||
padding:10px 5px;
|
padding: 10px 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 10px 16px 0;
|
margin: 10px 16px 0;
|
||||||
@ -450,24 +450,29 @@
|
|||||||
.dialog-top-message-content {
|
.dialog-top-message-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
||||||
&.content {
|
&.content {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
>span{
|
|
||||||
|
> span {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.personnel {
|
&.personnel {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #afafaf;
|
color: #afafaf;
|
||||||
|
|
||||||
.avatar-name {
|
.avatar-name {
|
||||||
color: #84C56A;
|
color: #84C56A;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
@ -476,11 +481,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-top-message-font{
|
.dialog-top-message-font {
|
||||||
line-height: 42px;
|
line-height: 42px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding:0 10px;
|
padding: 0 10px;
|
||||||
.taskfont{
|
|
||||||
|
.taskfont {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -494,12 +500,14 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding:0 10px;
|
padding: 0 10px;
|
||||||
|
|
||||||
.taskfont {
|
.taskfont {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.common-pureing {
|
.common-pureing {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
@ -509,6 +517,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-position {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
height: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(100%);
|
||||||
|
animation: position-in-animation 200ms ease-out forwards;
|
||||||
|
animation-delay: 300ms;
|
||||||
|
|
||||||
|
.position-label {
|
||||||
|
position: absolute;
|
||||||
|
top: 24px;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 18px 0 0 18px;
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: $primary-color;
|
||||||
|
cursor: pointer;
|
||||||
|
> i {
|
||||||
|
margin-right: 4px;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dialog-scroller {
|
.dialog-scroller {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -1534,38 +1577,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-position {
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
right: 0;
|
|
||||||
z-index: 2;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(100%);
|
|
||||||
animation: position-in-animation 200ms ease-out forwards;
|
|
||||||
animation-delay: 300ms;
|
|
||||||
|
|
||||||
.position-label {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 18px 0 0 18px;
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: $primary-color;
|
|
||||||
cursor: pointer;
|
|
||||||
> i {
|
|
||||||
margin-right: 4px;
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -2216,6 +2227,10 @@ body.window-portrait {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.tagged {
|
||||||
|
margin-bottom: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
.dialog-back,
|
.dialog-back,
|
||||||
.dialog-menu {
|
.dialog-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -2307,21 +2322,12 @@ body.window-portrait {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.dialog-top-message {
|
|
||||||
&.default-header {
|
|
||||||
margin-top: 34px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.dialog-scroller {
|
.dialog-scroller {
|
||||||
padding-right: 14px;
|
padding-right: 14px;
|
||||||
padding-left: 14px;
|
padding-left: 14px;
|
||||||
overscroll-behavior: none;
|
overscroll-behavior: none;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
|
||||||
&.default-header {
|
|
||||||
margin-top: 34px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-item {
|
.dialog-item {
|
||||||
.dialog-view {
|
.dialog-view {
|
||||||
&.text {
|
&.text {
|
||||||
@ -2363,11 +2369,6 @@ body.window-portrait {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.dialog-position {
|
|
||||||
&.down {
|
|
||||||
top: 130px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user