diff options
Diffstat (limited to 'src/components')
47 files changed, 752 insertions, 620 deletions
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue index ab5d1d29..1e31151c 100644 --- a/src/components/account_actions/account_actions.vue +++ b/src/components/account_actions/account_actions.vue @@ -6,10 +6,7 @@ :bound-to="{ x: 'container' }" remove-padding > - <div - slot="content" - class="account-tools-popover" - > + <template v-slot:content> <div class="dropdown-menu"> <template v-if="relationship.following"> <button @@ -59,16 +56,15 @@ {{ $t('user_card.message') }} </button> </div> - </div> - <div - slot="trigger" - class="ellipsis-button" - > - <FAIcon - class="icon" - icon="ellipsis-v" - /> - </div> + </template> + <template v-slot:trigger> + <button class="button-unstyled ellipsis-button"> + <FAIcon + class="icon" + icon="ellipsis-v" + /> + </button> + </template> </Popover> </div> </template> @@ -83,7 +79,6 @@ } .ellipsis-button { - cursor: pointer; width: 2.5em; margin: -0.5em 0; padding: 0.5em 0; diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js index 5f5779a0..8849f501 100644 --- a/src/components/attachment/attachment.js +++ b/src/components/attachment/attachment.js @@ -1,4 +1,5 @@ import StillImage from '../still-image/still-image.vue' +import Flash from '../flash/flash.vue' import VideoAttachment from '../video_attachment/video_attachment.vue' import nsfwImage from '../../assets/nsfw.png' import fileTypeService from '../../services/file_type/file_type.service.js' @@ -43,6 +44,7 @@ const Attachment = { } }, components: { + Flash, StillImage, VideoAttachment }, diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue index 2c1c1682..f80badfd 100644 --- a/src/components/attachment/attachment.vue +++ b/src/components/attachment/attachment.vue @@ -117,6 +117,11 @@ <!-- eslint-enable vue/no-v-html --> </div> </div> + + <Flash + v-if="type === 'flash'" + :src="attachment.large_thumb_url || attachment.url" + /> </div> </template> @@ -172,6 +177,7 @@ } .non-gallery.attachment { + &.flash, &.video { flex: 1 0 40%; } diff --git a/src/components/chat_list/chat_list.vue b/src/components/chat_list/chat_list.vue index e23eec13..f98b7ed2 100644 --- a/src/components/chat_list/chat_list.vue +++ b/src/components/chat_list/chat_list.vue @@ -23,10 +23,7 @@ class="timeline" > <List :items="sortedChatList"> - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <ChatListItem :key="item.id" :compact="false" diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue index 0777f880..0f3fc97d 100644 --- a/src/components/chat_message/chat_message.vue +++ b/src/components/chat_message/chat_message.vue @@ -50,7 +50,7 @@ @show="menuOpened = true" @close="menuOpened = false" > - <div slot="content"> + <template v-slot:content> <div class="dropdown-menu"> <button class="button-default dropdown-item dropdown-item-icon" @@ -59,26 +59,28 @@ <FAIcon icon="times" /> {{ $t("chats.delete") }} </button> </div> - </div> - <button - slot="trigger" - class="button-default menu-icon" - :title="$t('chats.more')" - > - <FAIcon icon="ellipsis-h" /> - </button> + </template> + <template v-slot:trigger> + <button + class="button-default menu-icon" + :title="$t('chats.more')" + > + <FAIcon icon="ellipsis-h" /> + </button> + </template> </Popover> </div> <StatusContent :status="messageForStatusContent" :full-content="true" > - <span - slot="footer" - class="created-at" - > - {{ createdAt }} - </span> + <template v-slot:footer> + <span + class="created-at" + > + {{ createdAt }} + </span> + </template> </StatusContent> </div> </div> diff --git a/src/components/domain_mute_card/domain_mute_card.vue b/src/components/domain_mute_card/domain_mute_card.vue index 3b5aec14..836688aa 100644 --- a/src/components/domain_mute_card/domain_mute_card.vue +++ b/src/components/domain_mute_card/domain_mute_card.vue @@ -9,7 +9,7 @@ class="btn button-default" > {{ $t('domain_mute_card.unmute') }} - <template slot="progress"> + <template v-slot:progress> {{ $t('domain_mute_card.unmute_progress') }} </template> </ProgressButton> @@ -19,7 +19,7 @@ class="btn button-default" > {{ $t('domain_mute_card.mute') }} - <template slot="progress"> + <template v-slot:progress> {{ $t('domain_mute_card.mute_progress') }} </template> </ProgressButton> diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue index c6cb9fbe..a3c3c767 100644 --- a/src/components/extra_buttons/extra_buttons.vue +++ b/src/components/extra_buttons/extra_buttons.vue @@ -7,10 +7,7 @@ :bound-to="{ x: 'container' }" remove-padding > - <div - slot="content" - slot-scope="{close}" - > + <template v-slot:content="{close}"> <div class="dropdown-menu"> <button v-if="canMute && !status.thread_muted" @@ -120,16 +117,15 @@ /><span>{{ $t("user_card.report") }}</span> </button> </div> - </div> - <span - slot="trigger" - class="popover-trigger" - > - <FAIcon - class="fa-scale-110 fa-old-padding" - icon="ellipsis-h" - /> - </span> + </template> + <template v-slot:trigger> + <button class="button-unstyled popover-trigger"> + <FAIcon + class="fa-scale-110 fa-old-padding" + icon="ellipsis-h" + /> + </button> + </template> </Popover> </template> diff --git a/src/components/flash/flash.js b/src/components/flash/flash.js new file mode 100644 index 00000000..d03384c7 --- /dev/null +++ b/src/components/flash/flash.js @@ -0,0 +1,52 @@ +import RuffleService from '../../services/ruffle_service/ruffle_service.js' +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faStop, + faExclamationTriangle +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faStop, + faExclamationTriangle +) + +const Flash = { + props: [ 'src' ], + data () { + return { + player: false, // can be true, "hidden", false. hidden = element exists + loaded: false, + ruffleInstance: null + } + }, + methods: { + openPlayer () { + if (this.player) return // prevent double-loading, or re-loading on failure + this.player = 'hidden' + RuffleService.getRuffle().then((ruffle) => { + const player = ruffle.newest().createPlayer() + player.config = { + letterbox: 'on' + } + const container = this.$refs.container + container.appendChild(player) + player.style.width = '100%' + player.style.height = '100%' + player.load(this.src).then(() => { + this.player = true + }).catch((e) => { + console.error('Error loading ruffle', e) + this.player = 'error' + }) + this.ruffleInstance = player + }) + }, + closePlayer () { + console.log(this.ruffleInstance) + this.ruffleInstance.remove() + this.player = false + } + } +} + +export default Flash diff --git a/src/components/flash/flash.vue b/src/components/flash/flash.vue new file mode 100644 index 00000000..d20d037b --- /dev/null +++ b/src/components/flash/flash.vue @@ -0,0 +1,88 @@ +<template> + <div class="Flash"> + <div + v-if="player === true || player === 'hidden'" + ref="container" + class="player" + :class="{ hidden: player === 'hidden' }" + /> + <button + v-if="player !== true" + class="button-unstyled placeholder" + @click="openPlayer" + > + <span + v-if="player === 'hidden'" + class="label" + > + {{ $t('general.loading') }} + </span> + <span + v-if="player === 'error'" + class="label" + > + {{ $t('general.flash_fail') }} + </span> + <span + v-else + class="label" + > + <p> + {{ $t('general.flash_content') }} + </p> + <p> + <FAIcon icon="exclamation-triangle" /> + {{ $t('general.flash_security') }} + </p> + </span> + </button> + <button + v-if="player" + class="button-unstyled hider" + @click="closePlayer" + > + <FAIcon icon="stop" /> + </button> + </div> +</template> + +<script src="./flash.js"></script> + +<style lang="scss"> +@import '../../_variables.scss'; +.Flash { + width: 100%; + height: 260px; + position: relative; + + .player { + height: 100%; + width: 100%; + } + + .hider { + top: 0; + } + + .label { + text-align: center; + flex: 1 1 0; + line-height: 1.2; + white-space: normal; + word-wrap: normal; + } + + .hidden { + display: none; + visibility: 'hidden'; + } + + .placeholder { + height: 100%; + flex: 1; + display: flex; + align-items: center; + justify-content: center; + } +} +</style> diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js index 6274780b..137ef9c0 100644 --- a/src/components/font_control/font_control.js +++ b/src/components/font_control/font_control.js @@ -1,14 +1,10 @@ import { set } from 'vue' -import { library } from '@fortawesome/fontawesome-svg-core' -import { - faChevronDown -} from '@fortawesome/free-solid-svg-icons' - -library.add( - faChevronDown -) +import Select from '../select/select.vue' export default { + components: { + Select + }, props: [ 'name', 'label', 'value', 'fallback', 'options', 'no-inherit' ], diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue index dd117ec0..29605084 100644 --- a/src/components/font_control/font_control.vue +++ b/src/components/font_control/font_control.vue @@ -22,30 +22,20 @@ class="opt-l" :for="name + '-o'" /> - <label - :for="name + '-font-switcher'" - class="select" + <Select + :id="name + '-font-switcher'" + v-model="preset" :disabled="!present" + class="font-switcher" > - <select - :id="name + '-font-switcher'" - v-model="preset" - :disabled="!present" - class="font-switcher" + <option + v-for="option in availableOptions" + :key="option" + :value="option" > - <option - v-for="option in availableOptions" - :key="option" - :value="option" - > - {{ option === 'custom' ? $t('settings.style.fonts.custom') : option }} - </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> + {{ option === 'custom' ? $t('settings.style.fonts.custom') : option }} + </option> + </Select> <input v-if="isCustom" :id="name" @@ -65,7 +55,8 @@ min-width: 10em; } &.custom { - .select { + /* TODO Should make proper joiners... */ + .font-switcher { border-top-right-radius: 0; border-bottom-right-radius: 0; } diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue index dc3bd408..cf307a24 100644 --- a/src/components/interface_language_switcher/interface_language_switcher.vue +++ b/src/components/interface_language_switcher/interface_language_switcher.vue @@ -3,27 +3,18 @@ <label for="interface-language-switcher"> {{ $t('settings.interfaceLanguage') }} </label> - <label - for="interface-language-switcher" - class="select" + <Select + id="interface-language-switcher" + v-model="language" > - <select - id="interface-language-switcher" - v-model="language" + <option + v-for="lang in languages" + :key="lang.code" + :value="lang.code" > - <option - v-for="lang in languages" - :key="lang.code" - :value="lang.code" - > - {{ lang.name }} - </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> + {{ lang.name }} + </option> + </Select> </div> </template> @@ -32,16 +23,12 @@ import languagesObject from '../../i18n/messages' import localeService from '../../services/locale/locale.service.js' import ISO6391 from 'iso-639-1' import _ from 'lodash' -import { library } from '@fortawesome/fontawesome-svg-core' -import { - faChevronDown -} from '@fortawesome/free-solid-svg-icons' - -library.add( - faChevronDown -) +import Select from '../select/select.vue' export default { + components: { + Select + }, computed: { languages () { return _.map(languagesObject.languages, (code) => ({ code: code, name: this.getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name)) diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue index c4c6ee46..96476abe 100644 --- a/src/components/moderation_tools/moderation_tools.vue +++ b/src/components/moderation_tools/moderation_tools.vue @@ -8,7 +8,7 @@ @show="setToggled(true)" @close="setToggled(false)" > - <div slot="content"> + <template v-slot:content> <div class="dropdown-menu"> <span v-if="user.is_local"> <button @@ -121,26 +121,27 @@ </button> </span> </div> - </div> - <button - slot="trigger" - class="btn button-default btn-block moderation-tools-button" - :class="{ toggled }" - > - {{ $t('user_card.admin_menu.moderation') }} - <FAIcon icon="chevron-down" /> - </button> + </template> + <template v-slot:trigger> + <button + class="btn button-default btn-block moderation-tools-button" + :class="{ toggled }" + > + {{ $t('user_card.admin_menu.moderation') }} + <FAIcon icon="chevron-down" /> + </button> + </template> </Popover> <portal to="modal"> <DialogModal v-if="showDeleteUserDialog" :on-cancel="deleteUserDialog.bind(this, false)" > - <template slot="header"> + <template v-slot:header> {{ $t('user_card.admin_menu.delete_user') }} </template> <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p> - <template slot="footer"> + <template v-slot:footer> <button class="btn button-default" @click="deleteUserDialog(false)" diff --git a/src/components/notifications/notification_filters.vue b/src/components/notifications/notification_filters.vue index e86a0fcc..ba0e90a0 100644 --- a/src/components/notifications/notification_filters.vue +++ b/src/components/notifications/notification_filters.vue @@ -5,9 +5,7 @@ placement="bottom" :bound-to="{ x: 'container' }" > - <template - v-slot:content - > + <template v-slot:content> <div class="dropdown-menu"> <button class="button-default dropdown-item" @@ -66,7 +64,9 @@ </div> </template> <template v-slot:trigger> - <FAIcon icon="filter" /> + <button class="button-unstyled"> + <FAIcon icon="filter" /> + </button> </template> </Popover> </template> diff --git a/src/components/poll/poll_form.js b/src/components/poll/poll_form.js index 1f8df3f9..e30645c3 100644 --- a/src/components/poll/poll_form.js +++ b/src/components/poll/poll_form.js @@ -1,19 +1,21 @@ import * as DateUtils from 'src/services/date_utils/date_utils.js' import { uniq } from 'lodash' import { library } from '@fortawesome/fontawesome-svg-core' +import Select from '../select/select.vue' import { faTimes, - faChevronDown, faPlus } from '@fortawesome/free-solid-svg-icons' library.add( faTimes, - faChevronDown, faPlus ) export default { + components: { + Select + }, name: 'PollForm', props: ['visible'], data: () => ({ diff --git a/src/components/poll/poll_form.vue b/src/components/poll/poll_form.vue index c4403210..3620075a 100644 --- a/src/components/poll/poll_form.vue +++ b/src/components/poll/poll_form.vue @@ -46,23 +46,19 @@ class="poll-type" :title="$t('polls.type')" > - <label - for="poll-type-selector" - class="select" + <Select + v-model="pollType" + class="poll-type-select" + unstyled="true" + @change="updatePollToParent" > - <select - v-model="pollType" - class="select" - @change="updatePollToParent" - > - <option value="single">{{ $t('polls.single_choice') }}</option> - <option value="multiple">{{ $t('polls.multiple_choices') }}</option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> + <option value="single"> + {{ $t('polls.single_choice') }} + </option> + <option value="multiple"> + {{ $t('polls.multiple_choices') }} + </option> + </Select> </div> <div class="poll-expiry" @@ -76,24 +72,20 @@ :max="maxExpirationInCurrentUnit" @change="expiryAmountChange" > - <label class="expiry-unit select"> - <select - v-model="expiryUnit" - @change="expiryAmountChange" + <Select + v-model="expiryUnit" + unstyled="true" + class="expiry-unit" + @change="expiryAmountChange" + > + <option + v-for="unit in expiryUnits" + :key="unit" + :value="unit" > - <option - v-for="unit in expiryUnits" - :key="unit" - :value="unit" - > - {{ $t(`time.${unit}_short`, ['']) }} - </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> + {{ $t(`time.${unit}_short`, ['']) }} + </option> + </Select> </div> </div> </div> @@ -147,10 +139,8 @@ .poll-type { margin-right: 0.75em; flex: 1 1 60%; - .select { - border: none; - box-shadow: none; - background-color: transparent; + + .poll-type-select { padding-right: 0.75em; } } @@ -162,12 +152,6 @@ width: 3em; text-align: right; } - - .expiry-unit { - border: none; - box-shadow: none; - background-color: transparent; - } } } </style> diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index bc6cd8e7..6ccf32f0 100644 --- a/src/components/popover/popover.js +++ b/src/components/popover/popover.js @@ -54,7 +54,7 @@ const Popover = { } // Popover will be anchored around this element, trigger ref is the container, so - // its children are what are inside the slot. Expect only one slot="trigger". + // its children are what are inside the slot. Expect only one v-slot:trigger. const anchorEl = (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el // SVGs don't have offsetWidth/Height, use fallback const anchorWidth = anchorEl.offsetWidth || anchorEl.clientWidth diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index e540654b..5342894f 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -11,10 +11,10 @@ import { reject, map, uniqBy, debounce } from 'lodash' import suggestor from '../emoji_input/suggestor.js' import { mapGetters, mapState } from 'vuex' import Checkbox from '../checkbox/checkbox.vue' +import Select from '../select/select.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { - faChevronDown, faSmileBeam, faPollH, faUpload, @@ -24,7 +24,6 @@ import { } from '@fortawesome/free-solid-svg-icons' library.add( - faChevronDown, faSmileBeam, faPollH, faUpload, @@ -84,6 +83,7 @@ const PostStatusForm = { PollForm, ScopeSelector, Checkbox, + Select, Attachment, StatusContent }, diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 6b490aee..fbda41d6 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -189,28 +189,19 @@ v-if="postFormats.length > 1" class="text-format" > - <label - for="post-content-type" - class="select" + <Select + id="post-content-type" + v-model="newStatus.contentType" + class="form-control" > - <select - id="post-content-type" - v-model="newStatus.contentType" - class="form-control" + <option + v-for="postFormat in postFormats" + :key="postFormat" + :value="postFormat" > - <option - v-for="postFormat in postFormats" - :key="postFormat" - :value="postFormat" - > - {{ $t(`post_status.content_type["${postFormat}"]`) }} - </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> + {{ $t(`post_status.content_type["${postFormat}"]`) }} + </option> + </Select> </div> <div v-if="postFormats.length === 1 && postFormats[0] !== 'text/plain'" diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue index 4839024c..c69c315b 100644 --- a/src/components/react_button/react_button.vue +++ b/src/components/react_button/react_button.vue @@ -8,10 +8,7 @@ remove-padding @show="focusInput" > - <div - slot="content" - slot-scope="{close}" - > + <template v-slot:content="{close}"> <div class="reaction-picker-filter"> <input v-model="filterWord" @@ -41,17 +38,18 @@ </span> <div class="reaction-bottom-fader" /> </div> - </div> - <span - slot="trigger" - class="popover-trigger" - :title="$t('tool_tip.add_reaction')" - > - <FAIcon - class="fa-scale-110 fa-old-padding" - :icon="['far', 'smile-beam']" - /> - </span> + </template> + <template v-slot:trigger> + <button + class="button-unstyled popover-trigger" + :title="$t('tool_tip.add_reaction')" + > + <FAIcon + class="fa-scale-110 fa-old-padding" + :icon="['far', 'smile-beam']" + /> + </button> + </template> </Popover> </template> diff --git a/src/components/select/select.js b/src/components/select/select.js new file mode 100644 index 00000000..49535d07 --- /dev/null +++ b/src/components/select/select.js @@ -0,0 +1,21 @@ +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faChevronDown +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faChevronDown +) + +export default { + model: { + prop: 'value', + event: 'change' + }, + props: [ + 'value', + 'disabled', + 'unstyled', + 'kind' + ] +} diff --git a/src/components/select/select.vue b/src/components/select/select.vue new file mode 100644 index 00000000..5ade1fa6 --- /dev/null +++ b/src/components/select/select.vue @@ -0,0 +1,62 @@ + +<template> + <label + class="Select input" + :class="{ disabled, unstyled }" + > + <select + :disabled="disabled" + :value="value" + @change="$emit('change', $event.target.value)" + > + <slot /> + </select> + <FAIcon + class="select-down-icon" + icon="chevron-down" + /> + </label> +</template> + +<script src="./select.js"> </script> + +<style lang="scss"> +@import '../../_variables.scss'; + +.Select { + padding: 0; + + select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent; + border: none; + color: $fallback--text; + color: var(--inputText, --text, $fallback--text); + margin: 0; + padding: 0 2em 0 .2em; + font-family: sans-serif; + font-family: var(--inputFont, sans-serif); + font-size: 14px; + width: 100%; + z-index: 1; + height: 28px; + line-height: 16px; + } + + .select-down-icon { + position: absolute; + top: 0; + bottom: 0; + right: 5px; + height: 100%; + color: $fallback--text; + color: var(--inputText, $fallback--text); + line-height: 28px; + z-index: 0; + pointer-events: none; + } + +} +</style> diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue index a9bb12a1..3f885881 100644 --- a/src/components/selectable_list/selectable_list.vue +++ b/src/components/selectable_list/selectable_list.vue @@ -24,10 +24,7 @@ :items="items" :get-key="getKey" > - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <div class="selectable-list-item-inner" :class="{ 'selectable-list-item-selected-inner': isSelected(item) }" @@ -44,7 +41,7 @@ /> </div> </template> - <template slot="empty"> + <template v-slot:empty> <slot name="empty" /> </template> </List> diff --git a/src/components/settings_modal/helpers/boolean_setting.js b/src/components/settings_modal/helpers/boolean_setting.js new file mode 100644 index 00000000..1dda49f2 --- /dev/null +++ b/src/components/settings_modal/helpers/boolean_setting.js @@ -0,0 +1,30 @@ +import { get, set } from 'lodash' +import Checkbox from 'src/components/checkbox/checkbox.vue' +import ModifiedIndicator from './modified_indicator.vue' +export default { + components: { + Checkbox, + ModifiedIndicator + }, + props: [ + 'path', + 'disabled' + ], + computed: { + pathDefault () { + const [firstSegment, ...rest] = this.path.split('.') + return [firstSegment + 'DefaultValue', ...rest].join('.') + }, + state () { + return get(this.$parent, this.path) + }, + isChanged () { + return get(this.$parent, this.path) !== get(this.$parent, this.pathDefault) + } + }, + methods: { + update (e) { + set(this.$parent, this.path, e) + } + } +} diff --git a/src/components/settings_modal/helpers/boolean_setting.vue b/src/components/settings_modal/helpers/boolean_setting.vue index 146ad6c1..c3ee6583 100644 --- a/src/components/settings_modal/helpers/boolean_setting.vue +++ b/src/components/settings_modal/helpers/boolean_setting.vue @@ -18,40 +18,4 @@ </label> </template> -<script> -import { get, set } from 'lodash' -import Checkbox from 'src/components/checkbox/checkbox.vue' -import ModifiedIndicator from './modified_indicator.vue' -export default { - components: { - Checkbox, - ModifiedIndicator - }, - props: [ - 'path', - 'disabled' - ], - computed: { - pathDefault () { - const [firstSegment, ...rest] = this.path.split('.') - return [firstSegment + 'DefaultValue', ...rest].join('.') - }, - state () { - return get(this.$parent, this.path) - }, - isChanged () { - return get(this.$parent, this.path) !== get(this.$parent, this.pathDefault) - } - }, - methods: { - update (e) { - set(this.$parent, this.path, e) - } - } -} -</script> - -<style lang="scss"> -.BooleanSetting { -} -</style> +<script src="./boolean_setting.js"></script> diff --git a/src/components/settings_modal/helpers/choice_setting.js b/src/components/settings_modal/helpers/choice_setting.js new file mode 100644 index 00000000..042e8106 --- /dev/null +++ b/src/components/settings_modal/helpers/choice_setting.js @@ -0,0 +1,34 @@ +import { get, set } from 'lodash' +import Select from 'src/components/select/select.vue' +import ModifiedIndicator from './modified_indicator.vue' +export default { + components: { + Select, + ModifiedIndicator + }, + props: [ + 'path', + 'disabled', + 'options' + ], + computed: { + pathDefault () { + const [firstSegment, ...rest] = this.path.split('.') + return [firstSegment + 'DefaultValue', ...rest].join('.') + }, + state () { + return get(this.$parent, this.path) + }, + defaultState () { + return get(this.$parent, this.pathDefault) + }, + isChanged () { + return get(this.$parent, this.path) !== get(this.$parent, this.pathDefault) + } + }, + methods: { + update (e) { + set(this.$parent, this.path, e) + } + } +} diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue new file mode 100644 index 00000000..fa17661b --- /dev/null +++ b/src/components/settings_modal/helpers/choice_setting.vue @@ -0,0 +1,29 @@ +<template> + <label + class="ChoiceSetting" + > + <slot /> + <Select + :value="state" + :disabled="disabled" + @change="update" + > + <option + v-for="option in options" + :key="option.key" + :value="option.value" + > + {{ option.label }} + {{ option.value === defaultState ? $t('settings.instance_default_simple') : '' }} + </option> + </Select> + <ModifiedIndicator :changed="isChanged" /> + </label> +</template> + +<script src="./choice_setting.js"></script> + +<style lang="scss"> +.ChoiceSetting { +} +</style> diff --git a/src/components/settings_modal/helpers/modified_indicator.vue b/src/components/settings_modal/helpers/modified_indicator.vue index 9f4e81fe..ad212db9 100644 --- a/src/components/settings_modal/helpers/modified_indicator.vue +++ b/src/components/settings_modal/helpers/modified_indicator.vue @@ -6,18 +6,18 @@ <Popover trigger="hover" > - <span slot="trigger"> + <template v-slot:trigger> <FAIcon icon="wrench" + :aria-label="$t('settings.setting_changed')" /> - </span> - <div - slot="content" - class="modified-tooltip" - > - {{ $t('settings.setting_changed') }} - </div> + </template> + <template v-slot:content> + <div class="modified-tooltip"> + {{ $t('settings.setting_changed') }} + </div> + </template> </Popover> </span> </template> diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue index c7da5433..583c2ecc 100644 --- a/src/components/settings_modal/settings_modal.vue +++ b/src/components/settings_modal/settings_modal.vue @@ -62,20 +62,18 @@ :bound-to="{ x: 'container' }" remove-padding > - <button - slot="trigger" - class="btn button-default" - :title="$t('general.close')" - > - <span>{{ $t("settings.file_export_import.backup_restore") }}</span> - <FAIcon - icon="chevron-down" - /> - </button> - <div - slot="content" - slot-scope="{close}" - > + <template v-slot:trigger> + <button + class="btn button-default" + :title="$t('general.close')" + > + <span>{{ $t("settings.file_export_import.backup_restore") }}</span> + <FAIcon + icon="chevron-down" + /> + </button> + </template> + <template v-slot:content="{close}"> <div class="dropdown-menu"> <button class="button-default dropdown-item dropdown-item-icon" @@ -108,7 +106,7 @@ /><span>{{ $t("settings.file_export_import.restore_settings") }}</span> </button> </div> - </div> + </template> </Popover> </div> </div> diff --git a/src/components/settings_modal/settings_modal_content.scss b/src/components/settings_modal/settings_modal_content.scss index f066234c..81ab434b 100644 --- a/src/components/settings_modal/settings_modal_content.scss +++ b/src/components/settings_modal/settings_modal_content.scss @@ -7,13 +7,24 @@ margin: 1em 1em 1.4em; padding-bottom: 1.4em; - > div { + > div, + > label { + display: block; margin-bottom: .5em; &:last-child { margin-bottom: 0; } } + .select-multiple { + display: flex; + + .option-list { + margin: 0; + padding-left: .5em; + } + } + &:last-child { border-bottom: none; padding-bottom: 0; diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js index 6e95f7af..4eaf4217 100644 --- a/src/components/settings_modal/tabs/filtering_tab.js +++ b/src/components/settings_modal/tabs/filtering_tab.js @@ -1,24 +1,23 @@ import { filter, trim } from 'lodash' import BooleanSetting from '../helpers/boolean_setting.vue' +import ChoiceSetting from '../helpers/choice_setting.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' -import { library } from '@fortawesome/fontawesome-svg-core' -import { - faChevronDown -} from '@fortawesome/free-solid-svg-icons' - -library.add( - faChevronDown -) const FilteringTab = { data () { return { - muteWordsStringLocal: this.$store.getters.mergedConfig.muteWords.join('\n') + muteWordsStringLocal: this.$store.getters.mergedConfig.muteWords.join('\n'), + replyVisibilityOptions: ['all', 'following', 'self'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.reply_visibility_${mode}`) + })) } }, components: { - BooleanSetting + BooleanSetting, + ChoiceSetting }, computed: { ...SharedComputedObject(), diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue index 402c2a4a..6fc9ceaa 100644 --- a/src/components/settings_modal/tabs/filtering_tab.vue +++ b/src/components/settings_modal/tabs/filtering_tab.vue @@ -36,29 +36,13 @@ </li> </ul> </div> - <div> + <ChoiceSetting + id="replyVisibility" + path="replyVisibility" + :options="replyVisibilityOptions" + > {{ $t('settings.replies_in_timeline') }} - <label - for="replyVisibility" - class="select" - > - <select - id="replyVisibility" - v-model="replyVisibility" - > - <option - value="all" - selected - >{{ $t('settings.reply_visibility_all') }}</option> - <option value="following">{{ $t('settings.reply_visibility_following') }}</option> - <option value="self">{{ $t('settings.reply_visibility_self') }}</option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> - </div> + </ChoiceSetting> <div> <BooleanSetting path="hidePostStats"> {{ $t('settings.hide_post_stats') }} diff --git a/src/components/settings_modal/tabs/general_tab.js b/src/components/settings_modal/tabs/general_tab.js index 2db523be..07fccf57 100644 --- a/src/components/settings_modal/tabs/general_tab.js +++ b/src/components/settings_modal/tabs/general_tab.js @@ -1,21 +1,25 @@ import BooleanSetting from '../helpers/boolean_setting.vue' +import ChoiceSetting from '../helpers/choice_setting.vue' import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' import { library } from '@fortawesome/fontawesome-svg-core' import { - faChevronDown, faGlobe } from '@fortawesome/free-solid-svg-icons' library.add( - faChevronDown, faGlobe ) const GeneralTab = { data () { return { + subjectLineOptions: ['email', 'noop', 'masto'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.subject_line_${mode === 'masto' ? 'mastodon' : mode}`) + })), loopSilentAvailable: // Firefox Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') || @@ -27,12 +31,20 @@ const GeneralTab = { }, components: { BooleanSetting, + ChoiceSetting, InterfaceLanguageSwitcher }, computed: { postFormats () { return this.$store.state.instance.postFormats || [] }, + postContentOptions () { + return this.postFormats.map(format => ({ + key: format, + value: format, + label: this.$t(`post_status.content_type["${format}"]`) + })) + }, instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel }, instanceWallpaperUsed () { return this.$store.state.instance.background && diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index 9228c78e..bdb29edf 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -11,6 +11,11 @@ {{ $t('settings.hide_isp') }} </BooleanSetting> </li> + <li> + <BooleanSetting path="sidebarRight"> + {{ $t('settings.right_sidebar') }} + </BooleanSetting> + </li> <li v-if="instanceWallpaperUsed"> <BooleanSetting path="hideInstanceWallpaper"> {{ $t('settings.hide_wallpaper') }} @@ -85,62 +90,22 @@ </BooleanSetting> </li> <li> - <div> + <ChoiceSetting + id="subjectLineBehavior" + path="subjectLineBehavior" + :options="subjectLineOptions" + > {{ $t('settings.subject_line_behavior') }} - <label - for="subjectLineBehavior" - class="select" - > - <select - id="subjectLineBehavior" - v-model="subjectLineBehavior" - > - <option value="email"> - {{ $t('settings.subject_line_email') }} - {{ subjectLineBehaviorDefaultValue == 'email' ? $t('settings.instance_default_simple') : '' }} - </option> - <option value="masto"> - {{ $t('settings.subject_line_mastodon') }} - {{ subjectLineBehaviorDefaultValue == 'mastodon' ? $t('settings.instance_default_simple') : '' }} - </option> - <option value="noop"> - {{ $t('settings.subject_line_noop') }} - {{ subjectLineBehaviorDefaultValue == 'noop' ? $t('settings.instance_default_simple') : '' }} - </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> - </div> + </ChoiceSetting> </li> <li v-if="postFormats.length > 0"> - <div> + <ChoiceSetting + id="postContentType" + path="postContentType" + :options="postContentOptions" + > {{ $t('settings.post_status_content_type') }} - <label - for="postContentType" - class="select" - > - <select - id="postContentType" - v-model="postContentType" - > - <option - v-for="postFormat in postFormats" - :key="postFormat" - :value="postFormat" - > - {{ $t(`post_status.content_type["${postFormat}"]`) }} - {{ postContentTypeDefaultValue === postFormat ? $t('settings.instance_default_simple') : '' }} - </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> - </div> + </ChoiceSetting> </li> <li> <BooleanSetting path="minimalScopesMode"> diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue index 63d36bf9..32a21415 100644 --- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue +++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue @@ -10,20 +10,18 @@ :query="queryUserIds" :placeholder="$t('settings.search_user_to_block')" > - <BlockCard - slot-scope="row" - :user-id="row.item" - /> + <template v-slot="row"> + <BlockCard + :user-id="row.item" + /> + </template> </Autosuggest> </div> <BlockList :refresh="true" :get-key="i => i" > - <template - slot="header" - slot-scope="{selected}" - > + <template v-slot:header="{selected}"> <div class="bulk-actions"> <ProgressButton v-if="selected.length > 0" @@ -31,7 +29,7 @@ :click="() => blockUsers(selected)" > {{ $t('user_card.block') }} - <template slot="progress"> + <template v-slot:progress> {{ $t('user_card.block_progress') }} </template> </ProgressButton> @@ -41,19 +39,16 @@ :click="() => unblockUsers(selected)" > {{ $t('user_card.unblock') }} - <template slot="progress"> + <template v-slot:progress> {{ $t('user_card.unblock_progress') }} </template> </ProgressButton> </div> </template> - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <BlockCard :user-id="item" /> </template> - <template slot="empty"> + <template v-slot:empty> {{ $t('settings.no_blocks') }} </template> </BlockList> @@ -68,20 +63,18 @@ :query="queryUserIds" :placeholder="$t('settings.search_user_to_mute')" > - <MuteCard - slot-scope="row" - :user-id="row.item" - /> + <template v-slot="row"> + <MuteCard + :user-id="row.item" + /> + </template> </Autosuggest> </div> <MuteList :refresh="true" :get-key="i => i" > - <template - slot="header" - slot-scope="{selected}" - > + <template v-slot:header="{selected}"> <div class="bulk-actions"> <ProgressButton v-if="selected.length > 0" @@ -89,7 +82,7 @@ :click="() => muteUsers(selected)" > {{ $t('user_card.mute') }} - <template slot="progress"> + <template v-slot:progress> {{ $t('user_card.mute_progress') }} </template> </ProgressButton> @@ -99,19 +92,16 @@ :click="() => unmuteUsers(selected)" > {{ $t('user_card.unmute') }} - <template slot="progress"> + <template v-slot:progress> {{ $t('user_card.unmute_progress') }} </template> </ProgressButton> </div> </template> - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <MuteCard :user-id="item" /> </template> - <template slot="empty"> + <template v-slot:empty> {{ $t('settings.no_mutes') }} </template> </MuteList> @@ -124,20 +114,18 @@ :query="queryKnownDomains" :placeholder="$t('settings.type_domains_to_mute')" > - <DomainMuteCard - slot-scope="row" - :domain="row.item" - /> + <template v-slot="row"> + <DomainMuteCard + :domain="row.item" + /> + </template> </Autosuggest> </div> <DomainMuteList :refresh="true" :get-key="i => i" > - <template - slot="header" - slot-scope="{selected}" - > + <template v-slot:header="{selected}"> <div class="bulk-actions"> <ProgressButton v-if="selected.length > 0" @@ -145,19 +133,16 @@ :click="() => unmuteDomains(selected)" > {{ $t('domain_mute_card.unmute') }} - <template slot="progress"> + <template v-slot:progress> {{ $t('domain_mute_card.unmute_progress') }} </template> </ProgressButton> </div> </template> - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <DomainMuteCard :domain="item" /> </template> - <template slot="empty"> + <template v-slot:empty> {{ $t('settings.no_mutes') }} </template> </DomainMuteList> diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 8960c566..1388f74b 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -36,16 +36,9 @@ import FontControl from 'src/components/font_control/font_control.vue' import ContrastRatio from 'src/components/contrast_ratio/contrast_ratio.vue' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js' import Checkbox from 'src/components/checkbox/checkbox.vue' +import Select from 'src/components/select/select.vue' import Preview from './preview.vue' -import { library } from '@fortawesome/fontawesome-svg-core' -import { - faChevronDown -} from '@fortawesome/free-solid-svg-icons' - -library.add( - faChevronDown -) // List of color values used in v1 const v1OnlyNames = [ @@ -395,7 +388,8 @@ export default { FontControl, TabSwitcher, Preview, - Checkbox + Checkbox, + Select }, methods: { loadTheme ( diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue index 62378867..548dc852 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue @@ -55,7 +55,7 @@ for="preset-switcher" class="select" > - <select + <Select id="preset-switcher" v-model="selected" class="preset-switcher" @@ -71,11 +71,7 @@ > {{ style[0] || style.name }} </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> + </Select> </label> </div> <div class="export-import"> @@ -907,28 +903,19 @@ <div class="tab-header shadow-selector"> <div class="select-container"> {{ $t('settings.style.shadows.component') }} - <label - for="shadow-switcher" - class="select" + <Select + id="shadow-switcher" + v-model="shadowSelected" + class="shadow-switcher" > - <select - id="shadow-switcher" - v-model="shadowSelected" - class="shadow-switcher" + <option + v-for="shadow in shadowsAvailable" + :key="shadow" + :value="shadow" > - <option - v-for="shadow in shadowsAvailable" - :key="shadow" - :value="shadow" - > - {{ $t('settings.style.shadows.components.' + shadow) }} - </option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> + {{ $t('settings.style.shadows.components.' + shadow) }} + </option> + </Select> </div> <div class="override"> <label diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js index 800c39d5..2d5d6eb1 100644 --- a/src/components/shadow_control/shadow_control.js +++ b/src/components/shadow_control/shadow_control.js @@ -1,5 +1,6 @@ import ColorInput from '../color_input/color_input.vue' import OpacityInput from '../opacity_input/opacity_input.vue' +import Select from '../select/select.vue' import { getCssShadow } from '../../services/style_setter/style_setter.js' import { hex2rgb } from '../../services/color_convert/color_convert.js' import { library } from '@fortawesome/fontawesome-svg-core' @@ -45,7 +46,8 @@ export default { }, components: { ColorInput, - OpacityInput + OpacityInput, + Select }, methods: { add () { diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue index 37d491f0..511e07f3 100644 --- a/src/components/shadow_control/shadow_control.vue +++ b/src/components/shadow_control/shadow_control.vue @@ -59,30 +59,20 @@ :disabled="usingFallback" class="id-control style-control" > - <label - for="shadow-switcher" - class="select" + <Select + id="shadow-switcher" + v-model="selectedId" + class="shadow-switcher" :disabled="!ready || usingFallback" > - <select - id="shadow-switcher" - v-model="selectedId" - class="shadow-switcher" - :disabled="!ready || usingFallback" + <option + v-for="(shadow, index) in cValue" + :key="index" + :value="index" > - <option - v-for="(shadow, index) in cValue" - :key="index" - :value="index" - > - {{ $t('settings.style.shadows.shadow_id', { value: index }) }} - </option> - </select> - <FAIcon - icon="chevron-down" - class="select-down-icon" - /> - </label> + {{ $t('settings.style.shadows.shadow_id', { value: index }) }} + </option> + </Select> <button class="btn button-default" :disabled="!ready || !present" @@ -316,20 +306,20 @@ .id-control { align-items: stretch; - .select, .btn { + + .shadow-switcher { + flex: 1; + } + + .shadow-switcher, .btn { min-width: 1px; margin-right: 5px; } + .btn { padding: 0 .4em; margin: 0 .1em; } - .select { - flex: 1; - select { - align-self: initial; - } - } } } } diff --git a/src/components/status_popover/status_popover.vue b/src/components/status_popover/status_popover.vue index 8237ce00..fdca8c9c 100644 --- a/src/components/status_popover/status_popover.vue +++ b/src/components/status_popover/status_popover.vue @@ -5,12 +5,10 @@ :bound-to="{ x: 'container' }" @show="enter" > - <template slot="trigger"> + <template v-slot:trigger> <slot /> </template> - <div - slot="content" - > + <template v-slot:content> <Status v-if="status" :is-preview="true" @@ -33,7 +31,7 @@ size="2x" /> </div> - </div> + </template> </Popover> </template> diff --git a/src/components/timeline/timeline_quick_settings.vue b/src/components/timeline/timeline_quick_settings.vue index 94997c0d..98996ebd 100644 --- a/src/components/timeline/timeline_quick_settings.vue +++ b/src/components/timeline/timeline_quick_settings.vue @@ -4,77 +4,78 @@ class="TimelineQuickSettings" :bound-to="{ x: 'container' }" > - <div - slot="content" - class="dropdown-menu" - > - <div v-if="loggedIn"> + <template v-slot:content> + <div class="dropdown-menu"> + <div v-if="loggedIn"> + <button + class="button-default dropdown-item" + @click="replyVisibilityAll = true" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-radio': replyVisibilityAll }" + />{{ $t('settings.reply_visibility_all') }} + </button> + <button + class="button-default dropdown-item" + @click="replyVisibilityFollowing = true" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-radio': replyVisibilityFollowing }" + />{{ $t('settings.reply_visibility_following_short') }} + </button> + <button + class="button-default dropdown-item" + @click="replyVisibilitySelf = true" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-radio': replyVisibilitySelf }" + />{{ $t('settings.reply_visibility_self_short') }} + </button> + <div + role="separator" + class="dropdown-divider" + /> + </div> <button class="button-default dropdown-item" - @click="replyVisibilityAll = true" + @click="hideMedia = !hideMedia" > <span class="menu-checkbox" - :class="{ 'menu-checkbox-radio': replyVisibilityAll }" - />{{ $t('settings.reply_visibility_all') }} + :class="{ 'menu-checkbox-checked': hideMedia }" + />{{ $t('settings.hide_media_previews') }} </button> <button class="button-default dropdown-item" - @click="replyVisibilityFollowing = true" + @click="hideMutedPosts = !hideMutedPosts" > <span class="menu-checkbox" - :class="{ 'menu-checkbox-radio': replyVisibilityFollowing }" - />{{ $t('settings.reply_visibility_following_short') }} + :class="{ 'menu-checkbox-checked': hideMutedPosts }" + />{{ $t('settings.hide_all_muted_posts') }} </button> <button - class="button-default dropdown-item" - @click="replyVisibilitySelf = true" + class="button-default dropdown-item dropdown-item-icon" + @click="openTab('filtering')" > - <span - class="menu-checkbox" - :class="{ 'menu-checkbox-radio': replyVisibilitySelf }" - />{{ $t('settings.reply_visibility_self_short') }} + <FAIcon icon="font" />{{ $t('settings.word_filter') }} + </button> + <button + class="button-default dropdown-item dropdown-item-icon" + @click="openTab('general')" + > + <FAIcon icon="wrench" />{{ $t('settings.more_settings') }} </button> - <div - role="separator" - class="dropdown-divider" - /> </div> - <button - class="button-default dropdown-item" - @click="hideMedia = !hideMedia" - > - <span - class="menu-checkbox" - :class="{ 'menu-checkbox-checked': hideMedia }" - />{{ $t('settings.hide_media_previews') }} - </button> - <button - class="button-default dropdown-item" - @click="hideMutedPosts = !hideMutedPosts" - > - <span - class="menu-checkbox" - :class="{ 'menu-checkbox-checked': hideMutedPosts }" - />{{ $t('settings.hide_all_muted_posts') }} - </button> - <button - class="button-default dropdown-item dropdown-item-icon" - @click="openTab('filtering')" - > - <FAIcon icon="font" />{{ $t('settings.word_filter') }} - </button> - <button - class="button-default dropdown-item dropdown-item-icon" - @click="openTab('general')" - > - <FAIcon icon="wrench" />{{ $t('settings.more_settings') }} + </template> + <template v-slot:trigger> + <button class="button-unstyled"> + <FAIcon icon="filter" /> </button> - </div> - <div slot="trigger"> - <FAIcon icon="filter" /> - </div> + </template> </Popover> </template> diff --git a/src/components/timeline_menu/timeline_menu.vue b/src/components/timeline_menu/timeline_menu.vue index 22dc3432..8f14093f 100644 --- a/src/components/timeline_menu/timeline_menu.vue +++ b/src/components/timeline_menu/timeline_menu.vue @@ -9,28 +9,26 @@ @show="openMenu" @close="() => isOpen = false" > - <div - slot="content" - class="timeline-menu-popover panel panel-default" - > - <TimelineMenuContent /> - </div> - <div - slot="trigger" - class="title timeline-menu-title" - > - <span class="timeline-title">{{ timelineName() }}</span> - <span> - <FAIcon - size="sm" - icon="chevron-down" + <template v-slot:content> + <div class="timeline-menu-popover popover-default"> + <TimelineMenuContent /> + </div> + </template> + <template v-slot:trigger> + <button class="button-unstyled title timeline-menu-title"> + <span class="timeline-title">{{ timelineName() }}</span> + <span> + <FAIcon + size="sm" + icon="chevron-down" + /> + </span> + <span + class="click-blocker" + @click="blockOpen" /> - </span> - <span - class="click-blocker" - @click="blockOpen" - /> - </div> + </button> + </template> </Popover> </template> diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 3a8efafc..d9fb64d1 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -4,13 +4,13 @@ import ProgressButton from '../progress_button/progress_button.vue' import FollowButton from '../follow_button/follow_button.vue' import ModerationTools from '../moderation_tools/moderation_tools.vue' import AccountActions from '../account_actions/account_actions.vue' +import Select from '../select/select.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' import { faBell, faRss, - faChevronDown, faSearchPlus, faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons' @@ -18,7 +18,6 @@ import { library.add( faRss, faBell, - faChevronDown, faSearchPlus, faExternalLinkAlt ) @@ -118,7 +117,8 @@ export default { ModerationTools, AccountActions, ProgressButton, - FollowButton + FollowButton, + Select }, methods: { muteUser () { diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 4b7ee7d5..a16f7873 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -53,17 +53,17 @@ > {{ user.name }} </div> - <a + <button v-if="isOtherUser && !user.is_local" :href="user.statusnet_profile_url" target="_blank" - class="external-link-button" + class="button-unstyled external-link-button" > <FAIcon class="icon" icon="external-link-alt" /> - </a> + </button> <AccountActions v-if="isOtherUser && loggedIn" :user="user" @@ -132,25 +132,24 @@ class="userHighlightCl" type="color" > - <label - for="theme_tab" - class="userHighlightSel select" + <Select + :id="'userHighlightSel'+user.id" + v-model="userHighlightType" + class="userHighlightSel" > - <select - :id="'userHighlightSel'+user.id" - v-model="userHighlightType" - class="userHighlightSel" - > - <option value="disabled">{{ $t('user_card.highlight.disabled') }}</option> - <option value="solid">{{ $t('user_card.highlight.solid') }}</option> - <option value="striped">{{ $t('user_card.highlight.striped') }}</option> - <option value="side">{{ $t('user_card.highlight.side') }}</option> - </select> - <FAIcon - class="select-down-icon" - icon="chevron-down" - /> - </label> + <option value="disabled"> + {{ $t('user_card.highlight.disabled') }} + </option> + <option value="solid"> + {{ $t('user_card.highlight.solid') }} + </option> + <option value="striped"> + {{ $t('user_card.highlight.striped') }} + </option> + <option value="side"> + {{ $t('user_card.highlight.side') }} + </option> + </Select> </div> </div> <div @@ -541,15 +540,11 @@ flex: 1 0 auto; } - .userHighlightSel, - .userHighlightSel.select { + .userHighlightSel { padding-top: 0; padding-bottom: 0; flex: 1 0 auto; } - .userHighlightSel.select svg { - line-height: 22px; - } .userHighlightText { width: 70px; @@ -558,9 +553,7 @@ .userHighlightCl, .userHighlightText, - .userHighlightSel, - .userHighlightSel.select { - height: 22px; + .userHighlightSel { vertical-align: top; margin-right: .5em; margin-bottom: .25em; diff --git a/src/components/user_list_popover/user_list_popover.vue b/src/components/user_list_popover/user_list_popover.vue index d0aa315e..f4b93c9a 100644 --- a/src/components/user_list_popover/user_list_popover.vue +++ b/src/components/user_list_popover/user_list_popover.vue @@ -4,40 +4,39 @@ placement="top" :offset="{ y: 5 }" > - <template slot="trigger"> + <template v-slot:trigger> <slot /> </template> - <div - slot="content" - class="user-list-popover" - > - <div v-if="users.length"> - <div - v-for="(user) in usersCapped" - :key="user.id" - class="user-list-row" - > - <UserAvatar - :user="user" - class="avatar-small" - :compact="true" - /> - <div class="user-list-names"> - <!-- eslint-disable vue/no-v-html --> - <span v-html="user.name_html" /> - <!-- eslint-enable vue/no-v-html --> - <span class="user-list-screen-name">{{ user.screen_name_ui }}</span> + <template v-slot:content> + <div class="user-list-popover"> + <template v-if="users.length"> + <div + v-for="(user) in usersCapped" + :key="user.id" + class="user-list-row" + > + <UserAvatar + :user="user" + class="avatar-small" + :compact="true" + /> + <div class="user-list-names"> + <!-- eslint-disable vue/no-v-html --> + <span v-html="user.name_html" /> + <!-- eslint-enable vue/no-v-html --> + <span class="user-list-screen-name">{{ user.screen_name_ui }}</span> + </div> </div> - </div> - </div> - <div v-else> - <FAIcon - icon="circle-notch" - spin - size="3x" - /> + </template> + <template v-else> + <FAIcon + icon="circle-notch" + spin + size="3x" + /> + </template> </div> - </div> + </template> </Popover> </template> diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index 745e795d..aef897ae 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -60,10 +60,7 @@ :disabled="!user.friends_count" > <FriendList :user-id="userId"> - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <FollowCard :user="item" /> </template> </FriendList> @@ -75,10 +72,7 @@ :disabled="!user.followers_count" > <FollowerList :user-id="userId"> - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <FollowCard :user="item" :no-follows-you="isUs" diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue index a71c02c1..1f67a5cc 100644 --- a/src/components/user_reporting_modal/user_reporting_modal.vue +++ b/src/components/user_reporting_modal/user_reporting_modal.vue @@ -45,10 +45,7 @@ </div> <div class="user-reporting-panel-right"> <List :items="statuses"> - <template - slot="item" - slot-scope="{item}" - > + <template v-slot:item="{item}"> <div class="status-fadein user-reporting-panel-sitem"> <Status :in-conversation="false" |
