diff --git a/resources/assets/js/pages/manage/components/DialogItem.vue b/resources/assets/js/pages/manage/components/DialogItem.vue
index 5ef9485b4..14d280917 100644
--- a/resources/assets/js/pages/manage/components/DialogItem.vue
+++ b/resources/assets/js/pages/manage/components/DialogItem.vue
@@ -10,6 +10,7 @@
:operate-visible="operateVisible"
:operate-action="operateVisible && source.id === operateItem.id"
@on-longpress="onLongpress"
+ @on-view-reply="onViewReply"
@on-view-text="onViewText"
@on-view-file="onViewFile"
@on-emoji="onEmoji"/>
@@ -74,6 +75,10 @@ export default {
this.dispatch("on-longpress", e)
},
+ onViewReply(replyId) {
+ this.dispatch("on-view-reply", replyId)
+ },
+
onViewText(e) {
this.dispatch("on-view-text", e)
},
diff --git a/resources/assets/js/pages/manage/components/DialogView.vue b/resources/assets/js/pages/manage/components/DialogView.vue
index 977769aef..f44cc24d5 100644
--- a/resources/assets/js/pages/manage/components/DialogView.vue
+++ b/resources/assets/js/pages/manage/components/DialogView.vue
@@ -10,7 +10,7 @@
:class="headClass"
v-longpress="{callback: handleLongpress, delay: 300}">
-
+
{{formatMsgDesc(replyData)}}
@@ -387,6 +387,10 @@ export default {
});
},
+ viewReply() {
+ this.$emit("on-view-reply", this.replyData.id)
+ },
+
viewText(e) {
this.$emit("on-view-text", e)
},
diff --git a/resources/assets/js/pages/manage/components/DialogWrapper.vue b/resources/assets/js/pages/manage/components/DialogWrapper.vue
index c21b07280..8c542a33a 100644
--- a/resources/assets/js/pages/manage/components/DialogWrapper.vue
+++ b/resources/assets/js/pages/manage/components/DialogWrapper.vue
@@ -76,6 +76,7 @@
:data-sources="allMsgs"
:data-component="msgItem"
+ :item-class-add="itemClassAdd"
:extra-props="{dialogData, isMyDialog, operateVisible, operateItem}"
:estimate-size="78"
:keeps="80"
@@ -83,6 +84,7 @@
@totop="loadNextPage"
@on-longpress="onLongpress"
+ @on-view-reply="onViewReply"
@on-view-text="onViewText"
@on-view-file="onViewFile"
@on-emoji="onEmoji">
@@ -326,6 +328,7 @@ export default {
wrapperStart: 0,
replyId: 0,
+ replyActiveIndex: -1,
}
},
@@ -629,6 +632,10 @@ export default {
}
},
+ itemClassAdd(index) {
+ return index === this.replyActiveIndex ? 'dialog-shake' : '';
+ },
+
inputFocus() {
this.$nextTick(_ => {
this.$refs.input.focus()
@@ -1014,6 +1021,22 @@ export default {
});
},
+ onViewReply(replyId) {
+ if (this.operateVisible) {
+ return
+ }
+ const index = this.allMsgs.findIndex(item => item.id === replyId)
+ if (index > -1) {
+ this.$refs.scroller?.scrollToIndex(index);
+ requestAnimationFrame(_ => {
+ this.replyActiveIndex = index;
+ setTimeout(_ => {
+ this.replyActiveIndex = -1;
+ }, 800)
+ });
+ }
+ },
+
onViewText({target}) {
if (this.operateVisible) {
return
diff --git a/resources/assets/sass/pages/components/dialog-wrapper.scss b/resources/assets/sass/pages/components/dialog-wrapper.scss
index 0d504176e..4df79f2b1 100644
--- a/resources/assets/sass/pages/components/dialog-wrapper.scss
+++ b/resources/assets/sass/pages/components/dialog-wrapper.scss
@@ -187,6 +187,11 @@
position: relative;
padding: 16px 32px 0;
+ .dialog-shake {
+ animation: ani-dialog-shake 500ms ease-in-out;
+ animation-delay: 200ms;
+ }
+
.dialog-item {
display: flex;
flex-direction: row;
@@ -243,6 +248,8 @@
position: relative;
padding-left: 9px;
margin-bottom: 4px;
+ cursor: pointer;
+
&:after {
content: "";
position: absolute;
@@ -1035,6 +1042,14 @@
}
}
+@keyframes ani-dialog-shake {
+ 10%, 90% { transform: translate3d(-1px, 0, 0); }
+ 20%, 80% { transform: translate3d(+2px, 0, 0); }
+ 30%, 70% { transform: translate3d(-4px, 0, 0); }
+ 40%, 60% { transform: translate3d(+4px, 0, 0); }
+ 50% { transform: translate3d(-4px, 0, 0); }
+}
+
@media (max-width: 768px) {
.dialog-wrapper {
background-color: #f8f8f8;