Merge branch 'feature/theming2' into shigusegubu

* feature/theming2:
  fallback for some weird case on my phone
  todo
  missing string
  some more themes, fixes
  localization strings, fixes
  making inset shadows work on avatars again
  fix retweeter avatar not getting proper shadow
  avatars shadows, also allows drop-shadow use
This commit is contained in:
Henry Jameson 2018-12-02 15:07:33 +03:00
commit 151d9767b2
13 changed files with 467 additions and 40 deletions

View file

@ -56,8 +56,8 @@
line-height: 0;
&.better-shadow {
box-shadow: none;
filter: drop-shadow(var(--avatarStatusShadowFilter))
box-shadow: var(--avatarStatusShadowInset);
filter: var(--avatarStatusShadowFilter)
}
&.animated::before {

View file

@ -14,6 +14,7 @@ export default {
data () {
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 || []
}
},

View file

@ -469,8 +469,8 @@
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
&.better-shadow {
box-shadow: none;
filter: drop-shadow(var(--avatarStatusShadowFilter))
box-shadow: var(--avatarStatusShadowInset);
filter: var(--avatarStatusShadowFilter)
}
}
@ -484,8 +484,8 @@
position: relative;
&.better-shadow {
box-shadow: none;
filter: drop-shadow(var(--avatarStatusShadowFilter))
box-shadow: var(--avatarStatusShadowInset);
filter: var(--avatarStatusShadowFilter)
}
img {

View file

@ -497,10 +497,9 @@ export default {
this.textColorLocal = rgb2hex(colors.fg)
}
this.clearV1()
const keys = new Set(version !== 1 ? Object.keys(colors) : [])
if (version === 1 || version === 'l1') {
// V1 ignores the rest
this.clearV1()
keys
.add('bg')
.add('link')

View file

@ -49,7 +49,7 @@
}
&:not([type=number]):not([type=text]) {
align-self: center;
align-self: flex-start;
}
}
}
@ -113,6 +113,7 @@
p {
flex: 1;
margin: 0;
margin-right: .5em;
}
margin-bottom: 1em;
@ -134,6 +135,12 @@
display: flex;
justify-content: center;
align-items: baseline;
flex-wrap: wrap;
.presets,
.import-export {
margin-bottom: .5em;
}
.import-export {
display: flex;
@ -148,7 +155,7 @@
flex-wrap: wrap;
margin-top: .5em;
span {
margin: 0 .5em;
margin: 0 .5em .5em;
}
}
@ -204,8 +211,8 @@
flex: 0 auto;
margin-left: 28px;
font-size: 12px;
width: 20px;
height: 20px;
min-width: 20px;
min-height: 20px;
line-height: 20px;
border-radius: $fallback--avatarAltRadius;
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);

View file

@ -2,7 +2,7 @@
<div class="style-switcher">
<div class="presets-container">
<div class="save-load">
<div>
<div class="presets">
{{$t('settings.presets')}}
<label for="preset-switcher" class='select'>
<select id="preset-switcher" v-model="selected" class="preset-switcher">
@ -83,7 +83,7 @@
</div>
<div class="content">
<h4>
Content
{{$t('settings.style.preview.content')}}
</h4>
<i18n path="settings.style.preview.text">
@ -224,7 +224,7 @@
</div>
<div class="color-item">
<h4>{{ $t('settings.style.advanced_colors.borders') }}</h4>
<ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
<ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" :label="$t('settings.style.common.color')"/>
<OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
</div>
<div class="color-item">
@ -282,12 +282,15 @@
<i18n path="settings.style.shadows.filter_hint.always_drop_shadow" tag="p">
<code>filter: drop-shadow()</code>
</i18n>
<i18n path="settings.style.shadows.filter_hint.text" tag="p">
<p>{{$t('settings.style.shadows.filter_hint.avatar_inset')}}</p>
<i18n path="settings.style.shadows.filter_hint.drop_shadow_syntax" tag="p">
<code>drop-shadow</code>
<code>spread-radius</code>
<code>inset</code>
</i18n>
<p>{{$t('settings.style.shadows.filter_hint.inset_ignored')}}</p>
<i18n path="settings.style.shadows.filter_hint.inset_classic" tag="p">
<code>box-shadow</code>
</i18n>
<p>{{$t('settings.style.shadows.filter_hint.spread_zero')}}</p>
</div>
</div>

View file

@ -160,8 +160,8 @@
object-fit: cover;
&.better-shadow {
box-shadow: none;
filter: drop-shadow(var(--avatarStatusShadowFilter))
box-shadow: var(--avatarShadowInset);
filter: var(--avatarShadowFilter)
}
&.animated::before {

View file

@ -207,7 +207,6 @@
"common_colors": {
"_tab_label": "Common",
"main": "Common colors",
"foreground": "Panel header, top bar, buttons, text fields",
"foreground_hint": "See \"Advanced\" tab for more detailed control",
"rgbo": "Icons, accents, badges"
},
@ -238,10 +237,10 @@
"hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
"filter_hint": {
"always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",
"text": "Please note that {0} does not support {1} parameter and {2} keyword.",
"drop_shadow_syntax": "{0} does not support {1} parameter and {2} keyword.",
"avatar_inset": "Please note that combining both inset and non-inset shadows on avatars might give unexpected results with transparent avatars.",
"spread_zero": "Shadows with spread > 0 will appear as if it was set to zero",
"inset_ignored": "Inset shadows using will be ignored",
"inset_substituted": "Inset shadows will be substituted with {1} equivalent"
"inset_classic": "Inset shadows will be using {0}"
},
"components": {
"panel": "Panel",
@ -273,6 +272,7 @@
},
"preview": {
"header": "Preview of header",
"content": "Content",
"error": "Example error",
"button": "Button",
"text": "A bunch of more {0} and {1}",

View file

@ -100,6 +100,7 @@
"import_followers_from_a_csv_file": "Импортировать читаемых из файла .csv",
"import_theme": "Загрузить Тему",
"inputRadius": "Поля ввода",
"checkboxRadius": "Чекбоксы",
"interfaceLanguage": "Язык интерфейса",
"limited_availability": "Не доступно в вашем браузере",
"links": "Ссылки",
@ -138,8 +139,118 @@
"text": "Текст",
"theme": "Тема",
"theme_help": "Используйте шестнадцатеричные коды цветов (#rrggbb) для настройки темы.",
"theme_help_v2_1": "Вы так же можете перепоределить цвета определенных компонентов нажав соотв. галочку. Используйте кнопку \"Очистить всё\" чтобы снять все переопределения",
"theme_help_v2_2": "Под некоторыми полями ввода это идикаторы контрастности, наведите на них мышью чтобы узнать больше. Приспользовании прозрачности контраст расчитывается для наихудшего варианта.",
"tooltipRadius": "Всплывающие подсказки/уведомления",
"user_settings": "Настройки пользователя"
"user_settings": "Настройки пользователя",
"style": {
"switcher": {
"keep_shadows": "Оставить тени",
"keep_opacity": "Оставить прозрачность",
"keep_roundness": "Оставить скругление",
"keep_fonts": "Оставить шрифты",
"save_load_hint": "Опции \"оставить...\" позволяют сохранить текущие настройки при выборе другой темы или импорта её из файла. Так же они влияют на то какие компоненты будут сохранены при экспорте темы. Когда все галочки сняты все компоненты будут экспортированы.",
"reset": "Сбросить",
"clear_all": "Очистить всё",
"clear_opacity": "Очистить прозрачность"
},
"common": {
"color": "Цвет",
"opacity": "Прозрачность",
"contrast": {
"hint": "Уровень контраста: {ratio}, что {level} {context}",
"level": {
"aa": "соответствует гайдлайну Level AA (минимальный)",
"aaa": "соответствует гайдлайну Level AAA (рекомендуемый)",
"bad": "не соответствует каким либо гайдлайнам"
},
"context": {
"18pt": "для крупного (18pt+) текста",
"text": "для текста"
}
}
},
"common_colors": {
"_tab_label": "Общие",
"main": "Общие цвета",
"foreground_hint": "См. вкладку \"Дополнительно\" для более детального контроля",
"rgbo": "Иконки, акценты, ярылки"
},
"advanced_colors": {
"_tab_label": "Дополнительно",
"alert": "Фон уведомлений",
"alert_error": "Ошибки",
"badge": "Фон значков",
"badge_notification": "Уведомления",
"panel_header": "Заголовок панели",
"top_bar": "Верняя полоска",
"borders": "Границы",
"buttons": "Кнопки",
"inputs": "Поля ввода",
"faint_text": "Маловажный текст"
},
"radii": {
"_tab_label": "Скругление"
},
"shadows": {
"_tab_label": "Светотень",
"component": "Компонент",
"override": "Переопределить",
"shadow_id": "Тень №{value}",
"blur": "Размытие",
"spread": "Разброс",
"inset": "Внутренняя",
"hint": "Для теней вы так же можете использовать --variable в качестве цвета чтобы использовать CSS3-переменные. В таком случае прозрачность работать не будет.",
"filter_hint": {
"always_drop_shadow": "Внимание, эта тень всегда использует {0} когда браузер поддерживает это",
"drop_shadow_syntax": "{0} не поддерживает параметр {1} и ключевое слово {2}",
"avatar_inset": "Одновременное использование внутренних и внешних теней на (прозрачных) аватарках может дать не те результаты что вы ожидаете",
"spread_zero": "Тени с разбросом > 0 будут выглядеть как если бы разброс установлен в 0",
"inset_classic": "Внутренние тени будут использовать {0}"
},
"components": {
"panel": "Панель",
"panelHeader": "Заголовок панели",
"topBar": "Верхняя полоска",
"avatar": "Аватарка (профиль)",
"avatarStatus": "Аватарка (в ленте)",
"popup": "Всплывающие подсказки",
"button": "Кнопки",
"buttonHover": "Кнопки (наведен курсор)",
"buttonPressed": "Кнопки (нажата)",
"buttonPressedHover": "Кнопки (нажата+наведен курсор)",
"input": "Поля ввода"
}
},
"fonts": {
"_tab_label": "Шрифты",
"help": "Выберите тип шрифта для использования в интерфейсе. При выборе варианта \"другой\" надо ввести название шрифта в точности как он называется в системе.",
"components": {
"interface": "Интерфейс",
"input": "Поля ввода",
"post": "Текст постов",
"postCode": "Моноширинный текст в посте (форматирование)"
},
"family": "Шрифт",
"size": "Размер (в пикселях)",
"weight": "Ширина",
"custom": "Другой"
},
"preview": {
"header": "Пример",
"content": "Контент",
"error": "Ошибка стоп 000",
"button": "Кнопка",
"text": "Еще немного {0} и масенькая {1}",
"mono": "контента",
"input": "Что нового?",
"faint_link": "Его придется убрать",
"fine_print": "Если проблемы остались — ваш гуртовщик мыши плохо стоит. {0}.",
"header_faint": "Все идет по плану",
"checkbox": "Я подтверждаю что не было ни единого разрыва",
"link": "ссылка"
}
}
},
"timeline": {
"collapse": "Свернуть",

View file

@ -94,20 +94,42 @@ const setColors = (input, commit) => {
commit('setOption', { name: 'colors', value: theme.colors })
}
const getCssShadow = (input) => {
const getCssShadow = (input, usesDropShadow) => {
if (input.length === 0) {
return 'none'
}
return input.map((shad) => [
shad.x,
shad.y,
shad.blur,
shad.spread
].map(_ => _ + 'px').concat([
getCssColor(shad.color, shad.alpha),
shad.inset ? 'inset' : ''
]).join(' ')).join(', ')
return input
.filter(_ => usesDropShadow ? _.inset : _)
.map((shad) => [
shad.x,
shad.y,
shad.blur,
shad.spread
].map(_ => _ + 'px').concat([
getCssColor(shad.color, shad.alpha),
shad.inset ? 'inset' : ''
]).join(' ')).join(', ')
}
const getCssShadowFilter = (input) => {
if (input.length === 0) {
return 'none'
}
return input
// drop-shadow doesn't support inset or spread
.filter((shad) => console.log(shad) || !shad.inset && Number(shad.spread) === 0)
.map((shad) => [
shad.x,
shad.y,
// drop-shadow's blur is twice as strong compared to box-shadow
shad.blur / 2
].map(_ => _ + 'px').concat([
getCssColor(shad.color, shad.alpha)
]).join(' '))
.map(_ => `drop-shadow(${_})`)
.join(' ')
}
const getCssShadowFilter = (input) => {
@ -201,10 +223,10 @@ const generateColors = (input) => {
colors.icon = mixrgb(colors.bg, colors.text)
colors.cBlue = col.cBlue
colors.cRed = col.cRed
colors.cGreen = col.cGreen
colors.cOrange = col.cOrange
colors.cBlue = col.cBlue || hex2rgb('#0000FF')
colors.cRed = col.cRed || hex2rgb('#FF0000')
colors.cGreen = col.cGreen || hex2rgb('#00FF00')
colors.cOrange = col.cOrange || hex2rgb('#E3FF00')
colors.alertError = col.alertError || Object.assign({}, col.cRed)
colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)
@ -406,7 +428,11 @@ const generateShadows = (input) => {
.entries(shadows)
// TODO for v2.1: if shadow doesn't have non-inset shadows with spread > 0 - optionally
// convert all non-inset shadows into filter: drop-shadow() to boost performance
.map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}; --${k}ShadowFilter: ${getCssShadowFilter(v)}`)
.map(([k, v]) => [
`--${k}Shadow: ${getCssShadow(v)}`,
`--${k}ShadowFilter: ${getCssShadowFilter(v)}`,
`--${k}ShadowInset: ${getCssShadow(v, true)}`
].join(';'))
.join(';')
},
theme: {

View file

@ -11,5 +11,7 @@
"redmond-xx": "./static/themes/redmond-xx.json",
"redmond-xx-se": "./static/themes/redmond-xx-se.json",
"redmond-xxi": "./static/themes/redmond-xxi.json"
"redmond-xxi": "./static/themes/redmond-xxi.json",
"breezy-dark": "./static/themes/breezy-dark.json",
"breezy-light": "./static/themes/breezy-light.json"
}

View file

@ -0,0 +1,139 @@
{
"_pleroma_theme_version": 2,
"name": "Breezy Dark (beta)",
"theme": {
"shadows": {
"panel": [
{
"x": "1",
"y": "2",
"blur": "6",
"spread": 0,
"color": "#000000",
"alpha": 0.6
}
],
"button": [
{
"x": 0,
"y": "0",
"blur": "0",
"spread": "1",
"color": "#ffffff",
"alpha": "0.15",
"inset": true
},
{
"x": "1",
"y": "1",
"blur": "1",
"spread": 0,
"color": "#000000",
"alpha": "0.3",
"inset": false
}
],
"panelHeader": [
{
"x": 0,
"y": "40",
"blur": "40",
"spread": "-40",
"inset": true,
"color": "#ffffff",
"alpha": "0.1"
}
],
"buttonHover": [
{
"x": 0,
"y": "0",
"blur": 0,
"spread": "1",
"color": "--link",
"alpha": "0.3",
"inset": true
},
{
"x": "1",
"y": "1",
"blur": "1",
"spread": 0,
"color": "#000000",
"alpha": "0.3",
"inset": false
}
],
"buttonPressed": [
{
"x": 0,
"y": 0,
"blur": "0",
"spread": "50",
"color": "--faint",
"alpha": 1,
"inset": true
},
{
"x": 0,
"y": "0",
"blur": 0,
"spread": "1",
"color": "#ffffff",
"alpha": 0.2,
"inset": true
},
{
"x": "1",
"y": "1",
"blur": 0,
"spread": 0,
"color": "#000000",
"alpha": "0.3",
"inset": false
}
],
"input": [
{
"x": 0,
"y": "0",
"blur": 0,
"spread": "1",
"color": "#FFFFFF",
"alpha": "0.2",
"inset": true
}
]
},
"fonts": {},
"opacity": {
"input": "1",
"panel": "0"
},
"colors": {
"bg": "#31363b",
"text": "#eff0f1",
"link": "#3daee9",
"fg": "#31363b",
"panel": "#31363b",
"input": "#232629",
"topBarLink": "#eff0f1",
"btn": "#31363b",
"border": "#4c545b",
"cRed": "#da4453",
"cBlue": "#3daee9",
"cGreen": "#27ae60",
"cOrange": "#f67400"
},
"radii": {
"btn": "2",
"input": "2",
"checkbox": "1",
"panel": "2",
"avatar": "2",
"avatarAlt": "2",
"tooltip": "2",
"attachment": "2"
}
}
}

View file

@ -0,0 +1,139 @@
{
"_pleroma_theme_version": 2,
"name": "Breezy Light (beta)",
"theme": {
"shadows": {
"panel": [
{
"x": "1",
"y": "2",
"blur": "6",
"spread": 0,
"color": "#000000",
"alpha": 0.6
}
],
"button": [
{
"x": 0,
"y": "0",
"blur": "0",
"spread": "1",
"color": "#000000",
"alpha": "0.3",
"inset": true
},
{
"x": "1",
"y": "1",
"blur": "1",
"spread": 0,
"color": "#000000",
"alpha": "0.3",
"inset": false
}
],
"panelHeader": [
{
"x": 0,
"y": "40",
"blur": "40",
"spread": "-40",
"inset": true,
"color": "#ffffff",
"alpha": "0.1"
}
],
"buttonHover": [
{
"x": 0,
"y": "0",
"blur": 0,
"spread": "1",
"color": "--link",
"alpha": "0.3",
"inset": true
},
{
"x": "1",
"y": "1",
"blur": "1",
"spread": 0,
"color": "#000000",
"alpha": "0.3",
"inset": false
}
],
"buttonPressed": [
{
"x": 0,
"y": 0,
"blur": "0",
"spread": "50",
"color": "--faint",
"alpha": 1,
"inset": true
},
{
"x": 0,
"y": "0",
"blur": 0,
"spread": "1",
"color": "#ffffff",
"alpha": 0.2,
"inset": true
},
{
"x": "1",
"y": "1",
"blur": 0,
"spread": 0,
"color": "#000000",
"alpha": "0.3",
"inset": false
}
],
"input": [
{
"x": 0,
"y": "0",
"blur": 0,
"spread": "1",
"color": "#000000",
"alpha": "0.2",
"inset": true
}
]
},
"fonts": {},
"opacity": {
"input": "1"
},
"colors": {
"bg": "#eff0f1",
"text": "#232627",
"link": "#2980b9",
"fg": "#bcc2c7",
"panel": "#475057",
"panelText": "#fcfcfc",
"input": "#fcfcfc",
"topBar": "#475057",
"topBarLink": "#eff0f1",
"btn": "#eff0f1",
"cRed": "#da4453",
"cBlue": "#2980b9",
"cGreen": "#27ae60",
"cOrange": "#f67400"
},
"radii": {
"btn": "2",
"input": "2",
"checkbox": "1",
"panel": "2",
"avatar": "2",
"avatarAlt": "2",
"tooltip": "2",
"attachment": "2"
}
}
}