kopia lustrzana https://github.com/nextcloud/social
👌 IMPROVE: move timeline to css grid layout and restructure code
Signed-off-by: Jonas Sulzer <jonas@violoncello.ch>pull/748/head
rodzic
19dfe49661
commit
ea53553e91
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div v-if="item.actor_info" class="post-avatar">
|
||||
<avatar v-if="item.local" :size="32" :user="userTest"
|
||||
:display-name="item.actor_info.account" :disable-tooltip="true" />
|
||||
<avatar v-else :size="32" :url="avatarUrl"
|
||||
:disable-tooltip="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from '@nextcloud/vue/dist/Components/Avatar'
|
||||
|
||||
export default {
|
||||
name: 'TimelineAvatar',
|
||||
components: {
|
||||
Avatar
|
||||
},
|
||||
props: {
|
||||
item: { type: Object, default: () => {} }
|
||||
},
|
||||
computed: {
|
||||
userTest() {
|
||||
return this.item.actor_info.preferredUsername
|
||||
},
|
||||
avatarUrl() {
|
||||
return OC.generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.item.attributedTo)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.post-avatar {
|
||||
margin: 5px;
|
||||
margin-right: 10px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
min-width: 32px;
|
||||
flex-shrink: 0;
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -1,9 +1,12 @@
|
|||
<template>
|
||||
<div class="timeline-entry">
|
||||
<div v-if="item.type === 'SocialAppNotification'">
|
||||
{{ actionSummary }}
|
||||
</div>
|
||||
<div v-if="item.type === 'Announce'" class="boost">
|
||||
<template v-if="item.type === 'SocialAppNotification'">
|
||||
<div class="notification-icon" :class="notificationIcon" />
|
||||
<span class="notification-action">
|
||||
{{ actionSummary }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="item.type === 'Announce'" class="boost">
|
||||
<div class="container-icon-boost">
|
||||
<span class="icon-boost" />
|
||||
</div>
|
||||
|
@ -18,24 +21,28 @@
|
|||
</span>
|
||||
</a>
|
||||
{{ boosted }}
|
||||
</div>
|
||||
<timeline-post
|
||||
v-if="item.type === 'SocialAppNotification' && item.details.post"
|
||||
:item="item.details.post" />
|
||||
<timeline-post
|
||||
v-else
|
||||
:item="entryContent"
|
||||
:parent-announce="isBoost" />
|
||||
</template>
|
||||
<user-entry v-if="item.type === 'SocialAppNotification' && item.details.actor" :key="item.details.actor.id" :item="item.details.actor" />
|
||||
<template v-else>
|
||||
<timeline-avatar :item="entryContent" />
|
||||
<timeline-post
|
||||
:item="entryContent"
|
||||
:parent-announce="isBoost" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TimelinePost from './TimelinePost.vue'
|
||||
import TimelineAvatar from './TimelineAvatar.vue'
|
||||
import UserEntry from './UserEntry.vue'
|
||||
|
||||
export default {
|
||||
name: 'TimelineEntry',
|
||||
components: {
|
||||
TimelinePost
|
||||
TimelinePost,
|
||||
TimelineAvatar,
|
||||
UserEntry
|
||||
},
|
||||
props: {
|
||||
item: { type: Object, default: () => {} }
|
||||
|
@ -48,6 +55,8 @@ export default {
|
|||
entryContent() {
|
||||
if (this.item.type === 'Announce') {
|
||||
return this.item.cache[this.item.object].object
|
||||
} else if (this.item.type === 'SocialAppNotification') {
|
||||
return this.item.details.post
|
||||
} else {
|
||||
return this.item
|
||||
}
|
||||
|
@ -102,12 +111,55 @@ export default {
|
|||
</script>
|
||||
<style scoped lang="scss">
|
||||
.timeline-entry {
|
||||
display: grid;
|
||||
grid-template-columns: 44px 1fr;
|
||||
grid-template-rows: 30px 1fr;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
&:hover {
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
}
|
||||
.notification-header {
|
||||
display: flex;
|
||||
align-items: bottom;
|
||||
}
|
||||
|
||||
.notification-action {
|
||||
flex-grow: 1;
|
||||
display: inline-block;
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
opacity: .5;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
overflow: hidden;
|
||||
height: 20px;
|
||||
min-width: 32px;
|
||||
flex-shrink: 0;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.icon-boost {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.icon-favorite {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.icon-user {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.container-icon-boost {
|
||||
display: inline-block;
|
||||
|
|
|
@ -1,55 +1,47 @@
|
|||
<template>
|
||||
<div class="entry-content">
|
||||
<div v-if="item.actor_info" class="post-avatar">
|
||||
<avatar v-if="item.local && item.type!=='SocialAppNotification'" :size="32" :user="item.actor_info.preferredUsername"
|
||||
:display-name="item.actor_info.account" :disable-tooltip="true" />
|
||||
<avatar v-else :size="32" :url="avatarUrl"
|
||||
:disable-tooltip="true" />
|
||||
</div>
|
||||
<div class="post-content">
|
||||
<div class="post-header">
|
||||
<div class="post-author-wrapper">
|
||||
<router-link v-if="item.actor_info"
|
||||
:to="{ name: 'profile',
|
||||
params: { account: (item.local && item.type!=='SocialAppNotification') ? item.actor_info.preferredUsername : item.actor_info.account }
|
||||
}">
|
||||
<span class="post-author">
|
||||
{{ userDisplayName(item.actor_info) }}
|
||||
</span>
|
||||
<span class="post-author-id">
|
||||
@{{ item.actor_info.account }}
|
||||
</span>
|
||||
</router-link>
|
||||
<a v-else :href="item.attributedTo">
|
||||
<span class="post-author-id">
|
||||
{{ item.attributedTo }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<a :data-timestamp="timestamp" class="post-timestamp live-relative-timestamp" @click="getSinglePostTimeline">
|
||||
{{ relativeTimestamp }}
|
||||
<div class="post-content">
|
||||
<div class="post-header">
|
||||
<div class="post-author-wrapper">
|
||||
<router-link v-if="item.actor_info"
|
||||
:to="{ name: 'profile',
|
||||
params: { account: (item.local && item.type!=='SocialAppNotification') ? item.actor_info.preferredUsername : item.actor_info.account }
|
||||
}">
|
||||
<span class="post-author">
|
||||
{{ userDisplayName(item.actor_info) }}
|
||||
</span>
|
||||
<span class="post-author-id">
|
||||
@{{ item.actor_info.account }}
|
||||
</span>
|
||||
</router-link>
|
||||
<a v-else :href="item.attributedTo">
|
||||
<span class="post-author-id">
|
||||
{{ item.attributedTo }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-if="item.content" class="post-message">
|
||||
<MessageContent :source="source" />
|
||||
</div>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-else class="post-message" v-html="item.actor_info.summary" />
|
||||
<div v-if="hasAttachments" class="post-attachments">
|
||||
<post-attachment :attachments="item.attachment" />
|
||||
</div>
|
||||
<div v-if="this.$route.params.type!=='notifications' && !serverData.public" v-click-outside="hidePopoverMenu" class="post-actions">
|
||||
<a v-tooltip.bottom="t('social', 'Reply')" class="icon-reply" @click.prevent="reply" />
|
||||
<a v-if="item.actor_info.account !== cloudId" v-tooltip.bottom="t('social', 'Boost')"
|
||||
:class="(isBoosted) ? 'icon-boosted' : 'icon-boost'"
|
||||
@click.prevent="boost" />
|
||||
<a v-tooltip.bottom="t('social', 'Like')" :class="(isLiked) ? 'icon-starred' : 'icon-favorite'" @click.prevent="like" />
|
||||
<div v-if="popoverMenu.length > 0" v-tooltip.bottom="menuOpened ? '' : t('social', 'More actions')" class="post-actions-more">
|
||||
<a class="icon-more" @click.prevent="togglePopoverMenu" />
|
||||
<div :class="{open: menuOpened}" class="popovermenu menu-center">
|
||||
<popover-menu :menu="popoverMenu" />
|
||||
</div>
|
||||
<a :data-timestamp="timestamp" class="post-timestamp live-relative-timestamp" @click="getSinglePostTimeline">
|
||||
{{ relativeTimestamp }}
|
||||
</a>
|
||||
</div>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-if="item.content" class="post-message">
|
||||
<MessageContent :source="source" />
|
||||
</div>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-else class="post-message" v-html="item.actor_info.summary" />
|
||||
<div v-if="hasAttachments" class="post-attachments">
|
||||
<post-attachment :attachments="item.attachment" />
|
||||
</div>
|
||||
<div v-if="this.$route.params.type!=='notifications' && !serverData.public" v-click-outside="hidePopoverMenu" class="post-actions">
|
||||
<a v-tooltip.bottom="t('social', 'Reply')" class="icon-reply" @click.prevent="reply" />
|
||||
<a v-if="item.actor_info.account !== cloudId" v-tooltip.bottom="t('social', 'Boost')"
|
||||
:class="(isBoosted) ? 'icon-boosted' : 'icon-boost'"
|
||||
@click.prevent="boost" />
|
||||
<a v-tooltip.bottom="t('social', 'Like')" :class="(isLiked) ? 'icon-starred' : 'icon-favorite'" @click.prevent="like" />
|
||||
<div v-if="popoverMenu.length > 0" v-tooltip.bottom="menuOpened ? '' : t('social', 'More actions')" class="post-actions-more">
|
||||
<a class="icon-more" @click.prevent="togglePopoverMenu" />
|
||||
<div :class="{open: menuOpened}" class="popovermenu menu-center">
|
||||
<popover-menu :menu="popoverMenu" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -57,7 +49,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from '@nextcloud/vue/dist/Components/Avatar'
|
||||
import * as linkify from 'linkifyjs'
|
||||
import pluginMention from 'linkifyjs/plugins/mention'
|
||||
import 'linkifyjs/string'
|
||||
|
@ -74,7 +65,6 @@ pluginMention(linkify)
|
|||
export default {
|
||||
name: 'TimelinePost',
|
||||
components: {
|
||||
Avatar,
|
||||
PostAttachment,
|
||||
MessageContent
|
||||
},
|
||||
|
@ -207,17 +197,6 @@ export default {
|
|||
opacity: .7;
|
||||
}
|
||||
|
||||
.post-avatar {
|
||||
margin: 5px;
|
||||
margin-right: 10px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
min-width: 32px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.post-timestamp {
|
||||
width: 120px;
|
||||
text-align: right;
|
||||
|
@ -262,6 +241,8 @@ export default {
|
|||
|
||||
.post-content {
|
||||
flex-grow: 1;
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
.post-header {
|
||||
|
|
|
@ -50,9 +50,7 @@ module.exports = {
|
|||
},
|
||||
plugins: [new VueLoaderPlugin()],
|
||||
resolve: {
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js'
|
||||
},
|
||||
extensions: ['*', '.js', '.vue', '.json']
|
||||
extensions: ['*', '.js', '.vue'],
|
||||
symlinks: false
|
||||
}
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue