diff options
| author | Henry Jameson <me@hjkos.com> | 2019-07-28 13:30:29 +0300 |
|---|---|---|
| committer | Henry Jameson <me@hjkos.com> | 2019-07-28 13:30:29 +0300 |
| commit | b3aff9bbae77b2fd34b2267ce9196c0ebd3e4691 (patch) | |
| tree | 1219e00b6bfe6784add1578a3bc986c1dbb5f34d /src/components/user_reporting_modal | |
| parent | 7f6f025792dcb3a10c94c8952d0312abd0b46989 (diff) | |
| parent | 4827e4d972f8ee11e606693e24ae4ca21711c6b1 (diff) | |
Merge remote-tracking branch 'upstream/develop' into emoji-selector-update
* upstream/develop: (469 commits)
Feature/add sticker picker
guard more secure routes
guard secure routes by redirecting to root
closest can returns itself as well
find inside status-content div only
try to use the closest a tag as target
Update es.json
Also apply keyword filter to subjects
Remove files I accidentally pushed in
fix issues caused by merges in usersearch on @
Add user search at
fix eslint warnings
remove vue-popperjs
fix moderation menu partially hidden by usercard boundary
migrate popper css
rewrite ModerationTools using v-tooltip
make popover position for status action dropdow relative to parent node
rewrite ExtraButtons using v-tooltip
install v-tooltip
i18n/Update pedantic Japanese translation
...
Diffstat (limited to 'src/components/user_reporting_modal')
| -rw-r--r-- | src/components/user_reporting_modal/user_reporting_modal.js | 106 | ||||
| -rw-r--r-- | src/components/user_reporting_modal/user_reporting_modal.vue | 187 |
2 files changed, 293 insertions, 0 deletions
diff --git a/src/components/user_reporting_modal/user_reporting_modal.js b/src/components/user_reporting_modal/user_reporting_modal.js new file mode 100644 index 00000000..7c6ea409 --- /dev/null +++ b/src/components/user_reporting_modal/user_reporting_modal.js @@ -0,0 +1,106 @@ + +import Status from '../status/status.vue' +import List from '../list/list.vue' +import Checkbox from '../checkbox/checkbox.vue' + +const UserReportingModal = { + components: { + Status, + List, + Checkbox + }, + data () { + return { + comment: '', + forward: false, + statusIdsToReport: [], + processing: false, + error: false + } + }, + computed: { + isLoggedIn () { + return !!this.$store.state.users.currentUser + }, + isOpen () { + return this.isLoggedIn && this.$store.state.reports.modalActivated + }, + userId () { + return this.$store.state.reports.userId + }, + user () { + return this.$store.getters.findUser(this.userId) + }, + remoteInstance () { + return !this.user.is_local && this.user.screen_name.substr(this.user.screen_name.indexOf('@') + 1) + }, + statuses () { + return this.$store.state.reports.statuses + } + }, + watch: { + userId: 'resetState' + }, + methods: { + resetState () { + // Reset state + this.comment = '' + this.forward = false + this.statusIdsToReport = [] + this.processing = false + this.error = false + }, + closeModal () { + this.$store.dispatch('closeUserReportingModal') + }, + reportUser () { + this.processing = true + this.error = false + const params = { + userId: this.userId, + comment: this.comment, + forward: this.forward, + statusIds: this.statusIdsToReport + } + this.$store.state.api.backendInteractor.reportUser(params) + .then(() => { + this.processing = false + this.resetState() + this.closeModal() + }) + .catch(() => { + this.processing = false + this.error = true + }) + }, + clearError () { + this.error = false + }, + isChecked (statusId) { + return this.statusIdsToReport.indexOf(statusId) !== -1 + }, + toggleStatus (checked, statusId) { + if (checked === this.isChecked(statusId)) { + return + } + + if (checked) { + this.statusIdsToReport.push(statusId) + } else { + this.statusIdsToReport.splice(this.statusIdsToReport.indexOf(statusId), 1) + } + }, + resize (e) { + const target = e.target || e + if (!(target instanceof window.Element)) { return } + // Auto is needed to make textbox shrink when removing lines + target.style.height = 'auto' + target.style.height = `${target.scrollHeight}px` + if (target.value === '') { + target.style.height = null + } + } + } +} + +export default UserReportingModal diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue new file mode 100644 index 00000000..c79a3707 --- /dev/null +++ b/src/components/user_reporting_modal/user_reporting_modal.vue @@ -0,0 +1,187 @@ +<template> + <div + v-if="isOpen" + class="modal-view" + @click="closeModal" + > + <div + class="user-reporting-panel panel" + @click.stop="" + > + <div class="panel-heading"> + <div class="title"> + {{ $t('user_reporting.title', [user.screen_name]) }} + </div> + </div> + <div class="panel-body"> + <div class="user-reporting-panel-left"> + <div> + <p>{{ $t('user_reporting.add_comment_description') }}</p> + <textarea + v-model="comment" + class="form-control" + :placeholder="$t('user_reporting.additional_comments')" + rows="1" + @input="resize" + /> + </div> + <div v-if="!user.is_local"> + <p>{{ $t('user_reporting.forward_description') }}</p> + <Checkbox v-model="forward"> + {{ $t('user_reporting.forward_to', [remoteInstance]) }} + </Checkbox> + </div> + <div> + <button + class="btn btn-default" + :disabled="processing" + @click="reportUser" + > + {{ $t('user_reporting.submit') }} + </button> + <div + v-if="error" + class="alert error" + > + {{ $t('user_reporting.generic_error') }} + </div> + </div> + </div> + <div class="user-reporting-panel-right"> + <List :items="statuses"> + <template + slot="item" + slot-scope="{item}" + > + <div class="status-fadein user-reporting-panel-sitem"> + <Status + :in-conversation="false" + :focused="false" + :statusoid="item" + /> + <Checkbox + :checked="isChecked(item.id)" + @change="checked => toggleStatus(checked, item.id)" + /> + </div> + </template> + </List> + </div> + </div> + </div> + </div> +</template> + +<script src="./user_reporting_modal.js"></script> + +<style lang="scss"> +@import '../../_variables.scss'; + +.user-reporting-panel { + width: 90vw; + max-width: 700px; + min-height: 20vh; + max-height: 80vh; + + .panel-heading { + .title { + text-align: center; + // TODO: Consider making these as default of panel + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + .panel-body { + display: flex; + flex-direction: column-reverse; + border-top: 1px solid; + border-color: $fallback--border; + border-color: var(--border, $fallback--border); + overflow: hidden; + } + + &-left { + padding: 1.1em 0.7em 0.7em; + line-height: 1.4em; + box-sizing: border-box; + + > div { + margin-bottom: 1em; + + &:last-child { + margin-bottom: 0; + } + } + + p { + margin-top: 0; + } + + textarea.form-control { + line-height: 16px; + resize: none; + overflow: hidden; + transition: min-height 200ms 100ms; + min-height: 44px; + width: 100%; + } + + .btn { + min-width: 10em; + padding: 0 2em; + } + + .alert { + margin: 1em 0 0 0; + line-height: 1.3em; + } + } + + &-right { + display: flex; + flex-direction: column; + overflow-y: auto; + } + + &-sitem { + display: flex; + justify-content: space-between; + + > .status-el { + flex: 1; + } + + > .checkbox { + margin: 0.75em; + } + } + + @media all and (min-width: 801px) { + .panel-body { + flex-direction: row; + } + + &-left { + width: 50%; + max-width: 320px; + border-right: 1px solid; + border-color: $fallback--border; + border-color: var(--border, $fallback--border); + padding: 1.1em; + + > div { + margin-bottom: 2em; + } + } + + &-right { + width: 50%; + flex: 1 1 auto; + margin-bottom: 12px; + } + } +} +</style> |
