diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/FollowButton.vue | 7 | ||||
-rw-r--r-- | src/components/ProfileInfo.vue | 37 | ||||
-rw-r--r-- | src/mixins/accountMixins.js | 48 | ||||
-rw-r--r-- | src/views/OStatus.vue | 45 | ||||
-rw-r--r-- | src/views/Profile.vue | 27 |
5 files changed, 102 insertions, 62 deletions
diff --git a/src/components/FollowButton.vue b/src/components/FollowButton.vue index d2c76953..f3aebfc1 100644 --- a/src/components/FollowButton.vue +++ b/src/components/FollowButton.vue @@ -22,7 +22,7 @@ <template> <!-- Show button only if user is authenticated and she is not the same as the account viewed --> - <div v-if="!serverData.public && actorInfo && actorInfo.viewerLink!='viewer'"> + <div v-if="!serverData.public && actorInfo(account) && actorInfo(account).viewerLink!='viewer'"> <button v-if="isCurrentUserFollowing" :class="{'icon-loading-small': followLoading}" @click="unfollow()" @mouseover="followingText=t('social', 'Unfollow')" @mouseleave="followingText=t('social', 'Following')"> @@ -36,11 +36,13 @@ </template> <script> +import accountMixins from '../mixins/accountMixins' import currentUser from '../mixins/currentUserMixin' export default { name: 'FollowButton', mixins: [ + accountMixins, currentUser ], props: { @@ -55,9 +57,6 @@ export default { } }, computed: { - actorInfo() { - return this.$store.getters.getAccount(this.account) - }, followLoading() { return false }, diff --git a/src/components/ProfileInfo.vue b/src/components/ProfileInfo.vue index a5911fa7..f7392e84 100644 --- a/src/components/ProfileInfo.vue +++ b/src/components/ProfileInfo.vue @@ -21,26 +21,26 @@ --> <template> - <div v-if="account && accountInfo" class="user-profile"> + <div v-if="profileAccount(uid) && accountInfo(uid)" class="user-profile"> <div> - <avatar v-if="accountInfo.local" :user="localUid" :disable-tooltip="true" + <avatar v-if="accountInfo(uid).local" :user="localUid" :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 }} + <p>@{{ accountInfo(uid).account }}</p> + <p v-if="accountInfo(uid).website"> + Website: <a :href="accountInfo(uid).website.value"> + {{ accountInfo(uid).website.value }} </a> </p> - <follow-button :account="accountInfo.account" /> + <follow-button :account="accountInfo(uid).account" /> <button v-if="serverData.public" class="primary" @click="followRemote"> {{ t('social', 'Follow') }} </button> </div> <!-- 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"> + <ul v-if="accountInfo(uid).details && accountInfo(uid).local" class="user-profile--sections"> <li> <router-link :to="{ name: 'profile', params: { account: uid } }" class="icon-category-monitoring"> {{ getCount('post') }} {{ t('social', 'posts') }} @@ -97,6 +97,7 @@ </style> <script> import Avatar from '@nextcloud/vue/dist/Components/Avatar' +import accountMixins from '../mixins/accountMixins' import serverData from '../mixins/serverData' import currentUser from '../mixins/currentUserMixin' import follow from '../mixins/follow' @@ -110,8 +111,9 @@ export default { Avatar }, mixins: [ - serverData, + accountMixins, currentUser, + serverData, follow ], props: { @@ -130,26 +132,21 @@ export default { // Returns only the local part of a username return (this.uid.indexOf('@') === -1) ? this.uid : this.uid.substr(0, this.uid.indexOf('@')) }, - 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 + if (typeof this.accountInfo(this.uid).name !== 'undefined' && this.accountInfo(this.uid).name !== '') { + return this.accountInfo(this.uid).name } if (typeof this.accountInfo.preferredUsername !== 'undefined' && this.accountInfo.preferredUsername !== '') { return this.accountInfo.preferredUsername } - return this.account - }, - accountInfo: function() { - return this.$store.getters.getAccount(this.account) + return this.profileAccount(this.uid) }, getCount() { - return (field) => this.accountInfo.details.count ? this.accountInfo.details.count[field] : '' + let account = this.accountInfo(this.uid) + return (field) => account.details.count ? account.details.count[field] : '' }, avatarUrl() { - return generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.accountInfo.id) + return generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.accountInfo(this.uid).id) } }, methods: { diff --git a/src/mixins/accountMixins.js b/src/mixins/accountMixins.js new file mode 100644 index 00000000..9384aac6 --- /dev/null +++ b/src/mixins/accountMixins.js @@ -0,0 +1,48 @@ +/* + * @copyright Copyright (c) 2019 Cyrille Bollu <cyrpub@bollu.be> + * + * @author Cyrille Bollu <cyrpub@bollu.be> + * + * @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/>. + * + */ + +/* + * This file provides global account related methods + */ + +import serverData from './serverData' + +export default { + mixins: [ + serverData + ], + methods: { + // Returns the complete account name + profileAccount(uid) { + return (uid.indexOf('@') === -1) ? uid + '@' + this.hostname : uid + }, + // Returns detailed information about an account (account must be loaded in the store first) + accountInfo(uid) { + return this.$store.getters.getAccount(this.profileAccount(uid)) + }, + // Somewhat duplicate with accountInfo(), but needed (for some reason) to avoid glitches + // where components would first show "user not found" before display an account's account info + accountLoaded(uid) { + return this.$store.getters.accountLoaded(this.profileAccount(uid)) + } + } +} diff --git a/src/views/OStatus.vue b/src/views/OStatus.vue index bdbe822c..2ce96cff 100644 --- a/src/views/OStatus.vue +++ b/src/views/OStatus.vue @@ -1,5 +1,5 @@ <template> - <div v-if="accountInfo"> + <div v-if="account"> <div v-if="!serverData.local"> <h2>{{ t('social', 'Follow on Nextcloud Social') }}</h2> <p>{{ t('social', 'Hello') }} <avatar :user="currentUser.uid" :size="16" />{{ currentUser.displayName }}</p> @@ -23,6 +23,7 @@ </button> </div> </div> + <!-- Some unauthenticated user wants to follow a local account --> <div v-if="serverData.local"> <p>{{ t('social', 'You are going to follow:') }}</p> <avatar :user="serverData.local" :disable-tooltip="true" :size="128" /> @@ -34,7 +35,7 @@ <p>{{ t('social', 'This step is needed as the user is probably not registered on the same server as you are. We will redirect you to your homeserver to follow this account.') }}</p> </div> </div> - <div v-else :class="{ 'icon-loading-dark': !accountInfo }" /> + <div v-else :class="{ 'icon-loading-dark': !account }" /> </template> <style scoped> @@ -62,7 +63,8 @@ <script> import Avatar from '@nextcloud/vue/dist/Components/Avatar' import axios from '@nextcloud/axios' -import currentuserMixin from './../mixins/currentUserMixin' +import accountMixins from '../mixins/accountMixins' +import currentuserMixin from '../mixins/currentUserMixin' import { loadState } from '@nextcloud/initial-state' import { generateUrl } from '@nextcloud/router' @@ -71,37 +73,36 @@ export default { components: { Avatar }, - mixins: [currentuserMixin], + mixins: [ + accountMixins, + currentuserMixin + ], data() { return { - remote: '' + remote: '', + account: {} } }, computed: { isFollowing() { - return this.$store.getters.isFollowingUser(this.account) - }, - account() { - return this.serverData.account + return this.$store.getters.isFollowingUser(this.account.id) }, avatarUrl() { - return generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.accountInfo.id) - }, - accountInfo: function() { - return this.$store.getters.getAccount(this.serverData.account) + return generateUrl('/apps/social/api/v1/global/actor/avatar?id=' + this.account.id) }, currentUser() { return window.oc_current_user }, displayName() { - if (typeof this.accountInfo.name !== 'undefined' && this.accountInfo.name !== '') { - return this.accountInfo.name + if (typeof this.account.id === 'undefined') { + return (this.serverData.account ? this.serverData.account : this.serverData.local) } - return this.account + + return (this.account.name ? this.account.name : this.account.preferredUsername) } }, beforeMount: function() { - // importing server data into the store + // importing server data into the store and fetching viewed account's information try { const serverData = loadState('social', 'serverData') if (serverData.currentUser) { @@ -109,10 +110,14 @@ export default { } this.$store.commit('setServerData', serverData) if (this.serverData.account && !this.serverData.local) { - this.$store.dispatch('fetchAccountInfo', this.serverData.account) + this.$store.dispatch('fetchAccountInfo', this.serverData.account).then((result) => { + this.account = result + }) } if (this.serverData.local) { - this.$store.dispatch('fetchPublicAccountInfo', this.serverData.local) + this.$store.dispatch('fetchPublicAccountInfo', this.serverData.local).then((result) => { + this.account = result + }) } } catch { /* empty */ @@ -120,7 +125,7 @@ export default { }, methods: { follow() { - this.$store.dispatch('followAccount', { currentAccount: this.cloudId, accountToFollow: this.account }).then(() => { + this.$store.dispatch('followAccount', { currentAccount: this.cloudId, accountToFollow: this.account.account }).then(() => { }) }, diff --git a/src/views/Profile.vue b/src/views/Profile.vue index 7e9f7e8d..8b549ae9 100644 --- a/src/views/Profile.vue +++ b/src/views/Profile.vue @@ -21,11 +21,11 @@ --> <template> - <div :class="{'icon-loading': !accountLoaded}" class="social__wrapper"> - <profile-info v-if="accountLoaded && accountInfo" :uid="uid" /> + <div :class="{'icon-loading': !accountLoaded(uid)}" class="social__wrapper"> + <profile-info v-if="accountLoaded(uid) && accountInfo(uid)" :uid="uid" /> <!-- 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" /> + <router-view v-if="accountLoaded(uid) && accountInfo(uid) && accountInfo(uid).local" name="details" /> + <empty-content v-if="accountLoaded(uid) && !accountInfo(uid)" :item="emptyContentData" /> </div> </template> @@ -40,6 +40,7 @@ <script> import ProfileInfo from './../components/ProfileInfo.vue' import EmptyContent from '../components/EmptyContent.vue' +import accountMixins from '../mixins/accountMixins' import serverData from '../mixins/serverData' export default { @@ -49,6 +50,7 @@ export default { ProfileInfo }, mixins: [ + accountMixins, serverData ], data() { @@ -58,18 +60,9 @@ export default { } }, computed: { - 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.profileAccount) - }, - accountLoaded() { - return this.$store.getters.accountLoaded(this.profileAccount) - }, emptyContentData() { return { image: 'img/undraw/profile.svg', @@ -78,12 +71,12 @@ export default { } } }, + // Start fetching account information before mounting the component beforeMount() { - - let fetchMethod = '' this.uid = this.$route.params.account || this.serverData.account // Are we authenticated? + let fetchMethod = '' if (this.serverData.public) { fetchMethod = 'fetchPublicAccountInfo' } else { @@ -92,11 +85,9 @@ export default { // We need to update this.uid because we may have asked info for an account whose domain part was a host-meta, // and the account returned by the backend always uses a non host-meta'ed domain for its ID - this.$store.dispatch(fetchMethod, this.profileAccount).then((response) => { + this.$store.dispatch(fetchMethod, this.profileAccount(this.uid)).then((response) => { this.uid = response.account }) - }, - methods: { } } </script> |