From 50ede338e7ed25f599aea76b34f061b76741663e Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 24 Nov 2025 17:06:55 +0200 Subject: [PATCH] further separation of tabs --- .../settings_modal/settings_modal.scss | 13 + .../settings_modal_user_content.js | 26 +- .../settings_modal_user_content.scss | 1 - .../settings_modal_user_content.vue | 96 ++-- .../settings_modal/tabs/appearance_tab.js | 47 +- .../settings_modal/tabs/appearance_tab.scss | 28 +- .../settings_modal/tabs/appearance_tab.vue | 398 +++---------- .../settings_modal/tabs/clutter_tab.js | 194 +++++++ .../settings_modal/tabs/clutter_tab.vue | 104 ++++ .../settings_modal/tabs/composing_tab.js | 178 ++++++ .../settings_modal/tabs/composing_tab.vue | 111 ++++ .../tabs/{version_tab.js => developer_tab.js} | 0 .../settings_modal/tabs/developer_tab.vue | 72 +++ .../settings_modal/tabs/filtering_tab.js | 1 + .../settings_modal/tabs/filtering_tab.vue | 71 +-- .../settings_modal/tabs/general_tab.js | 108 +--- .../settings_modal/tabs/general_tab.vue | 544 +++--------------- .../settings_modal/tabs/layout_tab.js | 49 ++ .../settings_modal/tabs/layout_tab.vue | 130 +++++ .../old_theme_tab.js} | 0 .../old_theme_tab.scss} | 2 +- .../old_theme_tab.vue} | 6 +- .../theme_preview.vue | 0 .../settings_modal/tabs/posts_tab.js | 76 +++ .../settings_modal/tabs/posts_tab.scss | 5 + .../settings_modal/tabs/posts_tab.vue | 253 ++++++++ .../tabs/style_tab/style_tab.js | 2 +- .../settings_modal/tabs/version_tab.vue | 31 - .../tab_switcher/vertical_tab_switcher.jsx | 29 +- src/i18n/en.json | 14 +- 30 files changed, 1489 insertions(+), 1100 deletions(-) create mode 100644 src/components/settings_modal/tabs/clutter_tab.js create mode 100644 src/components/settings_modal/tabs/clutter_tab.vue create mode 100644 src/components/settings_modal/tabs/composing_tab.js create mode 100644 src/components/settings_modal/tabs/composing_tab.vue rename src/components/settings_modal/tabs/{version_tab.js => developer_tab.js} (100%) create mode 100644 src/components/settings_modal/tabs/developer_tab.vue create mode 100644 src/components/settings_modal/tabs/layout_tab.js create mode 100644 src/components/settings_modal/tabs/layout_tab.vue rename src/components/settings_modal/tabs/{theme_tab/theme_tab.js => old_theme_tab/old_theme_tab.js} (100%) rename src/components/settings_modal/tabs/{theme_tab/theme_tab.scss => old_theme_tab/old_theme_tab.scss} (99%) rename src/components/settings_modal/tabs/{theme_tab/theme_tab.vue => old_theme_tab/old_theme_tab.vue} (99%) rename src/components/settings_modal/tabs/{theme_tab => old_theme_tab}/theme_preview.vue (100%) create mode 100644 src/components/settings_modal/tabs/posts_tab.js create mode 100644 src/components/settings_modal/tabs/posts_tab.scss create mode 100644 src/components/settings_modal/tabs/posts_tab.vue delete mode 100644 src/components/settings_modal/tabs/version_tab.vue diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss index 2c975917f..9c78cd901 100644 --- a/src/components/settings_modal/settings_modal.scss +++ b/src/components/settings_modal/settings_modal.scss @@ -1,7 +1,20 @@ .settings-modal { overflow: hidden; + h3 { + font-size: 1.4rem; + margin-top: 1em; + margin-bottom: 1em; + } + h4 { + font-size: 1.2rem; + margin-top: 1em; + margin-bottom: 0.5em; + } + + h5 { + font-size: 1rem; margin-bottom: 0.5em; } diff --git a/src/components/settings_modal/settings_modal_user_content.js b/src/components/settings_modal/settings_modal_user_content.js index 55f2a9ce9..9c6e3bba6 100644 --- a/src/components/settings_modal/settings_modal_user_content.js +++ b/src/components/settings_modal/settings_modal_user_content.js @@ -7,15 +7,20 @@ import FilteringTab from './tabs/filtering_tab.vue' import SecurityTab from './tabs/security_tab/security_tab.vue' import ProfileTab from './tabs/profile_tab.vue' import GeneralTab from './tabs/general_tab.vue' +import PostsTab from './tabs/posts_tab.vue' +import ComposingTab from './tabs/composing_tab.vue' +import ClutterTab from './tabs/clutter_tab.vue' +import LayoutTab from './tabs/layout_tab.vue' import AppearanceTab from './tabs/appearance_tab.vue' -import VersionTab from './tabs/version_tab.vue' -import ThemeTab from './tabs/theme_tab/theme_tab.vue' +import DeveloperTab from './tabs/developer_tab.vue' +import OldThemeTab from './tabs/old_theme_tab/old_theme_tab.vue' import StyleTab from './tabs/style_tab/style_tab.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { faWrench, faUser, + faMessage, faFilter, faPaintBrush, faPalette, @@ -23,13 +28,16 @@ import { faDownload, faEyeSlash, faInfo, - faWindowRestore + faWindowRestore, + faCode, + faBroom } from '@fortawesome/free-solid-svg-icons' import { useInterfaceStore } from 'src/stores/interface' library.add( faWrench, faUser, + faMessage, faFilter, faPaintBrush, faPalette, @@ -37,7 +45,9 @@ library.add( faDownload, faEyeSlash, faInfo, - faWindowRestore + faWindowRestore, + faBroom, + faCode ) const SettingsModalContent = { @@ -51,10 +61,14 @@ const SettingsModalContent = { SecurityTab, ProfileTab, GeneralTab, + PostsTab, + ComposingTab, + ClutterTab, + LayoutTab, AppearanceTab, StyleTab, - VersionTab, - ThemeTab + DeveloperTab, + OldThemeTab }, computed: { isLoggedIn () { diff --git a/src/components/settings_modal/settings_modal_user_content.scss b/src/components/settings_modal/settings_modal_user_content.scss index 25e9bda3a..2884938b4 100644 --- a/src/components/settings_modal/settings_modal_user_content.scss +++ b/src/components/settings_modal/settings_modal_user_content.scss @@ -12,7 +12,6 @@ } h5 { - margin-bottom: 0; margin-top: 0.25em; } diff --git a/src/components/settings_modal/settings_modal_user_content.vue b/src/components/settings_modal/settings_modal_user_content.vue index 22271d533..58a0adbd9 100644 --- a/src/components/settings_modal/settings_modal_user_content.vue +++ b/src/components/settings_modal/settings_modal_user_content.vue @@ -13,14 +13,34 @@ icon="wrench" data-tab-name="general" > - + + +
+ +
+
+ +
+
+
- -
-
- -
-
- +
+
+ +
- + +
+
+ +
+
+
diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index 2978142ef..3bb5ec508 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -5,10 +5,8 @@ import ChoiceSetting from '../helpers/choice_setting.vue' import IntegerSetting from '../helpers/integer_setting.vue' import FloatSetting from '../helpers/float_setting.vue' import UnitSetting from '../helpers/unit_setting.vue' -import { defaultHorizontalUnits } from '../helpers/unit_setting.js' import PaletteEditor from 'src/components/palette_editor/palette_editor.vue' -import Preview from './theme_tab/theme_preview.vue' -import FontControl from 'src/components/font_control/font_control.vue' +import Preview from './old_theme_tab/theme_preview.vue' import { newImporter } from 'src/services/export_import/export_import.js' import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js' @@ -67,11 +65,6 @@ const AppearanceTab = { ], userPalette: {}, intersectionObserver: null, - thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({ - key: mode, - value: mode, - label: this.$t(`settings.third_column_mode_${mode}`) - })), forcedRoundnessOptions: ['disabled', 'sharp', 'nonsharp', 'round'].map((mode, i) => ({ key: mode, value: i - 1, @@ -94,7 +87,6 @@ const AppearanceTab = { FloatSetting, UnitSetting, ProfileSettingIndicator, - FontControl, Preview, PaletteEditor, VerticalTabSwitcher @@ -209,8 +201,6 @@ const AppearanceTab = { paletteDataUsed () { return useInterfaceStore().paletteDataUsed }, - instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel }, - instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable }, availableStyles () { return [ ...this.availableThemesV3, @@ -264,33 +254,10 @@ const AppearanceTab = { noIntersectionObserver () { return !window.IntersectionObserver }, - horizontalUnits () { - return defaultHorizontalUnits - }, - fontsOverride () { - return this.$store.getters.mergedConfig.fontsOverride - }, - 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] - } - }, instanceWallpaperUsed () { return this.$store.state.instance.background && !this.$store.state.users.currentUser.background_image }, - language: { - get: function () { return this.$store.getters.mergedConfig.interfaceLanguage }, - set: function (val) { - this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val }) - } - }, customThemeVersion () { const { themeVersion } = useInterfaceStore() return themeVersion @@ -306,18 +273,6 @@ const AppearanceTab = { ...SharedComputedObject() }, methods: { - updateFont (key, value) { - this.$store.dispatch('setOption', { - name: 'theme3hacks', - value: { - ...this.mergedConfig.theme3hacks, - fonts: { - ...this.mergedConfig.theme3hacks.fonts, - [key]: value - } - } - }) - }, importFile () { this.fileImporter.importData() }, diff --git a/src/components/settings_modal/tabs/appearance_tab.scss b/src/components/settings_modal/tabs/appearance_tab.scss index aa6bd5b45..ccc494d32 100644 --- a/src/components/settings_modal/tabs/appearance_tab.scss +++ b/src/components/settings_modal/tabs/appearance_tab.scss @@ -5,23 +5,18 @@ margin: 1em; } - .setting-item { - padding-bottom: 0; - - &.heading { - display: grid; - align-items: baseline; - grid-template-columns: 1fr auto auto auto; - grid-gap: 0.5em; - - h2 { - flex: 1 0 auto; - } - } + .theme-name { + font-weight: 900; + padding-bottom: 0.5em; } h4 { - margin: 0.5em 0; + margin: 2em 0; + line-height: 1.5; + } + + h5 { + display: block; } input[type="file"] { @@ -71,6 +66,7 @@ border-radius: var(--roundness); border: 1px solid var(--border); margin: -0.5em; + margin-top: 0; } .palettes { @@ -80,9 +76,9 @@ padding: 0.5em; width: 100%; - h4 { - margin: 0; + h5 { grid-column: 1 / span 2; + margin-bottom: 0; } } diff --git a/src/components/settings_modal/tabs/appearance_tab.vue b/src/components/settings_modal/tabs/appearance_tab.vue index f70b4042c..868fb8bfa 100644 --- a/src/components/settings_modal/tabs/appearance_tab.vue +++ b/src/components/settings_modal/tabs/appearance_tab.vue @@ -1,288 +1,14 @@ diff --git a/src/components/settings_modal/tabs/clutter_tab.js b/src/components/settings_modal/tabs/clutter_tab.js new file mode 100644 index 000000000..8e12104fc --- /dev/null +++ b/src/components/settings_modal/tabs/clutter_tab.js @@ -0,0 +1,194 @@ +import { mapState, mapActions } from 'pinia' +import { mapState as mapVuexState } from 'vuex' +import { v4 as uuidv4 } from 'uuid'; + +import { useServerSideStorageStore } from 'src/stores/serverSideStorage' + +import BooleanSetting from '../helpers/boolean_setting.vue' +import ChoiceSetting from '../helpers/choice_setting.vue' +import UnitSetting from '../helpers/unit_setting.vue' +import IntegerSetting from '../helpers/integer_setting.vue' +import HelpIndicator from '../helpers/help_indicator.vue' +import Checkbox from 'src/components/checkbox/checkbox.vue' +import Select from 'src/components/select/select.vue' + +import SharedComputedObject from '../helpers/shared_computed_object.js' + + +const ClutterTab = { + components: { + BooleanSetting, + ChoiceSetting, + UnitSetting, + IntegerSetting, + Checkbox, + Select, + HelpIndicator + }, + computed: { + instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel }, + ...SharedComputedObject(), + ...mapState( + useServerSideStorageStore, + { + muteFilters: store => Object.entries(store.prefsStorage.simple.muteFilters), + muteFiltersObject: store => store.prefsStorage.simple.muteFilters + } + ), + ...mapVuexState({ + blockExpirationSupported: state => state.instance.blockExpiration + }), + onMuteDefaultActionLv1: { + get () { + const value = this.$store.state.config.onMuteDefaultAction + if (value === 'ask' || value === 'forever') { + return value + } else { + return 'temporarily' + } + }, + set (value) { + let realValue = value + if (value !== 'ask' && value !== 'forever') { + realValue = '14d' + } + this.$store.dispatch('setOption', { name: 'onMuteDefaultAction', value: realValue }) + } + }, + onBlockDefaultActionLv1: { + get () { + const value = this.$store.state.config.onBlockDefaultAction + if (value === 'ask' || value === 'forever') { + return value + } else { + return 'temporarily' + } + }, + set (value) { + let realValue = value + if (value !== 'ask' && value !== 'forever') { + realValue = '14d' + } + this.$store.dispatch('setOption', { name: 'onBlockDefaultAction', value: realValue }) + } + }, + muteFiltersDraft () { + return Object.entries(this.muteFiltersDraftObject) + }, + muteFiltersExpired () { + const now = Date.now() + return Object + .entries(this.muteFiltersDraftObject) + .filter(([, { expires }]) => expires != null && expires <= now) + } + }, + methods: { + ...mapActions(useServerSideStorageStore, ['setPreference', 'unsetPreference', 'pushServerSideStorage']), + getDatetimeLocal (timestamp) { + const date = new Date(timestamp) + const fmt = new Intl.NumberFormat("en-US", {minimumIntegerDigits: 2}) + const datetime = [ + date.getFullYear(), + '-', + fmt.format(date.getMonth() + 1), + '-', + fmt.format(date.getDate()), + 'T', + fmt.format(date.getHours()), + ':', + fmt.format(date.getMinutes()) + ].join('') + return datetime + }, + checkRegexValid (id) { + const filter = this.muteFiltersObject[id] + if (filter.type !== 'regexp') return true + if (filter.type !== 'user_regexp') return true + const { value } = filter + let valid = true + try { + new RegExp(value) + } catch { + valid = false + console.error('Invalid RegExp: ' + value) + } + return valid + }, + createFilter (filter = { + type: 'word', + value: '', + name: 'New Filter', + enabled: true, + expires: null, + hide: false, + }) { + const newId = uuidv4() + + filter.order = this.muteFilters.length + 2 + this.muteFiltersDraftObject[newId] = filter + this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter }) + this.pushServerSideStorage() + }, + exportFilter(id) { + this.exportedFilter = { ...this.muteFiltersDraftObject[id] } + delete this.exportedFilter.order + this.filterExporter.exportData() + }, + importFilter() { + this.filterImporter.importData() + }, + copyFilter (id) { + const filter = { ...this.muteFiltersDraftObject[id] } + const newId = uuidv4() + + this.muteFiltersDraftObject[newId] = filter + this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter }) + this.pushServerSideStorage() + }, + deleteFilter (id) { + delete this.muteFiltersDraftObject[id] + this.unsetPreference({ path: 'simple.muteFilters.' + id , value: null }) + this.pushServerSideStorage() + }, + purgeExpiredFilters () { + this.muteFiltersExpired.forEach(([id]) => { + console.log(id) + delete this.muteFiltersDraftObject[id] + this.unsetPreference({ path: 'simple.muteFilters.' + id , value: null }) + }) + this.pushServerSideStorage() + }, + updateFilter(id, field, value) { + const filter = { ...this.muteFiltersDraftObject[id] } + if (field === 'expires-never') { + if (!value) { + const offset = 1000 * 60 * 60 * 24 * 14 // 2 weeks + const date = Date.now() + offset + filter.expires = date + } else { + filter.expires = null + } + } else if (field === 'expires') { + const parsed = Date.parse(value) + filter.expires = parsed.valueOf() + } else { + filter[field] = value + } + this.muteFiltersDraftObject[id] = filter + this.muteFiltersDraftDirty[id] = true + }, + saveFilter(id) { + this.setPreference({ path: 'simple.muteFilters.' + id , value: this.muteFiltersDraftObject[id] }) + this.pushServerSideStorage() + this.muteFiltersDraftDirty[id] = false + }, + }, + // Updating nested properties + watch: { + replyVisibility () { + this.$store.dispatch('queueFlushAll') + } + } +} + +export default ClutterTab diff --git a/src/components/settings_modal/tabs/clutter_tab.vue b/src/components/settings_modal/tabs/clutter_tab.vue new file mode 100644 index 000000000..12514c330 --- /dev/null +++ b/src/components/settings_modal/tabs/clutter_tab.vue @@ -0,0 +1,104 @@ + + + diff --git a/src/components/settings_modal/tabs/composing_tab.js b/src/components/settings_modal/tabs/composing_tab.js new file mode 100644 index 000000000..7efbe7047 --- /dev/null +++ b/src/components/settings_modal/tabs/composing_tab.js @@ -0,0 +1,178 @@ +import { mapState } from 'vuex' + +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 FloatSetting from '../helpers/float_setting.vue' +import UnitSetting from '../helpers/unit_setting.vue' +import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' +import Select from 'src/components/select/select.vue' +import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue' +import FontControl from 'src/components/font_control/font_control.vue' + +import SharedComputedObject from '../helpers/shared_computed_object.js' + +import localeService from 'src/services/locale/locale.service.js' +import { clearCache, cacheKey, emojiCacheKey } from 'src/services/sw/sw.js' +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faGlobe, + faMessage, + faPenAlt, + faDatabase, + faSliders +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faGlobe, + faMessage, + faPenAlt, + faDatabase, + faSliders +) + +const ComposingTab = { + props: { + parentCollapsed: { + required: true, + type: Boolean + } + }, + data () { + return { + subjectLineOptions: ['email', 'noop', 'masto'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.subject_line_${mode === 'masto' ? 'mastodon' : mode}`) + })), + conversationDisplayOptions: ['tree', 'linear'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.conversation_display_${mode}`) + })), + absoluteTime12hOptions: ['24h', '12h'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.absolute_time_format_12h_${mode}`) + })), + conversationOtherRepliesButtonOptions: ['below', 'inside'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.conversation_other_replies_button_${mode}`) + })), + mentionLinkDisplayOptions: ['short', 'full_for_remote', 'full'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.mention_link_display_${mode}`) + })), + userPopoverAvatarActionOptions: ['close', 'zoom', 'open'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.user_popover_avatar_action_${mode}`) + })), + unsavedPostActionOptions: ['save', 'discard', 'confirm'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.unsaved_post_action_${mode}`) + })), + loopSilentAvailable: + // Firefox + Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') || + // Chrome-likes + Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'webkitAudioDecodedByteCount') || + // Future spec, still not supported in Nightly 63 as of 08/2018 + Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks'), + emailLanguage: this.$store.state.users.currentUser.language || [''] + } + }, + components: { + BooleanSetting, + ChoiceSetting, + IntegerSetting, + FloatSetting, + UnitSetting, + InterfaceLanguageSwitcher, + ProfileSettingIndicator, + ScopeSelector, + Select, + FontControl + }, + computed: { + postFormats () { + return this.$store.state.instance.postFormats || [] + }, + postContentOptions () { + return this.postFormats.map(format => ({ + key: format, + value: format, + label: this.$t(`post_status.content_type["${format}"]`) + })) + }, + language: { + get: function () { return this.$store.getters.mergedConfig.interfaceLanguage }, + set: function (val) { + this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val }) + } + }, + ...SharedComputedObject(), + ...mapState({ + blockExpirationSupported: state => state.instance.blockExpiration, + }) + }, + methods: { + changeDefaultScope (value) { + this.$store.dispatch('setProfileOption', { name: 'defaultScope', value }) + }, + clearCache (key) { + clearCache(key) + .then(() => { + this.$store.dispatch('settingsSaved', { success: true }) + }) + .catch(error => { + this.$store.dispatch('settingsSaved', { error }) + }) + }, + tooSmall () { + this.$emit('tooSmall') + }, + tooBig () { + this.$emit('tooBig') + }, + getNavMode () { + return this.$refs.tabSwitcher.getNavMode() + }, + clearAssetCache () { + this.clearCache(cacheKey) + }, + clearEmojiCache () { + this.clearCache(emojiCacheKey) + }, + updateProfile () { + const params = { + language: localeService.internalToBackendLocaleMulti(this.emailLanguage) + } + + this.$store.state.api.backendInteractor + .updateProfile({ params }) + .then((user) => { + this.$store.commit('addNewUsers', [user]) + this.$store.commit('setCurrentUser', user) + }) + }, + updateFont (key, value) { + this.$store.dispatch('setOption', { + name: 'theme3hacks', + value: { + ...this.mergedConfig.theme3hacks, + fonts: { + ...this.mergedConfig.theme3hacks.fonts, + [key]: value + } + } + }) + }, + } +} + +export default ComposingTab diff --git a/src/components/settings_modal/tabs/composing_tab.vue b/src/components/settings_modal/tabs/composing_tab.vue new file mode 100644 index 000000000..a48e6928e --- /dev/null +++ b/src/components/settings_modal/tabs/composing_tab.vue @@ -0,0 +1,111 @@ + + + diff --git a/src/components/settings_modal/tabs/version_tab.js b/src/components/settings_modal/tabs/developer_tab.js similarity index 100% rename from src/components/settings_modal/tabs/version_tab.js rename to src/components/settings_modal/tabs/developer_tab.js diff --git a/src/components/settings_modal/tabs/developer_tab.vue b/src/components/settings_modal/tabs/developer_tab.vue new file mode 100644 index 000000000..8c9c9efc1 --- /dev/null +++ b/src/components/settings_modal/tabs/developer_tab.vue @@ -0,0 +1,72 @@ + + diff --git a/src/components/settings_modal/tabs/layout_tab.js b/src/components/settings_modal/tabs/layout_tab.js new file mode 100644 index 000000000..355933a65 --- /dev/null +++ b/src/components/settings_modal/tabs/layout_tab.js @@ -0,0 +1,49 @@ +import BooleanSetting from '../helpers/boolean_setting.vue' +import ChoiceSetting from '../helpers/choice_setting.vue' +import UnitSetting from '../helpers/unit_setting.vue' +import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue' + +import SharedComputedObject from '../helpers/shared_computed_object.js' + +const GeneralTab = { + props: { + parentCollapsed: { + required: true, + type: Boolean + } + }, + data () { + return { + thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.third_column_mode_${mode}`) + })) + } + }, + components: { + BooleanSetting, + ChoiceSetting, + UnitSetting, + ProfileSettingIndicator + }, + computed: { + postFormats () { + return this.$store.state.instance.postFormats || [] + }, + 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] + } + }, + ...SharedComputedObject(), + } +} + +export default GeneralTab diff --git a/src/components/settings_modal/tabs/layout_tab.vue b/src/components/settings_modal/tabs/layout_tab.vue new file mode 100644 index 000000000..d4a7e757a --- /dev/null +++ b/src/components/settings_modal/tabs/layout_tab.vue @@ -0,0 +1,130 @@ + + + diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.js similarity index 100% rename from src/components/settings_modal/tabs/theme_tab/theme_tab.js rename to src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.js diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss b/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.scss similarity index 99% rename from src/components/settings_modal/tabs/theme_tab/theme_tab.scss rename to src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.scss index ae2364dcc..96a1b154f 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss +++ b/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.scss @@ -1,4 +1,4 @@ -.theme-tab { +.old-theme-tab { min-width: var(--themeEditorMinWidth, fit-content); .deprecation-warning { diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.vue similarity index 99% rename from src/components/settings_modal/tabs/theme_tab/theme_tab.vue rename to src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.vue index ec3f0cb5d..751e113a0 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue +++ b/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.vue @@ -1,5 +1,5 @@ - + - + diff --git a/src/components/settings_modal/tabs/theme_tab/theme_preview.vue b/src/components/settings_modal/tabs/old_theme_tab/theme_preview.vue similarity index 100% rename from src/components/settings_modal/tabs/theme_tab/theme_preview.vue rename to src/components/settings_modal/tabs/old_theme_tab/theme_preview.vue diff --git a/src/components/settings_modal/tabs/posts_tab.js b/src/components/settings_modal/tabs/posts_tab.js new file mode 100644 index 000000000..d0399037b --- /dev/null +++ b/src/components/settings_modal/tabs/posts_tab.js @@ -0,0 +1,76 @@ +import BooleanSetting from '../helpers/boolean_setting.vue' +import ChoiceSetting from '../helpers/choice_setting.vue' +import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue' +import FontControl from 'src/components/font_control/font_control.vue' + +import SharedComputedObject from '../helpers/shared_computed_object.js' + +const GeneralTab = { + props: { + parentCollapsed: { + required: true, + type: Boolean + } + }, + data () { + return { + conversationDisplayOptions: ['tree', 'linear'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.conversation_display_${mode}`) + })), + conversationOtherRepliesButtonOptions: ['below', 'inside'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.conversation_other_replies_button_${mode}`) + })), + mentionLinkDisplayOptions: ['short', 'full_for_remote', 'full'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.mention_link_display_${mode}`) + })), + userPopoverAvatarActionOptions: ['close', 'zoom', 'open'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.user_popover_avatar_action_${mode}`) + })), + unsavedPostActionOptions: ['save', 'discard', 'confirm'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.unsaved_post_action_${mode}`) + })), + loopSilentAvailable: + // Firefox + Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') || + // Chrome-likes + Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'webkitAudioDecodedByteCount') || + // Future spec, still not supported in Nightly 63 as of 08/2018 + Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks') + } + }, + components: { + BooleanSetting, + ChoiceSetting, + FontControl, + ProfileSettingIndicator + }, + computed: { + ...SharedComputedObject(), + }, + methods: { + updateFont (key, value) { + this.$store.dispatch('setOption', { + name: 'theme3hacks', + value: { + ...this.mergedConfig.theme3hacks, + fonts: { + ...this.mergedConfig.theme3hacks.fonts, + [key]: value + } + } + }) + }, + } +} + +export default GeneralTab diff --git a/src/components/settings_modal/tabs/posts_tab.scss b/src/components/settings_modal/tabs/posts_tab.scss new file mode 100644 index 000000000..84c3d0dd2 --- /dev/null +++ b/src/components/settings_modal/tabs/posts_tab.scss @@ -0,0 +1,5 @@ +.posts-tab { + .greentext { + color: var(--funtextGreentext); + } +} diff --git a/src/components/settings_modal/tabs/posts_tab.vue b/src/components/settings_modal/tabs/posts_tab.vue new file mode 100644 index 000000000..70bc6ea23 --- /dev/null +++ b/src/components/settings_modal/tabs/posts_tab.vue @@ -0,0 +1,253 @@ + + + + diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.js b/src/components/settings_modal/tabs/style_tab/style_tab.js index 5453da57b..35626a103 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.js +++ b/src/components/settings_modal/tabs/style_tab/style_tab.js @@ -15,7 +15,7 @@ import RoundnessInput from 'src/components/roundness_input/roundness_input.vue' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import Tooltip from 'src/components/tooltip/tooltip.vue' import ContrastRatio from 'src/components/contrast_ratio/contrast_ratio.vue' -import Preview from '../theme_tab/theme_preview.vue' +import Preview from '../old_theme_tab/theme_preview.vue' import VirtualDirectivesTab from './virtual_directives_tab.vue' diff --git a/src/components/settings_modal/tabs/version_tab.vue b/src/components/settings_modal/tabs/version_tab.vue deleted file mode 100644 index 917a618e6..000000000 --- a/src/components/settings_modal/tabs/version_tab.vue +++ /dev/null @@ -1,31 +0,0 @@ - -