abstracted mute confirmation dialog into its own component. mutes in status actions work now
This commit is contained in:
parent
41f54b687b
commit
68093b6276
13 changed files with 356 additions and 139 deletions
111
src/components/confirm_modal/mute_confirm.js
Normal file
111
src/components/confirm_modal/mute_confirm.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
import { unitToSeconds } from 'src/services/date_utils/date_utils.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
import ConfirmModal from './confirm_modal.vue'
|
||||
import Select from 'src/components/select/select.vue'
|
||||
|
||||
export default {
|
||||
props: ['type', 'user'],
|
||||
emits: ['hide', 'show', 'muted'],
|
||||
data: () => ({
|
||||
showing: false,
|
||||
muteExpiryAmount: 2,
|
||||
muteExpiryUnit: 'hours'
|
||||
}),
|
||||
components: {
|
||||
ConfirmModal,
|
||||
Select
|
||||
},
|
||||
computed: {
|
||||
muteExpiryValue () {
|
||||
unitToSeconds(this.muteExpiryUnit, this.muteExpiryAmount)
|
||||
},
|
||||
muteExpiryUnits () {
|
||||
return ['minutes', 'hours', 'days']
|
||||
},
|
||||
domain () {
|
||||
return this.user.fqn.split('@')[1]
|
||||
},
|
||||
keypath () {
|
||||
if (this.type === 'domain') {
|
||||
return 'status.mute_domain_confirm'
|
||||
} else if (this.type === 'conversation') {
|
||||
return 'status.mute_conversation_confirm'
|
||||
} else {
|
||||
return 'user_card.mute_confirm'
|
||||
}
|
||||
},
|
||||
userIsMuted () {
|
||||
return this.$store.getters.relationship(this.user.id).muting
|
||||
},
|
||||
conversationIsMuted () {
|
||||
return this.status.conversation_muted
|
||||
},
|
||||
domainIsMuted () {
|
||||
return new Set(this.$store.state.users.currentUser.domainMutes).has(this.domain)
|
||||
},
|
||||
shouldConfirm () {
|
||||
switch (this.type) {
|
||||
case 'domain': {
|
||||
return this.mergedConfig.modalOnMuteDomain
|
||||
}
|
||||
case 'conversation': {
|
||||
return this.mergedConfig.modalOnMuteConversation
|
||||
}
|
||||
default: {
|
||||
return this.mergedConfig.modalOnMute
|
||||
}
|
||||
}
|
||||
},
|
||||
...mapGetters(['mergedConfig'])
|
||||
},
|
||||
methods: {
|
||||
optionallyPrompt () {
|
||||
console.log('Triggered')
|
||||
if (this.shouldConfirm) {
|
||||
console.log('SHAWN!!')
|
||||
this.show()
|
||||
} else {
|
||||
this.doMute()
|
||||
}
|
||||
},
|
||||
show () {
|
||||
this.showing = true
|
||||
this.$emit('show')
|
||||
},
|
||||
hide () {
|
||||
this.showing = false
|
||||
this.$emit('hide')
|
||||
},
|
||||
doMute () {
|
||||
switch (this.type) {
|
||||
case 'domain': {
|
||||
if (!this.domainIsMuted) {
|
||||
this.$store.dispatch('muteDomain', { id: this.domain, expiresIn: this.muteExpiryValue })
|
||||
} else {
|
||||
this.$store.dispatch('unmuteDomain', { id: this.domain })
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'conversation': {
|
||||
if (!this.conversationIsMuted) {
|
||||
this.$store.dispatch('muteConversation', { id: this.status.id, expiresIn: this.muteExpiryValue })
|
||||
} else {
|
||||
this.$store.dispatch('unmuteConversation', { id: this.status.id })
|
||||
}
|
||||
break
|
||||
}
|
||||
default: {
|
||||
if (!this.userIsMuted) {
|
||||
this.$store.dispatch('muteUser', { id: this.user.id, expiresIn: this.muteExpiryValue })
|
||||
} else {
|
||||
this.$store.dispatch('unmuteUser', { id: this.user.id })
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
this.$emit('muted')
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
}
|
58
src/components/confirm_modal/mute_confirm.vue
Normal file
58
src/components/confirm_modal/mute_confirm.vue
Normal file
|
@ -0,0 +1,58 @@
|
|||
<template>
|
||||
<confirm-modal
|
||||
v-if="showing"
|
||||
:title="$t('user_card.mute_confirm_title')"
|
||||
:confirm-text="$t('user_card.mute_confirm_accept_button')"
|
||||
:cancel-text="$t('user_card.mute_confirm_cancel_button')"
|
||||
@accepted="doMute"
|
||||
@cancelled="hide"
|
||||
>
|
||||
<i18n-t
|
||||
:keypath="keypath"
|
||||
tag="div"
|
||||
>
|
||||
<template #domain>
|
||||
<span v-text="domain" />
|
||||
</template>
|
||||
<template #user>
|
||||
<span v-text="user.screen_name_ui" />
|
||||
</template>
|
||||
</i18n-t>
|
||||
<div class="mute-expiry" v-if="type !== 'domain'">
|
||||
<p>
|
||||
<label>
|
||||
{{ $t('user_card.mute_duration_prompt') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="muteExpiryAmount"
|
||||
type="number"
|
||||
class="input expiry-amount hide-number-spinner"
|
||||
:min="0"
|
||||
>
|
||||
{{ ' ' }}
|
||||
<Select
|
||||
v-model="muteExpiryUnit"
|
||||
unstyled="true"
|
||||
class="expiry-unit"
|
||||
>
|
||||
<option
|
||||
v-for="unit in muteExpiryUnits"
|
||||
:key="unit"
|
||||
:value="unit"
|
||||
>
|
||||
{{ $t(`time.unit.${unit}_short`, ['']) }}
|
||||
</option>
|
||||
</Select>
|
||||
</p>
|
||||
</div>
|
||||
</confirm-modal>
|
||||
</template>
|
||||
|
||||
<script src="./mute_confirm.js" />
|
||||
|
||||
<style lang="scss">
|
||||
.expiry-amount {
|
||||
width: 4em;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
|
@ -116,6 +116,16 @@
|
|||
{{ $t('settings.confirm_dialogs_mute') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="modalOnMuteConversation">
|
||||
{{ $t('settings.confirm_dialogs_mute_conversation') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="modalOnMuteDomain">
|
||||
{{ $t('settings.confirm_dialogs_mute_domain') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="modalOnDelete">
|
||||
{{ $t('settings.confirm_dialogs_delete') }}
|
||||
|
|
|
@ -84,8 +84,13 @@ export default {
|
|||
}
|
||||
]
|
||||
},
|
||||
userIsMuted () {
|
||||
return this.$store.getters.relationship(this.status.user.id).muting
|
||||
},
|
||||
threadIsMuted () {
|
||||
return this.status.thread_muted
|
||||
},
|
||||
buttonInnerClass () {
|
||||
if (!this.extra) console.log(this.button.name)
|
||||
return [
|
||||
this.button.name + '-button',
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import ActionButton from './action_button.vue'
|
||||
import Popover from 'src/components/popover/popover.vue'
|
||||
import MuteConfirm from 'src/components/confirm_modal/mute_confirm.vue'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
|
@ -17,7 +18,72 @@ library.add(
|
|||
export default {
|
||||
components: {
|
||||
ActionButton,
|
||||
Popover
|
||||
Popover,
|
||||
MuteConfirm
|
||||
},
|
||||
props: ['button']
|
||||
props: ['button', 'status'],
|
||||
mounted () {
|
||||
if (this.button.name === 'mute') {
|
||||
this.$store.dispatch('fetchDomainMutes')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
buttonClass () {
|
||||
return [
|
||||
this.button.name + '-button',
|
||||
{
|
||||
'-with-extra': this.button.name === 'bookmark',
|
||||
'-extra': this.extra,
|
||||
'-quick': !this.extra
|
||||
}
|
||||
]
|
||||
},
|
||||
user () {
|
||||
return this.status.user
|
||||
},
|
||||
userIsMuted () {
|
||||
return this.$store.getters.relationship(this.user.id).muting
|
||||
},
|
||||
conversationIsMuted () {
|
||||
return this.status.thread_muted
|
||||
},
|
||||
domain () {
|
||||
return this.user.fqn.split('@')[1]
|
||||
},
|
||||
domainIsMuted () {
|
||||
return new Set(this.$store.state.users.currentUser.domainMutes).has(this.domain)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
unmuteUser () {
|
||||
return this.$store.dispatch('unmuteUser', this.user.id)
|
||||
},
|
||||
unmuteThread () {
|
||||
return this.$store.dispatch('unmuteConversation', this.user.id)
|
||||
},
|
||||
unmuteDomain () {
|
||||
return this.$store.dispatch('unmuteDomain', this.user.id)
|
||||
},
|
||||
toggleUserMute () {
|
||||
if (this.userIsMuted) {
|
||||
this.unmuteUser()
|
||||
} else {
|
||||
this.$refs.confirmUser.optionallyPrompt()
|
||||
}
|
||||
},
|
||||
toggleConversationMute () {
|
||||
if (this.conversationIsMuted) {
|
||||
this.unmuteConversation()
|
||||
} else {
|
||||
this.$refs.confirmConversation.optionallyPrompt()
|
||||
}
|
||||
},
|
||||
toggleDomainMute () {
|
||||
if (this.domainIsMuted) {
|
||||
this.unmuteDomain()
|
||||
} else {
|
||||
this.$refs.confirmDomain.optionallyPrompt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<Popover
|
||||
trigger="hover"
|
||||
:placement="$attrs.extra ? 'right' : 'top'"
|
||||
|
@ -8,6 +9,7 @@
|
|||
{{ props }}
|
||||
<ActionButton
|
||||
:button="button"
|
||||
:status="status"
|
||||
v-bind.prop="$attrs"
|
||||
/>
|
||||
</template>
|
||||
|
@ -21,28 +23,43 @@
|
|||
<div class="menu-item dropdown-item extra-action -icon">
|
||||
<button
|
||||
class="main-button"
|
||||
@click="() => {}"
|
||||
@click="toggleUserMute"
|
||||
>
|
||||
<FAIcon icon="user" fixed-width />
|
||||
<template v-if="userIsMuted">
|
||||
{{ $t('status.unmute_user') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ $t('status.mute_user') }}
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
<div class="menu-item dropdown-item extra-action -icon">
|
||||
<button
|
||||
class="main-button"
|
||||
@click="() => {}"
|
||||
@click="toggleUserMute"
|
||||
>
|
||||
<FAIcon icon="folder-tree" fixed-width />
|
||||
<template v-if="threadIsMuted">
|
||||
{{ $t('status.unmute_conversation') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ $t('status.mute_conversation') }}
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
<div class="menu-item dropdown-item extra-action -icon">
|
||||
<button
|
||||
class="main-button"
|
||||
@click="() => {}"
|
||||
@click="toggleDomainMute"
|
||||
>
|
||||
<FAIcon icon="globe" fixed-width />
|
||||
<template v-if="domainIsMuted">
|
||||
{{ $t('status.unmute_domain') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ $t('status.mute_domain') }}
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -51,8 +68,27 @@
|
|||
<ActionButton
|
||||
v-else
|
||||
:button="button"
|
||||
:status="status"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
<teleport to="#modal">
|
||||
<mute-confirm
|
||||
type="conversation"
|
||||
:status="this.status"
|
||||
ref="confirmConversation"
|
||||
/>
|
||||
<mute-confirm
|
||||
type="domain"
|
||||
:user="this.user"
|
||||
ref="confirmDomain"
|
||||
/>
|
||||
<mute-confirm
|
||||
type="user"
|
||||
:user="this.user"
|
||||
ref="confirmUser"
|
||||
/>
|
||||
</teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./action_button_container.js"/>
|
||||
|
|
|
@ -94,11 +94,6 @@ export const BUTTONS = [{
|
|||
toggleable: true,
|
||||
dropdown: true
|
||||
// action ({ status, dispatch, emit }) {
|
||||
// if (status.thread_muted) {
|
||||
// return dispatch('unmuteConversation', { id: status.id })
|
||||
// } else {
|
||||
// return dispatch('muteConversation', { id: status.id })
|
||||
// }
|
||||
// }
|
||||
}, {
|
||||
// =========
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { unitToSeconds } from 'src/services/date_utils/date_utils.js'
|
||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||
import RemoteFollow from '../remote_follow/remote_follow.vue'
|
||||
import ProgressButton from '../progress_button/progress_button.vue'
|
||||
|
@ -9,7 +8,7 @@ import UserNote from '../user_note/user_note.vue'
|
|||
import Select from '../select/select.vue'
|
||||
import UserLink from '../user_link/user_link.vue'
|
||||
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||
import MuteConfirm from '../confirm_modal/mute_confirm.vue'
|
||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
|
@ -48,7 +47,6 @@ export default {
|
|||
data () {
|
||||
return {
|
||||
followRequestInProgress: false,
|
||||
showingConfirmMute: false,
|
||||
muteExpiryAmount: 0,
|
||||
muteExpiryUnit: 'minutes'
|
||||
}
|
||||
|
@ -141,12 +139,6 @@ export default {
|
|||
supportsNote () {
|
||||
return 'note' in this.relationship
|
||||
},
|
||||
shouldConfirmMute () {
|
||||
return this.mergedConfig.modalOnMute
|
||||
},
|
||||
muteExpiryUnits () {
|
||||
return ['minutes', 'hours', 'days']
|
||||
},
|
||||
...mapGetters(['mergedConfig'])
|
||||
},
|
||||
components: {
|
||||
|
@ -160,28 +152,11 @@ export default {
|
|||
RichContent,
|
||||
UserLink,
|
||||
UserNote,
|
||||
ConfirmModal
|
||||
MuteConfirm
|
||||
},
|
||||
methods: {
|
||||
showConfirmMute () {
|
||||
this.showingConfirmMute = true
|
||||
},
|
||||
hideConfirmMute () {
|
||||
this.showingConfirmMute = false
|
||||
},
|
||||
muteUser () {
|
||||
if (!this.shouldConfirmMute) {
|
||||
this.doMuteUser()
|
||||
} else {
|
||||
this.showConfirmMute()
|
||||
}
|
||||
},
|
||||
doMuteUser () {
|
||||
this.$store.dispatch('muteUser', {
|
||||
id: this.user.id,
|
||||
expiresIn: this.shouldConfirmMute ? unitToSeconds(this.muteExpiryUnit, this.muteExpiryAmount) : 0
|
||||
})
|
||||
this.hideConfirmMute()
|
||||
this.$refs.confirmation.optionallyPrompt()
|
||||
},
|
||||
unmuteUser () {
|
||||
this.$store.dispatch('unmuteUser', this.user.id)
|
||||
|
|
|
@ -325,8 +325,3 @@
|
|||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mute-expiry {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
|
|
@ -311,51 +311,11 @@
|
|||
/>
|
||||
</div>
|
||||
<teleport to="#modal">
|
||||
<confirm-modal
|
||||
v-if="showingConfirmMute"
|
||||
:title="$t('user_card.mute_confirm_title')"
|
||||
:confirm-text="$t('user_card.mute_confirm_accept_button')"
|
||||
:cancel-text="$t('user_card.mute_confirm_cancel_button')"
|
||||
@accepted="doMuteUser"
|
||||
@cancelled="hideConfirmMute"
|
||||
>
|
||||
<i18n-t
|
||||
keypath="user_card.mute_confirm"
|
||||
tag="div"
|
||||
>
|
||||
<template #user>
|
||||
<span
|
||||
v-text="user.screen_name_ui"
|
||||
<mute-confirm
|
||||
type="user"
|
||||
:user="this.user"
|
||||
ref="confirmation"
|
||||
/>
|
||||
</template>
|
||||
</i18n-t>
|
||||
<div
|
||||
class="mute-expiry"
|
||||
>
|
||||
<label>
|
||||
{{ $t('user_card.mute_duration_prompt') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="muteExpiryAmount"
|
||||
type="number"
|
||||
class="expiry-amount hide-number-spinner"
|
||||
:min="0"
|
||||
>
|
||||
<Select
|
||||
v-model="muteExpiryUnit"
|
||||
unstyled="true"
|
||||
class="expiry-unit"
|
||||
>
|
||||
<option
|
||||
v-for="unit in muteExpiryUnits"
|
||||
:key="unit"
|
||||
:value="unit"
|
||||
>
|
||||
{{ $t(`time.${unit}_short`, ['']) }}
|
||||
</option>
|
||||
</Select>
|
||||
</div>
|
||||
</confirm-modal>
|
||||
</teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -490,6 +490,8 @@
|
|||
"confirm_dialogs_unfollow": "unfollowing a user",
|
||||
"confirm_dialogs_block": "blocking a user",
|
||||
"confirm_dialogs_mute": "muting a user",
|
||||
"confirm_dialogs_mute_domain": "muting domains",
|
||||
"confirm_dialogs_mute_conversation": "muting conversations",
|
||||
"confirm_dialogs_delete": "deleting a status",
|
||||
"confirm_dialogs_logout": "logging out",
|
||||
"confirm_dialogs_approve_follow": "approving a follower",
|
||||
|
|
|
@ -137,6 +137,8 @@ export const defaultState = {
|
|||
modalOnUnfollow: undefined, // instance default
|
||||
modalOnBlock: undefined, // instance default
|
||||
modalOnMute: undefined, // instance default
|
||||
modalOnMuteConversation: undefined, // instance default
|
||||
modalOnMuteDomain: undefined, // instance default
|
||||
modalOnDelete: undefined, // instance default
|
||||
modalOnLogout: undefined, // instance default
|
||||
modalOnApproveFollow: undefined, // instance default
|
||||
|
|
|
@ -77,6 +77,8 @@ const defaultState = {
|
|||
modalOnUnfollow: false,
|
||||
modalOnBlock: true,
|
||||
modalOnMute: false,
|
||||
modalOnMuteConversation: false,
|
||||
modalOnMuteDomain: true,
|
||||
modalOnDelete: true,
|
||||
modalOnLogout: true,
|
||||
modalOnApproveFollow: false,
|
||||
|
|
Loading…
Add table
Reference in a new issue