kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
297 wiersze
8.8 KiB
Vue
297 wiersze
8.8 KiB
Vue
<template>
|
|
<form
|
|
class="ui form"
|
|
@submit.prevent="createOrUpdate"
|
|
>
|
|
<h3 class="ui header">
|
|
<translate
|
|
v-if="object"
|
|
translate-context="Content/Moderation/Card.Title/Verb"
|
|
>
|
|
Edit moderation rule
|
|
</translate>
|
|
<translate
|
|
v-else
|
|
translate-context="Content/Moderation/Card.Button.Label/Verb"
|
|
>
|
|
Add a new moderation rule
|
|
</translate>
|
|
</h3>
|
|
<div
|
|
v-if="errors && errors.length > 0"
|
|
role="alert"
|
|
class="ui negative message"
|
|
>
|
|
<h4 class="header">
|
|
<translate translate-context="Content/Moderation/Error message.Title">
|
|
Error while creating rule
|
|
</translate>
|
|
</h4>
|
|
<ul class="list">
|
|
<li
|
|
v-for="(error, key) in errors"
|
|
:key="key"
|
|
>
|
|
{{ error }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div
|
|
v-if="object"
|
|
class="field"
|
|
>
|
|
<div class="ui toggle checkbox">
|
|
<input
|
|
id="policy-is-active"
|
|
v-model="current.isActive"
|
|
type="checkbox"
|
|
>
|
|
<label for="policy-is-active">
|
|
<translate
|
|
v-if="current.isActive"
|
|
translate-context="*/*/*/State of feature"
|
|
>Enabled</translate>
|
|
<translate
|
|
v-else
|
|
translate-context="*/*/*/State of feature"
|
|
>Disabled</translate>
|
|
<tooltip :content="labels.isActiveHelp" />
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<label for="policy-summary">
|
|
<translate translate-context="Content/Moderation/*/Noun">Reason</translate>
|
|
<tooltip :content="labels.summaryHelp" />
|
|
</label>
|
|
<textarea
|
|
id="policy-summary"
|
|
v-model="current.summary"
|
|
name="policy-summary"
|
|
rows="5"
|
|
/>
|
|
</div>
|
|
<div class="field">
|
|
<div class="ui toggle checkbox">
|
|
<input
|
|
id="policy-is-active"
|
|
v-model="current.blockAll"
|
|
type="checkbox"
|
|
>
|
|
<label for="policy-is-active">
|
|
<translate translate-context="Content/Moderation/*/Verb">Block everything</translate>
|
|
<tooltip :content="labels.blockAllHelp" />
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="ui horizontal divider">
|
|
<translate translate-context="Content/Moderation/Card.Title">
|
|
Or customize your rule
|
|
</translate>
|
|
</div>
|
|
<div
|
|
v-for="(config, key) in fieldConfig"
|
|
:key="key"
|
|
:class="['field']"
|
|
>
|
|
<div class="ui toggle checkbox">
|
|
<input
|
|
:id="'policy-' + config.id"
|
|
v-model="current[config.id]"
|
|
type="checkbox"
|
|
>
|
|
<label :for="'policy-' + config.id">
|
|
<i :class="[config.icon, 'icon']" />
|
|
{{ labels[config.id].label }}
|
|
<tooltip :content="labels[config.id].help" />
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="ui hidden divider" />
|
|
<button
|
|
class="ui basic left floated button"
|
|
@click.prevent="$emit('cancel')"
|
|
>
|
|
<translate translate-context="*/*/Button.Label/Verb">
|
|
Cancel
|
|
</translate>
|
|
</button>
|
|
<button
|
|
:class="['ui', 'right', 'floated', 'success', {'disabled loading': isLoading}, 'button']"
|
|
:disabled="isLoading || null"
|
|
>
|
|
<translate
|
|
v-if="object"
|
|
translate-context="Content/Moderation/Card.Button.Label/Verb"
|
|
>
|
|
Update
|
|
</translate>
|
|
<translate
|
|
v-else
|
|
translate-context="Content/Moderation/Card.Button.Label/Verb"
|
|
>
|
|
Create
|
|
</translate>
|
|
</button>
|
|
<dangerous-button
|
|
v-if="object"
|
|
class="ui right floated basic danger button"
|
|
@confirm="remove"
|
|
>
|
|
<translate translate-context="*/*/*/Verb">
|
|
Delete
|
|
</translate>
|
|
<template #modal-header>
|
|
<p>
|
|
<translate translate-context="Popup/Moderation/Title">
|
|
Delete this moderation rule?
|
|
</translate>
|
|
</p>
|
|
</template>
|
|
<template #modal-content>
|
|
<p>
|
|
<translate translate-context="Popup/Moderation/Paragraph">
|
|
This action is irreversible.
|
|
</translate>
|
|
</p>
|
|
</template>
|
|
<template #modal-confirm>
|
|
<div>
|
|
<translate translate-context="Popup/Moderation/Button.Label/Verb">
|
|
Delete moderation rule
|
|
</translate>
|
|
</div>
|
|
</template>
|
|
</dangerous-button>
|
|
</form>
|
|
</template>
|
|
|
|
<script>
|
|
import axios from 'axios'
|
|
import { get } from 'lodash-es'
|
|
|
|
export default {
|
|
props: {
|
|
type: { type: String, required: true },
|
|
object: { type: Object, default: null },
|
|
target: { type: String, required: true }
|
|
},
|
|
data () {
|
|
const current = this.object || {}
|
|
return {
|
|
isLoading: false,
|
|
errors: [],
|
|
current: {
|
|
summary: get(current, 'summary', ''),
|
|
isActive: get(current, 'is_active', true),
|
|
blockAll: get(current, 'block_all', true),
|
|
silenceActivity: get(current, 'silence_activity', false),
|
|
silenceNotifications: get(current, 'silence_notifications', false),
|
|
rejectMedia: get(current, 'reject_media', false)
|
|
},
|
|
fieldConfig: [
|
|
// we hide those until we actually have the related features implemented :)
|
|
// {id: "silenceActivity", icon: "feed"},
|
|
// {id: "silenceNotifications", icon: "bell"},
|
|
{ id: 'rejectMedia', icon: 'file' }
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
labels () {
|
|
return {
|
|
summaryHelp: this.$pgettext('Content/Moderation/Help text', "Explain why you're applying this policy: this will help you remember why you added this rule. Depending on your pod configuration, this may be displayed publicly to help users understand the moderation rules in place."),
|
|
isActiveHelp: this.$pgettext('Content/Moderation/Help text', 'Use this setting to temporarily enable/disable the policy without completely removing it.'),
|
|
blockAllHelp: this.$pgettext('Content/Moderation/Help text', 'Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)'),
|
|
silenceActivity: {
|
|
help: this.$pgettext('Content/Moderation/Help text', 'Hide account or domain content, except from followers.'),
|
|
label: this.$pgettext('Content/Moderation/*/Verb', 'Mute activity')
|
|
},
|
|
silenceNotifications: {
|
|
help: this.$pgettext('Content/Moderation/Help text', 'Prevent account or domain from triggering notifications, except from followers.'),
|
|
label: this.$pgettext('Content/Moderation/*/Verb', 'Mute notifications')
|
|
},
|
|
rejectMedia: {
|
|
help: this.$pgettext('Content/Moderation/Help text', 'Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well.'),
|
|
label: this.$pgettext('Content/Moderation/*/Verb', 'Reject media')
|
|
}
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
'current.silenceActivity': function (v) {
|
|
if (v) {
|
|
this.current.blockAll = false
|
|
}
|
|
},
|
|
'current.silenceNotifications': function (v) {
|
|
if (v) {
|
|
this.current.blockAll = false
|
|
}
|
|
},
|
|
'current.rejectMedia': function (v) {
|
|
if (v) {
|
|
this.current.blockAll = false
|
|
}
|
|
},
|
|
'current.blockAll': function (v) {
|
|
if (v) {
|
|
const self = this
|
|
this.fieldConfig.forEach((f) => {
|
|
self.current[f.id] = false
|
|
})
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
createOrUpdate () {
|
|
const self = this
|
|
this.isLoading = true
|
|
this.errors = []
|
|
let url, method
|
|
const data = {
|
|
summary: this.current.summary,
|
|
is_active: this.current.isActive,
|
|
block_all: this.current.blockAll,
|
|
silence_activity: this.current.silenceActivity,
|
|
silence_notifications: this.current.silenceNotifications,
|
|
reject_media: this.current.rejectMedia,
|
|
target: {
|
|
type: this.type,
|
|
id: this.target
|
|
}
|
|
}
|
|
if (this.object) {
|
|
url = `manage/moderation/instance-policies/${this.object.id}/`
|
|
method = 'patch'
|
|
} else {
|
|
url = 'manage/moderation/instance-policies/'
|
|
method = 'post'
|
|
}
|
|
axios[method](url, data).then((response) => {
|
|
this.isLoading = false
|
|
self.$emit('save', response.data)
|
|
}, (error) => {
|
|
self.isLoading = false
|
|
self.errors = error.backendErrors
|
|
})
|
|
},
|
|
remove () {
|
|
const self = this
|
|
this.isLoading = true
|
|
this.errors = []
|
|
|
|
const url = `manage/moderation/instance-policies/${this.object.id}/`
|
|
axios.delete(url).then((response) => {
|
|
this.isLoading = false
|
|
self.$emit('delete')
|
|
}, (error) => {
|
|
self.isLoading = false
|
|
self.errors = error.backendErrors
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|