summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2019-09-10 11:55:32 -0100
committerGitHub <noreply@github.com>2019-09-10 11:55:32 -0100
commitfd069f3e60ceb6a646f5c344f12db2434ad897b5 (patch)
tree134a773004fd8a8934913290c8e3ac39dcd8a4b2
parent5f374f9b9e16c26da22f5c5bc71d701aba1d9e83 (diff)
parent66419f061fa798ed36b14060a3bf1481bfb2903a (diff)
Merge pull request #625 from nextcloud/feature/605/notificationsTimeline
[WIP] Notifications timeline (frontend)
-rw-r--r--css/style.scss1
-rw-r--r--img/notifications.svg4
-rw-r--r--lib/Traits/TDetails.php2
-rw-r--r--src/App.vue20
-rw-r--r--src/components/TimelineEntry.vue38
-rw-r--r--src/components/TimelineList.vue17
-rw-r--r--src/components/TimelinePost.vue13
-rw-r--r--src/components/UserEntry.vue6
-rw-r--r--src/views/ProfileFollowers.vue5
9 files changed, 76 insertions, 30 deletions
diff --git a/css/style.scss b/css/style.scss
index 8ae989f4..7cf637a2 100644
--- a/css/style.scss
+++ b/css/style.scss
@@ -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);
diff --git a/img/notifications.svg b/img/notifications.svg
new file mode 100644
index 00000000..1bc88f4c
--- /dev/null
+++ b/img/notifications.svg
@@ -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>
diff --git a/lib/Traits/TDetails.php b/lib/Traits/TDetails.php
index 0135cd38..bc5795ae 100644
--- a/lib/Traits/TDetails.php
+++ b/lib/Traits/TDetails.php
@@ -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;
diff --git a/src/App.vue b/src/App.vue
index 985612ff..0266d5f7 100644
--- a/src/App.vue
+++ b/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: [],
diff --git a/src/components/TimelineEntry.vue b/src/components/TimelineEntry.vue
index 5e1c7555..d1adbe6d 100644
--- a/src/components/TimelineEntry.vue
+++ b/src/components/TimelineEntry.vue
@@ -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
}
},
diff --git a/src/components/TimelineList.vue b/src/components/TimelineList.vue
index 54981066..4d58b486 100644
--- a/src/components/TimelineList.vue
+++ b/src/components/TimelineList.vue
@@ -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() {
diff --git a/src/components/TimelinePost.vue b/src/components/TimelinePost.vue
index 26edfa0a..6c86b936 100644
--- a/src/components/TimelinePost.vue
+++ b/src/components/TimelinePost.vue
@@ -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'"
diff --git a/src/components/UserEntry.vue b/src/components/UserEntry.vue
index 4cb455dd..d0210751 100644
--- a/src/components/UserEntry.vue
+++ b/src/components/UserEntry.vue
@@ -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;
diff --git a/src/views/ProfileFollowers.vue b/src/views/ProfileFollowers.vue
index 4703bc2d..dd026771 100644
--- a/src/views/ProfileFollowers.vue
+++ b/src/views/ProfileFollowers.vue
@@ -34,6 +34,11 @@
display: flex;
flex-wrap: wrap;
}
+ .user-entry {
+ width: 100%;
+ padding: 20px;
+ margin-bottom: 10px;
+ }
</style>
<script>