Merge pull request #625 from nextcloud/feature/605/notificationsTimeline

[WIP] Notifications timeline (frontend)
pull/732/head
Maxence Lange 2019-09-10 11:55:32 -01:00 zatwierdzone przez GitHub
commit fd069f3e60
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
9 zmienionych plików z 76 dodań i 30 usunięć

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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: [],

Wyświetl plik

@ -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
}
},

Wyświetl plik

@ -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() {

Wyświetl plik

@ -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'"

Wyświetl plik

@ -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;

Wyświetl plik

@ -34,6 +34,11 @@
display: flex;
flex-wrap: wrap;
}
.user-entry {
width: 100%;
padding: 20px;
margin-bottom: 10px;
}
</style>
<script>