...
|
...
|
@@ -5,8 +5,27 @@ |
|
|
<div class="loading" v-if="firstLoading">
|
|
|
<Loading></Loading>
|
|
|
</div>
|
|
|
<Scroll v-else ref="scroll" :data="commentList" :options="scrollOption" @pulling-up="onPullingUp">
|
|
|
<Scroll v-else ref="scroll" :data="commentList" :scroll-events="['scroll', 'scroll-end']" :options="scrollOption" @scroll="onScrollHandle" @scroll-end="onScrollEndHandle" @pulling-up="onPullingUp">
|
|
|
<div class="comment-list">
|
|
|
<div ref="commentListTop" class="comment-list-top">
|
|
|
<div ref="commentPre" class="comment-pre-list">
|
|
|
<div
|
|
|
v-for="(comments, index) in commentPreList"
|
|
|
:key="commentPreList.length - index">
|
|
|
<CommentItem
|
|
|
v-for="comment in comments"
|
|
|
:key="comment.parentComment.id"
|
|
|
:parent-comment="comment.parentComment"
|
|
|
:children-comments="comment.childrenComments"
|
|
|
:column-type="columnType"
|
|
|
:pos-id="posId"
|
|
|
:article-id="articleId"
|
|
|
@on-reply="onReply"
|
|
|
@on-close="onClose">
|
|
|
</CommentItem>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<CommentItem
|
|
|
v-for="comment in commentList"
|
|
|
:key="comment.parentComment.id"
|
...
|
...
|
@@ -40,7 +59,7 @@ |
|
|
<script>
|
|
|
import CommentItem from './comment-item.vue';
|
|
|
import {Scroll, Loading} from 'cube-ui';
|
|
|
import {get} from 'lodash';
|
|
|
import {get, throttle} from 'lodash';
|
|
|
import {createNamespacedHelpers} from 'vuex';
|
|
|
const {mapActions} = createNamespacedHelpers('comment');
|
|
|
|
...
|
...
|
@@ -53,12 +72,17 @@ export default { |
|
|
default: 1001
|
|
|
},
|
|
|
posId: Number,
|
|
|
articleId: Number
|
|
|
articleId: Number,
|
|
|
commentId: Number
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
page: 1,
|
|
|
prePage: 1,
|
|
|
totalPage: 1,
|
|
|
commentPaddingTop: 0,
|
|
|
commentList: [],
|
|
|
commentPreList: [],
|
|
|
firstLoading: true,
|
|
|
scrollOption: {
|
|
|
bounce: false,
|
...
|
...
|
@@ -73,38 +97,82 @@ export default { |
|
|
show: false
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
|
this.fetchCommentsEvent = throttle(this.fetchComments.bind(this), 1500);
|
|
|
},
|
|
|
methods: {
|
|
|
...mapActions(['fetchCommentList', 'fetchReplayList', 'postComment']),
|
|
|
async fetchComments() {
|
|
|
const result = await this.fetchCommentList({
|
|
|
async fetchCommentsAsync(pre) {
|
|
|
let params = {
|
|
|
destId: this.destId,
|
|
|
columnType: this.columnType,
|
|
|
page: this.page,
|
|
|
});
|
|
|
let dirty = true;
|
|
|
page: pre ? this.prePage : this.page
|
|
|
};
|
|
|
|
|
|
if (params.page < 1 || params.page > this.totalPage) {
|
|
|
return {code: 200};
|
|
|
}
|
|
|
|
|
|
if (this.commentId && (this.prePage === this.page)) {
|
|
|
params.rootCommentId = this.commentId;
|
|
|
}
|
|
|
|
|
|
const result = await this.fetchCommentList(params);
|
|
|
|
|
|
if (result.code === 200) {
|
|
|
const comments = get(result, 'data.commentInfos', []);
|
|
|
if (params.rootCommentId) {
|
|
|
this.page = get(result, 'data.page', 1);
|
|
|
this.prePage = this.page - 1;
|
|
|
}
|
|
|
|
|
|
this.totalPage = get(result, 'data.totalPage', 1);
|
|
|
|
|
|
this.$emit('on-page-change', {
|
|
|
page: this.page,
|
|
|
size: result.data.total
|
|
|
});
|
|
|
if (this.page === 1) {
|
|
|
await new Promise((r) => {
|
|
|
setTimeout(() => {
|
|
|
r();
|
|
|
}, 400);
|
|
|
});
|
|
|
this.commentList = comments;
|
|
|
}
|
|
|
|
|
|
if (pre) {
|
|
|
this.prePage--;
|
|
|
} else {
|
|
|
this.commentList = this.commentList.concat(comments);
|
|
|
this.page++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
},
|
|
|
async fetchComments(pre) {
|
|
|
const result = await this.fetchCommentsAsync(pre);
|
|
|
let dirty = true;
|
|
|
|
|
|
if (result.code === 200) {
|
|
|
const comments = get(result, 'data.commentInfos', []);
|
|
|
|
|
|
if (comments.length) {
|
|
|
this.page++;
|
|
|
this.$emit('on-page-change', {
|
|
|
page: result.data.page,
|
|
|
size: result.data.total
|
|
|
});
|
|
|
|
|
|
if (pre) {
|
|
|
this.commentPreList.unshift(comments);
|
|
|
this.$nextTick(() => {
|
|
|
this.loadPreComment();
|
|
|
});
|
|
|
} else {
|
|
|
if (this.page <= 2) {
|
|
|
this.commentList = comments;
|
|
|
} else {
|
|
|
this.commentList = this.commentList.concat(comments);
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
dirty = false;
|
|
|
}
|
|
|
|
|
|
this.firstLoading = false;
|
|
|
this.$nextTick(() => {
|
|
|
this.$refs.scroll.forceUpdate(dirty);
|
...
|
...
|
@@ -122,17 +190,48 @@ export default { |
|
|
onPullingUp() {
|
|
|
this.fetchComments();
|
|
|
},
|
|
|
onScrollHandle(e) {
|
|
|
this.scrollY = e.y;
|
|
|
},
|
|
|
onScrollEndHandle(e) {
|
|
|
this.scrollY = e.y;
|
|
|
|
|
|
if (this.prePage < 1) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!this.loadPreComment() && this.scrollY < 1000) {
|
|
|
this.fetchCommentsEvent(true);
|
|
|
}
|
|
|
},
|
|
|
loadPreComment() {
|
|
|
let offsetHeight = this.$refs.commentPre.offsetHeight;
|
|
|
|
|
|
if (this.commentPaddingTop !== offsetHeight) {
|
|
|
this.$refs.commentListTop.style.height = offsetHeight + 'px';
|
|
|
this.scrollY = this.scrollY - offsetHeight + this.commentPaddingTop;
|
|
|
this.commentPaddingTop = offsetHeight;
|
|
|
this.$refs.scroll.scrollTo(0, this.scrollY);
|
|
|
this.$refs.scroll.forceUpdate(true);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
},
|
|
|
async onComment() {
|
|
|
this.page = 1;
|
|
|
this.$refs.scroll.scrollTo(0, 0, 200);
|
|
|
this.fetchComments(false);
|
|
|
this.fetchComments();
|
|
|
this.$emit('on-comment', {destId: this.destId});
|
|
|
},
|
|
|
async init() {
|
|
|
this.page = 1;
|
|
|
this.perPage = 1;
|
|
|
this.totalPage = 1;
|
|
|
this.commentList = [];
|
|
|
this.firstLoading = true;
|
|
|
this.fetchComments(true);
|
|
|
this.fetchComments();
|
|
|
},
|
|
|
async onReply({commentId}) {
|
|
|
const result = await this.fetchReplayList({
|
...
|
...
|
@@ -178,6 +277,27 @@ export default { |
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
|
|
|
.comment-list-top {
|
|
|
margin-bottom: 40px;
|
|
|
height: 0;
|
|
|
position: relative;
|
|
|
}
|
|
|
|
|
|
.comment-pre-list {
|
|
|
position: absolute;
|
|
|
bottom: 0;
|
|
|
|
|
|
> * {
|
|
|
padding-bottom: 40px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.comment-pre-hide {
|
|
|
visibility: hidden;
|
|
|
position: absolute;
|
|
|
z-index: -1;
|
|
|
}
|
|
|
|
|
|
.comment-content-flex {
|
|
|
flex: 1;
|
|
|
overflow: hidden;
|
...
|
...
|
@@ -196,7 +316,6 @@ export default { |
|
|
}
|
|
|
|
|
|
.comment-list {
|
|
|
padding-top: 40px;
|
|
|
padding-left: 30px;
|
|
|
padding-right: 30px;
|
|
|
}
|
...
|
...
|
|