fixed design differences between alpha & nitro - Post Page

- [X] Title and Author Position reversed
- [X] Design & Format of Post-Date + Position
- [X] No Category Names
- [X] Actions/Reactions & Tags reversed
This commit is contained in:
Ulf Gebhardt 2019-04-08 15:53:00 +02:00
parent cece32f55d
commit 0e09b0fb74
No known key found for this signature in database
GPG Key ID: 44C888923CC8E7F3
5 changed files with 174 additions and 128 deletions

View File

@ -0,0 +1,16 @@
<template>
<ds-tag>
<ds-icon size="large" :name="icon"/>
{{ name }}
</ds-tag>
</template>
<script>
export default {
name: 'hc-category',
props: {
icon: { type: String },
name: { type: String }
}
}
</script>

View File

@ -0,0 +1,72 @@
<template>
<span :title="absoluteTime">{{ relativeDateTime }}</span>
</template>
<script>
import moment from 'moment'
export default {
name: 'hc-relative-date-time',
props: {
dateTime: {
type: [Date, String]
}
},
data() {
return {
relativeDateTime: null,
interval: 15000,
timeout: null,
absoluteTime: null
}
},
computed: {
locale() {
return this.$i18n.locale() || 'en'
}
},
watch: {
locale() {
this.calcRelativeDateTime()
},
dateTime(dateTime) {
this.calcRelativeDateTime()
}
},
methods: {
calcRelativeDateTime() {
clearTimeout(this.timeout)
let t = moment(this.dateTime).locale(this.locale)
this.absoluteTime = t.format('llll')
this.relativeDateTime = t.utc().fromNow()
if (!process.browser) {
return
}
if (
this.relativeDateTime ===
t
.add(this.interval, 'milliseconds')
.utc()
.fromNow()
) {
this.interval += 15000
}
this.timeout = setTimeout(() => {
this.calcRelativeDateTime()
}, this.interval)
}
},
created() {
this.calcRelativeDateTime()
},
mounted() {
this.calcRelativeDateTime()
},
destroyed() {
clearTimeout(this.timeout)
}
}
</script>

15
webapp/components/Tag.vue Normal file
View File

@ -0,0 +1,15 @@
<template>
<ds-tag>
<ds-icon name="tag"/>
{{ name }}
</ds-tag>
</template>
<script>
export default {
name: 'hc-tag',
props: {
name: { type: String }
}
}
</script>

View File

@ -1,39 +1,21 @@
<template> <template>
<div v-if="!user || ((user.disabled || user.deleted) && !isModerator)"> <div v-if="!user || ((user.disabled || user.deleted) && !isModerator)">
<div style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"> <div
<ds-avatar style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
style="display: inline-block; vertical-align: middle;" >
size="32px" <ds-avatar style="display: inline-block; vertical-align: middle;" size="32px"/>
/>
</div> </div>
<div style="display: inline-block; height: 100%; vertical-align: middle;"> <div style="display: inline-block; height: 100%; vertical-align: middle;">
<b <b class="username" style="vertical-align: middle;">Anonymus</b>
class="username"
style="vertical-align: middle;"
>
Anonymus
</b>
</div> </div>
</div> </div>
<dropdown <dropdown v-else :class="{'disabled-content': user.disabled}" placement="top-start" offset="0">
v-else <template slot="default" slot-scope="{openMenu, closeMenu, isOpen}">
:class="{'disabled-content': user.disabled}" <nuxt-link :to="userLink" :class="['user', isOpen && 'active']">
placement="top-start" <div @mouseover="openMenu(true)" @mouseleave="closeMenu(true)">
offset="0" <div
> style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
<template >
slot="default"
slot-scope="{openMenu, closeMenu, isOpen}"
>
<nuxt-link
:to="userLink"
:class="['user', isOpen && 'active']"
>
<div
@mouseover="openMenu(true)"
@mouseleave="closeMenu(true)"
>
<div style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;">
<ds-avatar <ds-avatar
:image="user.avatar" :image="user.avatar"
:name="user.name" :name="user.name"
@ -45,21 +27,21 @@
<b <b
class="username" class="username"
style="vertical-align: middle;" style="vertical-align: middle;"
> >{{ user.name | truncate(trunc, 18) }}</b>
{{ user.name | truncate(trunc, 18) }} </div>
</b> <!-- Time -->
<div v-if="dateTime" style="display: inline;">
<ds-text align="right" size="small" color="soft">
<ds-icon name="clock"/>&nbsp;
<hc-relative-date-time :dateTime="dateTime"/>
</ds-text>
</div> </div>
</div> </div>
</nuxt-link> </nuxt-link>
</template> </template>
<template <template slot="popover">
slot="popover"
>
<div style="min-width: 250px"> <div style="min-width: 250px">
<hc-badges <hc-badges v-if="user.badges && user.badges.length" :badges="user.badges"/>
v-if="user.badges && user.badges.length"
:badges="user.badges"
/>
<ds-text <ds-text
v-if="user.location" v-if="user.location"
align="center" align="center"
@ -68,18 +50,13 @@
style="margin-top: 5px" style="margin-top: 5px"
bold bold
> >
<ds-icon name="map-marker" /> {{ user.location.name }} <ds-icon name="map-marker"/>
{{ user.location.name }}
</ds-text> </ds-text>
<ds-flex <ds-flex style="margin-top: -10px">
style="margin-top: -10px"
>
<ds-flex-item class="ds-tab-nav-item"> <ds-flex-item class="ds-tab-nav-item">
<ds-space margin="small"> <ds-space margin="small">
<ds-number <ds-number :count="fanCount" :label="$t('profile.followers')" size="x-large"/>
:count="fanCount"
:label="$t('profile.followers')"
size="x-large"
/>
</ds-space> </ds-space>
</ds-flex-item> </ds-flex-item>
<ds-flex-item class="ds-tab-nav-item ds-tab-nav-item-active"> <ds-flex-item class="ds-tab-nav-item ds-tab-nav-item-active">
@ -99,11 +76,7 @@
</ds-space> </ds-space>
</ds-flex-item> </ds-flex-item>
</ds-flex> </ds-flex>
<ds-flex <ds-flex v-if="!itsMe" gutter="x-small" style="margin-bottom: 0;">
v-if="!itsMe"
gutter="x-small"
style="margin-bottom: 0;"
>
<ds-flex-item :width="{base: 3}"> <ds-flex-item :width="{base: 3}">
<hc-follow-button <hc-follow-button
:follow-id="user.id" :follow-id="user.id"
@ -114,7 +87,7 @@
</ds-flex-item> </ds-flex-item>
<ds-flex-item :width="{base: 1}"> <ds-flex-item :width="{base: 1}">
<ds-button fullwidth> <ds-button fullwidth>
<ds-icon name="user-times" /> <ds-icon name="user-times"/>
</ds-button> </ds-button>
</ds-flex-item> </ds-flex-item>
</ds-flex> </ds-flex>
@ -125,21 +98,25 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'
import HcRelativeDateTime from '~/components/RelativeDateTime.vue'
import HcFollowButton from '~/components/FollowButton.vue' import HcFollowButton from '~/components/FollowButton.vue'
import HcBadges from '~/components/Badges.vue' import HcBadges from '~/components/Badges.vue'
import Dropdown from '~/components/Dropdown' import Dropdown from '~/components/Dropdown'
import { mapGetters } from 'vuex'
export default { export default {
name: 'HcUser', name: 'HcUser',
components: { components: {
HcRelativeDateTime,
HcFollowButton, HcFollowButton,
HcBadges, HcBadges,
Dropdown Dropdown
}, },
props: { props: {
user: { type: Object, default: null }, user: { type: Object, default: null },
trunc: { type: Number, default: null } trunc: { type: Number, default: null },
dateTime: { type: [Date, String], default: null }
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({

View File

@ -1,15 +1,12 @@
<template> <template>
<transition <transition name="fade" appear>
name="fade"
appear
>
<ds-card <ds-card
v-if="post && ready" v-if="post && ready"
:image="post.image" :image="post.image"
:header="post.title"
:class="{'post-card': true, 'disabled-content': post.disabled}" :class="{'post-card': true, 'disabled-content': post.disabled}"
> >
<hc-user :user="post.author" /> <ds-space margin-bottom="small"/>
<hc-user :user="post.author" :dateTime="post.createdAt"/>
<no-ssr> <no-ssr>
<content-menu <content-menu
placement="bottom-end" placement="bottom-end"
@ -18,27 +15,33 @@
:is-owner="isAuthor(post.author.id)" :is-owner="isAuthor(post.author.id)"
/> />
</no-ssr> </no-ssr>
<ds-space margin-bottom="small" /> <ds-space margin-bottom="small"/>
<ds-heading tag="h3" no-margin>{{ post.title }}</ds-heading>
<ds-space margin-bottom="small"/>
<!-- Content --> <!-- Content -->
<!-- eslint-disable vue/no-v-html --> <!-- eslint-disable vue/no-v-html -->
<!-- TODO: replace editor content with tiptap render view --> <!-- TODO: replace editor content with tiptap render view -->
<div <div class="content hc-editor-content" v-html="post.content"/>
class="content hc-editor-content"
v-html="post.content"
/>
<ds-space>
<ds-text
v-if="post.createdAt"
align="right"
size="small"
color="soft"
>
{{ post.createdAt | dateTime('dd. MMMM yyyy HH:mm') }}
</ds-text>
</ds-space>
<!-- eslint-enable vue/no-v-html --> <!-- eslint-enable vue/no-v-html -->
<ds-space margin="xx-large"/>
<!-- Categories -->
<div class="categories">
<ds-space margin="xx-small"/>
<hc-category
v-for="category in post.categories"
v-tooltip="{content: category.name, placement: 'top-start', delay: { show: 300 }}"
:key="category.id"
:icon="category.icon"
:name="category.name"
/>
</div>
<ds-space margin-bottom="small"/>
<!-- Tags -->
<div class="tags" v-if="post.tags && post.tags.length">
<ds-space margin="xx-small"/>
<hc-tag v-for="tag in post.tags" :key="tag.id" :name="tag.name"/>
</div>
<!-- Shout Button --> <!-- Shout Button -->
<ds-space margin="xx-large" />
<hc-shout-button <hc-shout-button
v-if="post.author" v-if="post.author"
:disabled="isAuthor(post.author.id)" :disabled="isAuthor(post.author.id)"
@ -46,68 +49,26 @@
:is-shouted="post.shoutedByCurrentUser" :is-shouted="post.shoutedByCurrentUser"
:post-id="post.id" :post-id="post.id"
/> />
<!-- Categories --> <ds-space margin="small"/>
<ds-icon
v-for="category in post.categories"
:key="category.id"
v-tooltip="{content: category.name, placement: 'top-start', delay: { show: 300 }}"
:name="category.icon"
size="large"
/>&nbsp;
<ds-space margin-bottom="small" />
<!--<div class="tags">
<ds-icon name="compass" /> <ds-tag
v-for="category in post.categories"
:key="category.id"
>
{{ category.name }}
</ds-tag>
</div>-->
<!-- Tags -->
<template v-if="post.tags && post.tags.length">
<ds-space margin="xx-small" />
<div class="tags">
<ds-icon name="tags" /> <ds-tag
v-for="tag in post.tags"
:key="tag.id"
>
<ds-icon name="tag" /> {{ tag.name }}
</ds-tag>
</div>
</template>
<ds-space margin="small" />
<!-- Comments --> <!-- Comments -->
<ds-section slot="footer"> <ds-section slot="footer">
<h3 style="margin-top: 0;"> <h3 style="margin-top: 0;">
<span> <span>
<ds-icon name="comments" /> <ds-icon name="comments"/>
<ds-tag <ds-tag
v-if="post.comments" v-if="post.comments"
style="margin-top: -4px; margin-left: -12px; position: absolute;" style="margin-top: -4px; margin-left: -12px; position: absolute;"
color="primary" color="primary"
size="small" size="small"
round round
> >{{ post.commentsCount }}</ds-tag>&nbsp; Comments
{{ post.commentsCount }}
</ds-tag> &nbsp; Comments
</span> </span>
</h3> </h3>
<ds-space margin-bottom="large" /> <ds-space margin-bottom="large"/>
<div <div v-if="post.comments" id="comments" class="comments">
v-if="post.comments" <comment v-for="comment in post.comments" :key="comment.id" :comment="comment"/>
id="comments"
class="comments"
>
<comment
v-for="comment in post.comments"
:key="comment.id"
:comment="comment"
/>
</div> </div>
<hc-empty <hc-empty v-else icon="messages"/>
v-else
icon="messages"
/>
</ds-section> </ds-section>
</ds-card> </ds-card>
</transition> </transition>
@ -115,6 +76,9 @@
<script> <script>
import gql from 'graphql-tag' import gql from 'graphql-tag'
import HcCategory from '~/components/Category.vue'
import HcTag from '~/components/Tag.vue'
import ContentMenu from '~/components/ContentMenu' import ContentMenu from '~/components/ContentMenu'
import HcUser from '~/components/User.vue' import HcUser from '~/components/User.vue'
import HcShoutButton from '~/components/ShoutButton.vue' import HcShoutButton from '~/components/ShoutButton.vue'
@ -127,6 +91,8 @@ export default {
mode: 'out-in' mode: 'out-in'
}, },
components: { components: {
HcTag,
HcCategory,
HcUser, HcUser,
HcShoutButton, HcShoutButton,
HcEmpty, HcEmpty,