diff options
author | Julius Härtl <jus@bitgrid.net> | 2018-12-05 10:50:37 +0100 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2018-12-05 10:50:37 +0100 |
commit | c3bd113694ef1e50f811684f8a71e9132ed10733 (patch) | |
tree | f0c29d717bf9bdb90a2c4a5044e1554866f5829d /src | |
parent | 9d71a7b50c710f12051dba04e05c3dc366798bd1 (diff) |
Add public stream to profile page
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/Composer.vue | 4 | ||||
-rw-r--r-- | src/components/TimelineEntry.vue | 7 | ||||
-rw-r--r-- | src/components/TimelineList.vue | 122 | ||||
-rw-r--r-- | src/store/timeline.js | 26 | ||||
-rw-r--r-- | src/views/ProfileTimeline.vue | 20 | ||||
-rw-r--r-- | src/views/Timeline.vue | 117 |
6 files changed, 164 insertions, 132 deletions
diff --git a/src/components/Composer.vue b/src/components/Composer.vue index 1bdb78b6..de440406 100644 --- a/src/components/Composer.vue +++ b/src/components/Composer.vue @@ -499,9 +499,7 @@ export default { this.$store.dispatch('post', this.getPostData()).then((response) => { this.post = '' this.$refs.composerInput.innerText = this.post - this.$store.dispatch('refreshTimeline', { - account: this.currentUser.uid - }) + this.$store.dispatch('refreshTimeline') }) }, remoteSearch(text) { diff --git a/src/components/TimelineEntry.vue b/src/components/TimelineEntry.vue index 7fa30b32..ba90f88d 100644 --- a/src/components/TimelineEntry.vue +++ b/src/components/TimelineEntry.vue @@ -7,15 +7,20 @@ <avatar v-else :size="32" :url="avatarUrl" /> </div> <div class="post-content"> + {{ item.account_info }} + <div class="post-author-wrapper"> <router-link v-if="item.actor_info && item.local" :to="{ name: 'profile', params: { account: item.actor_info.preferredUsername }}"> <span class="post-author">{{ item.actor_info.preferredUsername }}</span> <span class="post-author-id">{{ item.actor_info.account }}</span> </router-link> - <a v-else :href="item.actor_info.url"> + <a v-else-if="item.actor_info" :href="item.actor_info.url"> <span class="post-author">{{ item.actor_info.preferredUsername }}</span> <span class="post-author-id">{{ item.actor_info.account }}</span> </a> + <a v-else :href="item.attributedTo"> + <span class="post-author-id">{{ item.attributedTo }}</span> + </a> </div> <div class="post-message" v-html="formatedMessage" /> </div> diff --git a/src/components/TimelineList.vue b/src/components/TimelineList.vue new file mode 100644 index 00000000..458ec3af --- /dev/null +++ b/src/components/TimelineList.vue @@ -0,0 +1,122 @@ +<!-- + - @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net> + - + - @author Julius Härtl <jus@bitgrid.net> + - + - @license GNU AGPL version 3 or any later version + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + - + --> + +<template> + <div class="social__timeline"> + <timeline-entry v-for="entry in timeline" :item="entry" :key="entry.id" /> + <infinite-loading ref="infiniteLoading" @infinite="infiniteHandler"> + <div slot="spinner"><div class="icon-loading" /></div> + <div slot="no-more"><div class="list-end" /></div> + <div slot="no-results"> + <empty-content :item="emptyContentData" /> + </div> + </infinite-loading> + </div> +</template> + +<script> +import { + PopoverMenu, + AppNavigation, + Multiselect +} from 'nextcloud-vue' +import InfiniteLoading from 'vue-infinite-loading' +import TimelineEntry from './../components/TimelineEntry' +import Composer from './../components/Composer' +import CurrentUserMixin from './../mixins/currentUserMixin' +import EmptyContent from './../components/EmptyContent' + +export default { + name: 'Timeline', + components: { + PopoverMenu, + AppNavigation, + TimelineEntry, + Multiselect, + Composer, + InfiniteLoading, + EmptyContent + }, + mixins: [CurrentUserMixin], + data: function() { + return { + infoHidden: false, + state: [], + emptyContent: { + default: { + image: 'img/undraw/posts.svg', + title: t('social', 'No posts found'), + description: t('social', 'Posts from people you follow will show up here') + }, + direct: { + image: 'img/undraw/direct.svg', + title: t('social', 'No direct messages found'), + description: t('social', 'Posts directed to you will show up here') + }, + timeline: { + image: 'img/undraw/local.svg', + title: t('social', 'No local posts found'), + description: t('social', 'Posts from other people on this instance will show up here') + }, + federated: { + image: 'img/undraw/global.svg', + title: t('social', 'No global posts found'), + description: t('social', 'Posts from federated instances will show up here') + } + } + } + }, + computed: { + emptyContentData() { + if (typeof this.emptyContent[this.$route.params.type] !== 'undefined') { + return this.emptyContent[this.$route.params.type] + } + return this.emptyContent.default + }, + timeline: function() { + return this.$store.getters.getTimeline + } + }, + beforeMount: function() { + + }, + methods: { + infiniteHandler($state) { + this.$store.dispatch('fetchTimeline', { + account: this.currentUser.uid + }).then((response) => { + if (response.status === -1) { + OC.Notification.showTemporary('Failed to load more timeline entries') + console.error('Failed to load more timeline entries', response) + $state.complete() + return + } + response.result.length > 0 ? $state.loaded() : $state.complete() + }).catch((error) => { + OC.Notification.showTemporary('Failed to load more timeline entries') + console.error('Failed to load more timeline entries', error) + $state.complete() + }) + } + } +} +</script> diff --git a/src/store/timeline.js b/src/store/timeline.js index cadbd990..c31fb245 100644 --- a/src/store/timeline.js +++ b/src/store/timeline.js @@ -26,7 +26,8 @@ import Vue from 'vue' const state = { timeline: {}, since: Math.floor(Date.now() / 1000) + 1, - type: 'home' + type: 'home', + account: '' } const mutations = { addToTimeline(state, data) { @@ -41,6 +42,9 @@ const mutations = { }, setTimelineType(state, type) { state.type = type + }, + setAccount(state, account) { + state.account = account } } const getters = { @@ -54,6 +58,12 @@ const actions = { changeTimelineType(context, type) { context.commit('resetTimeline') context.commit('setTimelineType', type) + context.commit('setAccount', '') + }, + changeTimelineTypeAccount(context, account) { + context.commit('resetTimeline') + context.commit('setTimelineType', 'account') + context.commit('setAccount', account) }, post(context, post) { return axios.post(OC.generateUrl('apps/social/api/v1/post'), { data: post }).then((response) => { @@ -64,14 +74,20 @@ const actions = { console.error('Failed to create a post', error) }) }, - refreshTimeline(context, account) { - return this.dispatch('fetchTimeline', { account: account, sinceTimestamp: Math.floor(Date.now() / 1000) + 1 }) + refreshTimeline(context) { + return this.dispatch('fetchTimeline', { sinceTimestamp: Math.floor(Date.now() / 1000) + 1 }) }, - fetchTimeline(context, { account, sinceTimestamp }) { + fetchTimeline(context, { sinceTimestamp }) { if (typeof sinceTimestamp === 'undefined') { sinceTimestamp = state.since - 1 } - return axios.get(OC.generateUrl(`apps/social/api/v1/stream/${state.type}?limit=5&since=` + sinceTimestamp)).then((response) => { + let url + if (state.type === 'account') { + url = OC.generateUrl(`apps/social/api/v1/account/${state.account}/stream?limit=25&since=` + sinceTimestamp) + } else { + url = OC.generateUrl(`apps/social/api/v1/stream/${state.type}?limit=25&since=` + sinceTimestamp) + } + return axios.get(url).then((response) => { if (response.status === -1) { throw response.message } diff --git a/src/views/ProfileTimeline.vue b/src/views/ProfileTimeline.vue index eb50a136..043dda4a 100644 --- a/src/views/ProfileTimeline.vue +++ b/src/views/ProfileTimeline.vue @@ -21,30 +21,26 @@ --> <template> - <div class="social__timeline"> - <timeline-entry v-for="entry in timeline" :item="entry" :key="entry.id" /> - </div> + <timeline-list /> </template> <style scoped> - .social__timeline { - max-width: 600px; - margin: 15px auto; - } + </style> <script> -import TimelineEntry from './../components/TimelineEntry' +import TimelineList from './../components/TimelineList' export default { name: 'ProfileTimeline', components: { - TimelineEntry + TimelineList }, computed: { - timeline: function() { - return this.$store.getters.getTimeline - } + + }, + beforeMount: function() { + this.$store.dispatch('changeTimelineTypeAccount', this.$route.params.account) } } </script> diff --git a/src/views/Timeline.vue b/src/views/Timeline.vue index 81b9fdea..4a6e986f 100644 --- a/src/views/Timeline.vue +++ b/src/views/Timeline.vue @@ -10,17 +10,8 @@ </p> </div> </transition> - <div class="social__timeline"> - <composer /> - <timeline-entry v-for="entry in timeline" :item="entry" :key="entry.id" /> - <infinite-loading ref="infiniteLoading" @infinite="infiniteHandler"> - <div slot="spinner"><div class="icon-loading" /></div> - <div slot="no-more"><div class="list-end" /></div> - <div slot="no-results"> - <empty-content :item="emptyContentData" /> - </div> - </infinite-loading> - </div> + <composer /> + <timeline-list /> </div> </template> @@ -88,6 +79,7 @@ import TimelineEntry from './../components/TimelineEntry' import Composer from './../components/Composer' import CurrentUserMixin from './../mixins/currentUserMixin' import EmptyContent from './../components/EmptyContent' +import TimelineList from './../components/TimelineList' export default { name: 'Timeline', @@ -98,104 +90,24 @@ export default { Multiselect, Composer, InfiniteLoading, - EmptyContent + EmptyContent, + TimelineList }, mixins: [CurrentUserMixin], data: function() { return { - infoHidden: false, - state: [], - emptyContent: { - default: { - image: 'img/undraw/posts.svg', - title: t('social', 'No posts found'), - description: t('social', 'Posts from people you follow will show up here') - }, - direct: { - image: 'img/undraw/direct.svg', - title: t('social', 'No direct messages found'), - description: t('social', 'Posts directed to you will show up here') - }, - timeline: { - image: 'img/undraw/local.svg', - title: t('social', 'No local posts found'), - description: t('social', 'Posts from other people on this instance will show up here') - }, - federated: { - image: 'img/undraw/global.svg', - title: t('social', 'No global posts found'), - description: t('social', 'Posts from federated instances will show up here') - } - } + infoHidden: false } }, computed: { - emptyContentData() { - if (typeof this.emptyContent[this.$route.params.type] !== 'undefined') { - return this.emptyContent[this.$route.params.type] - } - return this.emptyContent.default - }, type: function() { if (this.$route.params.type) { return this.$route.params.type } return 'home' }, - url: function() { - return OC.linkTo('social', 'img/nextcloud.png') - }, - timeline: function() { - return this.$store.getters.getTimeline - }, showInfo() { return this.$store.getters.getServerData.firstrun && !this.infoHidden - }, - menu: function() { - let defaultCategories = [ - { - id: 'social-timeline', - classes: [], - href: '#', - icon: 'icon-category-monitoring', - text: t('social', 'Timeline') - }, - { - id: 'social-account', - classes: [], - href: '#', - icon: 'icon-category-user', - text: t('social', 'Profile') - }, - { - id: 'social-friends', - classes: [], - href: '#', - icon: 'icon-category-social', - text: t('social', 'Friends') - }, - { - id: 'social-favorites', - classes: [], - href: '#', - icon: 'icon-favorite', - text: t('social', 'Favorites') - }, - { - id: 'social-direct-messages', - classes: [], - href: '#', - icon: 'icon-comment', - utils: { - counter: 3 - }, - text: t('social', 'Direct messages') - } - ] - return { - items: defaultCategories, - loading: false - } } }, beforeMount: function() { @@ -204,23 +116,6 @@ export default { methods: { hideInfo() { this.infoHidden = true - }, - infiniteHandler($state) { - this.$store.dispatch('fetchTimeline', { - account: this.currentUser.uid - }).then((response) => { - if (response.status === -1) { - OC.Notification.showTemporary('Failed to load more timeline entries') - console.error('Failed to load more timeline entries', response) - $state.complete() - return - } - response.result.length > 0 ? $state.loaded() : $state.complete() - }).catch((error) => { - OC.Notification.showTemporary('Failed to load more timeline entries') - console.error('Failed to load more timeline entries', error) - $state.complete() - }) } } } |