logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 3e7e31d4a98f4cbdfdd3c92d952e58616c027beb
parent 6b80ce122f18633b11fa43ec19ee74aeb5578f6b
Author: Alexander Tumin <iamtakingiteasy@eientei.org>
Date:   Sun,  5 Jun 2022 17:10:44 +0300

Allow column width configuration
Group column configuration in settings
Column width configuration: do not act on defaults

Diffstat:

Msrc/App.scss19++++++++++++++++---
Msrc/boot/after_store.js4+++-
Msrc/components/settings_modal/helpers/boolean_setting.js3+++
Msrc/components/settings_modal/helpers/boolean_setting.vue7++++++-
Msrc/components/settings_modal/helpers/choice_setting.js3+++
Msrc/components/settings_modal/helpers/choice_setting.vue5++++-
Msrc/components/settings_modal/helpers/integer_setting.js3+++
Msrc/components/settings_modal/helpers/integer_setting.vue5++++-
Asrc/components/settings_modal/helpers/size_setting.js67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/settings_modal/helpers/size_setting.vue54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/settings_modal/tabs/general_tab.js16++++++++++++++++
Msrc/components/settings_modal/tabs/general_tab.vue38+++++++++++++-------------------------
Msrc/i18n/en.json5+++++
Msrc/i18n/ru.json9+++++++++
Msrc/modules/config.js9+++++++--
Msrc/services/style_setter/style_setter.js31+++++++++++++++++++++++++++++++
16 files changed, 244 insertions(+), 34 deletions(-)

diff --git a/src/App.scss b/src/App.scss @@ -186,9 +186,13 @@ nav { --columnGap: 1em; --status-margin: 0.75em; + --effectiveContentColumnWidth: minmax(var(--miniColumn), var(--contentColumnWidth, var(--maxiColumn))); + position: relative; display: grid; - grid-template-columns: var(--miniColumn) var(--maxiColumn); + grid-template-columns: + var(--sidebarColumnWidth, var(--miniColumn)) + var(--effectiveContentColumnWidth); grid-template-areas: "sidebar content"; grid-template-rows: 1fr; box-sizing: border-box; @@ -282,15 +286,24 @@ nav { } &.-reverse:not(.-wide):not(.-mobile) { - grid-template-columns: var(--maxiColumn) var(--miniColumn); + grid-template-columns: + var(--effectiveContentColumnWidth) + minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn))); grid-template-areas: "content sidebar"; } &.-wide { - grid-template-columns: var(--miniColumn) var(--maxiColumn) var(--miniColumn); + grid-template-columns: + minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn))) + var(--effectiveContentColumnWidth) + minmax(var(--miniColumn), var(--notifsColumnWidth, var(--miniColumn))); grid-template-areas: "sidebar content notifs"; &.-reverse { + grid-template-columns: + minmax(var(--miniColumn), var(--notifsColumnWidth, var(--miniColumn))) + var(--effectiveContentColumnWidth) + minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn))); grid-template-areas: "notifs content sidebar"; } } diff --git a/src/boot/after_store.js b/src/boot/after_store.js @@ -12,7 +12,7 @@ import { windowWidth, windowHeight } from '../services/window_utils/window_utils import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js' import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' -import { applyTheme } from '../services/style_setter/style_setter.js' +import { applyTheme, applyConfig } from '../services/style_setter/style_setter.js' import FaviconService from '../services/favicon_service/favicon_service.js' let staticInitialResults = null @@ -360,6 +360,8 @@ const afterStoreSetup = async ({ store, i18n }) => { console.error('Failed to load any theme!') } + applyConfig(store.state.config) + // Now we can try getting the server settings and logging in // Most of these are preloaded into the index.html so blocking is minimized await Promise.all([ diff --git a/src/components/settings_modal/helpers/boolean_setting.js b/src/components/settings_modal/helpers/boolean_setting.js @@ -42,6 +42,9 @@ export default { methods: { update (e) { set(this.$parent, this.path, e) + }, + reset () { + set(this.$parent, this.path, this.defaultState) } } } diff --git a/src/components/settings_modal/helpers/boolean_setting.vue b/src/components/settings_modal/helpers/boolean_setting.vue @@ -15,7 +15,12 @@ <slot /> </span> {{ ' ' }} - <ModifiedIndicator :changed="isChanged" /><ServerSideIndicator :server-side="isServerSide" /> </Checkbox> + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> + <ServerSideIndicator :server-side="isServerSide" /> + </Checkbox> </label> </template> diff --git a/src/components/settings_modal/helpers/choice_setting.js b/src/components/settings_modal/helpers/choice_setting.js @@ -43,6 +43,9 @@ export default { methods: { update (e) { set(this.$parent, this.path, e) + }, + reset () { + set(this.$parent, this.path, this.defaultState) } } } diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue @@ -19,7 +19,10 @@ {{ option.value === defaultState ? $t('settings.instance_default_simple') : '' }} </option> </Select> - <ModifiedIndicator :changed="isChanged" /> + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> <ServerSideIndicator :server-side="isServerSide" /> </label> </template> diff --git a/src/components/settings_modal/helpers/integer_setting.js b/src/components/settings_modal/helpers/integer_setting.js @@ -36,6 +36,9 @@ export default { methods: { update (e) { set(this.$parent, this.path, parseInt(e.target.value)) + }, + reset () { + set(this.$parent, this.path, this.defaultState) } } } diff --git a/src/components/settings_modal/helpers/integer_setting.vue b/src/components/settings_modal/helpers/integer_setting.vue @@ -17,7 +17,10 @@ @change="update" > {{ ' ' }} - <ModifiedIndicator :changed="isChanged" /> + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> </span> </template> diff --git a/src/components/settings_modal/helpers/size_setting.js b/src/components/settings_modal/helpers/size_setting.js @@ -0,0 +1,67 @@ +import { get, set } from 'lodash' +import ModifiedIndicator from './modified_indicator.vue' +import Select from 'src/components/select/select.vue' + +export const allCssUnits = ['cm', 'mm', 'in', 'px', 'pt', 'pc', 'em', 'ex', 'ch', 'rem', 'vw', 'vh', 'vmin', 'vmax', '%'] +export const defaultHorizontalUnits = ['px', 'rem', 'vw'] +export const defaultVerticalUnits = ['px', 'rem', 'vh'] + +export default { + components: { + ModifiedIndicator, + Select + }, + props: { + path: String, + disabled: Boolean, + min: Number, + units: { + type: [String], + default: () => allCssUnits + }, + expert: [Number, String] + }, + computed: { + pathDefault () { + const [firstSegment, ...rest] = this.path.split('.') + return [firstSegment + 'DefaultValue', ...rest].join('.') + }, + stateUnit () { + return (this.state || '').replace(/\d+/, '') + }, + stateValue () { + return (this.state || '').replace(/\D+/, '') + }, + state () { + const value = get(this.$parent, this.path) + if (value === undefined) { + return this.defaultState + } else { + return value + } + }, + defaultState () { + return get(this.$parent, this.pathDefault) + }, + isChanged () { + return this.state !== this.defaultState + }, + matchesExpertLevel () { + return (this.expert || 0) <= this.$parent.expertLevel + } + }, + methods: { + update (e) { + set(this.$parent, this.path, e) + }, + reset () { + set(this.$parent, this.path, this.defaultState) + }, + updateValue (e) { + set(this.$parent, this.path, parseInt(e.target.value) + this.stateUnit) + }, + updateUnit (e) { + set(this.$parent, this.path, this.stateValue + e.target.value) + } + } +} diff --git a/src/components/settings_modal/helpers/size_setting.vue b/src/components/settings_modal/helpers/size_setting.vue @@ -0,0 +1,54 @@ +<template> + <span + v-if="matchesExpertLevel" + class="SizeSetting" + > + <label + :for="path" + class="size-label" + > + <slot /> + </label> + <input + :id="path" + class="number-input" + type="number" + step="1" + :disabled="disabled" + :min="min || 0" + :value="stateValue" + @change="updateValue" + > + <Select + :id="path" + :model-value="stateUnit" + :disabled="disabled" + class="css-unit-input" + @change="updateUnit" + > + <option + v-for="option in units" + :key="option" + :value="option" + > + {{ option }} + </option> + </Select> + {{ ' ' }} + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> + </span> +</template> + +<script src="./size_setting.js"></script> + +<style lang="scss"> +.css-unit-input, .css-unit-input select { + margin-left: 0.5em; + width: 4em !important; + max-width: 4em !important; + min-width: 4em !important; +} +</style> diff --git a/src/components/settings_modal/tabs/general_tab.js b/src/components/settings_modal/tabs/general_tab.js @@ -2,6 +2,7 @@ import BooleanSetting from '../helpers/boolean_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue' import ScopeSelector from 'src/components/scope_selector/scope_selector.vue' import IntegerSetting from '../helpers/integer_setting.vue' +import SizeSetting, { defaultHorizontalUnits } from '../helpers/size_setting.vue' import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' @@ -56,11 +57,15 @@ const GeneralTab = { BooleanSetting, ChoiceSetting, IntegerSetting, + SizeSetting, InterfaceLanguageSwitcher, ScopeSelector, ServerSideIndicator }, computed: { + horizontalUnits () { + return defaultHorizontalUnits + }, postFormats () { return this.$store.state.instance.postFormats || [] }, @@ -71,6 +76,17 @@ const GeneralTab = { label: this.$t(`post_status.content_type["${format}"]`) })) }, + columns () { + const mode = this.$store.getters.mergedConfig.thirdColumnMode + + const notif = mode === 'none' ? [] : ['notifs'] + + if (this.$store.getters.mergedConfig.sidebarRight || mode === 'postform') { + return [...notif, 'content', 'sidebar'] + } else { + return ['sidebar', 'content', ...notif] + } + }, instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel }, instanceWallpaperUsed () { return this.$store.state.instance.background && diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue @@ -15,11 +15,6 @@ {{ $t('settings.hide_isp') }} </BooleanSetting> </li> - <li> - <BooleanSetting path="sidebarRight"> - {{ $t('settings.right_sidebar') }} - </BooleanSetting> - </li> <li v-if="instanceWallpaperUsed"> <BooleanSetting path="hideInstanceWallpaper"> {{ $t('settings.hide_wallpaper') }} @@ -65,16 +60,6 @@ </BooleanSetting> </li> <li> - <BooleanSetting path="disableStickyHeaders"> - {{ $t('settings.disable_sticky_headers') }} - </BooleanSetting> - </li> - <li> - <BooleanSetting path="showScrollbars"> - {{ $t('settings.show_scrollbars') }} - </BooleanSetting> - </li> - <li> <BooleanSetting path="userPopoverZoom" expert="1" @@ -91,16 +76,6 @@ </BooleanSetting> </li> <li> - <ChoiceSetting - v-if="user" - id="thirdColumnMode" - path="thirdColumnMode" - :options="thirdColumnModeOptions" - > - {{ $t('settings.third_column_mode') }} - </ChoiceSetting> - </li> - <li> <BooleanSetting path="alwaysShowNewPostButton" expert="1" @@ -480,3 +455,16 @@ </template> <script src="./general_tab.js"></script> + +<style lang="scss"> +.column-settings { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; +} +.column-settings .size-label { + display: block; + margin-bottom: 0.5em; + margin-top: 0.5em; +} +</style> diff --git a/src/i18n/en.json b/src/i18n/en.json @@ -533,6 +533,11 @@ "third_column_mode_none": "Don't show third column at all", "third_column_mode_notifications": "Notifications column", "third_column_mode_postform": "Main post form and navigation", + "columns": "Columns", + "column_sizes": "Column sizes", + "column_sizes_sidebar": "Sidebar", + "column_sizes_content": "Content", + "column_sizes_notifs": "Notifications", "tree_advanced": "Allow more flexible navigation in tree view", "tree_fade_ancestors": "Display ancestors of the current status in faint text", "conversation_display_linear": "Linear-style", diff --git a/src/i18n/ru.json b/src/i18n/ru.json @@ -456,6 +456,15 @@ "subject_line_mastodon": "Как в Mastodon: скопировать как есть", "subject_line_email": "Как в электронной почте: \"re: тема\"", "subject_line_behavior": "Копировать тему в ответах", + "third_column_mode": "Когда недостаточно места, показывать третью колонку содержащую", + "third_column_mode_none": "Не показывать третью колонку совсем", + "third_column_mode_notifications": "Колонку уведомлений", + "third_column_mode_postform": "Форму отправки сообщения и навигацию", + "columns": "Колонки", + "column_sizes": "Размеры колонок", + "column_sizes_sidebar": "Боковой", + "column_sizes_content": "Содержимого", + "column_sizes_notifs": "Уведомлений", "no_mutes": "Нет игнорируемых", "no_blocks": "Нет блокировок", "notification_visibility_emoji_reactions": "Реакции", diff --git a/src/modules/config.js b/src/modules/config.js @@ -1,5 +1,5 @@ import Cookies from 'js-cookie' -import { setPreset, applyTheme } from '../services/style_setter/style_setter.js' +import { setPreset, applyTheme, applyConfig } from '../services/style_setter/style_setter.js' import messages from '../i18n/messages' import localeService from '../services/locale/locale.service.js' @@ -165,12 +165,17 @@ const config = { setHighlight ({ commit, dispatch }, { user, color, type }) { commit('setHighlight', { user, color, type }) }, - setOption ({ commit, dispatch }, { name, value }) { + setOption ({ commit, dispatch, state }, { name, value }) { commit('setOption', { name, value }) switch (name) { case 'theme': setPreset(value) break + case 'sidebarColumnWidth': + case 'contentColumnWidth': + case 'notifsColumnWidth': + applyConfig(state) + break case 'customTheme': case 'customThemeSource': applyTheme(value) diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js @@ -1,6 +1,7 @@ import { convert } from 'chromatism' import { rgb2hex, hex2rgb, rgba2css, getCssColor, relativeLuminance } from '../color_convert/color_convert.js' import { getColors, computeDynamicColor, getOpacitySlot } from '../theme_data/theme_data.service.js' +import { defaultState } from '../../modules/config.js' export const applyTheme = (input) => { const { rules } = generatePreset(input) @@ -20,6 +21,36 @@ export const applyTheme = (input) => { body.classList.remove('hidden') } +const configColumns = ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth }) => + ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth }) + +const defaultConfigColumns = configColumns(defaultState) + +export const applyConfig = (config) => { + const columns = configColumns(config) + + if (columns === defaultConfigColumns) { + return + } + + const head = document.head + const body = document.body + body.classList.add('hidden') + + const rules = Object + .entries(columns) + .filter(([k, v]) => v) + .map(([k, v]) => `--${k}: ${v}`).join(';') + + const styleEl = document.createElement('style') + head.appendChild(styleEl) + const styleSheet = styleEl.sheet + + styleSheet.toString() + styleSheet.insertRule(`:root { ${rules} }`, 'index-max') + body.classList.remove('hidden') +} + export const getCssShadow = (input, usesDropShadow) => { if (input.length === 0) { return 'none'