Authored by yyq

commit

... ... @@ -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;
}
... ...
... ... @@ -6,7 +6,7 @@
<i class="iconfont icon-close icon" @touchend.prevent="onClose"></i>
</template>
</LayoutHeader>
<CommentList ref="commentList" :dest-id="destId" :pos-id="posId" :article-id="articleId" :column-type="1001" @on-page-change="onPageChange" @on-comment="onComment" @on-page-ready="onPageReady" @on-close="onClose"></CommentList>
<CommentList ref="commentList" :dest-id="destId" :pos-id="posId" :article-id="articleId" :comment-id="commentId" :column-type="1001" @on-page-change="onPageChange" @on-comment="onComment" @on-page-ready="onPageReady" @on-close="onClose"></CommentList>
</Layout>
</template>
... ... @@ -23,6 +23,7 @@ export default {
},
posId: Number,
articleId: Number,
commentId: Number,
commentCount: Number
},
data() {
... ...
... ... @@ -27,9 +27,6 @@ export default {
userUid: -1
};
},
created() {
this.id = +this.$route.params.id;
},
activated() {
if (+this.$route.params.id !== this.id) {
this.id = +this.$route.params.id;
... ... @@ -37,7 +34,7 @@ export default {
}
},
computed: {
...mapState(['articleThumbList'])
...mapState(['articleThumbList', 'articleStates']),
},
methods: {
...mapActions(['fetchArticleList']),
... ... @@ -45,6 +42,19 @@ export default {
this.page = 1;
this.$refs.article.init();
if (this.$route.query.commentId) {
setTimeout(() => {
let articleState = this.articleStates[this.id] || {};
this.$refs.article.onShowComment({
articleId: this.id,
index: 0,
commentCount: articleState.commentCount,
commentId: +this.$route.query.commentId
});
}, 400);
}
this.$sdk.getUser().then(user => {
if (user && user.uid) {
this.userUid = +user.uid;
... ...
... ... @@ -41,6 +41,7 @@
:destId="articleId"
:popup="true"
:article-id="articleId"
:comment-id="commentId"
:commentCount="onShowCommentCount"
:pos-id="posId"
@on-close="onClose"
... ... @@ -87,6 +88,7 @@ export default {
data() {
return {
articleId: 0,
commentId: 0,
articleIndex: -1,
onShowCommentCount: 0,
showCommentAction: false,
... ... @@ -133,8 +135,9 @@ export default {
this.reportClickAvatar();
},
onShowComment({articleId, index, commentCount}) {
onShowComment({articleId, index, commentCount, commentId}) {
this.articleId = articleId;
this.commentId = commentId || 0;
this.articleIndex = index;
this.onShowCommentCount = commentCount || 0;
this.showCommentAction = true;
... ...
... ... @@ -215,7 +215,7 @@ export default {
},
[Types.FETCH_TOPIC_INFO_SUCCESS](state, data) {
state.fetchTopicInfo = false;
data.hasAttention = true || data.isAttend === 'Y';
data.hasAttention = data.isAttend === 'Y';
state.topicInfo = data;
},
[Types.FETCH_TOPIC_INFO_FAILD](state) {
... ...
import * as Types from './types';
export default {
async fetchCommentList({commit}, {destId, columnType = 1001, limit = 20, page = 1}) {
async fetchCommentList({commit}, {destId, columnType = 1001, limit = 20, page = 1, rootCommentId}) {
commit(Types.FETCH_COMMENT_REQUEST);
const result = await this.$api.get('/api/grass/queryArticleComments', {
let params = {
destId,
limit,
page,
columnType
});
}
if (rootCommentId > 0) {
params.rootCommentId = rootCommentId;
}
const result = await this.$api.get('/api/grass/queryArticleComments', params);
if (result && result.code === 200) {
if (!result.data.commentInfos) {
... ...
... ... @@ -130,6 +130,7 @@ module.exports = {
limit: {type: Number, require: false},
destId: {type: Number},
columnType: {type: Number},
rootCommentId: {type: Number},
}
},
'/api/grass/queryArticleCommentReply': {
... ...