diff options
-rw-r--r-- | lib/Controller/LocalController.php | 1 | ||||
-rw-r--r-- | src/App.vue | 2 | ||||
-rw-r--r-- | src/components/FollowButton.vue | 111 | ||||
-rw-r--r-- | src/components/ProfileInfo.vue | 40 | ||||
-rw-r--r-- | src/components/Search.vue | 43 | ||||
-rw-r--r-- | src/components/UserEntry.vue | 21 | ||||
-rw-r--r-- | src/mixins/currentUserMixin.js | 4 | ||||
-rw-r--r-- | src/mixins/serverData.js | 5 | ||||
-rw-r--r-- | src/store/account.js | 130 | ||||
-rw-r--r-- | src/views/Profile.vue | 29 | ||||
-rw-r--r-- | src/views/ProfileFollowers.vue | 15 | ||||
-rw-r--r-- | src/views/Timeline.vue | 19 |
12 files changed, 326 insertions, 94 deletions
diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index 95b5434e..cd78c297 100644 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -514,6 +514,7 @@ class LocalController extends Controller { /** * @NoCSRFRequired * @NoAdminRequired + * @PublicPage * * @param string $id * diff --git a/src/App.vue b/src/App.vue index 0041d6b8..7bfea6ab 100644 --- a/src/App.vue +++ b/src/App.vue @@ -183,7 +183,9 @@ export default { if (!this.serverData.public) { this.search = new OCA.Search(this.search, this.resetSearch) + this.$store.dispatch('fetchCurrentAccountInfo', this.cloudId) } + }, methods: { hideInfo() { diff --git a/src/components/FollowButton.vue b/src/components/FollowButton.vue new file mode 100644 index 00000000..ae90b402 --- /dev/null +++ b/src/components/FollowButton.vue @@ -0,0 +1,111 @@ +<!-- + - @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 v-if="!serverData.public && cloudId !== account && actorInfo"> + <button v-if="isCurrentUserFollowing" :class="{'icon-loading-small': followLoading}" + @click="unfollow()" + @mouseover="followingText=t('social', 'Unfollow')" @mouseleave="followingText=t('social', 'Following')"> + <span><span class="icon-checkmark" />{{ followingText }}</span></button> + <button v-else :class="{'icon-loading-small': followLoading}" class="primary" + @click="follow"><span>{{ t('social', 'Follow') }}</span></button> + </div> +</template> + +<script> +import currentUser from '../mixins/currentUserMixin' + +export default { + name: 'FollowButton', + mixins: [ + currentUser + ], + props: { + account: { + type: String, + default: '' + } + }, + data: function() { + return { + followingText: t('social', 'Following') + } + }, + computed: { + actorInfo() { + return this.$store.getters.getAccount(this.account) + }, + followLoading() { + return false + }, + isCurrentUserFollowing() { + return this.$store.getters.isFollowingUser(this.account) + } + }, + methods: { + follow() { + this.$store.dispatch('followAccount', { currentAccount: this.cloudId, accountToFollow: this.account }) + }, + unfollow() { + this.$store.dispatch('unfollowAccount', { currentAccount: this.cloudId, accountToUnfollow: this.account }) + } + } +} +</script> +<style scoped> + .user-entry { + padding: 20px; + margin-bottom: 10px; + } + + .user-avatar { + margin: 5px; + margin-right: 10px; + border-radius: 50%; + flex-shrink: 0; + } + + .post-author { + font-weight: bold; + } + + .entry-content { + display: flex; + align-items: flex-start; + } + + .user-details { + flex-grow: 1; + } + + .user-description { + opacity: 0.7; + } + + button { + min-width: 110px; + } + + button * { + cursor: pointer; + } +</style> diff --git a/src/components/ProfileInfo.vue b/src/components/ProfileInfo.vue index 02f72bd5..d8633306 100644 --- a/src/components/ProfileInfo.vue +++ b/src/components/ProfileInfo.vue @@ -21,30 +21,27 @@ --> <template> - <div v-if="uid && accountInfo" class="user-profile"> + <div v-if="account && accountInfo" class="user-profile"> <div class="user-profile--info"> - <avatar :user="uid" :disable-tooltip="true" :size="128" /> + <avatar v-if="accountInfo.local" :user="uid" :disable-tooltip="true" + :size="128" /> + <avatar v-else :url="avatarUrl" :disable-tooltip="true" + :size="128" /> <h2>{{ displayName }}</h2> <p>{{ accountInfo.account }}</p> <p v-if="accountInfo.website">Website: <a :href="accountInfo.website.value">{{ accountInfo.website.value }}</a></p> - <template v-if="cloudId !== accountInfo.account && !serverData.public"> - <button v-if="accountInfo.details && accountInfo.details.following" :class="{'icon-loading-small': followLoading}" - @click="unfollow()" - @mouseover="followingText=t('social', 'Unfollow')" @mouseleave="followingText=t('social', 'Following')"> - <span><span class="icon-checkmark" />{{ followingText }}</span></button> - <button v-else-if="accountInfo.details" :class="{'icon-loading-small': followLoading}" class="primary" - @click="follow"><span>{{ t('social', 'Follow') }}</span></button> - </template> + <follow-button :account="accountInfo.account" /> </div> - <ul v-if="accountInfo.details" class="user-profile--sections"> + <!-- TODO: we have no details, timeline and follower list for non-local accounts for now --> + <ul v-if="accountInfo.details && accountInfo.local" class="user-profile--sections"> <li> - <router-link :to="{ name: 'profile', params: { account: uid } }" class="icon-category-monitoring">{{ accountInfo.details.count.post }} {{ t('social', 'posts') }}</router-link> + <router-link :to="{ name: 'profile', params: { account: uid } }" class="icon-category-monitoring">{{ getCount('post') }} {{ t('social', 'posts') }}</router-link> </li> <li> - <router-link :to="{ name: 'profile.following', params: { account: uid } }" class="icon-category-social">{{ accountInfo.details.count.following }} {{ t('social', 'following') }}</router-link> + <router-link :to="{ name: 'profile.following', params: { account: uid } }" class="icon-category-social">{{ getCount('following') }} {{ t('social', 'following') }}</router-link> </li> <li> - <router-link :to="{ name: 'profile.followers', params: { account: uid } }" class="icon-category-social">{{ accountInfo.details.count.followers }} {{ t('social', 'followers') }}</router-link> + <router-link :to="{ name: 'profile.followers', params: { account: uid } }" class="icon-category-social">{{ getCount('followers') }} {{ t('social', 'followers') }}</router-link> </li> </ul> </div> @@ -93,10 +90,12 @@ import { Avatar } from 'nextcloud-vue' import serverData from '../mixins/serverData' import currentUser from '../mixins/currentUserMixin' import follow from '../mixins/follow' +import FollowButton from './FollowButton' export default { name: 'ProfileInfo', components: { + FollowButton, Avatar }, mixins: [ @@ -116,14 +115,23 @@ export default { } }, computed: { + account() { + return (this.uid.indexOf('@') === -1) ? this.uid + '@' + this.hostname : this.uid + }, displayName() { if (typeof this.accountInfo.name !== 'undefined' && this.accountInfo.name !== '') { return this.accountInfo.name } - return this.uid + return this.account }, accountInfo: function() { - return this.$store.getters.getAccount(this.uid) + return this.$store.getters.getAccount(this.account) + }, + getCount() { + return (field) => this.accountInfo.details.count ? this.accountInfo.details.count[field] : '' + }, + avatarUrl() { + return OC.generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.accountInfo.id) } }, methods: { diff --git a/src/components/Search.vue b/src/components/Search.vue index c88f0653..e39e78a6 100644 --- a/src/components/Search.vue +++ b/src/components/Search.vue @@ -22,14 +22,14 @@ <template> <div class="social__wrapper"> - <div v-if="results.length < 1" id="emptycontent" :class="{'icon-loading': loading}"> + <div v-if="allResults.length < 1" id="emptycontent" :class="{'icon-loading': loading || remoteLoading}"> <div v-if="!loading" class="icon-search" /> <h2 v-if="!loading">{{ t('social', 'No accounts found') }}</h2> <p v-if="!loading">No accounts found for {{ term }}</p> </div> - <div v-if="match || results.length > 0"> + <div v-if="allResults.length > 0"> <h3>{{ t('social', 'Searching for') }} {{ term }}</h3> - <UserEntry v-for="result in results" :key="result.id" :item="result" /> + <UserEntry v-for="result in allResults" :key="result.id" :item="result" /> </div> </div> </template> @@ -65,12 +65,20 @@ export default { return { results: [], loading: false, + remoteLoading: false, match: null } }, + computed: { + allResults() { + if (!this.match) { + return this.results + } + return [this.match, ...this.results.filter((item) => item.id !== this.match.id)] + } + }, watch: { term(val) { - // TODO: debounce this.search(val) } }, @@ -83,21 +91,26 @@ export default { return } this.loading = true - const re = /@((\w+)(@[\w.]+)?)/g - if (val.match(re)) { + const re = /((\w+)(@[\w.]+)+)/g + if (val.match(re) && !this.remoteLoading) { + this.remoteLoading = true this.remoteSearch(val).then((response) => { this.match = response.data.result.account - this.accountSearch(val).then((response) => { - this.results = response.data.result.accounts - this.loading = false - }) - }).catch((e) => { this.match = null }) - } else { - this.accountSearch(val).then((response) => { - this.results = response.data.result.accounts - this.loading = false + this.$store.commit('addAccount', { actorId: this.match.id, data: this.match }) + this.remoteLoading = false + }).catch((e) => { + this.remoteLoading = false + this.match = null }) } + this.accountSearch(val).then((response) => { + this.results = response.data.result.accounts + this.loading = false + this.results.forEach((account) => { + this.$store.commit('addAccount', { actorId: account.id, data: account }) + }) + }) + }, accountSearch(term) { this.loading = true diff --git a/src/components/UserEntry.vue b/src/components/UserEntry.vue index 933ac618..7aa1fd15 100644 --- a/src/components/UserEntry.vue +++ b/src/components/UserEntry.vue @@ -29,22 +29,19 @@ <avatar v-else :url="avatarUrl" /> </div> <div class="user-details"> - <router-link v-if="item.local" :to="{ name: 'profile', params: { account: item.preferredUsername }}"> - <span class="post-author">{{ item.preferredUsername }}</span> + <router-link v-if="!serverData.public" :to="{ name: 'profile', params: { account: item.local ? item.preferredUsername : item.account }}"> + <span class="post-author">{{ item.name }}</span> + <span class="user-description">{{ item.account }}</span> </router-link> <a v-else :href="item.id" target="_blank" - rel="noreferrer">{{ item.name }} <span class="user-description">{{ item.account }}</span></a> + rel="noreferrer"> + <span class="post-author">{{ item.name }}</span> + <span class="user-description">{{ item.account }}</span> + </a> <!-- TODO check where the html is coming from to avoid security issues --> <p v-html="item.summary" /> </div> - <template v-if="!serverData.public && cloudId !== item.account"> - <button v-if="item.details && item.details.following" :class="{'icon-loading-small': followLoading}" - @click="unfollow()" - @mouseover="followingText=t('social', 'Unfollow')" @mouseleave="followingText=t('social', 'Following')"> - <span><span class="icon-checkmark" />{{ followingText }}</span></button> - <button v-else-if="item.details" :class="{'icon-loading-small': followLoading}" class="primary" - @click="follow"><span>{{ t('social', 'Follow') }}</span></button> - </template> + <follow-button :account="item.account" /> </div> </div> </template> @@ -53,10 +50,12 @@ import { Avatar } from 'nextcloud-vue' import follow from '../mixins/follow' import currentUser from '../mixins/currentUserMixin' +import FollowButton from './FollowButton' export default { name: 'UserEntry', components: { + FollowButton, Avatar }, mixins: [ diff --git a/src/mixins/currentUserMixin.js b/src/mixins/currentUserMixin.js index 1678b3f3..d961ab80 100644 --- a/src/mixins/currentUserMixin.js +++ b/src/mixins/currentUserMixin.js @@ -33,9 +33,7 @@ export default { return '@' + this.cloudId }, cloudId() { - const url = document.createElement('a') - url.setAttribute('href', this.serverData.cloudAddress) - return this.currentUser.uid + '@' + url.hostname + return this.currentUser.uid + '@' + this.hostname } } } diff --git a/src/mixins/serverData.js b/src/mixins/serverData.js index 24783e3c..1fdcbfd1 100644 --- a/src/mixins/serverData.js +++ b/src/mixins/serverData.js @@ -24,6 +24,11 @@ export default { computed: { serverData: function() { return this.$store.getters.getServerData + }, + hostname() { + const url = document.createElement('a') + url.setAttribute('href', this.serverData.cloudAddress) + return url.hostname } } } diff --git a/src/store/account.js b/src/store/account.js index 30971023..41ac3782 100644 --- a/src/store/account.js +++ b/src/store/account.js @@ -24,59 +24,143 @@ import axios from 'nextcloud-axios' import Vue from 'vue' const state = { + currentAccount: {}, accounts: {}, - accountsFollowers: {}, - accountsFollowing: {} + accountIdMap: {} } +const addAccount = (state, { actorId, data }) => { + Vue.set(state.accounts, actorId, Object.assign({ followersList: [], followingList: [], details: { following: false, follower: false } }, state.accounts[actorId], data)) + Vue.set(state.accountIdMap, data.account, data.id) +} +const _getActorIdForAccount = (account) => state.accountIdMap[account] + const mutations = { - addAccount(state, { uid, data }) { - Vue.set(state.accounts, uid, data) + setCurrentAccount(state, account) { + state.currentAccount = account + }, + addAccount(state, { actorId, data }) { + addAccount(state, { actorId, data }) }, - addFollowers(state, { uid, data }) { + addFollowers(state, { account, data }) { let users = [] for (var index in data) { - users.push(data[index].actor_info) + const actor = data[index].actor_info + users.push(actor.id) + addAccount(state, { + actorId: actor.id, + data: actor + }) } - Vue.set(state.accountsFollowers, uid, users) + Vue.set(state.accounts[_getActorIdForAccount(account)], 'followersList', users) }, - addFollowing(state, { uid, data }) { + addFollowing(state, { account, data }) { let users = [] for (var index in data) { - users.push(data[index].actor_info) + const actor = data[index].actor_info + users.push(actor.id) + addAccount(state, { + actorId: actor.id, + data: actor + }) } - Vue.set(state.accountsFollowing, uid, users) + Vue.set(state.accounts[_getActorIdForAccount(account)], 'followingList', users) + }, + followAccount(state, accountToFollow) { + Vue.set(state.accounts[_getActorIdForAccount(accountToFollow)].details, 'following', true) + }, + unfollowAccount(state, accountToUnfollow) { + Vue.set(state.accounts[_getActorIdForAccount(accountToUnfollow)].details, 'following', false) } } + const getters = { - getAccount(state) { - return (uid) => state.accounts[uid] + getAccount(state, getters) { + return (account) => { + return state.accounts[_getActorIdForAccount(account)] + } + }, + accountFollowing(state) { + return (account, isFollowing) => _getActorIdForAccount(isFollowing) in state.accounts[_getActorIdForAccount(account)] }, accountLoaded(state) { - return (uid) => uid in state.accounts + return (account) => state.accounts[_getActorIdForAccount(account)] }, getAccountFollowers(state) { - return (uid) => state.accountsFollowers[uid] + return (id) => state.accounts[_getActorIdForAccount(id)].followersList.map((actorId) => state.accounts[actorId]) }, getAccountFollowing(state) { - return (uid) => state.accountsFollowing[uid] + return (id) => state.accounts[_getActorIdForAccount(id)].followingList.map((actorId) => state.accounts[actorId]) + }, + getActorIdForAccount() { + return _getActorIdForAccount + }, + isFollowingUser(state) { + return (followingAccount) => { + let account = state.accounts[_getActorIdForAccount(followingAccount)] + return account && account.details ? account.details.following : false + } } } + const actions = { - fetchAccountInfo(context, uid) { + fetchAccountInfo(context, account) { + return axios.get(OC.generateUrl(`apps/social/api/v1/global/account/info?account=${account}`)).then((response) => { + context.commit('addAccount', { actorId: response.data.result.account.id, data: response.data.result.account }) + }).catch(() => { + OC.Notification.showTemporary(`Failed to load account details ${account}`) + }) + }, + fetchPublicAccountInfo(context, uid) { axios.get(OC.generateUrl(`apps/social/api/v1/account/${uid}/info`)).then((response) => { - context.commit('addAccount', { uid: uid, data: response.data.result.account }) - }).catch((response) => { - context.commit('addAccount', { uid: uid, data: null }) + context.commit('addAccount', { actorId: response.data.result.account.id, data: response.data.result.account }) + }).catch(() => { + OC.Notification.showTemporary(`Failed to load account details ${uid}`) + }) + }, + fetchCurrentAccountInfo({ commit, dispatch }, account) { + commit('setCurrentAccount', account) + dispatch('fetchAccountInfo', account) + }, + followAccount(context, { currentAccount, accountToFollow }) { + return axios.put(OC.generateUrl('/apps/social/api/v1/current/follow?account=' + accountToFollow)).then((response) => { + if (response.data.status === -1) { + return Promise.reject(response) + } + context.commit('followAccount', accountToFollow) + return Promise.resolve(response) + }).catch((error) => { + OC.Notification.showTemporary(`Failed to follow user ${accountToFollow}`) + console.error(`Failed to follow user ${accountToFollow}`, error) + }) + + }, + unfollowAccount(context, { currentAccount, accountToUnfollow }) { + return axios.delete(OC.generateUrl('/apps/social/api/v1/current/follow?account=' + accountToUnfollow)).then((response) => { + if (response.data.status === -1) { + return Promise.reject(response) + } + context.commit('unfollowAccount', accountToUnfollow) + return Promise.resolve(response) + }).catch((error) => { + OC.Notification.showTemporary(`Failed to unfollow user ${accountToUnfollow}`) + console.error(`Failed to unfollow user ${accountToUnfollow}`, error.response.data) + return Promise.reject(error.response.data) }) }, - fetchAccountFollowers(context, uid) { + fetchAccountFollowers(context, account) { + // TODO: fetching followers/following information of remotes is currently not supported + const parts = account.split('@') + const uid = (parts.length === 2 ? parts[0] : account) axios.get(OC.generateUrl(`apps/social/api/v1/account/${uid}/followers`)).then((response) => { - context.commit('addFollowers', { uid: uid, data: response.data.result }) + context.commit('addFollowers', { account, data: response.data.result }) }) }, - fetchAccountFollowing(context, uid) { + fetchAccountFollowing(context, account) { + // TODO: fetching followers/following information of remotes is currently not supported + const parts = account.split('@') + const uid = (parts.length === 2 ? parts[0] : account) axios.get(OC.generateUrl(`apps/social/api/v1/account/${uid}/following`)).then((response) => { - context.commit('addFollowing', { uid: uid, data: response.data.result }) + context.commit('addFollowing', { account, data: response.data.result }) }) } } diff --git a/src/views/Profile.vue b/src/views/Profile.vue index db547c4a..8cda5dde 100644 --- a/src/views/Profile.vue +++ b/src/views/Profile.vue @@ -23,7 +23,8 @@ <template> <div :class="{'icon-loading': !accountLoaded}" class="social__wrapper"> <profile-info v-if="accountLoaded && accountInfo" :uid="uid" /> - <router-view v-if="accountLoaded && accountInfo" name="details" /> + <!-- TODO: we have no details, timeline and follower list for non-local accounts for now --> + <router-view v-if="accountLoaded && accountInfo && accountInfo.local" name="details" /> <empty-content v-if="accountLoaded && !accountInfo" :item="emptyContentData" /> </div> </template> @@ -46,6 +47,7 @@ import { import TimelineEntry from './../components/TimelineEntry' import ProfileInfo from './../components/ProfileInfo' import EmptyContent from '../components/EmptyContent' +import serverData from '../mixins/serverData' export default { name: 'Profile', @@ -58,30 +60,27 @@ export default { Avatar, ProfileInfo }, - data: function() { + mixins: [ + serverData + ], + data() { return { state: [], uid: null } }, computed: { - serverData: function() { - return this.$store.getters.getServerData - }, - currentUser: function() { - return OC.getCurrentUser() - }, - socialId: function() { - return '@' + OC.getCurrentUser().uid + '@' + OC.getHost() + profileAccount() { + return (this.uid.indexOf('@') === -1) ? this.uid + '@' + this.hostname : this.uid }, timeline: function() { return this.$store.getters.getTimeline }, accountInfo: function() { - return this.$store.getters.getAccount(this.uid) + return this.$store.getters.getAccount(this.profileAccount) }, accountLoaded() { - return this.$store.getters.accountLoaded(this.uid) + return this.$store.getters.accountLoaded(this.profileAccount) }, emptyContentData() { return { @@ -93,7 +92,11 @@ export default { }, beforeMount() { this.uid = this.$route.params.account - this.$store.dispatch('fetchAccountInfo', this.uid) + if (this.serverData.public) { + this.$store.dispatch('fetchPublicAccountInfo', this.uid) + } else { + this.$store.dispatch('fetchAccountInfo', this.profileAccount) + } }, methods: { } diff --git a/src/views/ProfileFollowers.vue b/src/views/ProfileFollowers.vue index 81c2c516..ffae8fbe 100644 --- a/src/views/ProfileFollowers.vue +++ b/src/views/ProfileFollowers.vue @@ -40,26 +40,33 @@ <script> import UserEntry from '../components/UserEntry' +import serverData from '../mixins/serverData' export default { name: 'ProfileFollowers', components: { UserEntry }, + mixins: [ + serverData + ], computed: { + profileAccount() { + return (this.$route.params.account.indexOf('@') === -1) ? this.$route.params.account + '@' + this.hostname : this.$route.params.account + }, users: function() { if (this.$route.name === 'profile.followers') { - return this.$store.getters.getAccountFollowers(this.$route.params.account) + return this.$store.getters.getAccountFollowers(this.profileAccount) } else { - return this.$store.getters.getAccountFollowing(this.$route.params.account) + return this.$store.getters.getAccountFollowing(this.profileAccount) } } }, beforeMount() { if (this.$route.name === 'profile.followers') { - this.$store.dispatch('fetchAccountFollowers', this.$route.params.account) + this.$store.dispatch('fetchAccountFollowers', this.profileAccount) } else { - this.$store.dispatch('fetchAccountFollowing', this.$route.params.account) + this.$store.dispatch('fetchAccountFollowing', this.profileAccount) } } } diff --git a/src/views/Timeline.vue b/src/views/Timeline.vue index 527fdb23..c0440101 100644 --- a/src/views/Timeline.vue +++ b/src/views/Timeline.vue @@ -8,7 +8,7 @@ {{ t('social', 'We automatically created a Social account for you. Your Social ID is the same as your federated cloud ID:') }} <span class="social-id">{{ socialId }}</span> </p> - <div ng-show="followingNextcloud" class="follow-nextcloud"> + <div v-show="!isFollowingNextcloudAccount" class="follow-nextcloud"> <p>{{ t('social', 'Since you are new to Social, start by following the official Nextcloud account so you don\'t miss any news') }}</p> <input :value="t('social', 'Follow Nextcloud on mastodon.xyz')" type="button" class="primary" @click="followNextcloud"> @@ -115,14 +115,11 @@ export default { data: function() { return { infoHidden: false, - followingNextcloud: false, - item: { - account: 'nextcloud@mastodon.xyz' - } + nextcloudAccount: 'nextcloud@mastodon.xyz' } }, computed: { - type: function() { + type() { if (this.$route.params.type) { return this.$route.params.type } @@ -130,19 +127,23 @@ export default { }, showInfo() { return this.$store.getters.getServerData.firstrun && !this.infoHidden + }, + isFollowingNextcloudAccount() { + return this.$store.getters.isFollowingUser(this.nextcloudAccount) } }, beforeMount: function() { this.$store.dispatch('changeTimelineType', this.type) + if (this.showInfo) { + this.$store.dispatch('fetchAccountInfo', this.nextcloudAccount) + } }, methods: { hideInfo() { this.infoHidden = true }, followNextcloud() { - this.follow().then(() => { - this.followingNextcloud = true - }) + this.$store.dispatch('followAccount', { accountToFollow: this.nextcloudAccount }) } } } |