diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index f7bff63f..6a0e4dfc 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -8,6 +8,7 @@ import Select from '../select/select.vue' import RichContent from 'src/components/rich_content/rich_content.jsx' import ConfirmModal from '../confirm_modal/confirm_modal.vue' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' +import { notificationsFromStore } from 'src/services/notification_utils/notification_utils.js' import { mapGetters } from 'vuex' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -34,7 +35,9 @@ export default { return { followRequestInProgress: false, betterShadow: this.$store.state.interface.browserSupport.cssFilter, - showingConfirmMute: false + showingConfirmMute: false, + showingApproveConfirmDialog: false, + showingDenyConfirmDialog: false } }, created () { @@ -117,6 +120,12 @@ export default { shouldConfirmMute () { return this.mergedConfig.modalOnMute }, + shouldConfirmApprove () { + return this.mergedConfig.modalOnApproveFollow + }, + shouldConfirmDeny () { + return this.mergedConfig.modalOnDenyFollow + }, ...mapGetters(['mergedConfig']) }, components: { @@ -193,6 +202,58 @@ export default { }, mentionUser () { this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user }) + }, + showApproveConfirmDialog () { + this.showingApproveConfirmDialog = true + }, + hideApproveConfirmDialog () { + this.showingApproveConfirmDialog = false + }, + showDenyConfirmDialog () { + this.showingDenyConfirmDialog = true + }, + hideDenyConfirmDialog () { + this.showingDenyConfirmDialog = false + }, + approveUser () { + if (this.shouldConfirmApprove) { + this.showApproveConfirmDialog() + } else { + this.doApprove() + } + }, + doApprove () { + const notifId = this.findFollowRequestNotificationId() + this.$store.dispatch('approveUser', this.user.id) + this.$store.dispatch('markSingleNotificationAsSeen', { id: notifId }) + this.$store.dispatch('updateNotification', { + id: notifId, + updater: notification => { + notification.type = 'follow' + } + }) + this.hideApproveConfirmDialog() + }, + denyUser () { + if (this.shouldConfirmDeny) { + this.showDenyConfirmDialog() + } else { + this.doDeny() + } + }, + doDeny () { + const notifId = this.findFollowRequestNotificationId() + this.$store.dispatch('denyUser', this.user.id) + .then(() => { + this.$store.dispatch('dismissNotificationLocal', { id: notifId }) + }) + this.hideDenyConfirmDialog() + }, + findFollowRequestNotificationId () { + const notif = notificationsFromStore(this.$store).find( + (notif) => notif.from_profile.id === this.user.id && notif.type === 'follow_request' + ) + return notif && notif.id } } } diff --git a/src/components/user_card/user_card.scss b/src/components/user_card/user_card.scss index 0a5e744e..c844fa3f 100644 --- a/src/components/user_card/user_card.scss +++ b/src/components/user_card/user_card.scss @@ -242,6 +242,12 @@ text-align: left; } + .requested_by { + .btn { + margin-right: .25em; + } + } + .highlighter { flex: 0 1 auto; display: flex; diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 289db15b..37ee4275 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -142,8 +142,29 @@
{{ $t('user_card.requested_by') }} + +
+ + {{ $t('user_card.approve_confirm', { user: user.screen_name_ui }) }} + + + {{ $t('user_card.deny_confirm', { user: user.screen_name_ui }) }} +
diff --git a/src/modules/users.js b/src/modules/users.js index 9d81f9bc..fee52446 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -54,6 +54,26 @@ const unblockUser = (store, id) => { .then((relationship) => store.commit('updateUserRelationship', [relationship])) } +const approveUser = (store, id) => { + const predictedRelationship = store.state.relationships[id] || { id } + predictedRelationship.requested_by = false + predictedRelationship.followed_by = true + store.commit('updateUserRelationship', [predictedRelationship]) + + return store.rootState.api.backendInteractor.approveUser({ id }) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + +const denyUser = (store, id) => { + const predictedRelationship = store.state.relationships[id] || { id } + predictedRelationship.requested_by = false + predictedRelationship.followed_by = false + store.commit('updateUserRelationship', [predictedRelationship]) + + return store.rootState.api.backendInteractor.denyUser({ id }) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + const removeUserFromFollowers = (store, id) => { return store.rootState.api.backendInteractor.removeUserFromFollowers({ id }) .then((relationship) => store.commit('updateUserRelationship', [relationship])) @@ -344,6 +364,12 @@ const users = { unblockUser (store, id) { return unblockUser(store, id) }, + approveUser (store, id) { + return approveUser(store, id) + }, + denyUser (store, id) { + return denyUser(store, id) + }, removeUserFromFollowers (store, id) { return removeUserFromFollowers(store, id) },