Merge branch 'themes-accent' into 'develop'
Themes v3 Part 1 "2.1" codenamed "One step for themes, a giant burder for code reviewers" Closes #750 and #774 See merge request pleroma/pleroma-fe!1037
This commit is contained in:
commit
3ddf7ebe2c
118 changed files with 3087 additions and 3077 deletions
|
@ -130,6 +130,8 @@
|
|||
.placeholder {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 4px;
|
||||
color: $fallback--link;
|
||||
color: var(--postLink, $fallback--link);
|
||||
}
|
||||
|
||||
.nsfw-placeholder {
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
top: 100%;
|
||||
right: 0;
|
||||
max-height: 400px;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: $fallback--border;
|
||||
|
|
|
@ -87,13 +87,13 @@ export default {
|
|||
|
||||
&:checked + .checkbox-indicator::before {
|
||||
color: $fallback--text;
|
||||
color: var(--text, $fallback--text);
|
||||
color: var(--inputText, $fallback--text);
|
||||
}
|
||||
|
||||
&:indeterminate + .checkbox-indicator::before {
|
||||
content: '–';
|
||||
color: $fallback--text;
|
||||
color: var(--text, $fallback--text);
|
||||
color: var(--inputText, $fallback--text);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
68
src/components/color_input/color_input.scss
Normal file
68
src/components/color_input/color_input.scss
Normal file
|
@ -0,0 +1,68 @@
|
|||
@import '../../_variables.scss';
|
||||
|
||||
.color-input {
|
||||
display: inline-flex;
|
||||
|
||||
&-field.input {
|
||||
display: inline-flex;
|
||||
flex: 0 0 0;
|
||||
max-width: 9em;
|
||||
align-items: stretch;
|
||||
padding: .2em 8px;
|
||||
|
||||
input {
|
||||
background: none;
|
||||
color: $fallback--lightText;
|
||||
color: var(--inputText, $fallback--lightText);
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
&.textColor {
|
||||
flex: 1 0 3em;
|
||||
min-width: 3em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.nativeColor {
|
||||
flex: 0 0 2em;
|
||||
min-width: 2em;
|
||||
align-self: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.computedIndicator,
|
||||
.transparentIndicator {
|
||||
flex: 0 0 2em;
|
||||
min-width: 2em;
|
||||
align-self: center;
|
||||
height: 100%;
|
||||
}
|
||||
.transparentIndicator {
|
||||
// forgot to install counter-strike source, ooops
|
||||
background-color: #FF00FF;
|
||||
position: relative;
|
||||
&::before, &::after {
|
||||
display: block;
|
||||
content: '';
|
||||
background-color: #000000;
|
||||
position: absolute;
|
||||
height: 50%;
|
||||
width: 50%;
|
||||
}
|
||||
&::after {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
&::before {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
class="color-control style-control"
|
||||
class="color-input style-control"
|
||||
:class="{ disabled: !present || disabled }"
|
||||
>
|
||||
<label
|
||||
|
@ -9,46 +9,100 @@
|
|||
>
|
||||
{{ label }}
|
||||
</label>
|
||||
<input
|
||||
v-if="typeof fallback !== 'undefined'"
|
||||
:id="name + '-o'"
|
||||
class="opt exlcude-disabled"
|
||||
type="checkbox"
|
||||
<Checkbox
|
||||
v-if="typeof fallback !== 'undefined' && showOptionalTickbox"
|
||||
:checked="present"
|
||||
@input="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
|
||||
>
|
||||
<label
|
||||
v-if="typeof fallback !== 'undefined'"
|
||||
class="opt-l"
|
||||
:for="name + '-o'"
|
||||
:disabled="disabled"
|
||||
class="opt"
|
||||
@change="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
|
||||
/>
|
||||
<input
|
||||
:id="name"
|
||||
class="color-input"
|
||||
type="color"
|
||||
:value="value || fallback"
|
||||
:disabled="!present || disabled"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
>
|
||||
<input
|
||||
:id="name + '-t'"
|
||||
class="text-input"
|
||||
type="text"
|
||||
:value="value || fallback"
|
||||
:disabled="!present || disabled"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
>
|
||||
<div class="input color-input-field">
|
||||
<input
|
||||
:id="name + '-t'"
|
||||
class="textColor unstyled"
|
||||
type="text"
|
||||
:value="value || fallback"
|
||||
:disabled="!present || disabled"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
>
|
||||
<input
|
||||
v-if="validColor"
|
||||
:id="name"
|
||||
class="nativeColor unstyled"
|
||||
type="color"
|
||||
:value="value || fallback"
|
||||
:disabled="!present || disabled"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
>
|
||||
<div
|
||||
v-if="transparentColor"
|
||||
class="transparentIndicator"
|
||||
/>
|
||||
<div
|
||||
v-if="computedColor"
|
||||
class="computedIndicator"
|
||||
:style="{backgroundColor: fallback}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" src="./color_input.scss"></style>
|
||||
<script>
|
||||
import Checkbox from '../checkbox/checkbox.vue'
|
||||
import { hex2rgb } from '../../services/color_convert/color_convert.js'
|
||||
export default {
|
||||
props: [
|
||||
'name', 'label', 'value', 'fallback', 'disabled'
|
||||
],
|
||||
components: {
|
||||
Checkbox
|
||||
},
|
||||
props: {
|
||||
// Name of color, used for identifying
|
||||
name: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
// Readable label
|
||||
label: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
// Color value, should be required but vue cannot tell the difference
|
||||
// between "property missing" and "property set to undefined"
|
||||
value: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
// Color fallback to use when value is not defeind
|
||||
fallback: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
// Disable the control
|
||||
disabled: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// Show "optional" tickbox, for when value might become mandatory
|
||||
showOptionalTickbox: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
present () {
|
||||
return typeof this.value !== 'undefined'
|
||||
},
|
||||
validColor () {
|
||||
return hex2rgb(this.value || this.fallback)
|
||||
},
|
||||
transparentColor () {
|
||||
return this.value === 'transparent'
|
||||
},
|
||||
computedColor () {
|
||||
return this.value && this.value.startsWith('--')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,17 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
props: [
|
||||
'large', 'contrast'
|
||||
],
|
||||
props: {
|
||||
large: {
|
||||
required: false
|
||||
},
|
||||
// TODO: Make theme switcher compute theme initially so that contrast
|
||||
// component won't be called without contrast data
|
||||
contrast: {
|
||||
required: false,
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hint () {
|
||||
const levelVal = this.contrast.aaa ? 'aaa' : (this.contrast.aa ? 'aa' : 'bad')
|
||||
|
|
|
@ -75,18 +75,18 @@
|
|||
.dialog-modal-content {
|
||||
margin: 0;
|
||||
padding: 1rem 1rem;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.dialog-modal-footer {
|
||||
margin: 0;
|
||||
padding: .5em .5em;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
border-top: 1px solid $fallback--bg;
|
||||
border-top: 1px solid var(--bg, $fallback--bg);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
border-top: 1px solid $fallback--border;
|
||||
border-top: 1px solid var(--border, $fallback--border);
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
|
|
|
@ -109,10 +109,16 @@
|
|||
box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: var(--popupShadow);
|
||||
min-width: 75%;
|
||||
background: $fallback--bg;
|
||||
background: var(--bg, $fallback--bg);
|
||||
color: $fallback--lightText;
|
||||
color: var(--lightText, $fallback--lightText);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--popover, $fallback--bg);
|
||||
color: $fallback--link;
|
||||
color: var(--popoverText, $fallback--link);
|
||||
--faint: var(--popoverFaintText, $fallback--faint);
|
||||
--faintLink: var(--popoverFaintLink, $fallback--faint);
|
||||
--lightText: var(--popoverLightText, $fallback--lightText);
|
||||
--postLink: var(--popoverPostLink, $fallback--link);
|
||||
--postFaintLink: var(--popoverPostFaintLink, $fallback--link);
|
||||
--icon: var(--popoverIcon, $fallback--icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +163,12 @@
|
|||
|
||||
&.highlighted {
|
||||
background-color: $fallback--fg;
|
||||
background-color: var(--lightBg, $fallback--fg);
|
||||
background-color: var(--selectedMenuPopover, $fallback--fg);
|
||||
color: var(--selectedMenuPopoverText, $fallback--text);
|
||||
--faint: var(--selectedMenuPopoverFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuPopoverLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuPopoverIcon, $fallback--icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,15 @@
|
|||
left: 0;
|
||||
margin: 0 !important;
|
||||
z-index: 1;
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--popover, $fallback--bg);
|
||||
color: $fallback--link;
|
||||
color: var(--popoverText, $fallback--link);
|
||||
--lightText: var(--popoverLightText, $fallback--faint);
|
||||
--faint: var(--popoverFaintText, $fallback--faint);
|
||||
--faintLink: var(--popoverFaintLink, $fallback--faint);
|
||||
--lightText: var(--popoverLightText, $fallback--lightText);
|
||||
--icon: var(--popoverIcon, $fallback--icon);
|
||||
|
||||
.keep-open,
|
||||
.too-many-emoji {
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
}
|
||||
|
||||
.picked-reaction {
|
||||
border: 1px solid var(--link, $fallback--link);
|
||||
border: 1px solid var(--accent, $fallback--link);
|
||||
margin-left: -1px; // offset the border, can't use inset shadows either
|
||||
margin-right: calc(0.5em - 1px);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
exportData () {
|
||||
const stringified = JSON.stringify(this.exportObject) // Pretty-print and indent with 2 spaces
|
||||
const stringified = JSON.stringify(this.exportObject, null, 2) // Pretty-print and indent with 2 spaces
|
||||
|
||||
// Create an invisible link with a data url and simulate a click
|
||||
const e = document.createElement('a')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<button
|
||||
class="btn btn-default follow-button"
|
||||
:class="{ pressed: isPressed }"
|
||||
:class="{ toggled: isPressed }"
|
||||
:disabled="inProgress"
|
||||
:title="title"
|
||||
@click="onClick"
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
</div>
|
||||
<button
|
||||
class="btn btn-default btn-block"
|
||||
:class="{ pressed: showDropDown }"
|
||||
:class="{ toggled: showDropDown }"
|
||||
>
|
||||
{{ $t('user_card.admin_menu.moderation') }}
|
||||
</button>
|
||||
|
|
|
@ -100,13 +100,25 @@
|
|||
|
||||
&:hover {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
background-color: var(--selectedMenu, $fallback--lightBg);
|
||||
color: $fallback--link;
|
||||
color: var(--selectedMenuText, $fallback--link);
|
||||
--faint: var(--selectedMenuFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuIcon, $fallback--icon);
|
||||
}
|
||||
|
||||
&.router-link-active {
|
||||
font-weight: bolder;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
background-color: var(--selectedMenu, $fallback--lightBg);
|
||||
color: $fallback--text;
|
||||
color: var(--selectedMenuText, $fallback--text);
|
||||
--faint: var(--selectedMenuFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuIcon, $fallback--icon);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
|
|
|
@ -68,6 +68,9 @@
|
|||
a {
|
||||
color: var(--faintLink);
|
||||
}
|
||||
.status-content a {
|
||||
color: var(--postFaintLink);
|
||||
}
|
||||
}
|
||||
padding: 0;
|
||||
.media-body {
|
||||
|
|
|
@ -9,18 +9,12 @@
|
|||
>
|
||||
{{ $t('settings.style.common.opacity') }}
|
||||
</label>
|
||||
<input
|
||||
<Checkbox
|
||||
v-if="typeof fallback !== 'undefined'"
|
||||
:id="name + '-o'"
|
||||
class="opt exclude-disabled"
|
||||
type="checkbox"
|
||||
:checked="present"
|
||||
@input="$emit('input', !present ? fallback : undefined)"
|
||||
>
|
||||
<label
|
||||
v-if="typeof fallback !== 'undefined'"
|
||||
class="opt-l"
|
||||
:for="name + '-o'"
|
||||
:disabled="disabled"
|
||||
class="opt"
|
||||
@change="$emit('input', !present ? fallback : undefined)"
|
||||
/>
|
||||
<input
|
||||
:id="name"
|
||||
|
@ -37,7 +31,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Checkbox from '../checkbox/checkbox.vue'
|
||||
export default {
|
||||
components: {
|
||||
Checkbox
|
||||
},
|
||||
props: [
|
||||
'name', 'value', 'fallback', 'disabled'
|
||||
],
|
||||
|
|
|
@ -104,8 +104,10 @@
|
|||
.result-fill {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
color: $fallback--text;
|
||||
color: var(--pollText, $fallback--text);
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--linkBg, $fallback--lightBg);
|
||||
background-color: var(--poll, $fallback--lightBg);
|
||||
border-radius: $fallback--panelRadius;
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
top: 0;
|
||||
|
|
|
@ -9,7 +9,15 @@
|
|||
border-radius: $fallback--btnRadius;
|
||||
border-radius: var(--btnRadius, $fallback--btnRadius);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
background-color: var(--popover, $fallback--bg);
|
||||
color: $fallback--text;
|
||||
color: var(--popoverText, $fallback--text);
|
||||
--faint: var(--popoverFaintText, $fallback--faint);
|
||||
--faintLink: var(--popoverFaintLink, $fallback--faint);
|
||||
--lightText: var(--popoverLightText, $fallback--lightText);
|
||||
--postLink: var(--popoverPostLink, $fallback--link);
|
||||
--postFaintLink: var(--popoverPostFaintLink, $fallback--link);
|
||||
--icon: var(--popoverIcon, $fallback--icon);
|
||||
}
|
||||
|
||||
.popover-arrow {
|
||||
|
@ -129,6 +137,8 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
--btnText: var(--popoverText, $fallback--text);
|
||||
|
||||
&-icon {
|
||||
padding-left: 0.5rem;
|
||||
|
||||
|
@ -137,11 +147,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
// TODO: improve the look on breeze themes
|
||||
background-color: $fallback--fg;
|
||||
background-color: var(--btn, $fallback--fg);
|
||||
box-shadow: none;
|
||||
&:active, &:hover {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--selectedMenuPopover, $fallback--lightBg);
|
||||
color: $fallback--link;
|
||||
color: var(--selectedMenuPopoverText, $fallback--link);
|
||||
--faint: var(--selectedMenuPopoverFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuPopoverLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuPopoverIcon, $fallback--icon);
|
||||
i {
|
||||
color: var(--selectedMenuPopoverIcon, $fallback--icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<input
|
||||
v-if="typeof fallback !== 'undefined'"
|
||||
:id="name + '-o'"
|
||||
class="opt exclude-disabled"
|
||||
class="opt"
|
||||
type="checkbox"
|
||||
:checked="present"
|
||||
@input="$emit('input', !present ? fallback : undefined)"
|
||||
|
|
|
@ -68,7 +68,12 @@
|
|||
|
||||
&-item-selected-inner {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
background-color: var(--selectedMenu, $fallback--lightBg);
|
||||
color: var(--selectedMenuText, $fallback--text);
|
||||
--faint: var(--selectedMenuFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuIcon, $fallback--icon);
|
||||
}
|
||||
|
||||
&-header {
|
||||
|
|
|
@ -76,9 +76,9 @@
|
|||
<li>
|
||||
<Checkbox v-model="useStreamingApi">
|
||||
{{ $t('settings.useStreamingApi') }}
|
||||
<br/>
|
||||
<br>
|
||||
<small>
|
||||
{{ $t('settings.useStreamingApiWarning') }}
|
||||
{{ $t('settings.useStreamingApiWarning') }}
|
||||
</small>
|
||||
</Checkbox>
|
||||
</li>
|
||||
|
|
|
@ -3,6 +3,17 @@ import OpacityInput from '../opacity_input/opacity_input.vue'
|
|||
import { getCssShadow } from '../../services/style_setter/style_setter.js'
|
||||
import { hex2rgb } from '../../services/color_convert/color_convert.js'
|
||||
|
||||
const toModel = (object = {}) => ({
|
||||
x: 0,
|
||||
y: 0,
|
||||
blur: 0,
|
||||
spread: 0,
|
||||
inset: false,
|
||||
color: '#000000',
|
||||
alpha: 1,
|
||||
...object
|
||||
})
|
||||
|
||||
export default {
|
||||
// 'Value' and 'Fallback' can be undefined, but if they are
|
||||
// initially vue won't detect it when they become something else
|
||||
|
@ -15,7 +26,7 @@ export default {
|
|||
return {
|
||||
selectedId: 0,
|
||||
// TODO there are some bugs regarding display of array (it's not getting updated when deleting for some reason)
|
||||
cValue: this.value || this.fallback || []
|
||||
cValue: (this.value || this.fallback || []).map(toModel)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
@ -24,12 +35,12 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
add () {
|
||||
this.cValue.push(Object.assign({}, this.selected))
|
||||
this.cValue.push(toModel(this.selected))
|
||||
this.selectedId = this.cValue.length - 1
|
||||
},
|
||||
del () {
|
||||
this.cValue.splice(this.selectedId, 1)
|
||||
this.selectedId = this.cValue.length === 0 ? undefined : this.selectedId - 1
|
||||
this.selectedId = this.cValue.length === 0 ? undefined : Math.max(this.selectedId - 1, 0)
|
||||
},
|
||||
moveUp () {
|
||||
const movable = this.cValue.splice(this.selectedId, 1)[0]
|
||||
|
@ -46,19 +57,24 @@ export default {
|
|||
this.cValue = this.value || this.fallback
|
||||
},
|
||||
computed: {
|
||||
anyShadows () {
|
||||
return this.cValue.length > 0
|
||||
},
|
||||
anyShadowsFallback () {
|
||||
return this.fallback.length > 0
|
||||
},
|
||||
selected () {
|
||||
if (this.ready && this.cValue.length > 0) {
|
||||
if (this.ready && this.anyShadows) {
|
||||
return this.cValue[this.selectedId]
|
||||
} else {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
blur: 0,
|
||||
spread: 0,
|
||||
inset: false,
|
||||
color: '#000000',
|
||||
alpha: 1
|
||||
}
|
||||
return toModel({})
|
||||
}
|
||||
},
|
||||
currentFallback () {
|
||||
if (this.ready && this.anyShadowsFallback) {
|
||||
return this.fallback[this.selectedId]
|
||||
} else {
|
||||
return toModel({})
|
||||
}
|
||||
},
|
||||
moveUpValid () {
|
||||
|
@ -80,7 +96,7 @@ export default {
|
|||
},
|
||||
style () {
|
||||
return this.ready ? {
|
||||
boxShadow: getCssShadow(this.cValue)
|
||||
boxShadow: getCssShadow(this.fallback)
|
||||
} : {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,15 +191,20 @@
|
|||
v-model="selected.color"
|
||||
:disabled="!present"
|
||||
:label="$t('settings.style.common.color')"
|
||||
:fallback="currentFallback.color"
|
||||
:show-optional-tickbox="false"
|
||||
name="shadow"
|
||||
/>
|
||||
<OpacityInput
|
||||
v-model="selected.alpha"
|
||||
:disabled="!present"
|
||||
/>
|
||||
<p>
|
||||
{{ $t('settings.style.shadows.hint') }}
|
||||
</p>
|
||||
<i18n
|
||||
path="settings.style.shadows.hintV3"
|
||||
tag="p"
|
||||
>
|
||||
<code>--variable,mod</code>
|
||||
</i18n>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -223,7 +223,13 @@
|
|||
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6);
|
||||
box-shadow: var(--panelShadow);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
background-color: var(--popover, $fallback--bg);
|
||||
color: $fallback--link;
|
||||
color: var(--popoverText, $fallback--link);
|
||||
--faint: var(--popoverFaintText, $fallback--faint);
|
||||
--faintLink: var(--popoverFaintLink, $fallback--faint);
|
||||
--lightText: var(--popoverLightText, $fallback--lightText);
|
||||
--icon: var(--popoverIcon, $fallback--icon);
|
||||
|
||||
.button-icon:before {
|
||||
width: 1.1em;
|
||||
|
@ -289,7 +295,13 @@
|
|||
|
||||
&:hover {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
background-color: var(--selectedMenuPopover, $fallback--lightBg);
|
||||
color: $fallback--text;
|
||||
color: var(--selectedMenuPopoverText, $fallback--text);
|
||||
--faint: var(--selectedMenuPopoverFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuPopoverLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuPopoverIcon, $fallback--icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -468,7 +468,15 @@ $status-margin: 0.75em;
|
|||
|
||||
&_focused {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
background-color: var(--selectedPost, $fallback--lightBg);
|
||||
color: $fallback--text;
|
||||
color: var(--selectedPostText, $fallback--text);
|
||||
--lightText: var(--selectedPostLightText, $fallback--light);
|
||||
--faint: var(--selectedPostFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedPostFaintLink, $fallback--faint);
|
||||
--postLink: var(--selectedPostPostLink, $fallback--faint);
|
||||
--postFaintLink: var(--selectedPostFaintPostLink, $fallback--faint);
|
||||
--icon: var(--selectedPostIcon, $fallback--icon);
|
||||
}
|
||||
|
||||
.timeline & {
|
||||
|
@ -596,8 +604,6 @@ $status-margin: 0.75em;
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0 0.4em 0 0.2em;
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
}
|
||||
|
||||
.replies-separator {
|
||||
|
@ -659,6 +665,11 @@ $status-margin: 0.75em;
|
|||
line-height: 1.4em;
|
||||
white-space: pre-wrap;
|
||||
|
||||
a {
|
||||
color: $fallback--link;
|
||||
color: var(--postLink, $fallback--link);
|
||||
}
|
||||
|
||||
img, video {
|
||||
max-width: 100%;
|
||||
max-height: 400px;
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
img {
|
||||
height: 100%;
|
||||
&:hover {
|
||||
filter: drop-shadow(0 0 5px var(--link, $fallback--link));
|
||||
filter: drop-shadow(0 0 5px var(--accent, $fallback--link));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,101 +1,117 @@
|
|||
<template>
|
||||
<div class="panel dummy">
|
||||
<div class="panel-heading">
|
||||
<div class="title">
|
||||
{{ $t('settings.style.preview.header') }}
|
||||
<span class="badge badge-notification">
|
||||
99
|
||||
<div class="preview-container">
|
||||
<div class="underlay underlay-preview" />
|
||||
<div class="panel dummy">
|
||||
<div class="panel-heading">
|
||||
<div class="title">
|
||||
{{ $t('settings.style.preview.header') }}
|
||||
<span class="badge badge-notification">
|
||||
99
|
||||
</span>
|
||||
</div>
|
||||
<span class="faint">
|
||||
{{ $t('settings.style.preview.header_faint') }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="faint">
|
||||
{{ $t('settings.style.preview.header_faint') }}
|
||||
</span>
|
||||
<span class="alert error">
|
||||
{{ $t('settings.style.preview.error') }}
|
||||
</span>
|
||||
<button class="btn">
|
||||
{{ $t('settings.style.preview.button') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="panel-body theme-preview-content">
|
||||
<div class="post">
|
||||
<div class="avatar">
|
||||
( ͡° ͜ʖ ͡°)
|
||||
</div>
|
||||
<div class="content">
|
||||
<h4>
|
||||
{{ $t('settings.style.preview.content') }}
|
||||
</h4>
|
||||
|
||||
<i18n path="settings.style.preview.text">
|
||||
<code style="font-family: var(--postCodeFont)">
|
||||
{{ $t('settings.style.preview.mono') }}
|
||||
</code>
|
||||
<a style="color: var(--link)">
|
||||
{{ $t('settings.style.preview.link') }}
|
||||
</a>
|
||||
</i18n>
|
||||
|
||||
<div class="icons">
|
||||
<i
|
||||
style="color: var(--cBlue)"
|
||||
class="button-icon icon-reply"
|
||||
/>
|
||||
<i
|
||||
style="color: var(--cGreen)"
|
||||
class="button-icon icon-retweet"
|
||||
/>
|
||||
<i
|
||||
style="color: var(--cOrange)"
|
||||
class="button-icon icon-star"
|
||||
/>
|
||||
<i
|
||||
style="color: var(--cRed)"
|
||||
class="button-icon icon-cancel"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="after-post">
|
||||
<div class="avatar-alt">
|
||||
:^)
|
||||
</div>
|
||||
<div class="content">
|
||||
<i18n
|
||||
path="settings.style.preview.fine_print"
|
||||
tag="span"
|
||||
class="faint"
|
||||
>
|
||||
<a style="color: var(--faintLink)">
|
||||
{{ $t('settings.style.preview.faint_link') }}
|
||||
</a>
|
||||
</i18n>
|
||||
</div>
|
||||
</div>
|
||||
<div class="separator" />
|
||||
|
||||
<span class="alert error">
|
||||
{{ $t('settings.style.preview.error') }}
|
||||
</span>
|
||||
<input
|
||||
:value="$t('settings.style.preview.input')"
|
||||
type="text"
|
||||
>
|
||||
|
||||
<div class="actions">
|
||||
<span class="checkbox">
|
||||
<input
|
||||
id="preview_checkbox"
|
||||
checked="very yes"
|
||||
type="checkbox"
|
||||
>
|
||||
<label for="preview_checkbox">{{ $t('settings.style.preview.checkbox') }}</label>
|
||||
<span class="alert error">
|
||||
{{ $t('settings.style.preview.error') }}
|
||||
</span>
|
||||
<button class="btn">
|
||||
{{ $t('settings.style.preview.button') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="panel-body theme-preview-content">
|
||||
<div class="post">
|
||||
<div class="avatar still-image">
|
||||
( ͡° ͜ʖ ͡°)
|
||||
</div>
|
||||
<div class="content">
|
||||
<h4>
|
||||
{{ $t('settings.style.preview.content') }}
|
||||
</h4>
|
||||
|
||||
<i18n path="settings.style.preview.text">
|
||||
<code style="font-family: var(--postCodeFont)">
|
||||
{{ $t('settings.style.preview.mono') }}
|
||||
</code>
|
||||
<a style="color: var(--link)">
|
||||
{{ $t('settings.style.preview.link') }}
|
||||
</a>
|
||||
</i18n>
|
||||
|
||||
<div class="icons">
|
||||
<i
|
||||
style="color: var(--cBlue)"
|
||||
class="button-icon icon-reply"
|
||||
/>
|
||||
<i
|
||||
style="color: var(--cGreen)"
|
||||
class="button-icon icon-retweet"
|
||||
/>
|
||||
<i
|
||||
style="color: var(--cOrange)"
|
||||
class="button-icon icon-star"
|
||||
/>
|
||||
<i
|
||||
style="color: var(--cRed)"
|
||||
class="button-icon icon-cancel"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="after-post">
|
||||
<div class="avatar-alt">
|
||||
:^)
|
||||
</div>
|
||||
<div class="content">
|
||||
<i18n
|
||||
path="settings.style.preview.fine_print"
|
||||
tag="span"
|
||||
class="faint"
|
||||
>
|
||||
<a style="color: var(--faintLink)">
|
||||
{{ $t('settings.style.preview.faint_link') }}
|
||||
</a>
|
||||
</i18n>
|
||||
</div>
|
||||
</div>
|
||||
<div class="separator" />
|
||||
|
||||
<span class="alert error">
|
||||
{{ $t('settings.style.preview.error') }}
|
||||
</span>
|
||||
<input
|
||||
:value="$t('settings.style.preview.input')"
|
||||
type="text"
|
||||
>
|
||||
|
||||
<div class="actions">
|
||||
<span class="checkbox">
|
||||
<input
|
||||
id="preview_checkbox"
|
||||
checked="very yes"
|
||||
type="checkbox"
|
||||
>
|
||||
<label for="preview_checkbox">{{ $t('settings.style.preview.checkbox') }}</label>
|
||||
</span>
|
||||
<button class="btn">
|
||||
{{ $t('settings.style.preview.button') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.preview-container {
|
||||
position: relative;
|
||||
}
|
||||
.underlay-preview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,29 @@
|
|||
import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
|
||||
import { set, delete as del } from 'vue'
|
||||
import { generateColors, generateShadows, generateRadii, generateFonts, composePreset, getThemes } from '../../services/style_setter/style_setter.js'
|
||||
import {
|
||||
rgb2hex,
|
||||
hex2rgb,
|
||||
getContrastRatioLayers
|
||||
} from '../../services/color_convert/color_convert.js'
|
||||
import {
|
||||
DEFAULT_SHADOWS,
|
||||
generateColors,
|
||||
generateShadows,
|
||||
generateRadii,
|
||||
generateFonts,
|
||||
composePreset,
|
||||
getThemes,
|
||||
shadows2to3,
|
||||
colors2to3
|
||||
} from '../../services/style_setter/style_setter.js'
|
||||
import {
|
||||
SLOT_INHERITANCE
|
||||
} from '../../services/theme_data/pleromafe.js'
|
||||
import {
|
||||
CURRENT_VERSION,
|
||||
OPACITIES,
|
||||
getLayers,
|
||||
getOpacitySlot
|
||||
} from '../../services/theme_data/theme_data.service.js'
|
||||
import ColorInput from '../color_input/color_input.vue'
|
||||
import RangeInput from '../range_input/range_input.vue'
|
||||
import OpacityInput from '../opacity_input/opacity_input.vue'
|
||||
|
@ -24,11 +47,22 @@ const v1OnlyNames = [
|
|||
'cOrange'
|
||||
].map(_ => _ + 'ColorLocal')
|
||||
|
||||
const colorConvert = (color) => {
|
||||
if (color.startsWith('--') || color === 'transparent') {
|
||||
return color
|
||||
} else {
|
||||
return hex2rgb(color)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
availableStyles: [],
|
||||
selected: this.$store.getters.mergedConfig.theme,
|
||||
themeWarning: undefined,
|
||||
tempImportFile: undefined,
|
||||
engineVersion: 0,
|
||||
|
||||
previewShadows: {},
|
||||
previewColors: {},
|
||||
|
@ -45,51 +79,13 @@ export default {
|
|||
keepRoundness: false,
|
||||
keepFonts: false,
|
||||
|
||||
textColorLocal: '',
|
||||
linkColorLocal: '',
|
||||
...Object.keys(SLOT_INHERITANCE)
|
||||
.map(key => [key, ''])
|
||||
.reduce((acc, [key, val]) => ({ ...acc, [ key + 'ColorLocal' ]: val }), {}),
|
||||
|
||||
bgColorLocal: '',
|
||||
bgOpacityLocal: undefined,
|
||||
|
||||
fgColorLocal: '',
|
||||
fgTextColorLocal: undefined,
|
||||
fgLinkColorLocal: undefined,
|
||||
|
||||
btnColorLocal: undefined,
|
||||
btnTextColorLocal: undefined,
|
||||
btnOpacityLocal: undefined,
|
||||
|
||||
inputColorLocal: undefined,
|
||||
inputTextColorLocal: undefined,
|
||||
inputOpacityLocal: undefined,
|
||||
|
||||
panelColorLocal: undefined,
|
||||
panelTextColorLocal: undefined,
|
||||
panelLinkColorLocal: undefined,
|
||||
panelFaintColorLocal: undefined,
|
||||
panelOpacityLocal: undefined,
|
||||
|
||||
topBarColorLocal: undefined,
|
||||
topBarTextColorLocal: undefined,
|
||||
topBarLinkColorLocal: undefined,
|
||||
|
||||
alertErrorColorLocal: undefined,
|
||||
alertWarningColorLocal: undefined,
|
||||
|
||||
badgeOpacityLocal: undefined,
|
||||
badgeNotificationColorLocal: undefined,
|
||||
|
||||
borderColorLocal: undefined,
|
||||
borderOpacityLocal: undefined,
|
||||
|
||||
faintColorLocal: undefined,
|
||||
faintOpacityLocal: undefined,
|
||||
faintLinkColorLocal: undefined,
|
||||
|
||||
cRedColorLocal: '',
|
||||
cBlueColorLocal: '',
|
||||
cGreenColorLocal: '',
|
||||
cOrangeColorLocal: '',
|
||||
...Object.keys(OPACITIES)
|
||||
.map(key => [key, ''])
|
||||
.reduce((acc, [key, val]) => ({ ...acc, [ key + 'OpacityLocal' ]: val }), {}),
|
||||
|
||||
shadowSelected: undefined,
|
||||
shadowsLocal: {},
|
||||
|
@ -108,69 +104,105 @@ export default {
|
|||
created () {
|
||||
const self = this
|
||||
|
||||
getThemes().then((themesComplete) => {
|
||||
self.availableStyles = themesComplete
|
||||
})
|
||||
getThemes()
|
||||
.then((promises) => {
|
||||
return Promise.all(
|
||||
Object.entries(promises)
|
||||
.map(([k, v]) => v.then(res => [k, res]))
|
||||
)
|
||||
})
|
||||
.then(themes => themes.reduce((acc, [k, v]) => {
|
||||
if (v) {
|
||||
return {
|
||||
...acc,
|
||||
[k]: v
|
||||
}
|
||||
} else {
|
||||
return acc
|
||||
}
|
||||
}, {}))
|
||||
.then((themesComplete) => {
|
||||
self.availableStyles = themesComplete
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
this.normalizeLocalState(this.$store.getters.mergedConfig.customTheme)
|
||||
this.loadThemeFromLocalStorage()
|
||||
if (typeof this.shadowSelected === 'undefined') {
|
||||
this.shadowSelected = this.shadowsAvailable[0]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
themeWarningHelp () {
|
||||
if (!this.themeWarning) return
|
||||
const t = this.$t
|
||||
const pre = 'settings.style.switcher.help.'
|
||||
const {
|
||||
origin,
|
||||
themeEngineVersion,
|
||||
type,
|
||||
noActionsPossible
|
||||
} = this.themeWarning
|
||||
if (origin === 'file') {
|
||||
// Loaded v2 theme from file
|
||||
if (themeEngineVersion === 2 && type === 'wrong_version') {
|
||||
return t(pre + 'v2_imported')
|
||||
}
|
||||
if (themeEngineVersion > CURRENT_VERSION) {
|
||||
return t(pre + 'future_version_imported') + ' ' +
|
||||
(
|
||||
noActionsPossible
|
||||
? t(pre + 'snapshot_missing')
|
||||
: t(pre + 'snapshot_present')
|
||||
)
|
||||
}
|
||||
if (themeEngineVersion < CURRENT_VERSION) {
|
||||
return t(pre + 'future_version_imported') + ' ' +
|
||||
(
|
||||
noActionsPossible
|
||||
? t(pre + 'snapshot_missing')
|
||||
: t(pre + 'snapshot_present')
|
||||
)
|
||||
}
|
||||
} else if (origin === 'localStorage') {
|
||||
if (type === 'snapshot_source_mismatch') {
|
||||
return t(pre + 'snapshot_source_mismatch')
|
||||
}
|
||||
// FE upgraded from v2
|
||||
if (themeEngineVersion === 2) {
|
||||
return t(pre + 'upgraded_from_v2')
|
||||
}
|
||||
// Admin downgraded FE
|
||||
if (themeEngineVersion > CURRENT_VERSION) {
|
||||
return t(pre + 'fe_downgraded') + ' ' +
|
||||
(
|
||||
noActionsPossible
|
||||
? t(pre + 'migration_snapshot_ok')
|
||||
: t(pre + 'migration_snapshot_gone')
|
||||
)
|
||||
}
|
||||
// Admin upgraded FE
|
||||
if (themeEngineVersion < CURRENT_VERSION) {
|
||||
return t(pre + 'fe_upgraded') + ' ' +
|
||||
(
|
||||
noActionsPossible
|
||||
? t(pre + 'migration_snapshot_ok')
|
||||
: t(pre + 'migration_snapshot_gone')
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
selectedVersion () {
|
||||
return Array.isArray(this.selected) ? 1 : 2
|
||||
},
|
||||
currentColors () {
|
||||
return {
|
||||
bg: this.bgColorLocal,
|
||||
text: this.textColorLocal,
|
||||
link: this.linkColorLocal,
|
||||
|
||||
fg: this.fgColorLocal,
|
||||
fgText: this.fgTextColorLocal,
|
||||
fgLink: this.fgLinkColorLocal,
|
||||
|
||||
panel: this.panelColorLocal,
|
||||
panelText: this.panelTextColorLocal,
|
||||
panelLink: this.panelLinkColorLocal,
|
||||
panelFaint: this.panelFaintColorLocal,
|
||||
|
||||
input: this.inputColorLocal,
|
||||
inputText: this.inputTextColorLocal,
|
||||
|
||||
topBar: this.topBarColorLocal,
|
||||
topBarText: this.topBarTextColorLocal,
|
||||
topBarLink: this.topBarLinkColorLocal,
|
||||
|
||||
btn: this.btnColorLocal,
|
||||
btnText: this.btnTextColorLocal,
|
||||
|
||||
alertError: this.alertErrorColorLocal,
|
||||
alertWarning: this.alertWarningColorLocal,
|
||||
badgeNotification: this.badgeNotificationColorLocal,
|
||||
|
||||
faint: this.faintColorLocal,
|
||||
faintLink: this.faintLinkColorLocal,
|
||||
border: this.borderColorLocal,
|
||||
|
||||
cRed: this.cRedColorLocal,
|
||||
cBlue: this.cBlueColorLocal,
|
||||
cGreen: this.cGreenColorLocal,
|
||||
cOrange: this.cOrangeColorLocal
|
||||
}
|
||||
return Object.keys(SLOT_INHERITANCE)
|
||||
.map(key => [key, this[key + 'ColorLocal']])
|
||||
.reduce((acc, [key, val]) => ({ ...acc, [ key ]: val }), {})
|
||||
},
|
||||
currentOpacity () {
|
||||
return {
|
||||
bg: this.bgOpacityLocal,
|
||||
btn: this.btnOpacityLocal,
|
||||
input: this.inputOpacityLocal,
|
||||
panel: this.panelOpacityLocal,
|
||||
topBar: this.topBarOpacityLocal,
|
||||
border: this.borderOpacityLocal,
|
||||
faint: this.faintOpacityLocal
|
||||
}
|
||||
return Object.keys(OPACITIES)
|
||||
.map(key => [key, this[key + 'OpacityLocal']])
|
||||
.reduce((acc, [key, val]) => ({ ...acc, [ key ]: val }), {})
|
||||
},
|
||||
currentRadii () {
|
||||
return {
|
||||
|
@ -193,75 +225,66 @@ export default {
|
|||
},
|
||||
// This needs optimization maybe
|
||||
previewContrast () {
|
||||
if (!this.previewTheme.colors.bg) return {}
|
||||
const colors = this.previewTheme.colors
|
||||
const opacity = this.previewTheme.opacity
|
||||
if (!colors.bg) return {}
|
||||
const hints = (ratio) => ({
|
||||
text: ratio.toPrecision(3) + ':1',
|
||||
// AA level, AAA level
|
||||
aa: ratio >= 4.5,
|
||||
aaa: ratio >= 7,
|
||||
// same but for 18pt+ texts
|
||||
laa: ratio >= 3,
|
||||
laaa: ratio >= 4.5
|
||||
})
|
||||
try {
|
||||
if (!this.previewTheme.colors.bg) return {}
|
||||
const colors = this.previewTheme.colors
|
||||
const opacity = this.previewTheme.opacity
|
||||
if (!colors.bg) return {}
|
||||
const hints = (ratio) => ({
|
||||
text: ratio.toPrecision(3) + ':1',
|
||||
// AA level, AAA level
|
||||
aa: ratio >= 4.5,
|
||||
aaa: ratio >= 7,
|
||||
// same but for 18pt+ texts
|
||||
laa: ratio >= 3,
|
||||
laaa: ratio >= 4.5
|
||||
})
|
||||
const colorsConverted = Object.entries(colors).reduce((acc, [key, value]) => ({ ...acc, [key]: colorConvert(value) }), {})
|
||||
|
||||
// fgsfds :DDDD
|
||||
const fgs = {
|
||||
text: hex2rgb(colors.text),
|
||||
panelText: hex2rgb(colors.panelText),
|
||||
panelLink: hex2rgb(colors.panelLink),
|
||||
btnText: hex2rgb(colors.btnText),
|
||||
topBarText: hex2rgb(colors.topBarText),
|
||||
inputText: hex2rgb(colors.inputText),
|
||||
const ratios = Object.entries(SLOT_INHERITANCE).reduce((acc, [key, value]) => {
|
||||
const slotIsBaseText = key === 'text' || key === 'link'
|
||||
const slotIsText = slotIsBaseText || (
|
||||
typeof value === 'object' && value !== null && value.textColor
|
||||
)
|
||||
if (!slotIsText) return acc
|
||||
const { layer, variant } = slotIsBaseText ? { layer: 'bg' } : value
|
||||
const background = variant || layer
|
||||
const opacitySlot = getOpacitySlot(background)
|
||||
const textColors = [
|
||||
key,
|
||||
...(background === 'bg' ? ['cRed', 'cGreen', 'cBlue', 'cOrange'] : [])
|
||||
]
|
||||
|
||||
link: hex2rgb(colors.link),
|
||||
topBarLink: hex2rgb(colors.topBarLink),
|
||||
const layers = getLayers(
|
||||
layer,
|
||||
variant || layer,
|
||||
opacitySlot,
|
||||
colorsConverted,
|
||||
opacity
|
||||
)
|
||||
|
||||
red: hex2rgb(colors.cRed),
|
||||
green: hex2rgb(colors.cGreen),
|
||||
blue: hex2rgb(colors.cBlue),
|
||||
orange: hex2rgb(colors.cOrange)
|
||||
return {
|
||||
...acc,
|
||||
...textColors.reduce((acc, textColorKey) => {
|
||||
const newKey = slotIsBaseText
|
||||
? 'bg' + textColorKey[0].toUpperCase() + textColorKey.slice(1)
|
||||
: textColorKey
|
||||
return {
|
||||
...acc,
|
||||
[newKey]: getContrastRatioLayers(
|
||||
colorsConverted[textColorKey],
|
||||
layers,
|
||||
colorsConverted[textColorKey]
|
||||
)
|
||||
}
|
||||
}, {})
|
||||
}
|
||||
}, {})
|
||||
|
||||
return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
|
||||
} catch (e) {
|
||||
console.warn('Failure computing contrasts', e)
|
||||
}
|
||||
|
||||
const bgs = {
|
||||
bg: hex2rgb(colors.bg),
|
||||
btn: hex2rgb(colors.btn),
|
||||
panel: hex2rgb(colors.panel),
|
||||
topBar: hex2rgb(colors.topBar),
|
||||
input: hex2rgb(colors.input),
|
||||
alertError: hex2rgb(colors.alertError),
|
||||
alertWarning: hex2rgb(colors.alertWarning),
|
||||
badgeNotification: hex2rgb(colors.badgeNotification)
|
||||
}
|
||||
|
||||
/* This is a bit confusing because "bottom layer" used is text color
|
||||
* This is done to get worst case scenario when background below transparent
|
||||
* layer matches text color, making it harder to read the lower alpha is.
|
||||
*/
|
||||
const ratios = {
|
||||
bgText: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.text), fgs.text),
|
||||
bgLink: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.link), fgs.link),
|
||||
bgRed: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.red), fgs.red),
|
||||
bgGreen: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.green), fgs.green),
|
||||
bgBlue: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.blue), fgs.blue),
|
||||
bgOrange: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.orange), fgs.orange),
|
||||
|
||||
tintText: getContrastRatio(alphaBlend(bgs.bg, 0.5, fgs.panelText), fgs.text),
|
||||
|
||||
panelText: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
|
||||
panelLink: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelLink), fgs.panelLink),
|
||||
|
||||
btnText: getContrastRatio(alphaBlend(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
|
||||
|
||||
inputText: getContrastRatio(alphaBlend(bgs.input, opacity.input, fgs.inputText), fgs.inputText),
|
||||
|
||||
topBarText: getContrastRatio(alphaBlend(bgs.topBar, opacity.topBar, fgs.topBarText), fgs.topBarText),
|
||||
topBarLink: getContrastRatio(alphaBlend(bgs.topBar, opacity.topBar, fgs.topBarLink), fgs.topBarLink)
|
||||
}
|
||||
|
||||
return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
|
||||
},
|
||||
previewRules () {
|
||||
if (!this.preview.rules) return ''
|
||||
|
@ -272,7 +295,7 @@ export default {
|
|||
].join(';')
|
||||
},
|
||||
shadowsAvailable () {
|
||||
return Object.keys(this.previewTheme.shadows).sort()
|
||||
return Object.keys(DEFAULT_SHADOWS).sort()
|
||||
},
|
||||
currentShadowOverriden: {
|
||||
get () {
|
||||
|
@ -287,7 +310,7 @@ export default {
|
|||
}
|
||||
},
|
||||
currentShadowFallback () {
|
||||
return this.previewTheme.shadows[this.shadowSelected]
|
||||
return (this.previewTheme.shadows || {})[this.shadowSelected]
|
||||
},
|
||||
currentShadow: {
|
||||
get () {
|
||||
|
@ -309,27 +332,34 @@ export default {
|
|||
!this.keepColor
|
||||
)
|
||||
|
||||
const theme = {}
|
||||
const source = {
|
||||
themeEngineVersion: CURRENT_VERSION
|
||||
}
|
||||
|
||||
if (this.keepFonts || saveEverything) {
|
||||
theme.fonts = this.fontsLocal
|
||||
source.fonts = this.fontsLocal
|
||||
}
|
||||
if (this.keepShadows || saveEverything) {
|
||||
theme.shadows = this.shadowsLocal
|
||||
source.shadows = this.shadowsLocal
|
||||
}
|
||||
if (this.keepOpacity || saveEverything) {
|
||||
theme.opacity = this.currentOpacity
|
||||
source.opacity = this.currentOpacity
|
||||
}
|
||||
if (this.keepColor || saveEverything) {
|
||||
theme.colors = this.currentColors
|
||||
source.colors = this.currentColors
|
||||
}
|
||||
if (this.keepRoundness || saveEverything) {
|
||||
theme.radii = this.currentRadii
|
||||
source.radii = this.currentRadii
|
||||
}
|
||||
|
||||
const theme = {
|
||||
themeEngineVersion: CURRENT_VERSION,
|
||||
...this.previewTheme
|
||||
}
|
||||
|
||||
return {
|
||||
// To separate from other random JSON files and possible future theme formats
|
||||
_pleroma_theme_version: 2, theme
|
||||
// To separate from other random JSON files and possible future source formats
|
||||
_pleroma_theme_version: 2, theme, source
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -346,10 +376,128 @@ export default {
|
|||
Checkbox
|
||||
},
|
||||
methods: {
|
||||
loadTheme (
|
||||
{
|
||||
theme,
|
||||
source,
|
||||
_pleroma_theme_version: fileVersion
|
||||
},
|
||||
origin,
|
||||
forceUseSource = false
|
||||
) {
|
||||
this.dismissWarning()
|
||||
if (!source && !theme) {
|
||||
throw new Error('Can\'t load theme: empty')
|
||||
}
|
||||
const version = (origin === 'localStorage' && !theme.colors)
|
||||
? 'l1'
|
||||
: fileVersion
|
||||
const snapshotEngineVersion = (theme || {}).themeEngineVersion
|
||||
const themeEngineVersion = (source || {}).themeEngineVersion || 2
|
||||
const versionsMatch = themeEngineVersion === CURRENT_VERSION
|
||||
const sourceSnapshotMismatch = (
|
||||
theme !== undefined &&
|
||||
source !== undefined &&
|
||||
themeEngineVersion !== snapshotEngineVersion
|
||||
)
|
||||
// Force loading of source if user requested it or if snapshot
|
||||
// is unavailable
|
||||
const forcedSourceLoad = (source && forceUseSource) || !theme
|
||||
if (!(versionsMatch && !sourceSnapshotMismatch) &&
|
||||
!forcedSourceLoad &&
|
||||
version !== 'l1' &&
|
||||
origin !== 'defaults'
|
||||
) {
|
||||
if (sourceSnapshotMismatch && origin === 'localStorage') {
|
||||
this.themeWarning = {
|
||||
origin,
|
||||
themeEngineVersion,
|
||||
type: 'snapshot_source_mismatch'
|
||||
}
|
||||
} else if (!theme) {
|
||||
this.themeWarning = {
|
||||
origin,
|
||||
noActionsPossible: true,
|
||||
themeEngineVersion,
|
||||
type: 'no_snapshot_old_version'
|
||||
}
|
||||
} else if (!versionsMatch) {
|
||||
this.themeWarning = {
|
||||
origin,
|
||||
noActionsPossible: !source,
|
||||
themeEngineVersion,
|
||||
type: 'wrong_version'
|
||||
}
|
||||
}
|
||||
}
|
||||
this.normalizeLocalState(theme, version, source, forcedSourceLoad)
|
||||
},
|
||||
forceLoadLocalStorage () {
|
||||
this.loadThemeFromLocalStorage(true)
|
||||
},
|
||||
dismissWarning () {
|
||||
this.themeWarning = undefined
|
||||
this.tempImportFile = undefined
|
||||
},
|
||||
forceLoad () {
|
||||
const { origin } = this.themeWarning
|
||||
switch (origin) {
|
||||
case 'localStorage':
|
||||
this.loadThemeFromLocalStorage(true)
|
||||
break
|
||||
case 'file':
|
||||
this.onImport(this.tempImportFile, true)
|
||||
break
|
||||
}
|
||||
this.dismissWarning()
|
||||
},
|
||||
forceSnapshot () {
|
||||
const { origin } = this.themeWarning
|
||||
switch (origin) {
|
||||
case 'localStorage':
|
||||
this.loadThemeFromLocalStorage(false, true)
|
||||
break
|
||||
case 'file':
|
||||
console.err('Forcing snapshout from file is not supported yet')
|
||||
break
|
||||
}
|
||||
this.dismissWarning()
|
||||
},
|
||||
loadThemeFromLocalStorage (confirmLoadSource = false, forceSnapshot = false) {
|
||||
const {
|
||||
customTheme: theme,
|
||||
customThemeSource: source
|
||||
} = this.$store.getters.mergedConfig
|
||||
if (!theme && !source) {
|
||||
// Anon user or never touched themes
|
||||
this.loadTheme(
|
||||
this.$store.state.instance.themeData,
|
||||
'defaults',
|
||||
confirmLoadSource
|
||||
)
|
||||
} else {
|
||||
this.loadTheme(
|
||||
{
|
||||
theme,
|
||||
source: forceSnapshot ? theme : source
|
||||
},
|
||||
'localStorage',
|
||||
confirmLoadSource
|
||||
)
|
||||
}
|
||||
},
|
||||
setCustomTheme () {
|
||||
this.$store.dispatch('setOption', {
|
||||
name: 'customTheme',
|
||||
value: {
|
||||
themeEngineVersion: CURRENT_VERSION,
|
||||
...this.previewTheme
|
||||
}
|
||||
})
|
||||
this.$store.dispatch('setOption', {
|
||||
name: 'customThemeSource',
|
||||
value: {
|
||||
themeEngineVersion: CURRENT_VERSION,
|
||||
shadows: this.shadowsLocal,
|
||||
fonts: this.fontsLocal,
|
||||
opacity: this.currentOpacity,
|
||||
|
@ -358,21 +506,27 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
onImport (parsed) {
|
||||
if (parsed._pleroma_theme_version === 1) {
|
||||
this.normalizeLocalState(parsed, 1)
|
||||
} else if (parsed._pleroma_theme_version === 2) {
|
||||
this.normalizeLocalState(parsed.theme, 2)
|
||||
}
|
||||
updatePreviewColorsAndShadows () {
|
||||
this.previewColors = generateColors({
|
||||
opacity: this.currentOpacity,
|
||||
colors: this.currentColors
|
||||
})
|
||||
this.previewShadows = generateShadows(
|
||||
{ shadows: this.shadowsLocal, opacity: this.previewTheme.opacity, themeEngineVersion: this.engineVersion },
|
||||
this.previewColors.theme.colors,
|
||||
this.previewColors.mod
|
||||
)
|
||||
},
|
||||
onImport (parsed, forceSource = false) {
|
||||
this.tempImportFile = parsed
|
||||
this.loadTheme(parsed, 'file', forceSource)
|
||||
},
|
||||
importValidator (parsed) {
|
||||
const version = parsed._pleroma_theme_version
|
||||
return version >= 1 || version <= 2
|
||||
},
|
||||
clearAll () {
|
||||
const state = this.$store.getters.mergedConfig.customTheme
|
||||
const version = state.colors ? 2 : 'l1'
|
||||
this.normalizeLocalState(this.$store.getters.mergedConfig.customTheme, version)
|
||||
this.loadThemeFromLocalStorage()
|
||||
},
|
||||
|
||||
// Clears all the extra stuff when loading V1 theme
|
||||
|
@ -411,19 +565,37 @@ export default {
|
|||
|
||||
/**
|
||||
* This applies stored theme data onto form. Supports three versions of data:
|
||||
* v3 (version >= 3) - newest version of themes which supports snapshots for better compatiblity
|
||||
* v2 (version = 2) - newer version of themes.
|
||||
* v1 (version = 1) - older version of themes (import from file)
|
||||
* v1l (version = l1) - older version of theme (load from local storage)
|
||||
* v1 and v1l differ because of way themes were stored/exported.
|
||||
* @param {Object} input - input data
|
||||
* @param {Object} theme - theme data (snapshot)
|
||||
* @param {Number} version - version of data. 0 means try to guess based on data. "l1" means v1, locastorage type
|
||||
* @param {Object} source - theme source - this will be used if compatible
|
||||
* @param {Boolean} source - by default source won't be used if version doesn't match since it might render differently
|
||||
* this allows importing source anyway
|
||||
*/
|
||||
normalizeLocalState (input, version = 0) {
|
||||
const colors = input.colors || input
|
||||
normalizeLocalState (theme, version = 0, source, forceSource = false) {
|
||||
let input
|
||||
if (typeof source !== 'undefined') {
|
||||
if (forceSource || source.themeEngineVersion === CURRENT_VERSION) {
|
||||
input = source
|
||||
version = source.themeEngineVersion
|
||||
} else {
|
||||
input = theme
|
||||
}
|
||||
} else {
|
||||
input = theme
|
||||
}
|
||||
|
||||
const radii = input.radii || input
|
||||
const opacity = input.opacity
|
||||
const shadows = input.shadows || {}
|
||||
const fonts = input.fonts || {}
|
||||
const colors = !input.themeEngineVersion
|
||||
? colors2to3(input.colors || input)
|
||||
: input.colors || input
|
||||
|
||||
if (version === 0) {
|
||||
if (input.version) version = input.version
|
||||
|
@ -437,6 +609,8 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
this.engineVersion = version
|
||||
|
||||
// Stuff that differs between V1 and V2
|
||||
if (version === 1) {
|
||||
this.fgColorLocal = rgb2hex(colors.btn)
|
||||
|
@ -445,7 +619,7 @@ export default {
|
|||
|
||||
if (!this.keepColor) {
|
||||
this.clearV1()
|
||||
const keys = new Set(version !== 1 ? Object.keys(colors) : [])
|
||||
const keys = new Set(version !== 1 ? Object.keys(SLOT_INHERITANCE) : [])
|
||||
if (version === 1 || version === 'l1') {
|
||||
keys
|
||||
.add('bg')
|
||||
|
@ -457,7 +631,17 @@ export default {
|
|||
}
|
||||
|
||||
keys.forEach(key => {
|
||||
this[key + 'ColorLocal'] = rgb2hex(colors[key])
|
||||
const color = colors[key]
|
||||
const hex = rgb2hex(colors[key])
|
||||
this[key + 'ColorLocal'] = hex === '#aN' ? color : hex
|
||||
})
|
||||
}
|
||||
|
||||
if (opacity && !this.keepOpacity) {
|
||||
this.clearOpacity()
|
||||
Object.entries(opacity).forEach(([k, v]) => {
|
||||
if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
|
||||
this[k + 'OpacityLocal'] = v
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -472,7 +656,11 @@ export default {
|
|||
|
||||
if (!this.keepShadows) {
|
||||
this.clearShadows()
|
||||
this.shadowsLocal = shadows
|
||||
if (version === 2) {
|
||||
this.shadowsLocal = shadows2to3(shadows, this.previewTheme.opacity)
|
||||
} else {
|
||||
this.shadowsLocal = shadows
|
||||
}
|
||||
this.shadowSelected = this.shadowsAvailable[0]
|
||||
}
|
||||
|
||||
|
@ -480,14 +668,6 @@ export default {
|
|||
this.clearFonts()
|
||||
this.fontsLocal = fonts
|
||||
}
|
||||
|
||||
if (opacity && !this.keepOpacity) {
|
||||
this.clearOpacity()
|
||||
Object.entries(opacity).forEach(([k, v]) => {
|
||||
if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
|
||||
this[k + 'OpacityLocal'] = v
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -502,8 +682,9 @@ export default {
|
|||
},
|
||||
shadowsLocal: {
|
||||
handler () {
|
||||
if (Object.getOwnPropertyNames(this.previewColors).length === 1) return
|
||||
try {
|
||||
this.previewShadows = generateShadows({ shadows: this.shadowsLocal })
|
||||
this.updatePreviewColorsAndShadows()
|
||||
this.shadowsInvalid = false
|
||||
} catch (e) {
|
||||
this.shadowsInvalid = true
|
||||
|
@ -526,27 +707,24 @@ export default {
|
|||
},
|
||||
currentColors () {
|
||||
try {
|
||||
this.previewColors = generateColors({
|
||||
opacity: this.currentOpacity,
|
||||
colors: this.currentColors
|
||||
})
|
||||
this.updatePreviewColorsAndShadows()
|
||||
this.colorsInvalid = false
|
||||
this.shadowsInvalid = false
|
||||
} catch (e) {
|
||||
this.colorsInvalid = true
|
||||
this.shadowsInvalid = true
|
||||
console.warn(e)
|
||||
}
|
||||
},
|
||||
currentOpacity () {
|
||||
try {
|
||||
this.previewColors = generateColors({
|
||||
opacity: this.currentOpacity,
|
||||
colors: this.currentColors
|
||||
})
|
||||
this.updatePreviewColorsAndShadows()
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
},
|
||||
selected () {
|
||||
this.dismissWarning()
|
||||
if (this.selectedVersion === 1) {
|
||||
if (!this.keepRoundness) {
|
||||
this.clearRoundness()
|
||||
|
@ -573,7 +751,7 @@ export default {
|
|||
this.cOrangeColorLocal = this.selected[8]
|
||||
}
|
||||
} else if (this.selectedVersion >= 2) {
|
||||
this.normalizeLocalState(this.selected.theme, 2)
|
||||
this.normalizeLocalState(this.selected.theme, 2, this.selected.source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
@import '../../_variables.scss';
|
||||
.style-switcher {
|
||||
.theme-warning {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-bottom: .5em;
|
||||
.buttons {
|
||||
.btn {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
.preset-switcher {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
@ -15,26 +25,23 @@
|
|||
|
||||
&.disabled {
|
||||
input, select {
|
||||
&:not(.exclude-disabled) {
|
||||
opacity: .5
|
||||
}
|
||||
opacity: .5
|
||||
}
|
||||
}
|
||||
|
||||
.opt {
|
||||
margin: .5em;
|
||||
}
|
||||
|
||||
.color-input {
|
||||
flex: 0 0 0;
|
||||
}
|
||||
|
||||
input, select {
|
||||
min-width: 3em;
|
||||
margin: 0;
|
||||
flex: 0;
|
||||
|
||||
&[type=color] {
|
||||
padding: 1px;
|
||||
cursor: pointer;
|
||||
height: 29px;
|
||||
min-width: 2em;
|
||||
border: none;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
&[type=number] {
|
||||
min-width: 5em;
|
||||
}
|
||||
|
@ -42,13 +49,6 @@
|
|||
&[type=range] {
|
||||
flex: 1;
|
||||
min-width: 3em;
|
||||
}
|
||||
|
||||
&[type=checkbox] + label {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
&:not([type=number]):not([type=text]) {
|
||||
align-self: flex-start;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,53 @@
|
|||
<div class="style-switcher">
|
||||
<div class="presets-container">
|
||||
<div class="save-load">
|
||||
<export-import
|
||||
<div
|
||||
v-if="themeWarning"
|
||||
class="theme-warning"
|
||||
>
|
||||
<div class="alert warning">
|
||||
{{ themeWarningHelp }}
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<template v-if="themeWarning.type === 'snapshot_source_mismatch'">
|
||||
<button
|
||||
class="btn"
|
||||
@click="forceLoad"
|
||||
>
|
||||
{{ $t('settings.style.switcher.use_source') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
@click="forceSnapshot"
|
||||
>
|
||||
{{ $t('settings.style.switcher.use_snapshot') }}
|
||||
</button>
|
||||
</template>
|
||||
<template v-else-if="themeWarning.noActionsPossible">
|
||||
<button
|
||||
class="btn"
|
||||
@click="dismissWarning"
|
||||
>
|
||||
{{ $t('general.dismiss') }}
|
||||
</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button
|
||||
class="btn"
|
||||
@click="forceLoad"
|
||||
>
|
||||
{{ $t('settings.style.switcher.load_theme') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
@click="dismissWarning"
|
||||
>
|
||||
{{ $t('settings.style.switcher.keep_as_is') }}
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<ExportImport
|
||||
:export-object="exportedTheme"
|
||||
:export-label="$t("settings.export_theme")"
|
||||
:import-label="$t("settings.import_theme")"
|
||||
|
@ -27,8 +73,8 @@
|
|||
:key="style.name"
|
||||
:value="style"
|
||||
:style="{
|
||||
backgroundColor: style[1] || style.theme.colors.bg,
|
||||
color: style[3] || style.theme.colors.text
|
||||
backgroundColor: style[1] || (style.theme || style.source).colors.bg,
|
||||
color: style[3] || (style.theme || style.source).colors.text
|
||||
}"
|
||||
>
|
||||
{{ style[0] || style.name }}
|
||||
|
@ -38,7 +84,7 @@
|
|||
</label>
|
||||
</div>
|
||||
</template>
|
||||
</export-import>
|
||||
</ExportImport>
|
||||
</div>
|
||||
<div class="save-load-options">
|
||||
<span class="keep-option">
|
||||
|
@ -70,9 +116,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-container">
|
||||
<preview :style="previewRules" />
|
||||
</div>
|
||||
<preview :style="previewRules" />
|
||||
|
||||
<keep-alive>
|
||||
<tab-switcher key="style-tweak">
|
||||
|
@ -106,7 +150,7 @@
|
|||
<OpacityInput
|
||||
v-model="bgOpacityLocal"
|
||||
name="bgOpacity"
|
||||
:fallback="previewTheme.opacity.bg || 1"
|
||||
:fallback="previewTheme.opacity.bg"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="textColorLocal"
|
||||
|
@ -114,10 +158,19 @@
|
|||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.bgText" />
|
||||
<ColorInput
|
||||
v-model="accentColorLocal"
|
||||
name="accentColor"
|
||||
:fallback="previewTheme.colors.link"
|
||||
:label="$t('settings.accent')"
|
||||
:show-optional-tickbox="typeof linkColorLocal !== 'undefined'"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="linkColorLocal"
|
||||
name="linkColor"
|
||||
:fallback="previewTheme.colors.accent"
|
||||
:label="$t('settings.links')"
|
||||
:show-optional-tickbox="typeof accentColorLocal !== 'undefined'"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.bgLink" />
|
||||
</div>
|
||||
|
@ -148,13 +201,13 @@
|
|||
name="cRedColor"
|
||||
:label="$t('settings.cRed')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.bgRed" />
|
||||
<ContrastRatio :contrast="previewContrast.bgCRed" />
|
||||
<ColorInput
|
||||
v-model="cBlueColorLocal"
|
||||
name="cBlueColor"
|
||||
:label="$t('settings.cBlue')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.bgBlue" />
|
||||
<ContrastRatio :contrast="previewContrast.bgCBlue" />
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<ColorInput
|
||||
|
@ -162,13 +215,13 @@
|
|||
name="cGreenColor"
|
||||
:label="$t('settings.cGreen')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.bgGreen" />
|
||||
<ContrastRatio :contrast="previewContrast.bgCGreen" />
|
||||
<ColorInput
|
||||
v-model="cOrangeColorLocal"
|
||||
name="cOrangeColor"
|
||||
:label="$t('settings.cOrange')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.bgOrange" />
|
||||
<ContrastRatio :contrast="previewContrast.bgCOrange" />
|
||||
</div>
|
||||
<p>{{ $t('settings.theme_help_v2_2') }}</p>
|
||||
</div>
|
||||
|
@ -193,6 +246,14 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.post') }}</h4>
|
||||
<ColorInput
|
||||
v-model="postLinkColorLocal"
|
||||
name="postLinkColor"
|
||||
:fallback="previewTheme.colors.accent"
|
||||
:label="$t('settings.links')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.postLink" />
|
||||
<h4>{{ $t('settings.style.advanced_colors.alert') }}</h4>
|
||||
<ColorInput
|
||||
v-model="alertErrorColorLocal"
|
||||
|
@ -200,14 +261,53 @@
|
|||
:label="$t('settings.style.advanced_colors.alert_error')"
|
||||
:fallback="previewTheme.colors.alertError"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.alertError" />
|
||||
<ColorInput
|
||||
v-model="alertErrorTextColorLocal"
|
||||
name="alertErrorText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.alertErrorText"
|
||||
/>
|
||||
<ContrastRatio
|
||||
:contrast="previewContrast.alertErrorText"
|
||||
large="true"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="alertWarningColorLocal"
|
||||
name="alertWarning"
|
||||
:label="$t('settings.style.advanced_colors.alert_warning')"
|
||||
:fallback="previewTheme.colors.alertWarning"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.alertWarning" />
|
||||
<ColorInput
|
||||
v-model="alertWarningTextColorLocal"
|
||||
name="alertWarningText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.alertWarningText"
|
||||
/>
|
||||
<ContrastRatio
|
||||
:contrast="previewContrast.alertWarningText"
|
||||
large="true"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="alertNeutralColorLocal"
|
||||
name="alertNeutral"
|
||||
:label="$t('settings.style.advanced_colors.alert_neutral')"
|
||||
:fallback="previewTheme.colors.alertNeutral"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="alertNeutralTextColorLocal"
|
||||
name="alertNeutralText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.alertNeutralText"
|
||||
/>
|
||||
<ContrastRatio
|
||||
:contrast="previewContrast.alertNeutralText"
|
||||
large="true"
|
||||
/>
|
||||
<OpacityInput
|
||||
v-model="alertOpacityLocal"
|
||||
name="alertOpacity"
|
||||
:fallback="previewTheme.opacity.alert"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.badge') }}</h4>
|
||||
|
@ -217,19 +317,30 @@
|
|||
:label="$t('settings.style.advanced_colors.badge_notification')"
|
||||
:fallback="previewTheme.colors.badgeNotification"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="badgeNotificationTextColorLocal"
|
||||
name="badgeNotificationText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.badgeNotificationText"
|
||||
/>
|
||||
<ContrastRatio
|
||||
:contrast="previewContrast.badgeNotificationText"
|
||||
large="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.panel_header') }}</h4>
|
||||
<ColorInput
|
||||
v-model="panelColorLocal"
|
||||
name="panelColor"
|
||||
:fallback="fgColorLocal"
|
||||
:fallback="previewTheme.colors.panel"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<OpacityInput
|
||||
v-model="panelOpacityLocal"
|
||||
name="panelOpacity"
|
||||
:fallback="previewTheme.opacity.panel || 1"
|
||||
:fallback="previewTheme.opacity.panel"
|
||||
:disabled="panelColorLocal === 'transparent'"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="panelTextColorLocal"
|
||||
|
@ -239,7 +350,7 @@
|
|||
/>
|
||||
<ContrastRatio
|
||||
:contrast="previewContrast.panelText"
|
||||
large="1"
|
||||
large="true"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="panelLinkColorLocal"
|
||||
|
@ -249,7 +360,7 @@
|
|||
/>
|
||||
<ContrastRatio
|
||||
:contrast="previewContrast.panelLink"
|
||||
large="1"
|
||||
large="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
|
@ -257,7 +368,7 @@
|
|||
<ColorInput
|
||||
v-model="topBarColorLocal"
|
||||
name="topBarColor"
|
||||
:fallback="fgColorLocal"
|
||||
:fallback="previewTheme.colors.topBar"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<ColorInput
|
||||
|
@ -280,13 +391,14 @@
|
|||
<ColorInput
|
||||
v-model="inputColorLocal"
|
||||
name="inputColor"
|
||||
:fallback="fgColorLocal"
|
||||
:fallback="previewTheme.colors.input"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<OpacityInput
|
||||
v-model="inputOpacityLocal"
|
||||
name="inputOpacity"
|
||||
:fallback="previewTheme.opacity.input || 1"
|
||||
:fallback="previewTheme.opacity.input"
|
||||
:disabled="inputColorLocal === 'transparent'"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="inputTextColorLocal"
|
||||
|
@ -301,13 +413,14 @@
|
|||
<ColorInput
|
||||
v-model="btnColorLocal"
|
||||
name="btnColor"
|
||||
:fallback="fgColorLocal"
|
||||
:fallback="previewTheme.colors.btn"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<OpacityInput
|
||||
v-model="btnOpacityLocal"
|
||||
name="btnOpacity"
|
||||
:fallback="previewTheme.opacity.btn || 1"
|
||||
:fallback="previewTheme.opacity.btn"
|
||||
:disabled="btnColorLocal === 'transparent'"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="btnTextColorLocal"
|
||||
|
@ -316,6 +429,124 @@
|
|||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnText" />
|
||||
<ColorInput
|
||||
v-model="btnPanelTextColorLocal"
|
||||
name="btnPanelTextColor"
|
||||
:fallback="previewTheme.colors.btnPanelText"
|
||||
:label="$t('settings.style.advanced_colors.panel_header')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnPanelText" />
|
||||
<ColorInput
|
||||
v-model="btnTopBarTextColorLocal"
|
||||
name="btnTopBarTextColor"
|
||||
:fallback="previewTheme.colors.btnTopBarText"
|
||||
:label="$t('settings.style.advanced_colors.top_bar')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnTopBarText" />
|
||||
<h5>{{ $t('settings.style.advanced_colors.pressed') }}</h5>
|
||||
<ColorInput
|
||||
v-model="btnPressedColorLocal"
|
||||
name="btnPressedColor"
|
||||
:fallback="previewTheme.colors.btnPressed"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="btnPressedTextColorLocal"
|
||||
name="btnPressedTextColor"
|
||||
:fallback="previewTheme.colors.btnPressedText"
|
||||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnPressedText" />
|
||||
<ColorInput
|
||||
v-model="btnPressedPanelTextColorLocal"
|
||||
name="btnPressedPanelTextColor"
|
||||
:fallback="previewTheme.colors.btnPressedPanelText"
|
||||
:label="$t('settings.style.advanced_colors.panel_header')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnPressedPanelText" />
|
||||
<ColorInput
|
||||
v-model="btnPressedTopBarTextColorLocal"
|
||||
name="btnPressedTopBarTextColor"
|
||||
:fallback="previewTheme.colors.btnPressedTopBarText"
|
||||
:label="$t('settings.style.advanced_colors.top_bar')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnPressedTopBarText" />
|
||||
<h5>{{ $t('settings.style.advanced_colors.disabled') }}</h5>
|
||||
<ColorInput
|
||||
v-model="btnDisabledColorLocal"
|
||||
name="btnDisabledColor"
|
||||
:fallback="previewTheme.colors.btnDisabled"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="btnDisabledTextColorLocal"
|
||||
name="btnDisabledTextColor"
|
||||
:fallback="previewTheme.colors.btnDisabledText"
|
||||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="btnDisabledPanelTextColorLocal"
|
||||
name="btnDisabledPanelTextColor"
|
||||
:fallback="previewTheme.colors.btnDisabledPanelText"
|
||||
:label="$t('settings.style.advanced_colors.panel_header')"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="btnDisabledTopBarTextColorLocal"
|
||||
name="btnDisabledTopBarTextColor"
|
||||
:fallback="previewTheme.colors.btnDisabledTopBarText"
|
||||
:label="$t('settings.style.advanced_colors.top_bar')"
|
||||
/>
|
||||
<h5>{{ $t('settings.style.advanced_colors.toggled') }}</h5>
|
||||
<ColorInput
|
||||
v-model="btnToggledColorLocal"
|
||||
name="btnToggledColor"
|
||||
:fallback="previewTheme.colors.btnToggled"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="btnToggledTextColorLocal"
|
||||
name="btnToggledTextColor"
|
||||
:fallback="previewTheme.colors.btnToggledText"
|
||||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnToggledText" />
|
||||
<ColorInput
|
||||
v-model="btnToggledPanelTextColorLocal"
|
||||
name="btnToggledPanelTextColor"
|
||||
:fallback="previewTheme.colors.btnToggledPanelText"
|
||||
:label="$t('settings.style.advanced_colors.panel_header')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnToggledPanelText" />
|
||||
<ColorInput
|
||||
v-model="btnToggledTopBarTextColorLocal"
|
||||
name="btnToggledTopBarTextColor"
|
||||
:fallback="previewTheme.colors.btnToggledTopBarText"
|
||||
:label="$t('settings.style.advanced_colors.top_bar')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.btnToggledTopBarText" />
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.tabs') }}</h4>
|
||||
<ColorInput
|
||||
v-model="tabColorLocal"
|
||||
name="tabColor"
|
||||
:fallback="previewTheme.colors.tab"
|
||||
:label="$t('settings.background')"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="tabTextColorLocal"
|
||||
name="tabTextColor"
|
||||
:fallback="previewTheme.colors.tabText"
|
||||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.tabText" />
|
||||
<ColorInput
|
||||
v-model="tabActiveTextColorLocal"
|
||||
name="tabActiveTextColor"
|
||||
:fallback="previewTheme.colors.tabActiveText"
|
||||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.tabActiveText" />
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.borders') }}</h4>
|
||||
|
@ -328,7 +559,8 @@
|
|||
<OpacityInput
|
||||
v-model="borderOpacityLocal"
|
||||
name="borderOpacity"
|
||||
:fallback="previewTheme.opacity.border || 1"
|
||||
:fallback="previewTheme.opacity.border"
|
||||
:disabled="borderColorLocal === 'transparent'"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
|
@ -336,7 +568,7 @@
|
|||
<ColorInput
|
||||
v-model="faintColorLocal"
|
||||
name="faintColor"
|
||||
:fallback="previewTheme.colors.faint || 1"
|
||||
:fallback="previewTheme.colors.faint"
|
||||
:label="$t('settings.text')"
|
||||
/>
|
||||
<ColorInput
|
||||
|
@ -354,9 +586,146 @@
|
|||
<OpacityInput
|
||||
v-model="faintOpacityLocal"
|
||||
name="faintOpacity"
|
||||
:fallback="previewTheme.opacity.faint || 0.5"
|
||||
:fallback="previewTheme.opacity.faint"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.underlay') }}</h4>
|
||||
<ColorInput
|
||||
v-model="underlayColorLocal"
|
||||
name="underlay"
|
||||
:label="$t('settings.style.advanced_colors.underlay')"
|
||||
:fallback="previewTheme.colors.underlay"
|
||||
/>
|
||||
<OpacityInput
|
||||
v-model="underlayOpacityLocal"
|
||||
name="underlayOpacity"
|
||||
:fallback="previewTheme.opacity.underlay"
|
||||
:disabled="underlayOpacityLocal === 'transparent'"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.poll') }}</h4>
|
||||
<ColorInput
|
||||
v-model="pollColorLocal"
|
||||
name="poll"
|
||||
:label="$t('settings.background')"
|
||||
:fallback="previewTheme.colors.poll"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="pollTextColorLocal"
|
||||
name="pollText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.pollText"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.icons') }}</h4>
|
||||
<ColorInput
|
||||
v-model="iconColorLocal"
|
||||
name="icon"
|
||||
:label="$t('settings.style.advanced_colors.icons')"
|
||||
:fallback="previewTheme.colors.icon"
|
||||
/>
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.highlight') }}</h4>
|
||||
<ColorInput
|
||||
v-model="highlightColorLocal"
|
||||
name="highlight"
|
||||
:label="$t('settings.background')"
|
||||
:fallback="previewTheme.colors.highlight"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="highlightTextColorLocal"
|
||||
name="highlightText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.highlightText"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.highlightText" />
|
||||
<ColorInput
|
||||
v-model="highlightLinkColorLocal"
|
||||
name="highlightLink"
|
||||
:label="$t('settings.links')"
|
||||
:fallback="previewTheme.colors.highlightLink"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.highlightLink" />
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.popover') }}</h4>
|
||||
<ColorInput
|
||||
v-model="popoverColorLocal"
|
||||
name="popover"
|
||||
:label="$t('settings.background')"
|
||||
:fallback="previewTheme.colors.popover"
|
||||
/>
|
||||
<OpacityInput
|
||||
v-model="popoverOpacityLocal"
|
||||
name="popoverOpacity"
|
||||
:fallback="previewTheme.opacity.popover"
|
||||
:disabled="popoverOpacityLocal === 'transparent'"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="popoverTextColorLocal"
|
||||
name="popoverText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.popoverText"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.popoverText" />
|
||||
<ColorInput
|
||||
v-model="popoverLinkColorLocal"
|
||||
name="popoverLink"
|
||||
:label="$t('settings.links')"
|
||||
:fallback="previewTheme.colors.popoverLink"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.popoverLink" />
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.selectedPost') }}</h4>
|
||||
<ColorInput
|
||||
v-model="selectedPostColorLocal"
|
||||
name="selectedPost"
|
||||
:label="$t('settings.background')"
|
||||
:fallback="previewTheme.colors.selectedPost"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="selectedPostTextColorLocal"
|
||||
name="selectedPostText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.selectedPostText"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.selectedPostText" />
|
||||
<ColorInput
|
||||
v-model="selectedPostLinkColorLocal"
|
||||
name="selectedPostLink"
|
||||
:label="$t('settings.links')"
|
||||
:fallback="previewTheme.colors.selectedPostLink"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.selectedPostLink" />
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<h4>{{ $t('settings.style.advanced_colors.selectedMenu') }}</h4>
|
||||
<ColorInput
|
||||
v-model="selectedMenuColorLocal"
|
||||
name="selectedMenu"
|
||||
:label="$t('settings.background')"
|
||||
:fallback="previewTheme.colors.selectedMenu"
|
||||
/>
|
||||
<ColorInput
|
||||
v-model="selectedMenuTextColorLocal"
|
||||
name="selectedMenuText"
|
||||
:label="$t('settings.text')"
|
||||
:fallback="previewTheme.colors.selectedMenuText"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.selectedMenuText" />
|
||||
<ColorInput
|
||||
v-model="selectedMenuLinkColorLocal"
|
||||
name="selectedMenuLink"
|
||||
:label="$t('settings.links')"
|
||||
:fallback="previewTheme.colors.selectedMenuLink"
|
||||
/>
|
||||
<ContrastRatio :contrast="previewContrast.selectedMenuLink" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
@ -491,7 +860,7 @@
|
|||
{{ $t('settings.style.switcher.clear_all') }}
|
||||
</button>
|
||||
</div>
|
||||
<shadow-control
|
||||
<ShadowControl
|
||||
v-model="currentShadow"
|
||||
:ready="!!currentShadowFallback"
|
||||
:fallback="currentShadowFallback"
|
||||
|
|
|
@ -52,6 +52,11 @@
|
|||
margin-bottom: 6px - 99px;
|
||||
white-space: nowrap;
|
||||
|
||||
color: $fallback--text;
|
||||
color: var(--tabText, $fallback--text);
|
||||
background-color: $fallback--fg;
|
||||
background-color: var(--tab, $fallback--fg);
|
||||
|
||||
&:not(.active) {
|
||||
z-index: 4;
|
||||
|
||||
|
@ -63,6 +68,8 @@
|
|||
&.active {
|
||||
background: transparent;
|
||||
z-index: 5;
|
||||
color: $fallback--text;
|
||||
color: var(--tabActiveText, $fallback--text);
|
||||
}
|
||||
|
||||
img {
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
</ProgressButton>
|
||||
<ProgressButton
|
||||
v-else
|
||||
class="btn btn-default pressed"
|
||||
class="btn btn-default toggled"
|
||||
:click="unsubscribeUser"
|
||||
:title="$t('user_card.unsubscribe')"
|
||||
>
|
||||
|
@ -162,7 +162,7 @@
|
|||
<div>
|
||||
<button
|
||||
v-if="user.muted"
|
||||
class="btn btn-default btn-block pressed"
|
||||
class="btn btn-default btn-block toggled"
|
||||
@click="unmuteUser"
|
||||
>
|
||||
{{ $t('user_card.muted') }}
|
||||
|
@ -299,6 +299,11 @@
|
|||
&-bio {
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
color: $fallback--link;
|
||||
color: var(--postLink, $fallback--link);
|
||||
}
|
||||
|
||||
img {
|
||||
object-fit: contain;
|
||||
vertical-align: middle;
|
||||
|
@ -460,14 +465,13 @@
|
|||
color: var(--text, $fallback--text);
|
||||
}
|
||||
|
||||
// TODO use proper colors
|
||||
.staff {
|
||||
flex: none;
|
||||
text-transform: capitalize;
|
||||
color: $fallback--text;
|
||||
color: var(--btnText, $fallback--text);
|
||||
color: var(--alertNeutralText, $fallback--text);
|
||||
background-color: $fallback--fg;
|
||||
background-color: var(--btn, $fallback--fg);
|
||||
background-color: var(--alertNeutral, $fallback--fg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,12 +542,6 @@
|
|||
|
||||
button {
|
||||
margin: 0;
|
||||
|
||||
&.pressed {
|
||||
// TODO: This should be themed.
|
||||
border-bottom-color: rgba(255, 255, 255, 0.2);
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue