You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
4.4 KiB
134 lines
4.4 KiB
<template>
|
|
<div :class="{'questions--chat': isChat, 'questions--loading': loading}">
|
|
<div v-show="nodes.length" class="questions__items">
|
|
<ul v-for="(node, index) in nodes" :key="index">
|
|
<li>
|
|
<comment v-if="! node.deactivated_at" :comment="node" :controller="controller" v-on:remove="remove"></comment>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<comment-form v-if="$root.store.user.id && ! replyTo" :controller="controller"></comment-form>
|
|
</div>
|
|
</template>
|
|
|
|
<script type="text/javascript">
|
|
import Comment from './Comment';
|
|
import CommentForm from './CommentForm';
|
|
import {api} from "../js/modules/api";
|
|
|
|
export default {
|
|
name: 'comments',
|
|
props: ['objType', 'objId', 'isChat'],
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
replyTo: null,
|
|
nodes: [],
|
|
controller: this,
|
|
flatComments: {},
|
|
}
|
|
},
|
|
methods: {
|
|
reply(comment) {
|
|
this.replyTo = comment;
|
|
},
|
|
cancelReply(){
|
|
this.replyTo = null;
|
|
},
|
|
addHeart(){
|
|
this.add('❤');
|
|
},
|
|
add(content){
|
|
let vm = this;
|
|
this.loading = true;
|
|
let request = api.addObjComment(this.objId, this.objType, {
|
|
content: content,
|
|
author: this.$root.store.user.id,
|
|
parent: this.replyTo && this.replyTo.id,
|
|
});
|
|
request.then((response) => {
|
|
vm.loading = false;
|
|
vm.onAdd(response.data);
|
|
if(vm.replyTo){
|
|
vm.cancelReply();
|
|
}
|
|
}).catch(() => {
|
|
vm.loading = false;
|
|
});
|
|
},
|
|
remove(comment){
|
|
if(! confirm('Удалить комментарий?')){
|
|
return;
|
|
}
|
|
let vm = this;
|
|
this.loading = true;
|
|
let request = api.removeObjComment(comment.id);
|
|
request.then((response) => {
|
|
vm.loading = false;
|
|
vm.onRemove(comment);
|
|
});
|
|
},
|
|
onAdd(comment){
|
|
if(this.flatComments[comment.id]){
|
|
return;
|
|
}
|
|
const method = this.isChat ? 'push' : 'unshift';
|
|
if(comment.parent){
|
|
this.flatComments[comment.parent].children[method](comment);
|
|
}
|
|
else{
|
|
this.nodes[method](comment);
|
|
}
|
|
this.flatComments[comment.id] = comment;
|
|
},
|
|
onRemove(comment){
|
|
let comments = [];
|
|
if(comment.parent){
|
|
comments = this.flatComments[comment.parent].children;
|
|
}
|
|
else{
|
|
comments = this.nodes;
|
|
}
|
|
let index = comments.findIndex((c) => +c.id === +comment.id);
|
|
if(index === -1){
|
|
return;
|
|
}
|
|
comments.splice(index, 1);
|
|
delete this.flatComments[comment.id];
|
|
},
|
|
connectToPusher(){
|
|
let vm = this;
|
|
// Enable pusher logging - don't include this in production
|
|
Pusher.logToConsole = true;
|
|
|
|
let pusher = new Pusher(this.$root.store.pusherKey, {
|
|
cluster: 'eu',
|
|
encrypted: true
|
|
});
|
|
|
|
let channel = pusher.subscribe('comments_' + this.objType + '_' + this.objId);
|
|
channel.bind('add', this.onAdd);
|
|
channel.bind('delete', this.onRemove);
|
|
}
|
|
},
|
|
mounted() {
|
|
let vm = this;
|
|
this.loading = true;
|
|
let request = api.getObjComments(this.objId, this.objType, this.isChat ? 'update_at' : '-update_at');
|
|
request
|
|
.then((response) => {
|
|
vm.loading = false;
|
|
vm.nodes = response.data;
|
|
vm.connectToPusher();
|
|
})
|
|
.catch(() => {
|
|
vm.loading = false;
|
|
});
|
|
},
|
|
components: {
|
|
Comment,
|
|
CommentForm
|
|
}
|
|
}
|
|
</script>
|
|
|
|
|