Files
site/resources/js/Shared/Overlay/ModalFeedBody.vue

362 lines
14 KiB
Vue
Executable File

<template>
<div class="col-span-5 modal-body flex flex-col">
<div class="modal-head mb-3 px-2 py-4 md:py-4 md:px-6 flex justify-between items-center border-b border-indigo-100">
<div v-if="entity.is_ads" class="flex items-center space-x-4">
<user-avatar :user="user" size="small"
class="w-12 h-12 md:w-16 md:h-16 border-2 border-orange text-lg"
/>
<p class="text-base md:text-xl font-semibold text-gray">
{{ user.name }}
</p>
</div>
<div v-else class="flex items-center space-x-4">
<inertia-link :href="route('profile.user', user.username)" class="flex-shrink-0 block">
<user-avatar :user="user" size="small"
class="w-12 h-12 md:w-16 md:h-16 border-2 border-orange text-lg"
/>
</inertia-link>
<inertia-link :href="route('profile.user', user.username)" class="flex flex-col">
<p class="text-base md:text-xl font-semibold text-gray">
{{ user.name }}
</p>
<p class="min-h-[24px]">
<span v-show="user.count_posts" class="md:mt-1 text-sm text-gray-light">{{ user.count_posts }} {{ countPosts }}</span>
</p>
</inertia-link>
</div>
<div v-if="is_exist_menu && entity.is_ads == false" class="text-white">
<dropdown-menu-point v-if="$page.props.auth.user">
<MenuItems class="origin-top-right absolute right-0 mt-2 w-64 bg-indigo-200 shadow-lg max-h-60 rounded-md text-base ring-1 ring-indigo-100 overflow-auto focus:outline-none">
<MenuItem v-if="user.id === $page.props.auth.user.id">
<inertia-link :href="route(`${entity.type}.edit`, entity.slug)" class="group flex items-center px-4 py-2 text-base hover:bg-indigo-300 text-gray-light">
<PencilAltIcon class="mr-3 h-5 w-5 text-gray-400 group-hover:text-orange" aria-hidden="true" />
Редактировать
</inertia-link>
</MenuItem>
<MenuItem v-if="user.id === $page.props.auth.user.id">
<button class="w-full group flex items-center px-4 py-2 text-base hover:bg-indigo-300 text-gray-light" @click="onRemoveFeed()">
<MinusCircleIcon class="mr-3 h-5 w-5 text-gray-400 group-hover:text-orange" aria-hidden="true" />
Удалить
</button>
</MenuItem>
<MenuItem v-if="user.id !== $page.props.auth.user.id">
<inertia-link :href="route('complaint.reason', feed_id)" class="group flex items-center px-4 py-2 text-base hover:bg-indigo-300 text-gray-light">
<ExclamationIcon class="mr-3 h-5 w-5 text-gray-400 group-hover:text-orange" aria-hidden="true" />
Пожаловаться
</inertia-link>
</MenuItem>
</MenuItems>
</dropdown-menu-point>
</div>
</div>
<!-- -->
<!-- max-h-[20rem] h-[20rem] -->
<div data-simplebar class="modal-feed min-h-[4rem] md:min-h-[22rem] max-h-[22rem] overflow-auto">
<div class="p-2 md:py-4 md:px-6 space-y-3 md:space-y-6">
<div v-if="entity.tags.length" class="">
<feed-tags :tags="entity.tags" />
</div>
<div v-if="entity.body" class="comment-line comment-line--head flex flex-col text-gray text-sm">
<div v-if="entity.is_ads" class="prose-content"
v-html="entity.body"
></div>
<div v-else class="flex group">
<inertia-link :href="route('profile.user', user.username)" class="flex-shrink-0 block mr-3">
<user-avatar :user="user" size="small"
class="w-10 h-10 border border-orange text-xs"
/>
</inertia-link>
<div>
<inertia-link :href="route('profile.user', user.username)" class="font-semibold underline inline-block mr-2">
{{ user.username }}
</inertia-link>
{{ entity.body }}
<div class="transition-opacity opacity-0 group-hover:opacity-100 flex space-x-4">
<span class="text-xs text-gray-light">{{ entity.created_at_humans }}</span>
</div>
</div>
</div>
</div>
<div v-for="comment in comments" :key="comment.id"
class="comment-line flex flex-col text-gray text-sm"
>
<user-comment :creator_id="user.id" :comment="comment"
@showChildren="loadChildrenComment" @toAnswer="sendAnswerParent"
@removeCommentItem="removeCommentItem"
/>
</div>
<div v-if="cursor" class="flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" width="24"
height="24"
viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round"
class="cursor-pointer text-white" @click="loadComments"
><circle cx="12" cy="12"
r="10"
></circle><line x1="12" y1="8"
x2="12" y2="16"
></line><line x1="8" y1="12"
x2="16" y2="12"
></line></svg>
</div>
</div>
</div>
<div v-if="$page.props.auth.user" class="modal-footer mt-auto p-2 md:py-4 md:px-6 border-t border-indigo-100">
<feed-paid-block
:is_paid="entity.is_paid"
:user_id="user.id"
:price="entity.price"
:feed_id="feed_id"
:paid_open="entity.paid_open"
class="text-white"
@onReplaceFeed="onReplaceFeed"
/>
<div class="misc-info mt-2 md:mt-0 mb-2 flex flex-row-reverse">
<div class="flex space-x-4">
<template v-if="entity.is_ads == false">
<like-count :likes="entity.likes" :liked="entity.liked"
@likeFeed="likeFeed"
/>
<comment-count :comments="entity.comments" />
<share-count @click="openShareModal" />
</template>
<view-count :count="entity.views_count" />
</div>
</div>
<div v-if="entity.is_ads == false" class="modal-send flex">
<div class="flex-1">
<textarea v-model="new_comment"
class="pl-0 pr-2 resize-none bg-indigo-300 w-full outline-none focus:ring-transparent focus:border-transparent focus:ring-offset-0 text-base text-gray border-transparent" placeholder="Написать комментарий..."
> </textarea>
</div>
<div class="mt-1 flex-shrink-0 text-pink">
<button class="default" @click="addComment">
<svg class="w-8 h-8 flex-shrink-0">
<use xlink:href="#arrow-circle"></use>
</svg>
</button>
</div>
</div>
</div>
<div v-else class="modal-footer mt-auto p-2 md:py-4 md:px-6 border-t border-indigo-100 flex justify-center">
<a rel="nofollow" href="/login"
class="my-1 transition shadow-none hover:shadow-classic2 inline-flex items-center px-8 py-1 md:py-3 justify-center text-sm md:text-base rounded-md text-white bg-pink focus:outline-none"
>
Купить
</a>
</div>
</div>
</template>
<script>
import { Inertia } from '@inertiajs/inertia'
import axios from 'axios'
import { MenuItem, MenuItems } from '@headlessui/vue'
import {
MinusCircleIcon,
ExclamationIcon,
PencilAltIcon,
} from '@heroicons/vue/solid'
import helper from '@/includes/helper'
import DropdownMenuPoint from '@/Shared/Form/DropdownMenuPoint.vue'
import FeedPaidBlock from '@/Shared/FeedList/FeedPaidBlock.vue'
import UserAvatar from '@/Shared/Misc/UserAvatar.vue'
import LikeCount from '@/Shared/Misc/LikeCount.vue'
import FeedTags from '@/Shared/Misc/FeedTags.vue'
import CommentCount from '@/Shared/Misc/CommentCount.vue'
import ShareCount from '@/Shared/Misc/ShareCount.vue'
import UserComment from '@/Shared/Partials/UserComment.vue'
import ViewCount from '@/Shared/Misc/ViewCount.vue'
export default {
components: {
DropdownMenuPoint,
MenuItem,
MenuItems,
MinusCircleIcon,
ExclamationIcon,
PencilAltIcon,
UserAvatar,
LikeCount,
ShareCount,
CommentCount,
UserComment,
FeedTags,
FeedPaidBlock,
ViewCount,
},
inject: ['is_exist_menu'],
props: {
user: Object,
entity: Object,
feed_id: Number,
},
emits: ['disableModal', 'onRemoveFeed', 'openShare'],
data() {
return {
new_comment: null,
to_user: null,
parent_send_comment: null,
comments: [],
cursor: null,
}
},
computed: {
countPosts() {
return helper.declNumPosts(this.user.count_posts)
},
},
mounted() {
if(this.entity.is_ads == false){
this.loadComments()
this.loadCountPostsUser()
}
this.addView()
},
unmounted() {
this.comments = []
this.cursor = null
},
methods: {
openShareModal(){
this.$emit('openShare')
},
sendAnswerParent(id, to_user_id, username) {
this.parent_send_comment = id
this.to_user = to_user_id
if (this.new_comment) {
this.new_comment = `@${username} ${this.new_comment}`
} else {
this.new_comment = `@${username} `
}
},
onReplaceFeed(data) {
this.entity.collection_medias = data.collection
this.entity.preview = data.preview
this.entity.paid_open = 1
},
loadCountPostsUser() {
if (
typeof this.user.count_posts === 'undefined' ||
parseInt(this.user.count_posts, 10) === 0
) {
axios.post(route('user.posts.count', this.user.id)).then(({ data }) => {
this.user.count_posts = data
})
}
},
onRemoveFeed() {
this.$emit('onRemoveFeed', this.feed_id)
},
loadComments() {
this.$emit('disableModal', 1)
const that = this
axios.post(route('comments.show', this.feed_id), { cursor: this.cursor }).then(({ data }) => {
data.items.forEach(element => {
that.comments.push(element)
})
that.cursor = data.nextCursor
that.$emit('disableModal', 0)
})
},
loadChildrenComment(id, items) {
const index = this.comments.findIndex((comment) => comment.id === id)
this.comments[index].closed_children_comments = 0
items.forEach(element => {
this.comments[index].childrens.push(element)
})
},
removeCommentItem(id, remove_count = 1, parent_id = null) {
if(parent_id){
const index = this.comments.findIndex((comment) => comment.id === parent_id)
const indexChild = this.comments[index].childrens.findIndex((comment) => comment.id === id)
this.comments[index].childrens.splice(indexChild, 1)
}else{
const index = this.comments.findIndex((comment) => comment.id === id)
this.comments.splice(index, 1)
}
this.entity.comments = this.entity.comments - remove_count
},
addView() {
axios
.post(route('add.view.feed', this.feed_id))
.then(({ data }) => {
data && this.entity.views_count++
})
},
addComment() {
if (!this.new_comment) {
return false
}
this.$emit('disableModal', 1)
axios
.post(route('comments.store', this.feed_id), {
body: this.new_comment,
parent: this.parent_send_comment,
to: this.to_user,
})
.then(({ data }) => {
if (this.parent_send_comment) {
const index = this.comments.findIndex(
(comment) => comment.id === this.parent_send_comment
)
this.comments[index].childrens.push(data)
} else {
this.comments.push(data)
}
this.entity.comments++
this.parent_send_comment = null
this.to_user = null
this.$emit('disableModal', 0)
})
this.new_comment = null
},
likeFeed() {
axios
.post(route('feed.like', this.feed_id))
.then(() => {
if (this.entity.liked) {
this.entity.liked = false
this.entity.likes--
} else {
this.entity.liked = true
this.entity.likes++
}
})
// Inertia.post(
// route('feed.like', this.feed_id),
// {},
// {
// preserveScroll: true,
// preserveState: true,
// }
// )
// if (this.entity.liked) {
// this.entity.liked = false
// this.entity.likes--
// } else {
// this.entity.liked = true
// this.entity.likes++
// }
},
},
}
</script>