mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
203 lines
4.8 KiB
Vue
203 lines
4.8 KiB
Vue
<template>
|
|
<div>
|
|
<ds-grid>
|
|
<ds-grid-item v-show="hashtag" :row-span="2" column-span="fullWidth">
|
|
<filter-menu :hashtag="hashtag" @clearSearch="clearSearch" />
|
|
</ds-grid-item>
|
|
<ds-grid-item :row-span="2" column-span="fullWidth">
|
|
<div class="sorting-dropdown">
|
|
<ds-select
|
|
v-model="selected"
|
|
:options="sortingOptions"
|
|
size="large"
|
|
v-bind:icon-right="sortingIcon"
|
|
@input="toggleOnlySorting"
|
|
></ds-select>
|
|
</div>
|
|
</ds-grid-item>
|
|
<hc-post-card
|
|
v-for="post in posts"
|
|
:key="post.id"
|
|
:post="post"
|
|
:width="{ base: '100%', xs: '100%', md: '50%', xl: '33%' }"
|
|
@removePostFromList="deletePost(index, post.id)"
|
|
/>
|
|
</ds-grid>
|
|
<no-ssr>
|
|
<ds-button
|
|
v-tooltip="{ content: 'Create a new Post', placement: 'left', delay: { show: 500 } }"
|
|
:path="{ name: 'post-create' }"
|
|
class="post-add-button"
|
|
icon="plus"
|
|
size="x-large"
|
|
primary
|
|
/>
|
|
</no-ssr>
|
|
<hc-load-more v-if="hasMore" :loading="$apollo.loading" @click="showMoreContributions" />
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import FilterMenu from '~/components/FilterMenu/FilterMenu.vue'
|
|
import uniqBy from 'lodash/uniqBy'
|
|
import HcPostCard from '~/components/PostCard'
|
|
import HcLoadMore from '~/components/LoadMore.vue'
|
|
import { mapGetters } from 'vuex'
|
|
import { filterPosts } from '~/graphql/PostQuery.js'
|
|
|
|
export default {
|
|
components: {
|
|
FilterMenu,
|
|
HcPostCard,
|
|
HcLoadMore,
|
|
},
|
|
data() {
|
|
const { hashtag = null } = this.$route.query
|
|
return {
|
|
posts: [],
|
|
hasMore: true,
|
|
// Initialize your apollo data
|
|
offset: 0,
|
|
pageSize: 12,
|
|
hashtag,
|
|
placeholder: this.$t('sorting.newest'),
|
|
selected: this.$t('sorting.newest'),
|
|
sortingIcon: 'sort-amount-desc',
|
|
sorting: 'createdAt_desc',
|
|
sortingOptions: [
|
|
{
|
|
label: this.$t('sorting.newest'),
|
|
value: 'Newest',
|
|
icons: 'sort-amount-desc',
|
|
order: 'createdAt_desc',
|
|
},
|
|
{
|
|
label: this.$t('sorting.oldest'),
|
|
value: 'Oldest',
|
|
icons: 'sort-amount-asc',
|
|
order: 'createdAt_asc',
|
|
},
|
|
{
|
|
label: this.$t('sorting.popular'),
|
|
value: 'Popular',
|
|
icons: 'fire',
|
|
order: 'shoutedCount_desc',
|
|
},
|
|
{
|
|
label: this.$t('sorting.commented'),
|
|
value: 'Commented',
|
|
icons: 'comment',
|
|
order: 'commentsCount_desc',
|
|
},
|
|
],
|
|
}
|
|
},
|
|
computed: {
|
|
...mapGetters({
|
|
postsFilter: 'postsFilter/postsFilter',
|
|
}),
|
|
finalFilters() {
|
|
let filter = this.postsFilter
|
|
if (this.hashtag) {
|
|
filter = {
|
|
...filter,
|
|
tags_some: { name: this.hashtag },
|
|
}
|
|
}
|
|
return filter
|
|
},
|
|
},
|
|
watch: {
|
|
postsFilter() {
|
|
this.offset = 0
|
|
this.posts = []
|
|
},
|
|
},
|
|
methods: {
|
|
toggleOnlySorting(x) {
|
|
this.offset = 0
|
|
this.posts = []
|
|
this.sortingIcon = x.icons
|
|
this.sorting = x.order
|
|
},
|
|
clearSearch() {
|
|
this.$router.push({ path: '/' })
|
|
this.hashtag = null
|
|
},
|
|
href(post) {
|
|
return this.$router.resolve({
|
|
name: 'post-id-slug',
|
|
params: { id: post.id, slug: post.slug },
|
|
}).href
|
|
},
|
|
showMoreContributions() {
|
|
this.offset += this.pageSize
|
|
},
|
|
deletePost(_index, postId) {
|
|
this.posts = this.posts.filter(post => {
|
|
return post.id !== postId
|
|
})
|
|
},
|
|
},
|
|
apollo: {
|
|
Post: {
|
|
query() {
|
|
return filterPosts(this.$i18n)
|
|
},
|
|
variables() {
|
|
const result = {
|
|
filter: this.finalFilters,
|
|
first: this.pageSize,
|
|
offset: this.offset,
|
|
orderBy: this.sorting,
|
|
}
|
|
return result
|
|
},
|
|
update({ Post }) {
|
|
// TODO: find out why `update` gets called twice initially.
|
|
// We have to filter for uniq posts only because we get the same
|
|
// result set twice.
|
|
this.hasMore = Post.length >= this.pageSize
|
|
const posts = uniqBy([...this.posts, ...Post], 'id')
|
|
this.posts = posts
|
|
},
|
|
fetchPolicy: 'cache-and-network',
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.masonry-grid {
|
|
display: grid;
|
|
grid-gap: 10px;
|
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
|
grid-auto-rows: 20px;
|
|
}
|
|
|
|
.grid-item {
|
|
grid-row-end: span 2;
|
|
|
|
&--full-width {
|
|
grid-column: 1 / -1;
|
|
}
|
|
}
|
|
|
|
.post-add-button {
|
|
z-index: 100;
|
|
position: fixed;
|
|
top: 98vh;
|
|
left: 98vw;
|
|
transform: translate(-120%, -120%);
|
|
box-shadow: $box-shadow-x-large;
|
|
}
|
|
|
|
.sorting-dropdown {
|
|
width: 250px;
|
|
position: relative;
|
|
float: right;
|
|
padding: 0 18px;
|
|
margin: 4px 0;
|
|
}
|
|
</style>
|