diff options
Diffstat (limited to 'src/components/settings_modal')
11 files changed, 251 insertions, 68 deletions
diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss index 833ff89a..90446b36 100644 --- a/src/components/settings_modal/settings_modal.scss +++ b/src/components/settings_modal/settings_modal.scss @@ -13,6 +13,13 @@ * - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible */ transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px)); + + @media all and (max-width: 800px) { + /* For mobile, the modal takes 100% of the available screen. + This ensures the minimized modal is always 50px above the browser bottom bar regardless of whether or not it is visible. + */ + transform: translateY(calc(100% - 50px)); + } } } @@ -27,10 +34,10 @@ @media all and (max-width: 800px) { max-width: 100vw; - height: 100vh; + height: 100%; } - .panel-body { + >.panel-body { height: 100%; overflow-y: hidden; diff --git a/src/components/settings_modal/settings_modal_content.js b/src/components/settings_modal/settings_modal_content.js index 48101a90..ef1a5ffa 100644 --- a/src/components/settings_modal/settings_modal_content.js +++ b/src/components/settings_modal/settings_modal_content.js @@ -27,6 +27,34 @@ const SettingsModalContent = { computed: { isLoggedIn () { return !!this.$store.state.users.currentUser + }, + open () { + return this.$store.state.interface.settingsModalState !== 'hidden' + } + }, + methods: { + onOpen () { + const targetTab = this.$store.state.interface.settingsModalTargetTab + // We're being told to open in specific tab + if (targetTab) { + const tabIndex = this.$refs.tabSwitcher.$slots.default.findIndex(elm => { + return elm.data && elm.data.attrs['data-tab-name'] === targetTab + }) + if (tabIndex >= 0) { + this.$refs.tabSwitcher.setTab(tabIndex) + } + } + // Clear the state of target tab, so that next time settings is opened + // it doesn't force it. + this.$store.dispatch('clearSettingsModalTargetTab') + } + }, + mounted () { + this.onOpen() + }, + watch: { + open: function (value) { + if (value) this.onOpen() } } } diff --git a/src/components/settings_modal/settings_modal_content.vue b/src/components/settings_modal/settings_modal_content.vue index 2156844f..bc30a0ff 100644 --- a/src/components/settings_modal/settings_modal_content.vue +++ b/src/components/settings_modal/settings_modal_content.vue @@ -8,6 +8,7 @@ <div :label="$t('settings.general')" icon="wrench" + data-tab-name="general" > <GeneralTab /> </div> @@ -15,6 +16,7 @@ v-if="isLoggedIn" :label="$t('settings.profile_tab')" icon="user" + data-tab-name="profile" > <ProfileTab /> </div> @@ -22,18 +24,21 @@ v-if="isLoggedIn" :label="$t('settings.security_tab')" icon="lock" + data-tab-name="security" > <SecurityTab /> </div> <div :label="$t('settings.filtering')" icon="filter" + data-tab-name="filtering" > <FilteringTab /> </div> <div :label="$t('settings.theme')" icon="brush" + data-tab-name="theme" > <ThemeTab /> </div> @@ -41,6 +46,7 @@ v-if="isLoggedIn" :label="$t('settings.notifications')" icon="bell-ringing-o" + data-tab-name="notifications" > <NotificationsTab /> </div> @@ -48,6 +54,7 @@ v-if="isLoggedIn" :label="$t('settings.data_import_export_tab')" icon="download" + data-tab-name="dataImportExport" > <DataImportExportTab /> </div> @@ -56,12 +63,14 @@ :label="$t('settings.mutes_and_blocks')" :fullHeight="true" icon="eye-off" + data-tab-name="mutesAndBlocks" > <MutesAndBlocksTab /> </div> <div :label="$t('settings.version.title')" icon="info-circled" + data-tab-name="version" > <VersionTab /> </div> diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js index 224a7f47..3b2df556 100644 --- a/src/components/settings_modal/tabs/filtering_tab.js +++ b/src/components/settings_modal/tabs/filtering_tab.js @@ -37,6 +37,9 @@ const FilteringTab = { }) }, deep: true + }, + replyVisibility () { + this.$store.dispatch('queueFlushAll') } } } diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index f89c0480..7f06d0bd 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -54,16 +54,6 @@ </Checkbox> </li> <li> - <Checkbox v-model="autoLoad"> - {{ $t('settings.autoload') }} - </Checkbox> - </li> - <li> - <Checkbox v-model="hoverPreview"> - {{ $t('settings.reply_link_preview') }} - </Checkbox> - </li> - <li> <Checkbox v-model="emojiReactionsOnTimeline"> {{ $t('settings.emoji_reactions_on_timeline') }} </Checkbox> diff --git a/src/components/settings_modal/tabs/notifications_tab.vue b/src/components/settings_modal/tabs/notifications_tab.vue index b7a3cb37..86eed3f5 100644 --- a/src/components/settings_modal/tabs/notifications_tab.vue +++ b/src/components/settings_modal/tabs/notifications_tab.vue @@ -2,38 +2,18 @@ <div :label="$t('settings.notifications')"> <div class="setting-item"> <h2>{{ $t('settings.notification_setting_filters') }}</h2> - <div class="select-multiple"> - <span class="label">{{ $t('settings.notification_setting') }}</span> - <ul class="option-list"> - <li> - <Checkbox v-model="notificationSettings.follows"> - {{ $t('settings.notification_setting_follows') }} - </Checkbox> - </li> - <li> - <Checkbox v-model="notificationSettings.followers"> - {{ $t('settings.notification_setting_followers') }} - </Checkbox> - </li> - <li> - <Checkbox v-model="notificationSettings.non_follows"> - {{ $t('settings.notification_setting_non_follows') }} - </Checkbox> - </li> - <li> - <Checkbox v-model="notificationSettings.non_followers"> - {{ $t('settings.notification_setting_non_followers') }} - </Checkbox> - </li> - </ul> - </div> + <p> + <Checkbox v-model="notificationSettings.block_from_strangers"> + {{ $t('settings.notification_setting_block_from_strangers') }} + </Checkbox> + </p> </div> <div class="setting-item"> <h2>{{ $t('settings.notification_setting_privacy') }}</h2> <p> - <Checkbox v-model="notificationSettings.privacy_option"> - {{ $t('settings.notification_setting_privacy_option') }} + <Checkbox v-model="notificationSettings.hide_notification_contents"> + {{ $t('settings.notification_setting_hide_notification_contents') }} </Checkbox> </p> </div> diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js index e6db802d..bd6bef6a 100644 --- a/src/components/settings_modal/tabs/profile_tab.js +++ b/src/components/settings_modal/tabs/profile_tab.js @@ -77,6 +77,33 @@ const ProfileTab = { }, maxFields () { return this.fieldsLimits ? this.fieldsLimits.maxFields : 0 + }, + defaultAvatar () { + return this.$store.state.instance.server + this.$store.state.instance.defaultAvatar + }, + defaultBanner () { + return this.$store.state.instance.server + this.$store.state.instance.defaultBanner + }, + isDefaultAvatar () { + const baseAvatar = this.$store.state.instance.defaultAvatar + return !(this.$store.state.users.currentUser.profile_image_url) || + this.$store.state.users.currentUser.profile_image_url.includes(baseAvatar) + }, + isDefaultBanner () { + const baseBanner = this.$store.state.instance.defaultBanner + return !(this.$store.state.users.currentUser.cover_photo) || + this.$store.state.users.currentUser.cover_photo.includes(baseBanner) + }, + isDefaultBackground () { + return !(this.$store.state.users.currentUser.background_image) + }, + avatarImgSrc () { + const src = this.$store.state.users.currentUser.profile_image_url_original + return (!src) ? this.defaultAvatar : src + }, + bannerImgSrc () { + const src = this.$store.state.users.currentUser.cover_photo + return (!src) ? this.defaultBanner : src } }, methods: { @@ -150,11 +177,29 @@ const ProfileTab = { } reader.readAsDataURL(file) }, + resetAvatar () { + const confirmed = window.confirm(this.$t('settings.reset_avatar_confirm')) + if (confirmed) { + this.submitAvatar(undefined, '') + } + }, + resetBanner () { + const confirmed = window.confirm(this.$t('settings.reset_banner_confirm')) + if (confirmed) { + this.submitBanner('') + } + }, + resetBackground () { + const confirmed = window.confirm(this.$t('settings.reset_background_confirm')) + if (confirmed) { + this.submitBackground('') + } + }, submitAvatar (cropper, file) { const that = this return new Promise((resolve, reject) => { function updateAvatar (avatar) { - that.$store.state.api.backendInteractor.updateAvatar({ avatar }) + that.$store.state.api.backendInteractor.updateProfileImages({ avatar }) .then((user) => { that.$store.commit('addNewUsers', [user]) that.$store.commit('setCurrentUser', user) @@ -172,11 +217,11 @@ const ProfileTab = { } }) }, - submitBanner () { - if (!this.bannerPreview) { return } + submitBanner (banner) { + if (!this.bannerPreview && banner !== '') { return } this.bannerUploading = true - this.$store.state.api.backendInteractor.updateBanner({ banner: this.banner }) + this.$store.state.api.backendInteractor.updateProfileImages({ banner }) .then((user) => { this.$store.commit('addNewUsers', [user]) this.$store.commit('setCurrentUser', user) @@ -187,11 +232,11 @@ const ProfileTab = { }) .then(() => { this.bannerUploading = false }) }, - submitBg () { - if (!this.backgroundPreview) { return } - let background = this.background + submitBackground (background) { + if (!this.backgroundPreview && background !== '') { return } + this.backgroundUploading = true - this.$store.state.api.backendInteractor.updateBg({ background }).then((data) => { + this.$store.state.api.backendInteractor.updateProfileImages({ background }).then((data) => { if (!data.error) { this.$store.commit('addNewUsers', [data]) this.$store.commit('setCurrentUser', data) diff --git a/src/components/settings_modal/tabs/profile_tab.scss b/src/components/settings_modal/tabs/profile_tab.scss index b3dcf42c..e14cf054 100644 --- a/src/components/settings_modal/tabs/profile_tab.scss +++ b/src/components/settings_modal/tabs/profile_tab.scss @@ -13,8 +13,14 @@ height: auto; } - .banner { + .banner-background-preview { max-width: 100%; + width: 300px; + position: relative; + + img { + width: 100%; + } } .uploading { @@ -26,18 +32,40 @@ width: 100%; } - .bg { - max-width: 100%; + .current-avatar-container { + position: relative; + width: 150px; + height: 150px; } .current-avatar { display: block; - width: 150px; - height: 150px; + width: 100%; + height: 100%; border-radius: $fallback--avatarRadius; border-radius: var(--avatarRadius, $fallback--avatarRadius); } + .reset-button { + position: absolute; + top: 0.2em; + right: 0.2em; + border-radius: $fallback--tooltipRadius; + border-radius: var(--tooltipRadius, $fallback--tooltipRadius); + background-color: rgba(0, 0, 0, 0.6); + opacity: 0.7; + color: white; + width: 1.5em; + height: 1.5em; + text-align: center; + line-height: 1.5em; + font-size: 1.5em; + cursor: pointer; + &:hover { + opacity: 1; + } + } + .oauth-tokens { width: 100%; @@ -86,6 +114,7 @@ &>.emoji-input { flex: 1 1 auto; margin: 0 .2em .5em; + min-width: 0; } &>.icon-container { diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue index 0f9210a6..cf88c4e4 100644 --- a/src/components/settings_modal/tabs/profile_tab.vue +++ b/src/components/settings_modal/tabs/profile_tab.vue @@ -161,11 +161,19 @@ <p class="visibility-notice"> {{ $t('settings.avatar_size_instruction') }} </p> - <p>{{ $t('settings.current_avatar') }}</p> - <img - :src="user.profile_image_url_original" - class="current-avatar" - > + <div class="current-avatar-container"> + <img + :src="user.profile_image_url_original" + class="current-avatar" + > + <i + v-if="!isDefaultAvatar && pickAvatarBtnVisible" + :title="$t('settings.reset_avatar')" + class="reset-button icon-cancel" + type="button" + @click="resetAvatar" + /> + </div> <p>{{ $t('settings.set_new_avatar') }}</p> <button v-show="pickAvatarBtnVisible" @@ -184,15 +192,20 @@ </div> <div class="setting-item"> <h2>{{ $t('settings.profile_banner') }}</h2> - <p>{{ $t('settings.current_profile_banner') }}</p> - <img - :src="user.cover_photo" - class="banner" - > + <div class="banner-background-preview"> + <img :src="user.cover_photo"> + <i + v-if="!isDefaultBanner" + :title="$t('settings.reset_profile_banner')" + class="reset-button icon-cancel" + type="button" + @click="resetBanner" + /> + </div> <p>{{ $t('settings.set_new_profile_banner') }}</p> <img v-if="bannerPreview" - class="banner" + class="banner-background-preview" :src="bannerPreview" > <div> @@ -208,7 +221,7 @@ <button v-else-if="bannerPreview" class="btn btn-default" - @click="submitBanner" + @click="submitBanner(banner)" > {{ $t('general.submit') }} </button> @@ -225,10 +238,20 @@ </div> <div class="setting-item"> <h2>{{ $t('settings.profile_background') }}</h2> + <div class="banner-background-preview"> + <img :src="user.background_image"> + <i + v-if="!isDefaultBackground" + :title="$t('settings.reset_profile_background')" + class="reset-button icon-cancel" + type="button" + @click="resetBackground" + /> + </div> <p>{{ $t('settings.set_new_profile_background') }}</p> <img v-if="backgroundPreview" - class="bg" + class="banner-background-preview" :src="backgroundPreview" > <div> @@ -244,7 +267,7 @@ <button v-else-if="backgroundPreview" class="btn btn-default" - @click="submitBg" + @click="submitBackground(background)" > {{ $t('general.submit') }} </button> 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 9d61b0c4..e3c5e80a 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -99,7 +99,8 @@ export default { avatarRadiusLocal: '', avatarAltRadiusLocal: '', attachmentRadiusLocal: '', - tooltipRadiusLocal: '' + tooltipRadiusLocal: '', + chatMessageRadiusLocal: '' } }, created () { @@ -214,7 +215,8 @@ export default { avatar: this.avatarRadiusLocal, avatarAlt: this.avatarAltRadiusLocal, tooltip: this.tooltipRadiusLocal, - attachment: this.attachmentRadiusLocal + attachment: this.attachmentRadiusLocal, + chatMessage: this.chatMessageRadiusLocal } }, preview () { 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 d14f854c..d57894de 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue @@ -735,6 +735,65 @@ /> <ContrastRatio :contrast="previewContrast.selectedMenuLink" /> </div> + <div class="color-item"> + <h4>{{ $t('chats.chats') }}</h4> + <ColorInput + v-model="chatBgColorLocal" + name="chatBgColor" + :fallback="previewTheme.colors.bg || 1" + :label="$t('settings.background')" + /> + <h5>{{ $t('settings.style.advanced_colors.chat.incoming') }}</h5> + <ColorInput + v-model="chatMessageIncomingBgColorLocal" + name="chatMessageIncomingBgColor" + :fallback="previewTheme.colors.bg || 1" + :label="$t('settings.background')" + /> + <ColorInput + v-model="chatMessageIncomingTextColorLocal" + name="chatMessageIncomingTextColor" + :fallback="previewTheme.colors.text || 1" + :label="$t('settings.text')" + /> + <ColorInput + v-model="chatMessageIncomingLinkColorLocal" + name="chatMessageIncomingLinkColor" + :fallback="previewTheme.colors.link || 1" + :label="$t('settings.links')" + /> + <ColorInput + v-model="chatMessageIncomingBorderColorLocal" + name="chatMessageIncomingBorderLinkColor" + :fallback="previewTheme.colors.fg || 1" + :label="$t('settings.style.advanced_colors.chat.border')" + /> + <h5>{{ $t('settings.style.advanced_colors.chat.outgoing') }}</h5> + <ColorInput + v-model="chatMessageOutgoingBgColorLocal" + name="chatMessageOutgoingBgColor" + :fallback="previewTheme.colors.bg || 1" + :label="$t('settings.background')" + /> + <ColorInput + v-model="chatMessageOutgoingTextColorLocal" + name="chatMessageOutgoingTextColor" + :fallback="previewTheme.colors.text || 1" + :label="$t('settings.text')" + /> + <ColorInput + v-model="chatMessageOutgoingLinkColorLocal" + name="chatMessageOutgoingLinkColor" + :fallback="previewTheme.colors.link || 1" + :label="$t('settings.links')" + /> + <ColorInput + v-model="chatMessageOutgoingBorderColorLocal" + name="chatMessageOutgoingBorderLinkColor" + :fallback="previewTheme.colors.bg || 1" + :label="$t('settings.style.advanced_colors.chat.border')" + /> + </div> </div> <div @@ -814,6 +873,14 @@ max="50" hard-min="0" /> + <RangeInput + v-model="chatMessageRadiusLocal" + name="chatMessageRadius" + :label="$t('settings.chatMessageRadius')" + :fallback="previewTheme.radii.chatMessage || 2" + max="50" + hard-min="0" + /> </div> <div |
