add optional categories to teaser and post

This commit is contained in:
Moriz Wahl 2022-07-25 20:03:00 +02:00
parent 1b2509229c
commit bc955003f7
3 changed files with 46 additions and 5 deletions

View File

@ -26,7 +26,19 @@
class="footer" class="footer"
v-observe-visibility="(isVisible, entry) => visibilityChanged(isVisible, entry, post.id)" v-observe-visibility="(isVisible, entry) => visibilityChanged(isVisible, entry, post.id)"
> >
<div class="categories-placeholder"></div> <div class="categories" v-if="categoriesActive">
<hc-category
v-for="category in post.categories"
:key="category.id"
v-tooltip="{
content: $t(`contribution.category.name.${category.slug}`),
placement: 'bottom-start',
delay: { show: 500 },
}"
:icon="category.icon"
/>
</div>
<div v-else class="categories-placeholder"></div>
<counter-icon <counter-icon
icon="bullhorn" icon="bullhorn"
:count="post.shoutedCount" :count="post.shoutedCount"
@ -70,6 +82,7 @@
import UserTeaser from '~/components/UserTeaser/UserTeaser' import UserTeaser from '~/components/UserTeaser/UserTeaser'
import ContentMenu from '~/components/ContentMenu/ContentMenu' import ContentMenu from '~/components/ContentMenu/ContentMenu'
import HcRibbon from '~/components/Ribbon' import HcRibbon from '~/components/Ribbon'
import HcCategory from '~/components/Category'
import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon' import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import PostMutations from '~/graphql/PostMutations' import PostMutations from '~/graphql/PostMutations'
@ -79,6 +92,7 @@ export default {
name: 'PostTeaser', name: 'PostTeaser',
components: { components: {
UserTeaser, UserTeaser,
HcCategory,
HcRibbon, HcRibbon,
ContentMenu, ContentMenu,
CounterIcon, CounterIcon,
@ -93,6 +107,11 @@ export default {
default: () => {}, default: () => {},
}, },
}, },
data() {
return {
categoriesActive: this.$env.CATEGORIES_ACTIVE,
}
},
mounted() { mounted() {
const { image } = this.post const { image } = this.post
if (!image) return if (!image) return

View File

@ -78,6 +78,12 @@ export const tagsCategoriesAndPinnedFragment = gql`
tags { tags {
id id
} }
categories {
id
slug
name
icon
}
pinnedBy { pinnedBy {
id id
name name

View File

@ -44,6 +44,19 @@
<h2 class="title hyphenate-text">{{ post.title }}</h2> <h2 class="title hyphenate-text">{{ post.title }}</h2>
<ds-space margin-bottom="small" /> <ds-space margin-bottom="small" />
<content-viewer class="content hyphenate-text" :content="post.content" /> <content-viewer class="content hyphenate-text" :content="post.content" />
<!-- Categories -->
<div v-if="categoriesActive" class="categories">
<!-- eslint-enable vue/no-v-html -->
<ds-space margin="xx-large" />
<ds-space margin="xx-small" />
<hc-category
v-for="category in post.categories"
:key="category.id"
:icon="category.icon"
:name="$t(`contribution.category.name.${category.slug}`)"
/>
</div>
<ds-space margin-bottom="small" />
<!-- Tags --> <!-- Tags -->
<div v-if="post.tags && post.tags.length" class="tags"> <div v-if="post.tags && post.tags.length" class="tags">
<ds-space margin="xx-small" /> <ds-space margin="xx-small" />
@ -91,6 +104,7 @@
<script> <script>
import ContentViewer from '~/components/Editor/ContentViewer' import ContentViewer from '~/components/Editor/ContentViewer'
import HcCategory from '~/components/Category'
import HcHashtag from '~/components/Hashtag/Hashtag' import HcHashtag from '~/components/Hashtag/Hashtag'
import ContentMenu from '~/components/ContentMenu/ContentMenu' import ContentMenu from '~/components/ContentMenu/ContentMenu'
import UserTeaser from '~/components/UserTeaser/UserTeaser' import UserTeaser from '~/components/UserTeaser/UserTeaser'
@ -118,6 +132,7 @@ export default {
CommentForm, CommentForm,
CommentList, CommentList,
ContentViewer, ContentViewer,
HcCategory,
HcHashtag, HcHashtag,
HcShoutButton, HcShoutButton,
PageParamsLink, PageParamsLink,
@ -138,6 +153,7 @@ export default {
blurred: false, blurred: false,
blocked: null, blocked: null,
postAuthor: null, postAuthor: null,
categoriesActive: this.$env.CATEGORIES_ACTIVE,
} }
}, },
mounted() { mounted() {
@ -171,12 +187,12 @@ export default {
heroImageStyle() { heroImageStyle() {
/* Return false when image property is not present or is not a number /* Return false when image property is not present or is not a number
so no unnecessary css variables are set. so no unnecessary css variables are set.
*/ */
if (!this.post.image || typeof this.post.image.aspectRatio !== 'number') return false if (!this.post.image || typeof this.post.image.aspectRatio !== 'number') return false
/* Return the aspect ratio as a css variable. Later to be used when calculating /* Return the aspect ratio as a css variable. Later to be used when calculating
the height with respect to the width. the height with respect to the width.
*/ */
return { return {
'--hero-image-aspect-ratio': 1.0 / this.post.image.aspectRatio, '--hero-image-aspect-ratio': 1.0 / this.post.image.aspectRatio,
} }
@ -253,12 +269,12 @@ export default {
/* The padding top makes sure the correct height is set (according to the /* The padding top makes sure the correct height is set (according to the
hero image aspect ratio) before the hero image loads so hero image aspect ratio) before the hero image loads so
the autoscroll works correctly when following a comment link. the autoscroll works correctly when following a comment link.
*/ */
padding-top: calc(var(--hero-image-aspect-ratio) * (100% + 48px)); padding-top: calc(var(--hero-image-aspect-ratio) * (100% + 48px));
/* Letting the image fill the container, since the container /* Letting the image fill the container, since the container
is the one determining height is the one determining height
*/ */
> .image { > .image {
position: absolute; position: absolute;
top: 0; top: 0;