summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCyrille Bollu <cyrpub@bollu.be>2019-10-07 11:10:16 +0200
committerRobin Appelman <robin@icewind.nl>2020-10-13 23:51:39 +0200
commit11f129a30cfd0ef2d97badd3bec01951d120d5d4 (patch)
treea197b45b39c9f11b612a2501157854580d4d8c2e /src
parentb5e374f3a3c14a13c68e4e6e1d1458637956eb19 (diff)
REFACTORING: Adds account-related mixins to avoid code duplication
Signed-off-by: Cyrille Bollu <cyrpub@bollu.be>
Diffstat (limited to 'src')
-rw-r--r--src/components/FollowButton.vue7
-rw-r--r--src/components/ProfileInfo.vue37
-rw-r--r--src/mixins/accountMixins.js48
-rw-r--r--src/views/OStatus.vue45
-rw-r--r--src/views/Profile.vue27
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>