commit: 0e6134b32e820deeb947aa5e9e0401eecfc80bba
parent: e1e9e50b981fe6507886cae26603e4fcf9b5af75
Author: Shpuld Shpludson <shp@cock.li>
Date: Mon, 11 Feb 2019 13:29:58 +0000
Merge branch 'issue-332-update-follow-tabs' into 'develop'
#332 - add follow/not follow button to follow list
See merge request pleroma/pleroma-fe!558
Diffstat:
6 files changed, 158 insertions(+), 76 deletions(-)
diff --git a/src/components/follow_list/follow_list.js b/src/components/follow_list/follow_list.js
@@ -25,7 +25,8 @@ const FollowList = {
},
entries () {
return this.showFollowers ? this.user.followers : this.user.friends
- }
+ },
+ showActions () { return this.$store.state.users.currentUser.id === this.userId }
},
methods: {
fetchEntries () {
diff --git a/src/components/follow_list/follow_list.vue b/src/components/follow_list/follow_list.vue
@@ -3,7 +3,8 @@
<user-card
v-for="entry in entries"
:key="entry.id" :user="entry"
- :showFollows="true"
+ :showFollows="!showFollowers"
+ :showActions="showActions"
/>
<div class="text-center panel-footer">
<a v-if="error" @click="fetchEntries" class="alert error">
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
@@ -1,16 +1,21 @@
import UserCardContent from '../user_card_content/user_card_content.vue'
import UserAvatar from '../user_avatar/user_avatar.vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
+import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
const UserCard = {
props: [
'user',
'showFollows',
- 'showApproval'
+ 'showApproval',
+ 'showActions'
],
data () {
return {
- userExpanded: false
+ userExpanded: false,
+ followRequestInProgress: false,
+ followRequestSent: false,
+ updated: false
}
},
components: {
@@ -18,7 +23,11 @@ const UserCard = {
UserAvatar
},
computed: {
- currentUser () { return this.$store.state.users.currentUser }
+ currentUser () { return this.$store.state.users.currentUser },
+ following () { return this.updated ? this.updated.following : this.user.following },
+ showFollow () {
+ return this.showActions && (!this.showFollows && !this.following || this.updated && !this.updated.following)
+ }
},
methods: {
toggleUserExpanded () {
@@ -34,6 +43,21 @@ const UserCard = {
},
userProfileLink (user) {
return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
+ },
+ followUser () {
+ this.followRequestInProgress = true
+ requestFollow(this.user, this.$store).then(({ sent, updated }) => {
+ this.followRequestInProgress = false
+ this.followRequestSent = sent
+ this.updated = updated
+ })
+ },
+ unfollowUser () {
+ this.followRequestInProgress = true
+ requestUnfollow(this.user, this.$store).then(({ updated }) => {
+ this.followRequestInProgress = false
+ this.updated = updated
+ })
}
}
}
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
@@ -7,22 +7,43 @@
<user-card-content :user="user" :switcher="false"></user-card-content>
</div>
<div class="name-and-screen-name" v-else>
- <div :title="user.name" v-if="user.name_html" class="user-name">
- <span v-html="user.name_html"></span>
+ <div :title="user.name" class="user-name">
+ <span v-if="user.name_html" v-html="user.name_html"></span>
+ <span v-else>{{ user.name }}</span>
<span class="follows-you" v-if="!userExpanded && showFollows && user.follows_you">
{{ currentUser.id == user.id ? $t('user_card.its_you') : $t('user_card.follows_you') }}
</span>
</div>
- <div :title="user.name" v-else class="user-name">
- {{ user.name }}
- <span class="follows-you" v-if="!userExpanded && showFollows && user.follows_you">
- {{ currentUser.id == user.id ? $t('user_card.its_you') : $t('user_card.follows_you') }}
- </span>
+ <div class="user-link-action">
+ <router-link class='user-screen-name' :to="userProfileLink(user)">
+ @{{user.screen_name}}
+ </router-link>
+ <button
+ v-if="showFollow"
+ class="btn btn-default"
+ @click="followUser"
+ :disabled="followRequestInProgress"
+ :title="followRequestSent ? $t('user_card.follow_again') : ''"
+ >
+ <template v-if="followRequestInProgress">
+ {{ $t('user_card.follow_progress') }}
+ </template>
+ <template v-else-if="followRequestSent">
+ {{ $t('user_card.follow_sent') }}
+ </template>
+ <template v-else>
+ {{ $t('user_card.follow') }}
+ </template>
+ </button>
+ <button v-if="showActions && showFollows && following" class="btn btn-default" @click="unfollowUser" :disabled="followRequestInProgress">
+ <template v-if="followRequestInProgress">
+ {{ $t('user_card.follow_progress') }}
+ </template>
+ <template v-else>
+ {{ $t('user_card.follow_unfollow') }}
+ </template>
+ </button>
</div>
-
- <router-link class='user-screen-name' :to="userProfileLink(user)">
- @{{user.screen_name}}
- </router-link>
</div>
<div class="approval" v-if="showApproval">
<button class="btn btn-default" @click="approveUser">{{ $t('user_card.approve') }}</button>
@@ -42,6 +63,9 @@
text-align: left;
width: 100%;
.user-name {
+ display: flex;
+ justify-content: space-between;
+
img {
object-fit: contain;
height: 16px;
@@ -49,11 +73,20 @@
vertical-align: middle;
}
}
+
+ .user-link-action {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+
+ button {
+ margin-top: 3px;
+ }
+ }
}
.follows-you {
margin-left: 2em;
- float: right;
}
.card {
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
@@ -1,5 +1,6 @@
import UserAvatar from '../user_avatar/user_avatar.vue'
import { hex2rgb } from '../../services/color_convert/color_convert.js'
+import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
export default {
@@ -92,69 +93,17 @@ export default {
},
methods: {
followUser () {
- const store = this.$store
this.followRequestInProgress = true
- store.state.api.backendInteractor.followUser(this.user.id)
- .then((followedUser) => store.commit('addNewUsers', [followedUser]))
- .then(() => {
- // For locked users we just mark it that we sent the follow request
- if (this.user.locked) {
- this.followRequestInProgress = false
- this.followRequestSent = true
- return
- }
-
- if (this.user.following) {
- // If we get result immediately, just stop.
- this.followRequestInProgress = false
- return
- }
-
- // But usually we don't get result immediately, so we ask server
- // for updated user profile to confirm if we are following them
- // Sometimes it takes several tries. Sometimes we end up not following
- // user anyway, probably because they locked themselves and we
- // don't know that yet.
- // Recursive Promise, it will call itself up to 3 times.
- const fetchUser = (attempt) => new Promise((resolve, reject) => {
- setTimeout(() => {
- store.state.api.backendInteractor.fetchUser({ id: this.user.id })
- .then((user) => store.commit('addNewUsers', [user]))
- .then(() => resolve([this.user.following, attempt]))
- .catch((e) => reject(e))
- }, 500)
- }).then(([following, attempt]) => {
- if (!following && attempt <= 3) {
- // If we BE reports that we still not following that user - retry,
- // increment attempts by one
- return fetchUser(++attempt)
- } else {
- // If we run out of attempts, just return whatever status is.
- return following
- }
- })
-
- return fetchUser(1)
- .then((following) => {
- if (following) {
- // We confirmed and everything its good.
- this.followRequestInProgress = false
- } else {
- // If after all the tries, just treat it as if user is locked
- this.followRequestInProgress = false
- this.followRequestSent = true
- }
- })
- })
+ requestFollow(this.user, this.$store).then(({sent}) => {
+ this.followRequestInProgress = false
+ this.followRequestSent = sent
+ })
},
unfollowUser () {
- const store = this.$store
this.followRequestInProgress = true
- store.state.api.backendInteractor.unfollowUser(this.user.id)
- .then((unfollowedUser) => store.commit('addNewUsers', [unfollowedUser]))
- .then(() => {
- this.followRequestInProgress = false
- })
+ requestUnfollow(this.user, this.$store).then(() => {
+ this.followRequestInProgress = false
+ })
},
blockUser () {
const store = this.$store
diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js
@@ -0,0 +1,74 @@
+const fetchUser = (attempt, user, store) => new Promise((resolve, reject) => {
+ setTimeout(() => {
+ store.state.api.backendInteractor.fetchUser({ id: user.id })
+ .then((user) => store.commit('addNewUsers', [user]))
+ .then(() => resolve([user.following, attempt]))
+ .catch((e) => reject(e))
+ }, 500)
+}).then(([following, attempt]) => {
+ if (!following && attempt <= 3) {
+ // If we BE reports that we still not following that user - retry,
+ // increment attempts by one
+ return fetchUser(++attempt, user, store)
+ } else {
+ // If we run out of attempts, just return whatever status is.
+ return following
+ }
+})
+
+export const requestFollow = (user, store) => new Promise((resolve, reject) => {
+ store.state.api.backendInteractor.followUser(user.id)
+ .then((updated) => {
+ store.commit('addNewUsers', [updated])
+
+ // For locked users we just mark it that we sent the follow request
+ if (updated.locked) {
+ resolve({
+ sent: true,
+ updated
+ })
+ }
+
+ if (updated.following) {
+ // If we get result immediately, just stop.
+ resolve({
+ sent: false,
+ updated
+ })
+ }
+
+ // But usually we don't get result immediately, so we ask server
+ // for updated user profile to confirm if we are following them
+ // Sometimes it takes several tries. Sometimes we end up not following
+ // user anyway, probably because they locked themselves and we
+ // don't know that yet.
+ // Recursive Promise, it will call itself up to 3 times.
+
+ return fetchUser(1, user, store)
+ .then((following) => {
+ if (following) {
+ // We confirmed and everything's good.
+ resolve({
+ sent: false,
+ updated
+ })
+ } else {
+ // If after all the tries, just treat it as if user is locked
+ resolve({
+ sent: false,
+ updated
+ })
+ }
+ })
+ })
+})
+
+export const requestUnfollow = (user, store) => new Promise((resolve, reject) => {
+ store.state.api.backendInteractor.unfollowUser(user.id)
+ .then((updated) => {
+ store.commit('addNewUsers', [updated])
+ resolve({
+ updated
+ })
+ })
+})