further separation of tabs
This commit is contained in:
parent
b0f725671a
commit
50ede338e7
30 changed files with 1489 additions and 1100 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
}
|
||||
|
||||
h5 {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,34 @@
|
|||
icon="wrench"
|
||||
data-tab-name="general"
|
||||
>
|
||||
<GeneralTab
|
||||
class="inner-tab -middle"
|
||||
ref="generalTab"
|
||||
:parent-collapsed="navCollapsed"
|
||||
@side-switch="(side) => nestedNavSide(side)"
|
||||
@too-small="() => nestedTooSmall()"
|
||||
@too-big="() => nestedTooBig()"
|
||||
/>
|
||||
<GeneralTab />
|
||||
</div>
|
||||
<div
|
||||
:full-width="true"
|
||||
:label="$t('settings.posts')"
|
||||
icon="message"
|
||||
data-tab-name="posts"
|
||||
:delay-render="true"
|
||||
>
|
||||
<PostsTab />
|
||||
</div>
|
||||
<div
|
||||
:full-width="true"
|
||||
:label="$t('settings.composing')"
|
||||
icon="pen-alt"
|
||||
data-tab-name="composing"
|
||||
:delay-render="true"
|
||||
>
|
||||
<ComposingTab />
|
||||
</div>
|
||||
<div
|
||||
:full-width="true"
|
||||
:label="$t('settings.layout')"
|
||||
icon="table-columns"
|
||||
data-tab-name="layout"
|
||||
:delay-render="true"
|
||||
>
|
||||
<LayoutTab />
|
||||
</div>
|
||||
<div
|
||||
:full-width="true"
|
||||
|
|
@ -29,30 +49,7 @@
|
|||
data-tab-name="appearance"
|
||||
:delay-render="true"
|
||||
>
|
||||
<AppearanceTab
|
||||
class="inner-tab -middle"
|
||||
:parent-collapsed="navCollapsed"
|
||||
@too-small="() => nestedTooSmall()"
|
||||
@too-big="() => nestedTooBig()"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="expertLevel > 0"
|
||||
:label="$t('settings.style.themes3.editor.title')"
|
||||
icon="palette"
|
||||
data-tab-name="style"
|
||||
:delay-render="true"
|
||||
>
|
||||
<StyleTab />
|
||||
</div>
|
||||
<div
|
||||
v-if="expertLevel > 0"
|
||||
:label="$t('settings.theme_old')"
|
||||
icon="paint-brush"
|
||||
data-tab-name="theme"
|
||||
:delay-render="true"
|
||||
>
|
||||
<ThemeTab />
|
||||
<AppearanceTab />
|
||||
</div>
|
||||
<div
|
||||
v-if="isLoggedIn"
|
||||
|
|
@ -78,6 +75,14 @@
|
|||
>
|
||||
<SecurityTab />
|
||||
</div>
|
||||
<div
|
||||
:label="$t('settings.clutter')"
|
||||
:fullHeight="true"
|
||||
icon="broom"
|
||||
data-tab-name="mutesAndBlocks"
|
||||
>
|
||||
<ClutterTab />
|
||||
</div>
|
||||
<div
|
||||
:label="$t('settings.filtering')"
|
||||
icon="filter"
|
||||
|
|
@ -103,11 +108,30 @@
|
|||
<DataImportExportTab />
|
||||
</div>
|
||||
<div
|
||||
:label="$t('settings.version.title')"
|
||||
icon="info"
|
||||
data-tab-name="version"
|
||||
v-if="expertLevel > 0"
|
||||
:label="$t('settings.style.themes3.editor.title')"
|
||||
icon="palette"
|
||||
data-tab-name="style"
|
||||
:delay-render="true"
|
||||
>
|
||||
<VersionTab />
|
||||
<StyleTab />
|
||||
</div>
|
||||
<div
|
||||
v-if="expertLevel > 0"
|
||||
:label="$t('settings.theme_old')"
|
||||
icon="paint-brush"
|
||||
data-tab-name="theme"
|
||||
:delay-render="true"
|
||||
>
|
||||
<ThemeTab />
|
||||
</div>
|
||||
<div
|
||||
v-if="expertLevel > 0"
|
||||
:label="$t('settings.developer')"
|
||||
icon="code"
|
||||
data-tab-name="developer"
|
||||
>
|
||||
<DeveloperTab />
|
||||
</div>
|
||||
</vertical-tab-switcher>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,288 +1,14 @@
|
|||
<template>
|
||||
<vertical-tab-switcher
|
||||
<div
|
||||
class="appearance-tab"
|
||||
:label="$t('settings.appearance')"
|
||||
ref="tabSwitcher"
|
||||
:side-tab-bar="true"
|
||||
:scrollable-tabs="true"
|
||||
@too-small="() => console.log('small') || $emit('tooSmall')"
|
||||
@too-big="() => $emit('tooBig')"
|
||||
:label="$t('settings.interface')"
|
||||
icon="table-columns"
|
||||
>
|
||||
<div
|
||||
:label="$t('settings.interface')"
|
||||
icon="table-columns"
|
||||
>
|
||||
<div class="alert neutral theme-notice">
|
||||
{{ $t("settings.style.appearance_tab_note") }}
|
||||
</div>
|
||||
<ul class="setting-list">
|
||||
<h3>{{ $t('settings.general') }}</h3>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="textSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 14, 'rem': 1 }"
|
||||
timed-apply-mode
|
||||
>
|
||||
{{ $t('settings.text_size') }}
|
||||
</UnitSetting>
|
||||
<div>
|
||||
<small>
|
||||
<i18n-t
|
||||
scope="global"
|
||||
keypath="settings.text_size_tip"
|
||||
tag="span"
|
||||
>
|
||||
<code>px</code>
|
||||
<code>rem</code>
|
||||
</i18n-t>
|
||||
<br>
|
||||
<i18n-t
|
||||
scope="global"
|
||||
keypath="settings.text_size_tip2"
|
||||
tag="span"
|
||||
>
|
||||
<code>14px</code>
|
||||
</i18n-t>
|
||||
</small>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.interface"
|
||||
name="ui"
|
||||
:label="$t('settings.style.fonts.components.interface')"
|
||||
:fallback="{ family: 'sans-serif' }"
|
||||
no-inherit="1"
|
||||
@update:model-value="v => updateFont('interface', v)"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.input"
|
||||
name="input"
|
||||
:fallback="{ family: 'inherit' }"
|
||||
:label="$t('settings.style.fonts.components.input')"
|
||||
@update:model-value="v => updateFont('input', v)"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="emojiSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 32, 'rem': 2.2 }"
|
||||
>
|
||||
{{ $t('settings.emoji_size') }}
|
||||
</UnitSetting>
|
||||
<ul
|
||||
class="setting-list suboptions"
|
||||
>
|
||||
<li>
|
||||
<FloatSetting
|
||||
v-if="user"
|
||||
path="emojiReactionsScale"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.emoji_reactions_scale') }}
|
||||
</FloatSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="userPopoverOverlay"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_popover_avatar_overlay') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="userCardLeftJustify"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_card_left_justify') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="userCardHidePersonalMarks"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_card_hide_personal_marks') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="instanceShoutboxPresent">
|
||||
<BooleanSetting
|
||||
path="hideShoutbox"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.hide_shoutbox') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<h3>{{ $t('settings.columns') }}</h3>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="navbarSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 55, 'rem': 3.5 }"
|
||||
>
|
||||
{{ $t('settings.navbar_size') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
<li v-if="instanceSpecificPanelPresent">
|
||||
<BooleanSetting path="hideISP">
|
||||
{{ $t('settings.hide_isp') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="panelHeaderSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 52, 'rem': 3.2 }"
|
||||
timed-apply-mode
|
||||
>
|
||||
{{ $t('settings.panel_header_size') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="sidebarRight">
|
||||
{{ $t('settings.right_sidebar') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="navbarColumnStretch">
|
||||
{{ $t('settings.navbar_column_stretch') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
v-if="user"
|
||||
id="thirdColumnMode"
|
||||
path="thirdColumnMode"
|
||||
:options="thirdColumnModeOptions"
|
||||
>
|
||||
{{ $t('settings.third_column_mode') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li v-if="expertLevel > 0">
|
||||
{{ $t('settings.column_sizes') }}
|
||||
<div class="column-settings">
|
||||
<UnitSetting
|
||||
v-for="column in columns"
|
||||
:key="column"
|
||||
:path="column + 'ColumnWidth'"
|
||||
:units="horizontalUnits"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.column_sizes_' + column) }}
|
||||
</UnitSetting>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="disableStickyHeaders">
|
||||
{{ $t('settings.disable_sticky_headers') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="showScrollbars">
|
||||
{{ $t('settings.show_scrollbars') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="themeEditorMinWidth"
|
||||
:units="['px', 'rem']"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.theme_editor_min_width') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="setting-list">
|
||||
<h3>{{ $t('settings.visual_tweaks') }}</h3>
|
||||
<li>
|
||||
<BooleanSetting path="modalMobileCenter">
|
||||
{{ $t('settings.mobile_center_dialog') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="forcedRoundness"
|
||||
path="forcedRoundness"
|
||||
:options="forcedRoundnessOptions"
|
||||
>
|
||||
{{ $t('settings.style.themes3.hacks.force_interface_roundness') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="underlayOverride"
|
||||
path="theme3hacks.underlay"
|
||||
:options="underlayOverrideModes"
|
||||
>
|
||||
{{ $t('settings.style.themes3.hacks.underlay_overrides') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li v-if="instanceWallpaperUsed">
|
||||
<BooleanSetting path="hideInstanceWallpaper">
|
||||
{{ $t('settings.hide_wallpaper') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
class="setting-item"
|
||||
:label="$t('settings.theme')"
|
||||
icon="paintbrush"
|
||||
>
|
||||
<div>
|
||||
<h3>{{ $t('settings.background') }}</h3>
|
||||
<div class="banner-background-preview">
|
||||
<img :src="user.background_image">
|
||||
<button
|
||||
v-if="!isDefaultBackground"
|
||||
class="button-unstyled reset-button"
|
||||
:title="$t('settings.reset_profile_background')"
|
||||
@click="resetBackground"
|
||||
>
|
||||
<FAIcon
|
||||
icon="times"
|
||||
type="button"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<p>{{ $t('settings.set_new_background') }}</p>
|
||||
<img
|
||||
v-if="backgroundPreview"
|
||||
class="banner-background-preview"
|
||||
:src="backgroundPreview"
|
||||
>
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
class="input"
|
||||
@change="uploadFile('background', $event)"
|
||||
>
|
||||
</div>
|
||||
<FAIcon
|
||||
v-if="backgroundUploading"
|
||||
class="uploading"
|
||||
spin
|
||||
icon="circle-notch"
|
||||
/>
|
||||
<button
|
||||
v-else-if="backgroundPreview"
|
||||
class="btn button-default"
|
||||
@click="submitBackground(background)"
|
||||
>
|
||||
{{ $t('settings.save') }}
|
||||
</button>
|
||||
</div>
|
||||
<h3>{{ $t('settings.style.style_section') }}</h3>
|
||||
<ul
|
||||
ref="themeList"
|
||||
|
|
@ -296,10 +22,10 @@
|
|||
@click="resetTheming"
|
||||
>
|
||||
<preview id="theme-preview-stock" />
|
||||
<h4 class="theme-name">
|
||||
<span class="theme-name">
|
||||
{{ $t('settings.style.stock_theme_used') }}
|
||||
<span class="alert neutral version">v3</span>
|
||||
</h4>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="isCustomThemeUsed"
|
||||
|
|
@ -307,10 +33,10 @@
|
|||
class="button-default theme-preview toggled"
|
||||
>
|
||||
<preview />
|
||||
<h4 class="theme-name">
|
||||
<span class="theme-name">
|
||||
{{ $t('settings.style.custom_theme_used') }}
|
||||
<span class="alert neutral version">v2</span>
|
||||
</h4>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="isCustomStyleUsed"
|
||||
|
|
@ -318,10 +44,10 @@
|
|||
class="button-default theme-preview toggled"
|
||||
>
|
||||
<preview />
|
||||
<h4 class="theme-name">
|
||||
<span class="theme-name">
|
||||
{{ $t('settings.style.custom_style_used') }}
|
||||
<span class="alert neutral version">v3</span>
|
||||
</h4>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-for="style in availableStyles"
|
||||
|
|
@ -333,10 +59,10 @@
|
|||
@click="style.version === 'v2' ? setTheme(style.key) : setStyle(style.key)"
|
||||
>
|
||||
<preview :id="'theme-preview-' + style.key" />
|
||||
<h4 class="theme-name">
|
||||
<span class="theme-name">
|
||||
{{ style.name }}
|
||||
<span class="alert neutral version">{{ style.version }}</span>
|
||||
</h4>
|
||||
</span>
|
||||
</button>
|
||||
</ul>
|
||||
<div class="import-file-container">
|
||||
|
|
@ -351,14 +77,14 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<h2>{{ $t('settings.style.themes3.palette.label') }}</h2>
|
||||
<h4>{{ $t('settings.style.themes3.palette.label') }}</h4>
|
||||
<div
|
||||
v-if="customThemeVersion === 'v3'"
|
||||
class="palettes-container"
|
||||
>
|
||||
<h4 v-if="stylePalettes?.length > 0">
|
||||
<h5 v-if="stylePalettes?.length > 0">
|
||||
{{ $t('settings.style.themes3.palette.style') }}
|
||||
</h4>
|
||||
</h5>
|
||||
<div class="palettes">
|
||||
<button
|
||||
v-for="p in stylePalettes || []"
|
||||
|
|
@ -382,7 +108,7 @@
|
|||
/>
|
||||
</div>
|
||||
</button>
|
||||
<h4>{{ $t('settings.style.themes3.palette.bundled') }}</h4>
|
||||
<h5>{{ $t('settings.style.themes3.palette.bundled') }}</h5>
|
||||
<button
|
||||
v-for="p in bundledPalettes"
|
||||
:key="p.name"
|
||||
|
|
@ -409,9 +135,9 @@
|
|||
</div>
|
||||
<div>
|
||||
<template v-if="customThemeVersion === 'v3'">
|
||||
<h4 v-if="expertLevel > 0">
|
||||
<h5 v-if="expertLevel > 0">
|
||||
{{ $t('settings.style.themes3.palette.user') }}
|
||||
</h4>
|
||||
</h5>
|
||||
<PaletteEditor
|
||||
v-if="expertLevel > 0"
|
||||
v-model="userPalette"
|
||||
|
|
@ -428,27 +154,79 @@
|
|||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="themeDebug"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.theme_debug') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="forceThemeRecompilation"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.force_theme_recompilation_debug') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>{{ $t('settings.background') }}</h3>
|
||||
<div class="banner-background-preview">
|
||||
<img :src="user.background_image">
|
||||
<button
|
||||
v-if="!isDefaultBackground"
|
||||
class="button-unstyled reset-button"
|
||||
:title="$t('settings.reset_profile_background')"
|
||||
@click="resetBackground"
|
||||
>
|
||||
<FAIcon
|
||||
icon="times"
|
||||
type="button"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<p>{{ $t('settings.set_new_background') }}</p>
|
||||
<img
|
||||
v-if="backgroundPreview"
|
||||
class="banner-background-preview"
|
||||
:src="backgroundPreview"
|
||||
>
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
class="input"
|
||||
@change="uploadFile('background', $event)"
|
||||
>
|
||||
</div>
|
||||
<FAIcon
|
||||
v-if="backgroundUploading"
|
||||
class="uploading"
|
||||
spin
|
||||
icon="circle-notch"
|
||||
/>
|
||||
<button
|
||||
v-else-if="backgroundPreview"
|
||||
class="btn button-default"
|
||||
@click="submitBackground(background)"
|
||||
>
|
||||
{{ $t('settings.save') }}
|
||||
</button>
|
||||
<h3>{{ $t('settings.visual_tweaks') }}</h3>
|
||||
<div class="alert neutral theme-notice">
|
||||
{{ $t("settings.style.visual_tweaks_section_note") }}
|
||||
</div>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="forcedRoundness"
|
||||
path="forcedRoundness"
|
||||
:options="forcedRoundnessOptions"
|
||||
>
|
||||
{{ $t('settings.style.themes3.hacks.force_interface_roundness') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="underlayOverride"
|
||||
path="theme3hacks.underlay"
|
||||
:options="underlayOverrideModes"
|
||||
>
|
||||
{{ $t('settings.style.themes3.hacks.underlay_overrides') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li v-if="instanceWallpaperUsed">
|
||||
<BooleanSetting path="hideInstanceWallpaper">
|
||||
{{ $t('settings.hide_wallpaper') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</vertical-tab-switcher>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./appearance_tab.js"></script>
|
||||
|
|
|
|||
194
src/components/settings_modal/tabs/clutter_tab.js
Normal file
194
src/components/settings_modal/tabs/clutter_tab.js
Normal file
|
|
@ -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
|
||||
104
src/components/settings_modal/tabs/clutter_tab.vue
Normal file
104
src/components/settings_modal/tabs/clutter_tab.vue
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<template>
|
||||
<div class="clutter-tab">
|
||||
<div class="setting-item">
|
||||
<h3>{{ $t('settings.interface') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="alwaysShowSubjectInput"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.subject_input_always_show') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="minimalScopesMode"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.minimal_scopes_mode') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
expert="1"
|
||||
path="hidePostStats"
|
||||
>
|
||||
{{ $t('settings.hide_post_stats') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
expert="1"
|
||||
path="hideUserStats"
|
||||
>
|
||||
{{ $t('settings.hide_user_stats') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideBotIndication">
|
||||
{{ $t('settings.hide_actor_type_indication') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideScrobbles">
|
||||
{{ $t('settings.hide_scrobbles') }}
|
||||
</BooleanSetting>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<UnitSetting
|
||||
key="hideScrobblesAfter"
|
||||
path="hideScrobblesAfter"
|
||||
:units="['m', 'h', 'd']"
|
||||
unit-set="time"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.hide_scrobbles_after') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.attachments') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<IntegerSetting
|
||||
path="maxThumbnails"
|
||||
expert="1"
|
||||
:min="0"
|
||||
>
|
||||
{{ $t('settings.max_thumbnails') }}
|
||||
</IntegerSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideAttachments">
|
||||
{{ $t('settings.hide_attachments_in_tl') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideAttachmentsInConv">
|
||||
{{ $t('settings.hide_attachments_in_convo') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="userCardHidePersonalMarks"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_card_hide_personal_marks') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="instanceShoutboxPresent">
|
||||
<BooleanSetting
|
||||
path="hideShoutbox"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.hide_shoutbox') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./clutter_tab.js"></script>
|
||||
178
src/components/settings_modal/tabs/composing_tab.js
Normal file
178
src/components/settings_modal/tabs/composing_tab.js
Normal file
|
|
@ -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
|
||||
111
src/components/settings_modal/tabs/composing_tab.vue
Normal file
111
src/components/settings_modal/tabs/composing_tab.vue
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<div :label="$t('settings.posts')">
|
||||
<div class="setting-item">
|
||||
<h3>{{ $t('settings.general') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<label for="default-vis">
|
||||
{{ $t('settings.default_vis') }}
|
||||
{{ ' ' }}
|
||||
<ScopeSelector
|
||||
class="scope-selector"
|
||||
:show-all="true"
|
||||
:user-default="$store.state.profileConfig.defaultScope"
|
||||
:initial-scope="$store.state.profileConfig.defaultScope"
|
||||
:on-scope-change="changeDefaultScope"
|
||||
:unstyled="false"uns
|
||||
/>
|
||||
<ProfileSettingIndicator :is-profile="true" />
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<!-- <BooleanSetting source="profile" path="defaultNSFW"> -->
|
||||
<BooleanSetting path="sensitiveByDefault">
|
||||
{{ $t('settings.sensitive_by_default') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="postFormats.length > 0">
|
||||
<ChoiceSetting
|
||||
id="postContentType"
|
||||
path="postContentType"
|
||||
:options="postContentOptions"
|
||||
>
|
||||
{{ $t('settings.default_post_status_content_type') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="padEmoji">
|
||||
{{ $t('settings.pad_emoji') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="autocompleteSelect"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.autocomplete_select_first') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="autoSaveDraft"
|
||||
>
|
||||
{{ $t('settings.auto_save_draft') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="!mergedConfig.autoSaveDraft">
|
||||
<ChoiceSetting
|
||||
id="unsavedPostAction"
|
||||
path="unsavedPostAction"
|
||||
:options="unsavedPostActionOptions"
|
||||
>
|
||||
{{ $t('settings.unsaved_post_action') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.replies') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="scopeCopy"
|
||||
>
|
||||
{{ $t('settings.scope_copy') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="subjectLineBehavior"
|
||||
path="subjectLineBehavior"
|
||||
:options="subjectLineOptions"
|
||||
>
|
||||
{{ $t('settings.subject_line_behavior') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 v-if="expertLevel > 0">{{ $t('settings.attachments') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="imageCompression"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.image_compression') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="alwaysUseJpeg"
|
||||
expert="1"
|
||||
parent-path="imageCompression"
|
||||
>
|
||||
{{ $t('settings.always_use_jpeg') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./composing_tab.js"></script>
|
||||
72
src/components/settings_modal/tabs/developer_tab.vue
Normal file
72
src/components/settings_modal/tabs/developer_tab.vue
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<template>
|
||||
<div :label="$t('settings.developer')">
|
||||
<div class="setting-item">
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<p>{{ $t('settings.version.backend_version') }}</p>
|
||||
<ul class="option-list">
|
||||
<li>
|
||||
<a
|
||||
:href="backendRepository"
|
||||
target="_blank"
|
||||
>{{ backendVersion }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>{{ $t('settings.version.frontend_version') }}</p>
|
||||
<ul class="option-list">
|
||||
<li>
|
||||
<a
|
||||
:href="frontendVersionLink"
|
||||
target="_blank"
|
||||
>{{ frontendVersion }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting path="virtualScrolling">
|
||||
{{ $t('settings.virtual_scrolling') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
class="btn button-default"
|
||||
@click="clearAssetCache"
|
||||
>
|
||||
{{ $t('settings.clear_asset_cache') }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
class="btn button-default"
|
||||
@click="clearEmojiCache"
|
||||
>
|
||||
{{ $t('settings.clear_emoji_cache') }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="themeDebug"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.theme_debug') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="forceThemeRecompilation"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.force_theme_recompilation_debug') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script src="./developer_tab.js" />
|
||||
|
|
@ -91,6 +91,7 @@ const FilteringTab = {
|
|||
HelpIndicator
|
||||
},
|
||||
computed: {
|
||||
instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel },
|
||||
...SharedComputedObject(),
|
||||
...mapState(
|
||||
useServerSideStorageStore,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
<template>
|
||||
<div
|
||||
:label="$t('settings.filtering')"
|
||||
class="filtering-tab"
|
||||
>
|
||||
<div class="filtering-tab">
|
||||
<div class="setting-item">
|
||||
<h2>{{ $t('settings.filter.clutter') }}</h2>
|
||||
<h3>{{ $t('settings.filter.mute_filter') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
|
|
@ -16,70 +13,6 @@
|
|||
{{ $t('settings.replies_in_timeline') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
expert="1"
|
||||
path="hidePostStats"
|
||||
>
|
||||
{{ $t('settings.hide_post_stats') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
expert="1"
|
||||
path="hideUserStats"
|
||||
>
|
||||
{{ $t('settings.hide_user_stats') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideBotIndication">
|
||||
{{ $t('settings.hide_actor_type_indication') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideScrobbles">
|
||||
{{ $t('settings.hide_scrobbles') }}
|
||||
</BooleanSetting>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<UnitSetting
|
||||
key="hideScrobblesAfter"
|
||||
path="hideScrobblesAfter"
|
||||
:units="['m', 'h', 'd']"
|
||||
unit-set="time"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.hide_scrobbles_after') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<h3>{{ $t('settings.attachments') }}</h3>
|
||||
<li>
|
||||
<IntegerSetting
|
||||
path="maxThumbnails"
|
||||
expert="1"
|
||||
:min="0"
|
||||
>
|
||||
{{ $t('settings.max_thumbnails') }}
|
||||
</IntegerSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideAttachments">
|
||||
{{ $t('settings.hide_attachments_in_tl') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideAttachmentsInConv">
|
||||
{{ $t('settings.hide_attachments_in_convo') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<h2>{{ $t('settings.filter.mute_filter') }}</h2>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
{{ $t('user_card.default_mute_expiration') }}
|
||||
<Select
|
||||
|
|
|
|||
|
|
@ -1,38 +1,18 @@
|
|||
import { mapState } from 'vuex'
|
||||
|
||||
import VerticalTabSwitcher from 'src/components/tab_switcher/vertical_tab_switcher.jsx'
|
||||
|
||||
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 FloatSetting from '../helpers/float_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 { defaultHorizontalUnits } from '../helpers/unit_setting.js'
|
||||
|
||||
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 GeneralTab = {
|
||||
props: {
|
||||
|
|
@ -43,75 +23,24 @@ const GeneralTab = {
|
|||
},
|
||||
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,
|
||||
FloatSetting,
|
||||
FontControl,
|
||||
InterfaceLanguageSwitcher,
|
||||
ProfileSettingIndicator,
|
||||
ScopeSelector,
|
||||
Select,
|
||||
VerticalTabSwitcher,
|
||||
FontControl
|
||||
ProfileSettingIndicator
|
||||
},
|
||||
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) {
|
||||
|
|
@ -124,33 +53,6 @@ const GeneralTab = {
|
|||
})
|
||||
},
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,8 @@
|
|||
<template>
|
||||
<vertical-tab-switcher
|
||||
:label="$t('settings.general')"
|
||||
ref="tabSwitcher"
|
||||
class="settings_tab-switcher"
|
||||
:parent-collapsed="parentCollapsed"
|
||||
@too-small="tooSmall"
|
||||
@too-big="tooBig"
|
||||
>
|
||||
<div
|
||||
:label="$t('settings.behavior')"
|
||||
icon="sliders"
|
||||
>
|
||||
<div>
|
||||
<div class="setting-item">
|
||||
<h3>{{ $t('settings.format_and_language') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<h3>{{ $t('settings.general') }}</h3>
|
||||
<li>
|
||||
<interface-language-switcher
|
||||
v-model="language"
|
||||
|
|
@ -31,13 +21,97 @@
|
|||
</interface-language-switcher>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="useAbsoluteTimeFormat"
|
||||
expert="1"
|
||||
>
|
||||
<BooleanSetting path="useAbsoluteTimeFormat">
|
||||
{{ $t('settings.absolute_time_format') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="absoluteTime12h"
|
||||
path="absoluteTime12h"
|
||||
:options="absoluteTime12hOptions"
|
||||
>
|
||||
{{ $t('settings.absolute_time_format_12h') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.scale_and_font') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="textSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 14, 'rem': 1 }"
|
||||
timed-apply-mode
|
||||
>
|
||||
{{ $t('settings.text_size') }}
|
||||
</UnitSetting>
|
||||
<div>
|
||||
<small>
|
||||
<i18n-t
|
||||
scope="global"
|
||||
keypath="settings.text_size_tip"
|
||||
tag="span"
|
||||
>
|
||||
<code>px</code>
|
||||
<code>rem</code>
|
||||
</i18n-t>
|
||||
<br>
|
||||
<i18n-t
|
||||
scope="global"
|
||||
keypath="settings.text_size_tip2"
|
||||
tag="span"
|
||||
>
|
||||
<code>14px</code>
|
||||
</i18n-t>
|
||||
</small>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.interface"
|
||||
name="ui"
|
||||
:label="$t('settings.style.fonts.components_inline.interface')"
|
||||
:fallback="{ family: 'sans-serif' }"
|
||||
no-inherit="1"
|
||||
@update:model-value="v => updateFont('interface', v)"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.input"
|
||||
name="input"
|
||||
:fallback="{ family: 'inherit' }"
|
||||
:label="$t('settings.style.fonts.components_inline.input')"
|
||||
@update:model-value="v => updateFont('input', v)"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="emojiSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 32, 'rem': 2.2 }"
|
||||
>
|
||||
{{ $t('settings.emoji_size') }}
|
||||
</UnitSetting>
|
||||
<ul
|
||||
class="setting-list suboptions"
|
||||
>
|
||||
<li>
|
||||
<FloatSetting
|
||||
v-if="user"
|
||||
path="emojiReactionsScale"
|
||||
>
|
||||
{{ $t('settings.emoji_reactions_scale') }}
|
||||
</FloatSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.timelines') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting path="streaming">
|
||||
{{ $t('settings.streaming') }}
|
||||
|
|
@ -61,40 +135,9 @@
|
|||
{{ $t('settings.useStreamingApi') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="virtualScrolling"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.virtual_scrolling') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="alwaysShowNewPostButton"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.always_show_post_button') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="autohideFloatingPostButton"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.autohide_floating_post_button') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="userPopoverAvatarAction"
|
||||
path="userPopoverAvatarAction"
|
||||
:options="userPopoverAvatarActionOptions"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_popover_avatar_action') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 v-if="expertLevel > 0">{{ $t('settings.confirmations') }}</h3>
|
||||
<ul v-if="expertLevel > 0" class="setting-list">
|
||||
<li class="select-multiple">
|
||||
<span class="label">{{ $t('settings.confirm_dialogs') }}</span>
|
||||
<ul class="option-list">
|
||||
|
|
@ -155,404 +198,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
:label="$t('settings.posts')"
|
||||
icon="message"
|
||||
>
|
||||
<ul class="setting-list">
|
||||
<h3>{{ $t('settings.general') }}</h3>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="conversationDisplay"
|
||||
path="conversationDisplay"
|
||||
:options="conversationDisplayOptions"
|
||||
>
|
||||
{{ $t('settings.conversation_display') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.post"
|
||||
name="post"
|
||||
:fallback="{ family: 'inherit' }"
|
||||
:label="$t('settings.style.fonts.components.post')"
|
||||
@update:model-value="v => updateFont('post', v)"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.monospace"
|
||||
name="postCode"
|
||||
:fallback="{ family: 'monospace' }"
|
||||
:label="$t('settings.style.fonts.components.monospace')"
|
||||
@update:model-value="v => updateFont('monospace', v)"
|
||||
/>
|
||||
</li>
|
||||
<ul
|
||||
v-if="mergedConfig.conversationDisplay !== 'linear'"
|
||||
class="setting-list suboptions"
|
||||
>
|
||||
<li>
|
||||
<BooleanSetting path="conversationTreeAdvanced">
|
||||
{{ $t('settings.tree_advanced') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="conversationTreeFadeAncestors"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.tree_fade_ancestors') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<IntegerSetting
|
||||
path="maxDepthInThread"
|
||||
:min="3"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.max_depth_in_thread') }}
|
||||
</IntegerSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="conversationOtherRepliesButton"
|
||||
path="conversationOtherRepliesButton"
|
||||
:options="conversationOtherRepliesButtonOptions"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.conversation_other_replies_button') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<li>
|
||||
<BooleanSetting path="collapseMessageWithSubject">
|
||||
{{ $t('settings.collapse_subject') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="emojiReactionsOnTimeline"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.emoji_reactions_on_timeline') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<h3>{{ $t('settings.mention_links') }}</h3>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="mentionLinkDisplay"
|
||||
path="mentionLinkDisplay"
|
||||
:options="mentionLinkDisplayOptions"
|
||||
>
|
||||
{{ $t('settings.mention_link_display') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="mentionLinkShowTooltip"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.mention_link_use_tooltip') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="mentionLinkShowAvatar">
|
||||
{{ $t('settings.mention_link_show_avatar') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="mentionLinkFadeDomain"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.mention_link_fade_domain') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="user">
|
||||
<BooleanSetting
|
||||
path="mentionLinkBoldenYou"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.mention_link_bolden_you') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="user"
|
||||
source="profile"
|
||||
path="stripRichContent"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.no_rich_text_description') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<ul
|
||||
v-if="mergedConfig.useAbsoluteTimeFormat"
|
||||
class="setting-list suboptions"
|
||||
>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="absoluteTimeFormatMinAge"
|
||||
unit-set="time"
|
||||
:units="['s', 'm', 'h', 'd']"
|
||||
:min="0"
|
||||
>
|
||||
{{ $t('settings.absolute_time_format_min_age') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="absoluteTime12h"
|
||||
path="absoluteTime12h"
|
||||
:options="absoluteTime12hOptions"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.absolute_time_format_12h') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.attachments') }}</h3>
|
||||
<li>
|
||||
<BooleanSetting path="stopGifs">
|
||||
{{ $t('settings.stop_gifs') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideNsfw">
|
||||
{{ $t('settings.nsfw_clickthrough') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="preloadImage"
|
||||
expert="1"
|
||||
parent-path="hideNsfw"
|
||||
>
|
||||
{{ $t('settings.preload_images') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="useOneClickNsfw"
|
||||
expert="1"
|
||||
parent-path="hideNsfw"
|
||||
>
|
||||
{{ $t('settings.use_one_click_nsfw') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="loopVideo"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.loop_video') }}
|
||||
</BooleanSetting>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="loopVideoSilentOnly"
|
||||
expert="1"
|
||||
parent-path="loopVideo"
|
||||
:disabled="!loopSilentAvailable"
|
||||
>
|
||||
{{ $t('settings.loop_video_silent_only') }}
|
||||
</BooleanSetting>
|
||||
<div
|
||||
v-if="!loopSilentAvailable"
|
||||
class="unavailable"
|
||||
>
|
||||
<FAIcon icon="globe" />! {{ $t('settings.limited_availability') }}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="playVideosInModal"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.play_videos_in_modal') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="useContainFit"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.use_contain_fit') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<h3 v-if="expertLevel > 0">
|
||||
{{ $t('settings.fun') }}
|
||||
</h3>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="greentext"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.greentext') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="user">
|
||||
<BooleanSetting
|
||||
path="mentionLinkShowYous"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.show_yous') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
v-if="user"
|
||||
:label="$t('settings.composing')"
|
||||
icon="pen-alt"
|
||||
>
|
||||
<ul class="setting-list">
|
||||
<h3>{{ $t('settings.composing') }}</h3>
|
||||
<li>
|
||||
<label for="default-vis">
|
||||
{{ $t('settings.default_vis') }} <ProfileSettingIndicator :is-profile="true" />
|
||||
<ScopeSelector
|
||||
class="scope-selector"
|
||||
:show-all="true"
|
||||
:user-default="$store.state.profileConfig.defaultScope"
|
||||
:initial-scope="$store.state.profileConfig.defaultScope"
|
||||
:on-scope-change="changeDefaultScope"
|
||||
/>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<!-- <BooleanSetting source="profile" path="defaultNSFW"> -->
|
||||
<BooleanSetting path="sensitiveByDefault">
|
||||
{{ $t('settings.sensitive_by_default') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="scopeCopy"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.scope_copy') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="alwaysShowSubjectInput"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.subject_input_always_show') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="subjectLineBehavior"
|
||||
path="subjectLineBehavior"
|
||||
:options="subjectLineOptions"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.subject_line_behavior') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li v-if="postFormats.length > 0">
|
||||
<ChoiceSetting
|
||||
id="postContentType"
|
||||
path="postContentType"
|
||||
:options="postContentOptions"
|
||||
>
|
||||
{{ $t('settings.post_status_content_type') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="minimalScopesMode"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.minimal_scopes_mode') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="padEmoji"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.pad_emoji') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="autocompleteSelect"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.autocomplete_select_first') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="autoSaveDraft"
|
||||
>
|
||||
{{ $t('settings.auto_save_draft') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="!mergedConfig.autoSaveDraft">
|
||||
<ChoiceSetting
|
||||
id="unsavedPostAction"
|
||||
path="unsavedPostAction"
|
||||
:options="unsavedPostActionOptions"
|
||||
>
|
||||
{{ $t('settings.unsaved_post_action') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<h3>{{ $t('settings.attachments') }}</h3>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="imageCompression"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.image_compression') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="alwaysUseJpeg"
|
||||
expert="1"
|
||||
parent-path="imageCompression"
|
||||
>
|
||||
{{ $t('settings.always_use_jpeg') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
:label="$t('settings.cache')"
|
||||
icon="database"
|
||||
v-if="expertLevel > 0"
|
||||
>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<button
|
||||
class="btn button-default"
|
||||
@click="clearAssetCache"
|
||||
>
|
||||
{{ $t('settings.clear_asset_cache') }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
class="btn button-default"
|
||||
@click="clearEmojiCache"
|
||||
>
|
||||
{{ $t('settings.clear_emoji_cache') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</vertical-tab-switcher>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./general_tab.js"></script>
|
||||
|
|
|
|||
49
src/components/settings_modal/tabs/layout_tab.js
Normal file
49
src/components/settings_modal/tabs/layout_tab.js
Normal file
|
|
@ -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
|
||||
130
src/components/settings_modal/tabs/layout_tab.vue
Normal file
130
src/components/settings_modal/tabs/layout_tab.vue
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<template>
|
||||
<div :label="$t('settings.layout')">
|
||||
<div class="setting-item">
|
||||
<h3>{{ $t('settings.general') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting path="modalMobileCenter">
|
||||
{{ $t('settings.mobile_center_dialog') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="alwaysShowNewPostButton"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.always_show_post_button') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="autohideFloatingPostButton"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.autohide_floating_post_button') }}
|
||||
</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="userPopoverOverlay"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_popover_avatar_overlay') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="userCardLeftJustify"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.user_card_left_justify') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="themeEditorMinWidth"
|
||||
:units="['px', 'rem']"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.theme_editor_min_width') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.columns') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="navbarSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 55, 'rem': 3.5 }"
|
||||
>
|
||||
{{ $t('settings.navbar_size') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
<li v-if="instanceSpecificPanelPresent">
|
||||
<BooleanSetting path="hideISP">
|
||||
{{ $t('settings.hide_isp') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="panelHeaderSize"
|
||||
:step="0.1"
|
||||
:units="['px', 'rem']"
|
||||
:reset-default="{ 'px': 52, 'rem': 3.2 }"
|
||||
timed-apply-mode
|
||||
>
|
||||
{{ $t('settings.panel_header_size') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="sidebarRight">
|
||||
{{ $t('settings.right_sidebar') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="navbarColumnStretch">
|
||||
{{ $t('settings.navbar_column_stretch') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
v-if="user"
|
||||
id="thirdColumnMode"
|
||||
path="thirdColumnMode"
|
||||
:options="thirdColumnModeOptions"
|
||||
>
|
||||
{{ $t('settings.third_column_mode') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li v-if="expertLevel > 0">
|
||||
{{ $t('settings.column_sizes') }}
|
||||
<div class="column-settings">
|
||||
<UnitSetting
|
||||
v-for="column in columns"
|
||||
:key="column"
|
||||
:path="column + 'ColumnWidth'"
|
||||
:units="horizontalUnits"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.column_sizes_' + column) }}
|
||||
</UnitSetting>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./layout_tab.js"></script>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
.theme-tab {
|
||||
.old-theme-tab {
|
||||
min-width: var(--themeEditorMinWidth, fit-content);
|
||||
|
||||
.deprecation-warning {
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="theme-tab">
|
||||
<div class="old-theme-tab">
|
||||
<div class="alert warning deprecation-warning">
|
||||
{{ $t("settings.style.themes2_outdated") }}
|
||||
</div>
|
||||
|
|
@ -1020,6 +1020,6 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./theme_tab.js"></script>
|
||||
<script src="./old_theme_tab.js"></script>
|
||||
|
||||
<style src="./theme_tab.scss" lang="scss"></style>
|
||||
<style src="./old_theme_tab.scss" lang="scss"></style>
|
||||
76
src/components/settings_modal/tabs/posts_tab.js
Normal file
76
src/components/settings_modal/tabs/posts_tab.js
Normal file
|
|
@ -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
|
||||
5
src/components/settings_modal/tabs/posts_tab.scss
Normal file
5
src/components/settings_modal/tabs/posts_tab.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.posts-tab {
|
||||
.greentext {
|
||||
color: var(--funtextGreentext);
|
||||
}
|
||||
}
|
||||
253
src/components/settings_modal/tabs/posts_tab.vue
Normal file
253
src/components/settings_modal/tabs/posts_tab.vue
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
<template>
|
||||
<div class="posts-tab">
|
||||
<div class="setting-item">
|
||||
<h3>{{ $t('settings.posts_appearance') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting path="collapseMessageWithSubject">
|
||||
{{ $t('settings.collapse_subject') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="conversationDisplay"
|
||||
path="conversationDisplay"
|
||||
:options="conversationDisplayOptions"
|
||||
>
|
||||
{{ $t('settings.conversation_display') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.post"
|
||||
name="post"
|
||||
:fallback="{ family: 'inherit' }"
|
||||
:label="$t('settings.style.fonts.components.post')"
|
||||
@update:model-value="v => updateFont('post', v)"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<FontControl
|
||||
:model-value="mergedConfig.theme3hacks.fonts.monospace"
|
||||
name="postCode"
|
||||
:fallback="{ family: 'monospace' }"
|
||||
:label="$t('settings.style.fonts.components.monospace')"
|
||||
@update:model-value="v => updateFont('monospace', v)"
|
||||
/>
|
||||
</li>
|
||||
<ul
|
||||
v-if="mergedConfig.conversationDisplay !== 'linear'"
|
||||
class="setting-list suboptions"
|
||||
>
|
||||
<li>
|
||||
<BooleanSetting path="conversationTreeAdvanced">
|
||||
{{ $t('settings.tree_advanced') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="conversationTreeFadeAncestors"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.tree_fade_ancestors') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<IntegerSetting
|
||||
path="maxDepthInThread"
|
||||
:min="3"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.max_depth_in_thread') }}
|
||||
</IntegerSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="conversationOtherRepliesButton"
|
||||
path="conversationOtherRepliesButton"
|
||||
:options="conversationOtherRepliesButtonOptions"
|
||||
:expert="1"
|
||||
>
|
||||
{{ $t('settings.conversation_other_replies_button') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<li>
|
||||
<BooleanSetting path="greentext">
|
||||
<i18n-t
|
||||
keypath="settings.plaintext_quotes"
|
||||
tag="span"
|
||||
>
|
||||
<span class="greentext">
|
||||
{{ $t('settings.greentext_quotes') }}
|
||||
</span>
|
||||
</i18n-t>
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="emojiReactionsOnTimeline"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.emoji_reactions_on_timeline') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.mention_links') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="mentionLinkDisplay"
|
||||
path="mentionLinkDisplay"
|
||||
:options="mentionLinkDisplayOptions"
|
||||
>
|
||||
{{ $t('settings.mention_link_display') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="mentionLinkShowTooltip"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.mention_link_use_tooltip') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="mentionLinkShowAvatar">
|
||||
{{ $t('settings.mention_link_show_avatar') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="mergedConfig.mentionLinkDisplay !== 'short'"
|
||||
path="mentionLinkFadeDomain"
|
||||
>
|
||||
{{ $t('settings.mention_link_fade_domain') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li v-if="user">
|
||||
<BooleanSetting
|
||||
path="mentionLinkBoldenYou"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.mention_link_bolden_you') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="user"
|
||||
source="profile"
|
||||
path="stripRichContent"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.no_rich_text_description') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<ul
|
||||
v-if="mergedConfig.useAbsoluteTimeFormat"
|
||||
class="setting-list suboptions"
|
||||
>
|
||||
<li>
|
||||
<UnitSetting
|
||||
path="absoluteTimeFormatMinAge"
|
||||
unit-set="time"
|
||||
:units="['s', 'm', 'h', 'd']"
|
||||
:min="0"
|
||||
>
|
||||
{{ $t('settings.absolute_time_format_min_age') }}
|
||||
</UnitSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<h3>{{ $t('settings.attachments') }}</h3>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting path="stopGifs">
|
||||
{{ $t('settings.stop_gifs') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="hideNsfw">
|
||||
{{ $t('settings.nsfw_clickthrough') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="preloadImage"
|
||||
expert="1"
|
||||
parent-path="hideNsfw"
|
||||
>
|
||||
{{ $t('settings.preload_images') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="useOneClickNsfw"
|
||||
expert="1"
|
||||
parent-path="hideNsfw"
|
||||
>
|
||||
{{ $t('settings.use_one_click_nsfw') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="loopVideo"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.loop_video') }}
|
||||
</BooleanSetting>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="loopVideoSilentOnly"
|
||||
expert="1"
|
||||
parent-path="loopVideo"
|
||||
:disabled="!loopSilentAvailable"
|
||||
>
|
||||
{{ $t('settings.loop_video_silent_only') }}
|
||||
</BooleanSetting>
|
||||
<div
|
||||
v-if="!loopSilentAvailable"
|
||||
class="unavailable"
|
||||
>
|
||||
<FAIcon icon="globe" />! {{ $t('settings.limited_availability') }}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="playVideosInModal"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.play_videos_in_modal') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="useContainFit"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.use_contain_fit') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<h3 v-if="expertLevel > 0">
|
||||
{{ $t('settings.fun') }}
|
||||
</h3>
|
||||
<li v-if="user">
|
||||
<BooleanSetting
|
||||
path="mentionLinkShowYous"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.show_yous') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./posts_tab.js"></script>
|
||||
<style src="./posts_tab.scss"></style>
|
||||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
<template>
|
||||
<div :label="$t('settings.version.title')">
|
||||
<div class="setting-item">
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<p>{{ $t('settings.version.backend_version') }}</p>
|
||||
<ul class="option-list">
|
||||
<li>
|
||||
<a
|
||||
:href="backendRepository"
|
||||
target="_blank"
|
||||
>{{ backendVersion }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>{{ $t('settings.version.frontend_version') }}</p>
|
||||
<ul class="option-list">
|
||||
<li>
|
||||
<a
|
||||
:href="frontendVersionLink"
|
||||
target="_blank"
|
||||
>{{ frontendVersion }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script src="./version_tab.js" />
|
||||
|
|
@ -44,7 +44,6 @@ export default {
|
|||
default: null
|
||||
}
|
||||
},
|
||||
emits: ['tooBig', 'tooSmall', 'sideSwitch'],
|
||||
data () {
|
||||
return {
|
||||
active: findFirstUsable(this.slots()),
|
||||
|
|
@ -103,24 +102,9 @@ export default {
|
|||
this.active = index
|
||||
this.changeNavSide('content')
|
||||
},
|
||||
showNav () {
|
||||
if (this.navMode) {
|
||||
this.navMode = false
|
||||
this.changeNavSide(null)
|
||||
this.onResize()
|
||||
}
|
||||
},
|
||||
hideNav () {
|
||||
if (!this.navMode) {
|
||||
this.navMode = true
|
||||
this.changeNavSide('content')
|
||||
this.onResize()
|
||||
}
|
||||
},
|
||||
changeNavSide (side) {
|
||||
if (this.navSide !== side) {
|
||||
this.navSide = side
|
||||
this.$emit('sideSwitch', side)
|
||||
this.onResize()
|
||||
}
|
||||
},
|
||||
|
|
@ -139,21 +123,12 @@ export default {
|
|||
|
||||
// if contents takes more space than its container
|
||||
if (contentsWidth < tabContentWidth) {
|
||||
if (this.parentCollapsed) {
|
||||
this.hideNav()
|
||||
} else {
|
||||
this.$emit('tooSmall')
|
||||
}
|
||||
// FIXME wrong again??
|
||||
this.hideNav()
|
||||
// If we (theoretically) have enough space to fit it in
|
||||
} else if (contentsWidth - navWidth >= tabContentWidth){
|
||||
// First expand the inner layer, then outer
|
||||
// if use same logic as above order will be reversed
|
||||
if (!this.navMode) {
|
||||
this.$emit('tooBig')
|
||||
} else {
|
||||
this.showNav()
|
||||
}
|
||||
this.showNav()
|
||||
}
|
||||
},
|
||||
// DO NOT put it to computed, it doesn't work (caching?)
|
||||
|
|
|
|||
|
|
@ -404,6 +404,7 @@
|
|||
"enter_current_password_to_confirm": "Enter your current password to confirm your identity",
|
||||
"post_look_feel": "Posts Look & Feel",
|
||||
"posts": "Posts",
|
||||
"developer": "Developer",
|
||||
"mention_links": "Mention links",
|
||||
"appearance": "Appearance",
|
||||
"confirm_new_setting": "Confirm new setting?",
|
||||
|
|
@ -419,9 +420,12 @@
|
|||
"visual_tweaks": "Minor visual tweaks",
|
||||
"theme_debug": "Show what background theme engine assumes when dealing with transparancy (DEBUG)",
|
||||
"scale_and_layout": "Interface scale and layout",
|
||||
"behavior": "Behavior",
|
||||
"timelines": "Timelines",
|
||||
"format_and_language": "Format and Language",
|
||||
"confirmations": "Confirmations",
|
||||
"layout": "Layout",
|
||||
"enabled": "Enabled",
|
||||
"clutter": "Clutter",
|
||||
"filter": {
|
||||
"clutter": "Remove clutter",
|
||||
"mute_filter": "Mute Filters",
|
||||
|
|
@ -536,6 +540,7 @@
|
|||
"chatMessageRadius": "Chat message",
|
||||
"collapse_subject": "Collapse posts with subjects",
|
||||
"composing": "Composing",
|
||||
"replies": "Replying",
|
||||
"confirm_new_password": "Confirm new password",
|
||||
"current_password": "Current password",
|
||||
"confirm_dialogs": "Ask for confirmation when",
|
||||
|
|
@ -763,6 +768,8 @@
|
|||
"column_sizes_sidebar": "Sidebar",
|
||||
"column_sizes_content": "Content",
|
||||
"column_sizes_notifs": "Notifications",
|
||||
"layout": "Layout",
|
||||
"scale_and_font": "Scale and Font",
|
||||
"theme_editor_min_width": "Minimum width of theme editor (0 for \"fit-content\")",
|
||||
"tree_advanced": "Allow more flexible navigation in tree view",
|
||||
"tree_fade_ancestors": "Display ancestors of the current status in faint text",
|
||||
|
|
@ -773,6 +780,7 @@
|
|||
"conversation_other_replies_button_inside": "Inside statuses",
|
||||
"max_depth_in_thread": "Maximum number of levels in thread to display by default",
|
||||
"post_status_content_type": "Post status content type",
|
||||
"default_post_status_content_type": "Default post status content type",
|
||||
"sensitive_by_default": "Mark posts as sensitive by default",
|
||||
"stop_gifs": "Pause animated images until you hover on them",
|
||||
"streaming": "Automatically show new posts when scrolled to the top",
|
||||
|
|
@ -814,8 +822,11 @@
|
|||
"user_popover_avatar_overlay": "Show user popover over user avatar",
|
||||
"user_card_left_justify": "Justify user bio to the left",
|
||||
"user_card_hide_personal_marks": "Hide personal marks (highlight/note) in user profiles",
|
||||
"posts_appearance": "Posts appearance",
|
||||
"fun": "Fun",
|
||||
"greentext": "Meme arrows",
|
||||
"plaintext_quotes": "Highlight plaintext {0}",
|
||||
"greentext_quotes": ">quotes",
|
||||
"show_yous": "Show (You)s",
|
||||
"notifications": "Notifications",
|
||||
"notification_setting_annoyance": "Annoyance",
|
||||
|
|
@ -841,6 +852,7 @@
|
|||
"stock_theme_used": "(Stock theme)",
|
||||
"themes2_outdated": "Editor for Themes V2 is being phased out and will eventually be replaced with a new one that takes advantage of new Themes V3 engine. It should still work but experience might be degraded and inconsistent.",
|
||||
"appearance_tab_note": "Changes on this tab do not affect the theme used, so exported theme will be different from what seen in the UI",
|
||||
"visual_tweaks_section_note": "Changes in this section do not affect the theme used, exported theme will be different from what seen in the UI",
|
||||
"update_preview": "Update preview",
|
||||
"themes3": {
|
||||
"define": "Override",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue