diff options
| author | Henry Jameson <me@hjkos.com> | 2019-04-27 12:26:17 +0300 |
|---|---|---|
| committer | Henry Jameson <me@hjkos.com> | 2019-04-27 12:26:17 +0300 |
| commit | e0247e21f6fad72481d8f04271d3a15e0d827acc (patch) | |
| tree | acc8a11074865a9cbdc50e9b52da918c48f7235e /src/components/moderation_tools | |
| parent | 2b5cf61a8f9a84467495721f170df7ae1288959b (diff) | |
| parent | 9e2fa50b74eb83e3c3eadb9a68d24ddaa1d9da48 (diff) | |
Merge remote-tracking branch 'upstream/develop' into webpack-4-dart-sass
* upstream/develop: (126 commits)
entity normalizer: hook up in_reply_to_account_acct
add BBCode strings
fix follow button not updating bug in follow-card
refer searched user objects from the global user rep
set max-width of textarea in settings page
Remove space in the timeline setting copy
user_card.vue: Fix .emoji to apply to img
Update oc.json
Update oc.json
Update oc.json
Update oc.json
replace pencil with wrench icon
rebuild fontello with wrench icon added
fetch all friends using pagination
stop fetching user relationship when user is unauthorized
Revert "recover border between basic-user-card using list component"
remove extra spacing
code readability
fix typos
clean up
...
Diffstat (limited to 'src/components/moderation_tools')
| -rw-r--r-- | src/components/moderation_tools/moderation_tools.js | 106 | ||||
| -rw-r--r-- | src/components/moderation_tools/moderation_tools.vue | 158 |
2 files changed, 264 insertions, 0 deletions
diff --git a/src/components/moderation_tools/moderation_tools.js b/src/components/moderation_tools/moderation_tools.js new file mode 100644 index 00000000..3eedeaa1 --- /dev/null +++ b/src/components/moderation_tools/moderation_tools.js @@ -0,0 +1,106 @@ +import DialogModal from '../dialog_modal/dialog_modal.vue' +import Popper from 'vue-popperjs/src/component/popper.js.vue' + +const FORCE_NSFW = 'mrf_tag:media-force-nsfw' +const STRIP_MEDIA = 'mrf_tag:media-strip' +const FORCE_UNLISTED = 'mrf_tag:force-unlisted' +const DISABLE_REMOTE_SUBSCRIPTION = 'mrf_tag:disable-remote-subscription' +const DISABLE_ANY_SUBSCRIPTION = 'mrf_tag:disable-any-subscription' +const SANDBOX = 'mrf_tag:sandbox' +const QUARANTINE = 'mrf_tag:quarantine' + +const ModerationTools = { + props: [ + 'user' + ], + data () { + return { + showDropDown: false, + tags: { + FORCE_NSFW, + STRIP_MEDIA, + FORCE_UNLISTED, + DISABLE_REMOTE_SUBSCRIPTION, + DISABLE_ANY_SUBSCRIPTION, + SANDBOX, + QUARANTINE + }, + showDeleteUserDialog: false + } + }, + components: { + DialogModal, + Popper + }, + computed: { + tagsSet () { + return new Set(this.user.tags) + }, + hasTagPolicy () { + return this.$store.state.instance.tagPolicyAvailable + } + }, + methods: { + toggleMenu () { + this.showDropDown = !this.showDropDown + }, + hasTag (tagName) { + return this.tagsSet.has(tagName) + }, + toggleTag (tag) { + const store = this.$store + if (this.tagsSet.has(tag)) { + store.state.api.backendInteractor.untagUser(this.user, tag).then(response => { + if (!response.ok) { return } + store.commit('untagUser', {user: this.user, tag}) + }) + } else { + store.state.api.backendInteractor.tagUser(this.user, tag).then(response => { + if (!response.ok) { return } + store.commit('tagUser', {user: this.user, tag}) + }) + } + }, + toggleRight (right) { + const store = this.$store + if (this.user.rights[right]) { + store.state.api.backendInteractor.deleteRight(this.user, right).then(response => { + if (!response.ok) { return } + store.commit('updateRight', {user: this.user, right: right, value: false}) + }) + } else { + store.state.api.backendInteractor.addRight(this.user, right).then(response => { + if (!response.ok) { return } + store.commit('updateRight', {user: this.user, right: right, value: true}) + }) + } + }, + toggleActivationStatus () { + const store = this.$store + const status = !!this.user.deactivated + store.state.api.backendInteractor.setActivationStatus(this.user, status).then(response => { + if (!response.ok) { return } + store.commit('updateActivationStatus', {user: this.user, status: status}) + }) + }, + deleteUserDialog (show) { + this.showDeleteUserDialog = show + }, + deleteUser () { + const store = this.$store + const user = this.user + const {id, name} = user + store.state.api.backendInteractor.deleteUser(user) + .then(e => { + this.$store.dispatch('markStatusesAsDeleted', status => user.id === status.user.id) + const isProfile = this.$route.name === 'external-user-profile' || this.$route.name === 'user-profile' + const isTargetUser = this.$route.params.name === name || this.$route.params.id === id + if (isProfile && isTargetUser) { + window.history.back() + } + }) + } + } +} + +export default ModerationTools diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue new file mode 100644 index 00000000..c24a2280 --- /dev/null +++ b/src/components/moderation_tools/moderation_tools.vue @@ -0,0 +1,158 @@ +<template> +<div class='block' style='position: relative'> + <Popper + trigger="click" + @hide='showDropDown = false' + append-to-body + :options="{ + placement: 'bottom-end', + modifiers: { + arrow: { enabled: true }, + offset: { offset: '0, 5px' }, + } + }"> + <div class="popper-wrapper"> + <div class="dropdown-menu"> + <span v-if='user.is_local'> + <button class="dropdown-item" @click='toggleRight("admin")'> + {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }} + </button> + <button class="dropdown-item" @click='toggleRight("moderator")'> + {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }} + </button> + <div role="separator" class="dropdown-divider"></div> + </span> + <button class="dropdown-item" @click='toggleActivationStatus()'> + {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }} + </button> + <button class="dropdown-item" @click='deleteUserDialog(true)'> + {{ $t('user_card.admin_menu.delete_account') }} + </button> + <div role="separator" class="dropdown-divider" v-if='hasTagPolicy'></div> + <span v-if='hasTagPolicy'> + <button class="dropdown-item" @click='toggleTag(tags.FORCE_NSFW)'> + {{ $t('user_card.admin_menu.force_nsfw') }} + <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"></span> + </button> + <button class="dropdown-item" @click='toggleTag(tags.STRIP_MEDIA)'> + {{ $t('user_card.admin_menu.strip_media') }} + <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"></span> + </button> + <button class="dropdown-item" @click='toggleTag(tags.FORCE_UNLISTED)'> + {{ $t('user_card.admin_menu.force_unlisted') }} + <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"></span> + </button> + <button class="dropdown-item" @click='toggleTag(tags.SANDBOX)'> + {{ $t('user_card.admin_menu.sandbox') }} + <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"></span> + </button> + <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)'> + {{ $t('user_card.admin_menu.disable_remote_subscription') }} + <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"></span> + </button> + <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)'> + {{ $t('user_card.admin_menu.disable_any_subscription') }} + <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"></span> + </button> + <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.QUARANTINE)'> + {{ $t('user_card.admin_menu.quarantine') }} + <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"></span> + </button> + </span> + </div> + </div> + <button slot="reference" v-bind:class="{ pressed: showDropDown }" @click='toggleMenu'> + {{ $t('user_card.admin_menu.moderation') }} + </button> + </Popper> + <DialogModal v-if="showDeleteUserDialog" :onCancel='deleteUserDialog.bind(this, false)'> + <span slot="header">{{ $t('user_card.admin_menu.delete_user') }}</span> + <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p> + <span slot="footer"> + <button @click='deleteUserDialog(false)'> + {{ $t('general.cancel') }} + </button> + <button class="danger" @click='deleteUser()'> + {{ $t('user_card.admin_menu.delete_user') }} + </button> + </span> + </DialogModal> +</div> +</template> + +<script src="./moderation_tools.js"></script> + +<style lang="scss"> +@import '../../_variables.scss'; +@import '../popper/popper.scss'; + +.dropdown-menu { + display: block; + padding: .5rem 0; + font-size: 1rem; + text-align: left; + list-style: none; + max-width: 100vw; + z-index: 10; + box-shadow: 1px 1px 4px rgba(0,0,0,.6); + box-shadow: var(--panelShadow); + border: none; + border-radius: $fallback--btnRadius; + border-radius: var(--btnRadius, $fallback--btnRadius); + background-color: $fallback--bg; + background-color: var(--bg, $fallback--bg); + + .dropdown-divider { + height: 0; + margin: .5rem 0; + overflow: hidden; + border-top: 1px solid $fallback--border; + border-top: 1px solid var(--border, $fallback--border); + } + + .dropdown-item { + line-height: 21px; + margin-right: 5px; + overflow: auto; + display: block; + padding: .25rem 1.0rem .25rem 1.5rem; + clear: both; + font-weight: 400; + text-align: inherit; + white-space: normal; + border: none; + border-radius: 0px; + background-color: transparent; + box-shadow: none; + width: 100%; + height: 100%; + + &:hover { + // TODO: improve the look on breeze themes + background-color: $fallback--fg; + background-color: var(--btn, $fallback--fg); + box-shadow: none; + } + } +} + +.menu-checkbox { + float: right; + min-width: 22px; + max-width: 22px; + min-height: 22px; + max-height: 22px; + line-height: 22px; + text-align: center; + border-radius: 0px; + background-color: $fallback--fg; + background-color: var(--input, $fallback--fg); + box-shadow: 0px 0px 2px black inset; + box-shadow: var(--inputShadow); + + &.menu-checkbox-checked::after { + content: '✔'; + } +} + +</style> |
