Add mute/unmute featrue and mutes management tab

This commit is contained in:
taehoon 2019-02-24 03:02:04 -05:00
parent 66e60572bc
commit 3255950b0e
8 changed files with 94 additions and 31 deletions

View file

@ -12,7 +12,7 @@ const MuteCard = {
return this.$store.getters.findUser(this.userId) return this.$store.getters.findUser(this.userId)
}, },
muted () { muted () {
return this.user.muted return this.user.mastodonMuted
} }
}, },
components: { components: {

View file

@ -121,21 +121,19 @@ export default {
}) })
}, },
blockUser () { blockUser () {
const store = this.$store this.$store.dispatch('blockUser', this.user.id)
store.state.api.backendInteractor.blockUser(this.user.id)
.then((blockedUser) => {
store.commit('addNewUsers', [blockedUser])
store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
store.commit('removeStatus', { timeline: 'public', userId: this.user.id })
store.commit('removeStatus', { timeline: 'publicAndExternal', userId: this.user.id })
})
}, },
unblockUser () { unblockUser () {
const store = this.$store this.$store.dispatch('unblockUser', this.user.id)
store.state.api.backendInteractor.unblockUser(this.user.id) },
.then((unblockedUser) => store.commit('addNewUsers', [unblockedUser])) muteUser () { // Mastodon Mute
this.$store.dispatch('muteUser', this.user.id)
},
unmuteUser () { // Mastodon Unmute
this.$store.dispatch('unmuteUser', this.user.id)
}, },
toggleMute () { toggleMute () {
// TODO: Pleroma mute/unmute, Need to migrate to the Mastodon API
const store = this.$store const store = this.$store
store.commit('setMuted', {user: this.user, muted: !this.user.muted}) store.commit('setMuted', {user: this.user, muted: !this.user.muted})
store.state.api.backendInteractor.setUserMute(this.user) store.state.api.backendInteractor.setUserMute(this.user)

View file

@ -74,12 +74,12 @@
</div> </div>
<div class='mute' v-if='isOtherUser && loggedIn'> <div class='mute' v-if='isOtherUser && loggedIn'>
<span v-if='user.muted'> <span v-if='user.muted'>
<button @click="toggleMute" class="pressed"> <button @click="unmuteUser" class="pressed">
{{ $t('user_card.muted') }} {{ $t('user_card.muted') }}
</button> </button>
</span> </span>
<span v-if='!user.muted'> <span v-if='!user.muted'>
<button @click="toggleMute"> <button @click="muteUser">
{{ $t('user_card.mute') }} {{ $t('user_card.mute') }}
</button> </button>
</span> </span>

View file

@ -192,6 +192,12 @@
<template slot="empty">{{$t('settings.no_blocks')}}</template> <template slot="empty">{{$t('settings.no_blocks')}}</template>
</block-list> </block-list>
</div> </div>
<div :label="$t('settings.mutes_tab')">
<mute-list :refresh="true">
<template slot="empty">{{$t('settings.no_mutes')}}</template>
</mute-list>
</div>
</tab-switcher> </tab-switcher>
</div> </div>
</div> </div>

View file

@ -177,9 +177,14 @@ const users = {
return blocks return blocks
}) })
}, },
blockUser (store, id) { blockUser (store, userId) {
return store.rootState.api.backendInteractor.blockUser(id) return store.rootState.api.backendInteractor.blockUser(userId)
.then((user) => store.commit('addNewUsers', [user])) .then((blockedUser) => {
store.commit('addNewUsers', [blockedUser])
store.commit('removeStatus', { timeline: 'friends', userId })
store.commit('removeStatus', { timeline: 'public', userId })
store.commit('removeStatus', { timeline: 'publicAndExternal', userId })
})
}, },
unblockUser (store, id) { unblockUser (store, id) {
return store.rootState.api.backendInteractor.unblockUser(id) return store.rootState.api.backendInteractor.unblockUser(id)
@ -188,18 +193,26 @@ const users = {
fetchMutes (store) { fetchMutes (store) {
return store.rootState.api.backendInteractor.fetchMutes() return store.rootState.api.backendInteractor.fetchMutes()
.then((mutedUsers) => { .then((mutedUsers) => {
each(mutedUsers, (user) => { user.muted = true }) each(mutedUsers, (user) => { user.mastodonMuted = true })
store.commit('addNewUsers', mutedUsers) store.commit('addNewUsers', mutedUsers)
store.commit('saveMutes', map(mutedUsers, 'id')) store.commit('saveMutes', map(mutedUsers, 'id'))
}) })
}, },
muteUser (store, id) { muteUser (store, id) {
return store.state.api.backendInteractor.setUserMute({ id, muted: true }) return store.rootState.api.backendInteractor.muteUser(id)
.then((user) => store.commit('addNewUsers', [user])) .then(() => {
const user = store.rootState.users.usersObject[id]
set(user, 'mastodonMuted', true)
store.commit('addNewUsers', [user])
})
}, },
unmuteUser (store, id) { unmuteUser (store, id) {
return store.state.api.backendInteractor.setUserMute({ id, muted: false }) return store.rootState.api.backendInteractor.unmuteUser(id)
.then((user) => store.commit('addNewUsers', [user])) .then(() => {
const user = store.rootState.users.usersObject[id]
set(user, 'mastodonMuted', false)
store.commit('addNewUsers', [user])
})
}, },
addFriends ({ rootState, commit }, fetchBy) { addFriends ({ rootState, commit }, fetchBy) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -350,9 +363,6 @@ const users = {
// Start getting fresh posts. // Start getting fresh posts.
store.dispatch('startFetching', { timeline: 'friends' }) store.dispatch('startFetching', { timeline: 'friends' })
// Get user mutes
store.dispatch('fetchMutes')
// Fetch our friends // Fetch our friends
store.rootState.api.backendInteractor.fetchFriends({ id: user.id }) store.rootState.api.backendInteractor.fetchFriends({ id: user.id })
.then((friends) => commit('addNewUsers', friends)) .then((friends) => commit('addNewUsers', friends))

View file

@ -1,3 +1,5 @@
import { generateUrl } from '../../utils/url'
/* eslint-env browser */ /* eslint-env browser */
const LOGIN_URL = '/api/account/verify_credentials.json' const LOGIN_URL = '/api/account/verify_credentials.json'
const FRIENDS_TIMELINE_URL = '/api/statuses/friends_timeline.json' const FRIENDS_TIMELINE_URL = '/api/statuses/friends_timeline.json'
@ -19,6 +21,9 @@ const DM_TIMELINE_URL = '/api/statuses/dm_timeline.json'
const FOLLOWERS_URL = '/api/statuses/followers.json' const FOLLOWERS_URL = '/api/statuses/followers.json'
const FRIENDS_URL = '/api/statuses/friends.json' const FRIENDS_URL = '/api/statuses/friends.json'
const BLOCKS_URL = '/api/statuses/blocks.json' const BLOCKS_URL = '/api/statuses/blocks.json'
const MUTES_URL = '/api/v1/mutes.json'
const MUTING_URL = '/api/v1/accounts/:id/mute'
const UNMUTING_URL = '/api/v1/accounts/:id/unmute'
const FOLLOWING_URL = '/api/friendships/create.json' const FOLLOWING_URL = '/api/friendships/create.json'
const UNFOLLOWING_URL = '/api/friendships/destroy.json' const UNFOLLOWING_URL = '/api/friendships/destroy.json'
const QVITTER_USER_PREF_URL = '/api/qvitter/set_profile_pref.json' const QVITTER_USER_PREF_URL = '/api/qvitter/set_profile_pref.json'
@ -538,14 +543,43 @@ const changePassword = ({credentials, password, newPassword, newPasswordConfirma
} }
const fetchMutes = ({credentials}) => { const fetchMutes = ({credentials}) => {
const url = '/api/qvitter/mutes.json' return fetch(MUTES_URL, {
return fetch(url, {
headers: authHeaders(credentials) headers: authHeaders(credentials)
}).then((data) => data.json()) }).then((data) => {
if (data.ok) {
return data.json()
}
throw new Error('Error fetching mutes', data)
})
} }
const fetchBlocks = ({page, credentials}) => { const muteUser = ({id, credentials}) => {
const url = generateUrl(MUTING_URL, { id })
return fetch(url, {
headers: authHeaders(credentials),
method: 'POST'
}).then((data) => {
if (data.ok) {
return data.json()
}
throw new Error('Error muting', data)
})
}
const unmuteUser = ({id, credentials}) => {
const url = generateUrl(UNMUTING_URL, { id })
return fetch(url, {
headers: authHeaders(credentials),
method: 'POST'
}).then((data) => {
if (data.ok) {
return data.json()
}
throw new Error('Error unmuting', data)
})
}
const fetchBlocks = ({credentials}) => {
return fetch(BLOCKS_URL, { return fetch(BLOCKS_URL, {
headers: authHeaders(credentials) headers: authHeaders(credentials)
}).then((data) => { }).then((data) => {
@ -620,6 +654,8 @@ const apiService = {
fetchAllFollowing, fetchAllFollowing,
setUserMute, setUserMute,
fetchMutes, fetchMutes,
muteUser,
unmuteUser,
fetchBlocks, fetchBlocks,
fetchOAuthTokens, fetchOAuthTokens,
revokeOAuthToken, revokeOAuthToken,

View file

@ -67,7 +67,9 @@ const backendInteractorService = (credentials) => {
} }
const fetchMutes = () => apiService.fetchMutes({credentials}) const fetchMutes = () => apiService.fetchMutes({credentials})
const fetchBlocks = (params) => apiService.fetchBlocks({credentials, ...params}) const muteUser = (id) => apiService.muteUser({credentials, id})
const unmuteUser = (id) => apiService.unmuteUser({credentials, id})
const fetchBlocks = () => apiService.fetchBlocks({credentials})
const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials}) const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
const fetchOAuthTokens = () => apiService.fetchOAuthTokens({credentials}) const fetchOAuthTokens = () => apiService.fetchOAuthTokens({credentials})
const revokeOAuthToken = (id) => apiService.revokeOAuthToken({id, credentials}) const revokeOAuthToken = (id) => apiService.revokeOAuthToken({id, credentials})
@ -102,6 +104,8 @@ const backendInteractorService = (credentials) => {
startFetching, startFetching,
setUserMute, setUserMute,
fetchMutes, fetchMutes,
muteUser,
unmuteUser,
fetchBlocks, fetchBlocks,
fetchOAuthTokens, fetchOAuthTokens,
revokeOAuthToken, revokeOAuthToken,

9
src/utils/url.js Normal file
View file

@ -0,0 +1,9 @@
// Generate url based on template
// Example: /api/v1/accounts/:id/mute -> /api/v1/accounts/123/mute
export const generateUrl = (template, params = {}) => {
let url = template
Object.entries(params).forEach(([key, value]) => {
url = url.replace(':' + key, value)
})
return url
}