Merge remote-tracking branch 'upstream/develop' into birthdays
This commit is contained in:
commit
b1e75c25bd
300 changed files with 13879 additions and 9055 deletions
|
|
@ -41,7 +41,16 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
update (e) {
|
||||
const [firstSegment, ...rest] = this.path.split('.')
|
||||
set(this.$parent, this.path, e)
|
||||
// Updating nested properties does not trigger update on its parent.
|
||||
// probably still not as reliable, but works for depth=1 at least
|
||||
if (rest.length > 0) {
|
||||
set(this.$parent, firstSegment, { ...get(this.$parent, firstSegment) })
|
||||
}
|
||||
},
|
||||
reset () {
|
||||
set(this.$parent, this.path, this.defaultState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,12 @@
|
|||
<slot />
|
||||
</span>
|
||||
{{ ' ' }}
|
||||
<ModifiedIndicator :changed="isChanged" /><ServerSideIndicator :server-side="isServerSide" /> </Checkbox>
|
||||
<ModifiedIndicator
|
||||
:changed="isChanged"
|
||||
:onclick="reset"
|
||||
/>
|
||||
<ServerSideIndicator :server-side="isServerSide" />
|
||||
</Checkbox>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ export default {
|
|||
methods: {
|
||||
update (e) {
|
||||
set(this.$parent, this.path, e)
|
||||
},
|
||||
reset () {
|
||||
set(this.$parent, this.path, this.defaultState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,14 +19,12 @@
|
|||
{{ option.value === defaultState ? $t('settings.instance_default_simple') : '' }}
|
||||
</option>
|
||||
</Select>
|
||||
<ModifiedIndicator :changed="isChanged" />
|
||||
<ModifiedIndicator
|
||||
:changed="isChanged"
|
||||
:onclick="reset"
|
||||
/>
|
||||
<ServerSideIndicator :server-side="isServerSide" />
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script src="./choice_setting.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.ChoiceSetting {
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ export default {
|
|||
methods: {
|
||||
update (e) {
|
||||
set(this.$parent, this.path, parseInt(e.target.value))
|
||||
},
|
||||
reset () {
|
||||
set(this.$parent, this.path, this.defaultState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@
|
|||
@change="update"
|
||||
>
|
||||
{{ ' ' }}
|
||||
<ModifiedIndicator :changed="isChanged" />
|
||||
<ModifiedIndicator
|
||||
:changed="isChanged"
|
||||
:onclick="reset"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
67
src/components/settings_modal/helpers/size_setting.js
Normal file
67
src/components/settings_modal/helpers/size_setting.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { get, set } from 'lodash'
|
||||
import ModifiedIndicator from './modified_indicator.vue'
|
||||
import Select from 'src/components/select/select.vue'
|
||||
|
||||
export const allCssUnits = ['cm', 'mm', 'in', 'px', 'pt', 'pc', 'em', 'ex', 'ch', 'rem', 'vw', 'vh', 'vmin', 'vmax', '%']
|
||||
export const defaultHorizontalUnits = ['px', 'rem', 'vw']
|
||||
export const defaultVerticalUnits = ['px', 'rem', 'vh']
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ModifiedIndicator,
|
||||
Select
|
||||
},
|
||||
props: {
|
||||
path: String,
|
||||
disabled: Boolean,
|
||||
min: Number,
|
||||
units: {
|
||||
type: [String],
|
||||
default: () => allCssUnits
|
||||
},
|
||||
expert: [Number, String]
|
||||
},
|
||||
computed: {
|
||||
pathDefault () {
|
||||
const [firstSegment, ...rest] = this.path.split('.')
|
||||
return [firstSegment + 'DefaultValue', ...rest].join('.')
|
||||
},
|
||||
stateUnit () {
|
||||
return (this.state || '').replace(/\d+/, '')
|
||||
},
|
||||
stateValue () {
|
||||
return (this.state || '').replace(/\D+/, '')
|
||||
},
|
||||
state () {
|
||||
const value = get(this.$parent, this.path)
|
||||
if (value === undefined) {
|
||||
return this.defaultState
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
},
|
||||
defaultState () {
|
||||
return get(this.$parent, this.pathDefault)
|
||||
},
|
||||
isChanged () {
|
||||
return this.state !== this.defaultState
|
||||
},
|
||||
matchesExpertLevel () {
|
||||
return (this.expert || 0) <= this.$parent.expertLevel
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
update (e) {
|
||||
set(this.$parent, this.path, e)
|
||||
},
|
||||
reset () {
|
||||
set(this.$parent, this.path, this.defaultState)
|
||||
},
|
||||
updateValue (e) {
|
||||
set(this.$parent, this.path, parseInt(e.target.value) + this.stateUnit)
|
||||
},
|
||||
updateUnit (e) {
|
||||
set(this.$parent, this.path, this.stateValue + e.target.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/components/settings_modal/helpers/size_setting.vue
Normal file
55
src/components/settings_modal/helpers/size_setting.vue
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<span
|
||||
v-if="matchesExpertLevel"
|
||||
class="SizeSetting"
|
||||
>
|
||||
<label
|
||||
:for="path"
|
||||
class="size-label"
|
||||
>
|
||||
<slot />
|
||||
</label>
|
||||
<input
|
||||
:id="path"
|
||||
class="number-input"
|
||||
type="number"
|
||||
step="1"
|
||||
:disabled="disabled"
|
||||
:min="min || 0"
|
||||
:value="stateValue"
|
||||
@change="updateValue"
|
||||
>
|
||||
<Select
|
||||
:id="path"
|
||||
:model-value="stateUnit"
|
||||
:disabled="disabled"
|
||||
class="css-unit-input"
|
||||
@change="updateUnit"
|
||||
>
|
||||
<option
|
||||
v-for="option in units"
|
||||
:key="option"
|
||||
:value="option"
|
||||
>
|
||||
{{ option }}
|
||||
</option>
|
||||
</Select>
|
||||
{{ ' ' }}
|
||||
<ModifiedIndicator
|
||||
:changed="isChanged"
|
||||
:onclick="reset"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script src="./size_setting.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.css-unit-input,
|
||||
.css-unit-input select {
|
||||
margin-left: 0.5em;
|
||||
width: 4em;
|
||||
max-width: 4em;
|
||||
min-width: 4em;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
@import 'src/_variables.scss';
|
||||
@import "src/variables";
|
||||
|
||||
.settings-modal {
|
||||
overflow: hidden;
|
||||
|
||||
|
|
@ -6,32 +7,13 @@
|
|||
.option-list {
|
||||
list-style-type: none;
|
||||
padding-left: 2em;
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.suboptions {
|
||||
margin-top: 0.3em
|
||||
}
|
||||
}
|
||||
|
||||
&.peek {
|
||||
.settings-modal-panel {
|
||||
/* Explanation:
|
||||
* Modal is positioned vertically centered.
|
||||
* 100vh - 100% = Distance between modal's top+bottom boundaries and screen
|
||||
* (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen
|
||||
* + 100% - we move modal completely off-screen, it's top boundary touches
|
||||
* bottom of the screen
|
||||
* - 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));
|
||||
}
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +45,7 @@
|
|||
|
||||
.settings-footer {
|
||||
display: flex;
|
||||
|
||||
>* {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
|
@ -72,4 +55,26 @@
|
|||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.peek {
|
||||
.settings-modal-panel {
|
||||
/* Explanation:
|
||||
* Modal is positioned vertically centered.
|
||||
* 100vh - 100% = Distance between modal's top+bottom boundaries and screen
|
||||
* (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen
|
||||
* + 100% - we move modal completely off-screen, it's top boundary touches
|
||||
* bottom of the screen
|
||||
* - 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import 'src/_variables.scss';
|
||||
@import "src/variables";
|
||||
|
||||
.settings_tab-switcher {
|
||||
height: 100%;
|
||||
|
||||
|
|
@ -10,7 +11,8 @@
|
|||
> div,
|
||||
> label {
|
||||
display: block;
|
||||
margin-bottom: .5em;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
@ -21,7 +23,7 @@
|
|||
|
||||
.option-list {
|
||||
margin: 0;
|
||||
padding-left: .5em;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,16 @@
|
|||
>
|
||||
{{ $t('settings.download_backup') }}
|
||||
</a>
|
||||
<span
|
||||
v-else-if="backup.state === 'running'"
|
||||
>
|
||||
{{ $tc('settings.backup_running', backup.processed_number, { number: backup.processed_number }) }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="backup.state === 'failed'"
|
||||
>
|
||||
{{ $t('settings.backup_failed') }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { filter, trim } from 'lodash'
|
||||
import { filter, trim, debounce } from 'lodash'
|
||||
import BooleanSetting from '../helpers/boolean_setting.vue'
|
||||
import ChoiceSetting from '../helpers/choice_setting.vue'
|
||||
import IntegerSetting from '../helpers/integer_setting.vue'
|
||||
|
|
@ -29,24 +29,20 @@ const FilteringTab = {
|
|||
},
|
||||
set (value) {
|
||||
this.muteWordsStringLocal = value
|
||||
this.debouncedSetMuteWords(value)
|
||||
}
|
||||
},
|
||||
debouncedSetMuteWords () {
|
||||
return debounce((value) => {
|
||||
this.$store.dispatch('setOption', {
|
||||
name: 'muteWords',
|
||||
value: filter(value.split('\n'), (word) => trim(word).length > 0)
|
||||
})
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
// Updating nested properties
|
||||
watch: {
|
||||
notificationVisibility: {
|
||||
handler (value) {
|
||||
this.$store.dispatch('setOption', {
|
||||
name: 'notificationVisibility',
|
||||
value: this.$store.getters.mergedConfig.notificationVisibility
|
||||
})
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
replyVisibility () {
|
||||
this.$store.dispatch('queueFlushAll')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import BooleanSetting from '../helpers/boolean_setting.vue'
|
|||
import ChoiceSetting from '../helpers/choice_setting.vue'
|
||||
import ScopeSelector from 'src/components/scope_selector/scope_selector.vue'
|
||||
import IntegerSetting from '../helpers/integer_setting.vue'
|
||||
import SizeSetting, { defaultHorizontalUnits } from '../helpers/size_setting.vue'
|
||||
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
|
||||
|
||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||
|
|
@ -43,6 +44,11 @@ const GeneralTab = {
|
|||
value: mode,
|
||||
label: this.$t(`settings.third_column_mode_${mode}`)
|
||||
})),
|
||||
userPopoverAvatarActionOptions: ['close', 'zoom', 'open'].map(mode => ({
|
||||
key: mode,
|
||||
value: mode,
|
||||
label: this.$t(`settings.user_popover_avatar_action_${mode}`)
|
||||
})),
|
||||
loopSilentAvailable:
|
||||
// Firefox
|
||||
Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') ||
|
||||
|
|
@ -56,11 +62,15 @@ const GeneralTab = {
|
|||
BooleanSetting,
|
||||
ChoiceSetting,
|
||||
IntegerSetting,
|
||||
SizeSetting,
|
||||
InterfaceLanguageSwitcher,
|
||||
ScopeSelector,
|
||||
ServerSideIndicator
|
||||
},
|
||||
computed: {
|
||||
horizontalUnits () {
|
||||
return defaultHorizontalUnits
|
||||
},
|
||||
postFormats () {
|
||||
return this.$store.state.instance.postFormats || []
|
||||
},
|
||||
|
|
@ -71,6 +81,17 @@ const GeneralTab = {
|
|||
label: this.$t(`post_status.content_type["${format}"]`)
|
||||
}))
|
||||
},
|
||||
columns () {
|
||||
const mode = this.$store.getters.mergedConfig.thirdColumnMode
|
||||
|
||||
const notif = mode === 'none' ? [] : ['notifs']
|
||||
|
||||
if (this.$store.getters.mergedConfig.sidebarRight || mode === 'postform') {
|
||||
return [...notif, 'content', 'sidebar']
|
||||
} else {
|
||||
return ['sidebar', 'content', ...notif]
|
||||
}
|
||||
},
|
||||
instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel },
|
||||
instanceWallpaperUsed () {
|
||||
return this.$store.state.instance.background &&
|
||||
|
|
|
|||
|
|
@ -15,11 +15,6 @@
|
|||
{{ $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') }}
|
||||
|
|
@ -65,22 +60,14 @@
|
|||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="disableStickyHeaders">
|
||||
{{ $t('settings.disable_sticky_headers') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="showScrollbars">
|
||||
{{ $t('settings.show_scrollbars') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="userPopoverZoom"
|
||||
<ChoiceSetting
|
||||
id="userPopoverAvatarAction"
|
||||
path="userPopoverAvatarAction"
|
||||
:options="userPopoverAvatarActionOptions"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_popover_avatar_zoom') }}
|
||||
</BooleanSetting>
|
||||
{{ $t('settings.user_popover_avatar_action') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
|
|
@ -90,16 +77,6 @@
|
|||
{{ $t('settings.user_popover_avatar_overlay') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
v-if="user"
|
||||
id="thirdColumnMode"
|
||||
path="thirdColumnMode"
|
||||
:options="thirdColumnModeOptions"
|
||||
>
|
||||
{{ $t('settings.third_column_mode') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="alwaysShowNewPostButton"
|
||||
|
|
@ -124,6 +101,53 @@
|
|||
{{ $t('settings.hide_shoutbox') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<h3>{{ $t('settings.columns') }}</h3>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="disableStickyHeaders">
|
||||
{{ $t('settings.disable_sticky_headers') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="showScrollbars">
|
||||
{{ $t('settings.show_scrollbars') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="sidebarRight">
|
||||
{{ $t('settings.right_sidebar') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="navbarColumnStretch">
|
||||
{{ $t('settings.navbar_column_stretch') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
v-if="user"
|
||||
id="thirdColumnMode"
|
||||
path="thirdColumnMode"
|
||||
:options="thirdColumnModeOptions"
|
||||
>
|
||||
{{ $t('settings.third_column_mode') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li v-if="expertLevel > 0">
|
||||
{{ $t('settings.column_sizes') }}
|
||||
<div class="column-settings">
|
||||
<SizeSetting
|
||||
v-for="column in columns"
|
||||
:key="column"
|
||||
:path="column + 'ColumnWidth'"
|
||||
:units="horizontalUnits"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.column_sizes_' + column) }}
|
||||
</SizeSetting>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
|
|
@ -433,3 +457,17 @@
|
|||
</template>
|
||||
|
||||
<script src="./general_tab.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.column-settings {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.column-settings .size-label {
|
||||
display: block;
|
||||
margin-bottom: 0.5em;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
.mutes-and-blocks-tab {
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
|
||||
.usersearch-wrapper {
|
||||
padding: 1em;
|
||||
}
|
||||
.usersearch-wrapper {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.bulk-actions {
|
||||
text-align: right;
|
||||
padding: 0 1em;
|
||||
min-height: 2em;
|
||||
}
|
||||
.bulk-actions {
|
||||
text-align: right;
|
||||
padding: 0 1em;
|
||||
min-height: 2em;
|
||||
}
|
||||
|
||||
.bulk-action-button {
|
||||
width: 10em
|
||||
}
|
||||
.bulk-action-button {
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
.domain-mute-form {
|
||||
padding: 1em;
|
||||
display: flex;
|
||||
flex-direction: column
|
||||
}
|
||||
.domain-mute-form {
|
||||
padding: 1em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.domain-mute-button {
|
||||
align-self: flex-end;
|
||||
margin-top: 1em;
|
||||
width: 10em
|
||||
}
|
||||
.domain-mute-button {
|
||||
align-self: flex-end;
|
||||
margin-top: 1em;
|
||||
width: 10em;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
<div :label="$t('settings.mutes_tab')">
|
||||
<tab-switcher>
|
||||
<div label="Users">
|
||||
<div :label="$t('settings.user_mutes')">
|
||||
<div class="usersearch-wrapper">
|
||||
<Autosuggest
|
||||
:filter="filterUnMutedUsers"
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ const ProfileTab = {
|
|||
emojiUserSuggestor () {
|
||||
return suggestor({
|
||||
emoji: [
|
||||
...this.$store.state.instance.emoji,
|
||||
...this.$store.getters.standardEmojiList,
|
||||
...this.$store.state.instance.customEmoji
|
||||
],
|
||||
store: this.$store
|
||||
|
|
@ -75,7 +75,7 @@ const ProfileTab = {
|
|||
emojiSuggestor () {
|
||||
return suggestor({
|
||||
emoji: [
|
||||
...this.$store.state.instance.emoji,
|
||||
...this.$store.getters.standardEmojiList,
|
||||
...this.$store.state.instance.customEmoji
|
||||
]
|
||||
})
|
||||
|
|
@ -157,7 +157,7 @@ const ProfileTab = {
|
|||
return false
|
||||
},
|
||||
deleteField (index, event) {
|
||||
this.$delete(this.newFields, index)
|
||||
this.newFields.splice(index, 1)
|
||||
},
|
||||
uploadFile (slot, e) {
|
||||
const file = e.target.files[0]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import '../../../_variables.scss';
|
||||
@import "../../../variables";
|
||||
|
||||
.profile-tab {
|
||||
.bio {
|
||||
margin: 0;
|
||||
|
|
@ -8,7 +9,7 @@
|
|||
padding-top: 5px;
|
||||
}
|
||||
|
||||
input[type=file] {
|
||||
input[type="file"] {
|
||||
padding: 5px;
|
||||
height: auto;
|
||||
}
|
||||
|
|
@ -52,7 +53,7 @@
|
|||
right: 0.2em;
|
||||
border-radius: $fallback--tooltipRadius;
|
||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
background-color: rgb(0 0 0 / 60%);
|
||||
opacity: 0.7;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
|
|
|
|||
|
|
@ -137,9 +137,11 @@
|
|||
|
||||
<script src="./mfa.js"></script>
|
||||
<style lang="scss">
|
||||
@import '../../../../_variables.scss';
|
||||
@import "../../../../variables";
|
||||
|
||||
.mfa-settings {
|
||||
.mfa-heading, .method-item {
|
||||
.mfa-heading,
|
||||
.method-item {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
|
@ -155,18 +157,19 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.qr-code {
|
||||
flex: 1;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.verify { flex: 1; }
|
||||
.error { margin: 4px 0 0 0; }
|
||||
.error { margin: 4px 0 0; }
|
||||
|
||||
.confirm-otp-actions {
|
||||
button {
|
||||
width: 15em;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,14 @@
|
|||
</template>
|
||||
<script src="./mfa_backup_codes.js"></script>
|
||||
<style lang="scss">
|
||||
@import '../../../../_variables.scss';
|
||||
@import "../../../../variables";
|
||||
|
||||
.mfa-backup-codes {
|
||||
.warning {
|
||||
color: $fallback--cOrange;
|
||||
color: var(--cOrange, $fallback--cOrange);
|
||||
}
|
||||
|
||||
.backup-codes {
|
||||
font-family: var(--postCodeFont, monospace);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@
|
|||
class="btn button-default"
|
||||
@click="confirmDelete"
|
||||
>
|
||||
{{ $t('settings.save') }}
|
||||
{{ $t('settings.delete_account') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@
|
|||
scope="global"
|
||||
keypath="settings.style.preview.text"
|
||||
>
|
||||
<code style="font-family: var(--postCodeFont)">
|
||||
<code style="font-family: var(--postCodeFont);">
|
||||
{{ $t('settings.style.preview.mono') }}
|
||||
</code>
|
||||
<a style="color: var(--link)">
|
||||
<a style="color: var(--link);">
|
||||
{{ $t('settings.style.preview.link') }}
|
||||
</a>
|
||||
</i18n-t>
|
||||
|
|
@ -44,25 +44,25 @@
|
|||
<div class="icons">
|
||||
<FAIcon
|
||||
fixed-width
|
||||
style="color: var(--cBlue)"
|
||||
style="color: var(--cBlue);"
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="reply"
|
||||
/>
|
||||
<FAIcon
|
||||
fixed-width
|
||||
style="color: var(--cGreen)"
|
||||
style="color: var(--cGreen);"
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="retweet"
|
||||
/>
|
||||
<FAIcon
|
||||
fixed-width
|
||||
style="color: var(--cOrange)"
|
||||
style="color: var(--cOrange);"
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="star"
|
||||
/>
|
||||
<FAIcon
|
||||
fixed-width
|
||||
style="color: var(--cRed)"
|
||||
style="color: var(--cRed);"
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="times"
|
||||
/>
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
class="faint"
|
||||
scope="global"
|
||||
>
|
||||
<a style="color: var(--faintLink)">
|
||||
<a style="color: var(--faintLink);">
|
||||
{{ $t('settings.style.preview.faint_link') }}
|
||||
</a>
|
||||
</i18n-t>
|
||||
|
|
@ -138,6 +138,7 @@ export default {}
|
|||
.preview-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.underlay-preview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
|
|||
|
|
@ -279,6 +279,9 @@ export default {
|
|||
opacity
|
||||
)
|
||||
|
||||
// Temporary patch for null-y value errors
|
||||
if (layers.flat().some(v => v == null)) return acc
|
||||
|
||||
return {
|
||||
...acc,
|
||||
...textColors.reduce((acc, textColorKey) => {
|
||||
|
|
@ -300,6 +303,7 @@ export default {
|
|||
return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
|
||||
} catch (e) {
|
||||
console.warn('Failure computing contrasts', e)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
previewRules () {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,17 @@
|
|||
@import 'src/_variables.scss';
|
||||
@import "src/variables";
|
||||
|
||||
.theme-tab {
|
||||
padding-bottom: 2em;
|
||||
.theme-warning {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-bottom: .5em;
|
||||
.buttons {
|
||||
.btn {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.preset-switcher {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-left: 0.25em;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
.style-control {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
|
@ -24,35 +21,37 @@
|
|||
flex: 1;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
input, select {
|
||||
opacity: .5
|
||||
}
|
||||
}
|
||||
|
||||
.opt {
|
||||
margin: .5em;
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
||||
.color-input {
|
||||
flex: 0 0 0;
|
||||
}
|
||||
|
||||
input, select {
|
||||
input,
|
||||
select {
|
||||
min-width: 3em;
|
||||
margin: 0;
|
||||
flex: 0;
|
||||
|
||||
&[type=number] {
|
||||
&[type="number"] {
|
||||
min-width: 5em;
|
||||
}
|
||||
|
||||
&[type=range] {
|
||||
&[type="range"] {
|
||||
flex: 1;
|
||||
min-width: 3em;
|
||||
align-self: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
input,
|
||||
select {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reset-container {
|
||||
|
|
@ -63,8 +62,7 @@
|
|||
.reset-container,
|
||||
.apply-container,
|
||||
.radius-container,
|
||||
.color-container,
|
||||
{
|
||||
.color-container, {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
|
@ -73,10 +71,11 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.color-container{
|
||||
.color-container {
|
||||
> h4 {
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
|
@ -100,7 +99,7 @@
|
|||
p {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
margin-right: .5em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,15 +111,16 @@
|
|||
min-width: 1px;
|
||||
flex: 0 auto;
|
||||
padding: 0 1em;
|
||||
margin-bottom: .5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.shadow-selector {
|
||||
.override {
|
||||
flex: 1;
|
||||
margin-left: .5em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.select-container {
|
||||
margin-top: -4px;
|
||||
margin-bottom: -3px;
|
||||
|
|
@ -136,7 +136,7 @@
|
|||
|
||||
.presets,
|
||||
.import-export {
|
||||
margin-bottom: .5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.import-export {
|
||||
|
|
@ -144,16 +144,17 @@
|
|||
}
|
||||
|
||||
.override {
|
||||
margin-left: .5em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.save-load-options {
|
||||
flex-wrap: wrap;
|
||||
margin-top: .5em;
|
||||
margin-top: 0.5em;
|
||||
justify-content: center;
|
||||
|
||||
.keep-option {
|
||||
margin: 0 .5em .5em;
|
||||
margin: 0 0.5em 0.5em;
|
||||
min-width: 25%;
|
||||
}
|
||||
}
|
||||
|
|
@ -179,11 +180,11 @@
|
|||
flex: 1;
|
||||
|
||||
h4 {
|
||||
margin-bottom: .25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
.icons {
|
||||
margin-top: .5em;
|
||||
margin-top: 0.5em;
|
||||
display: flex;
|
||||
|
||||
i {
|
||||
|
|
@ -199,8 +200,20 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.avatar, .avatar-alt{
|
||||
background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
|
||||
.avatar,
|
||||
.avatar-alt {
|
||||
background:
|
||||
linear-gradient(
|
||||
135deg,
|
||||
#b8e1fc 0%,
|
||||
#a9d2f3 10%,
|
||||
#90bae4 25%,
|
||||
#90bcea 37%,
|
||||
#90bff0 50%,
|
||||
#6ba8e5 51%,
|
||||
#a2daf5 83%,
|
||||
#bdf3fd 100%
|
||||
);
|
||||
color: black;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
|
|
@ -251,33 +264,33 @@
|
|||
}
|
||||
}
|
||||
|
||||
.radius-item {
|
||||
flex-basis: auto;
|
||||
}
|
||||
|
||||
.radius-item,
|
||||
.color-item {
|
||||
min-width: 20em;
|
||||
margin: 5px 6px 0 0;
|
||||
display:flex;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 0;
|
||||
|
||||
&.wide {
|
||||
min-width: 60%
|
||||
min-width: 60%;
|
||||
}
|
||||
|
||||
&:not(.wide):nth-child(2n+1) {
|
||||
margin-right: 7px;
|
||||
|
||||
}
|
||||
|
||||
.color, .opacity {
|
||||
display:flex;
|
||||
.color,
|
||||
.opacity {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
.radius-item {
|
||||
flex-basis: auto;
|
||||
}
|
||||
|
||||
.theme-radius-rn,
|
||||
.theme-color-cl {
|
||||
border: 0;
|
||||
|
|
@ -295,14 +308,11 @@
|
|||
|
||||
.theme-radius-in {
|
||||
min-width: 1em;
|
||||
}
|
||||
|
||||
.theme-radius-in {
|
||||
max-width: 7em;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.theme-radius-lb{
|
||||
.theme-radius-lb {
|
||||
max-width: 50em;
|
||||
}
|
||||
|
||||
|
|
@ -310,9 +320,16 @@
|
|||
padding: 20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-left: .25em;
|
||||
margin-right: .25em;
|
||||
.theme-warning {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
.buttons {
|
||||
.btn {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -323,6 +340,7 @@
|
|||
justify-content: space-around;
|
||||
flex-grow: 1;
|
||||
|
||||
/* stylelint-disable-next-line no-descending-specificity */
|
||||
.btn {
|
||||
flex-grow: 1;
|
||||
min-height: 2em;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue