kopia lustrzana https://github.com/nextcloud/social
Merge pull request #625 from nextcloud/feature/605/notificationsTimeline
[WIP] Notifications timeline (frontend)pull/732/head
commit
fd069f3e60
|
@ -2,6 +2,7 @@
|
|||
@include icon-black-white('emoji', 'social', 1);
|
||||
@include icon-black-white('boost', 'social', 1);
|
||||
@include icon-black-white('upload', 'actions', 1, true);
|
||||
@include icon-black-white('notifications', 'social', 1);
|
||||
|
||||
.icon-boosted {
|
||||
@include icon-color('boost', 'social', '#0082c9', 1);
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16">
|
||||
<path d="m8 2c-0.5523 0-1 0.4477-1 1 0 0.0472 0.021 0.0873 0.0273 0.1328-1.7366 0.4362-3.0273 1.9953-3.0273 3.8672v2l-1 1v1h10v-1l-1-1v-2c0-1.8719-1.291-3.431-3.0273-3.8672 0.0063-0.0455 0.0273-0.0856 0.0273-0.1328 0-0.5523-0.4477-1-1-1zm-2 10c0 1.1046 0.8954 2 2 2s2-0.8954 2-2z" fill="#000"/>
|
||||
</svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 456 B |
|
@ -122,6 +122,8 @@ trait TDetails {
|
|||
public function addDetail(string $detail, string $value) {
|
||||
if (!array_key_exists($detail, $this->details) || !is_array($this->details[$detail])) {
|
||||
$this->details[$detail] = [];
|
||||
} else if (in_array($value, $this->details[$detail])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->details[$detail][] = $value;
|
||||
|
|
20
src/App.vue
20
src/App.vue
|
@ -136,16 +136,16 @@ export default {
|
|||
icon: 'icon-comment',
|
||||
text: t('social', 'Direct messages')
|
||||
},
|
||||
// {
|
||||
// id: 'social-notifications',
|
||||
// classes: [],
|
||||
// router: {
|
||||
// name: 'timeline',
|
||||
// params: { type: 'notifications' }
|
||||
// },
|
||||
// icon: 'icon-comment',
|
||||
// text: t('social', 'Notifications')
|
||||
// },
|
||||
{
|
||||
id: 'social-notifications',
|
||||
classes: [],
|
||||
router: {
|
||||
name: 'timeline',
|
||||
params: { type: 'notifications' }
|
||||
},
|
||||
icon: 'icon-notifications',
|
||||
text: t('social', 'Notifications')
|
||||
},
|
||||
{
|
||||
id: 'social-account',
|
||||
classes: [],
|
||||
|
|
|
@ -19,20 +19,23 @@
|
|||
</a>
|
||||
{{ boosted }}
|
||||
</div>
|
||||
<timeline-post v-if="(item.type === 'Note' || item.type === 'Announce')" :item="entryContent" :parent-announce="isBoost" />
|
||||
<user-entry v-if="item.type === 'SocialAppNotificationUser'" :key="user.id" :item="user" />
|
||||
<timeline-post
|
||||
v-if="item.type === 'SocialAppNotification' && item.details.post"
|
||||
:item="item.details.post" />
|
||||
<timeline-post
|
||||
v-else
|
||||
:item="entryContent"
|
||||
:parent-announce="isBoost" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TimelinePost from './TimelinePost.vue'
|
||||
import UserEntry from './UserEntry.vue'
|
||||
|
||||
export default {
|
||||
name: 'TimelineEntry',
|
||||
components: {
|
||||
TimelinePost,
|
||||
UserEntry
|
||||
TimelinePost
|
||||
},
|
||||
props: {
|
||||
item: { type: Object, default: () => {} }
|
||||
|
@ -59,11 +62,34 @@ export default {
|
|||
return t('social', 'boosted')
|
||||
},
|
||||
actionSummary() {
|
||||
|
||||
let summary = this.item.summary
|
||||
for (var key in this.item.details) {
|
||||
|
||||
let keyword = '{' + key + '}'
|
||||
summary = summary.replace(keyword, JSON.stringify(this.item.details[key]))
|
||||
if (typeof this.item.details[key] !== 'string' && this.item.details[key].length > 1) {
|
||||
|
||||
let concatination = ''
|
||||
for (var stringKey in this.item.details[key]) {
|
||||
|
||||
if (this.item.details[key].length > 3 && stringKey === '3') {
|
||||
// ellipses the actors' list to 3 actors when it's big
|
||||
concatination = concatination.substring(0, concatination.length - 2)
|
||||
concatination += ' and ' + (this.item.details[key].length - 3).toString() + ' other(s), '
|
||||
break
|
||||
} else {
|
||||
concatination += this.item.details[key][stringKey] + ', '
|
||||
}
|
||||
}
|
||||
|
||||
concatination = concatination.substring(0, concatination.length - 2)
|
||||
summary = summary.replace(keyword, concatination)
|
||||
|
||||
} else {
|
||||
summary = summary.replace(keyword, this.item.details[key])
|
||||
}
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
},
|
||||
|
|
|
@ -92,15 +92,24 @@ export default {
|
|||
title: t('social', 'No local posts found'),
|
||||
description: t('social', 'Posts from other people on this instance will show up here')
|
||||
},
|
||||
notifications: {
|
||||
image: 'img/undraw/notifications.svg',
|
||||
title: t('social', 'No notifications found'),
|
||||
description: t('social', 'You haven\'t receive any notifications yet')
|
||||
},
|
||||
federated: {
|
||||
image: 'img/undraw/global.svg',
|
||||
title: t('social', 'No global posts found'),
|
||||
description: t('social', 'Posts from federated instances will show up here')
|
||||
},
|
||||
liked: {
|
||||
image: 'img/undraw/profile.svg',
|
||||
image: 'img/undraw/likes.svg',
|
||||
title: t('social', 'No liked posts found')
|
||||
},
|
||||
profile: {
|
||||
image: 'img/undraw/profile.svg',
|
||||
title: t('social', 'You haven\'t tooted yet')
|
||||
},
|
||||
tags: {
|
||||
image: 'img/undraw/profile.svg',
|
||||
title: t('social', 'No posts found for this tag')
|
||||
|
@ -110,12 +119,12 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
emptyContentData() {
|
||||
if (typeof this.emptyContent[this.$route.name] !== 'undefined') {
|
||||
return this.emptyContent[this.$route.name]
|
||||
}
|
||||
if (typeof this.emptyContent[this.$route.params.type] !== 'undefined') {
|
||||
return this.emptyContent[this.$route.params.type]
|
||||
}
|
||||
if (typeof this.emptyContent[this.$route.name] !== 'undefined') {
|
||||
return this.$route.name === 'timeline' ? this.emptyContent['default'] : this.emptyContent[this.$route.name]
|
||||
}
|
||||
return this.emptyContent.default
|
||||
},
|
||||
timeline: function() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="entry-content">
|
||||
<div v-if="item.actor_info" class="post-avatar">
|
||||
<avatar v-if="item.local" :size="32" :user="item.actor_info.preferredUsername"
|
||||
<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" />
|
||||
|
@ -9,7 +9,10 @@
|
|||
<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.actor_info.preferredUsername : item.actor_info.account }}">
|
||||
<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>
|
||||
|
@ -28,11 +31,13 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div class="post-message" v-html="formatedMessage" />
|
||||
<div v-if="item.content" class="post-message" v-html="formatedMessage" />
|
||||
<!-- 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-click-outside="hidePopoverMenu" class="post-actions">
|
||||
<div v-if="this.$route.params.type!=='notifications'" 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'"
|
||||
|
|
|
@ -92,12 +92,6 @@ export default {
|
|||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.user-entry {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
margin: 5px;
|
||||
margin-right: 10px;
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.user-entry {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
|
Ładowanie…
Reference in New Issue