diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2019-09-10 11:55:32 -0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-10 11:55:32 -0100 |
commit | fd069f3e60ceb6a646f5c344f12db2434ad897b5 (patch) | |
tree | 134a773004fd8a8934913290c8e3ac39dcd8a4b2 | |
parent | 5f374f9b9e16c26da22f5c5bc71d701aba1d9e83 (diff) | |
parent | 66419f061fa798ed36b14060a3bf1481bfb2903a (diff) |
Merge pull request #625 from nextcloud/feature/605/notificationsTimeline
[WIP] Notifications timeline (frontend)
-rw-r--r-- | css/style.scss | 1 | ||||
-rw-r--r-- | img/notifications.svg | 4 | ||||
-rw-r--r-- | lib/Traits/TDetails.php | 2 | ||||
-rw-r--r-- | src/App.vue | 20 | ||||
-rw-r--r-- | src/components/TimelineEntry.vue | 38 | ||||
-rw-r--r-- | src/components/TimelineList.vue | 17 | ||||
-rw-r--r-- | src/components/TimelinePost.vue | 13 | ||||
-rw-r--r-- | src/components/UserEntry.vue | 6 | ||||
-rw-r--r-- | src/views/ProfileFollowers.vue | 5 |
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> |