working prototype
This commit is contained in:
parent
50ede338e7
commit
7c57be22e4
15 changed files with 266 additions and 215 deletions
|
|
@ -1,14 +1,26 @@
|
||||||
.settings-modal {
|
.settings-modal {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
h3 {
|
h2 {
|
||||||
font-size: 1.4rem;
|
font-size: 1.3rem;
|
||||||
|
font-weight: 500;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h3 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
padding-bottom: 0.25em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.1rem;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
@ -16,19 +28,21 @@
|
||||||
h5 {
|
h5 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-list,
|
.setting-list,
|
||||||
.option-list {
|
.option-list {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding-left: 2em;
|
padding-left: 2em;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
.btn:not(.dropdown-button) {
|
.btn:not(.dropdown-button) {
|
||||||
padding: 0 2em;
|
padding: 0 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
margin-bottom: 0.5em;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.suboptions {
|
.suboptions {
|
||||||
|
|
@ -55,7 +69,7 @@
|
||||||
transition: transform;
|
transition: transform;
|
||||||
transition-timing-function: ease-in-out;
|
transition-timing-function: ease-in-out;
|
||||||
transition-duration: 300ms;
|
transition-duration: 300ms;
|
||||||
width: 1000px;
|
width: 70em;
|
||||||
max-width: 90vw;
|
max-width: 90vw;
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
|
|
||||||
|
|
@ -90,6 +104,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.-mobile {
|
&.-mobile {
|
||||||
|
.tabs {
|
||||||
|
.menu-item {
|
||||||
|
font-size: 1.2em
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.setting-list,
|
.setting-list,
|
||||||
.option-list {
|
.option-list {
|
||||||
padding-left: 0.25em;
|
padding-left: 0.25em;
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,6 @@ const SettingsModalContent = {
|
||||||
},
|
},
|
||||||
expertLevel () {
|
expertLevel () {
|
||||||
return this.$store.state.config.expertLevel
|
return this.$store.state.config.expertLevel
|
||||||
},
|
|
||||||
isMobileLayout () {
|
|
||||||
return useInterfaceStore().layoutType === 'mobile'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
|
@ -108,21 +105,6 @@ const SettingsModalContent = {
|
||||||
// Clear the state of target tab, so that next time settings is opened
|
// Clear the state of target tab, so that next time settings is opened
|
||||||
// it doesn't force it.
|
// it doesn't force it.
|
||||||
useInterfaceStore().clearSettingsModalTargetTab()
|
useInterfaceStore().clearSettingsModalTargetTab()
|
||||||
},
|
|
||||||
nestedTooBig () {
|
|
||||||
if (this.navCollapsed) {
|
|
||||||
this.navCollapsed = false
|
|
||||||
this.$refs.tabSwitcher.showNav()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
nestedTooSmall () {
|
|
||||||
if (!this.navCollapsed) {
|
|
||||||
this.navCollapsed = true
|
|
||||||
this.$refs.tabSwitcher.hideNav()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
nestedNavSide (side) {
|
|
||||||
this.navHideHeader = side === 'content'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,6 @@
|
||||||
.settings_tab-switcher {
|
.settings_tab-switcher {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin-top: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-item {
|
.setting-item {
|
||||||
border-bottom: 2px solid var(--border);
|
border-bottom: 2px solid var(--border);
|
||||||
margin: 1em 1em 1.4em;
|
margin: 1em 1em 1.4em;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
:hide-header="navHideHeader"
|
:hide-header="navHideHeader"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:full-width="true"
|
|
||||||
:label="$t('settings.general')"
|
:label="$t('settings.general')"
|
||||||
icon="wrench"
|
icon="wrench"
|
||||||
data-tab-name="general"
|
data-tab-name="general"
|
||||||
|
|
@ -16,16 +15,15 @@
|
||||||
<GeneralTab />
|
<GeneralTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
v-if="isLoggedIn"
|
||||||
|
:label="$t('settings.profile_tab')"
|
||||||
|
icon="user"
|
||||||
|
data-tab-name="profile"
|
||||||
:full-width="true"
|
:full-width="true"
|
||||||
:label="$t('settings.posts')"
|
|
||||||
icon="message"
|
|
||||||
data-tab-name="posts"
|
|
||||||
:delay-render="true"
|
|
||||||
>
|
>
|
||||||
<PostsTab />
|
<ProfileTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
:full-width="true"
|
|
||||||
:label="$t('settings.composing')"
|
:label="$t('settings.composing')"
|
||||||
icon="pen-alt"
|
icon="pen-alt"
|
||||||
data-tab-name="composing"
|
data-tab-name="composing"
|
||||||
|
|
@ -34,13 +32,12 @@
|
||||||
<ComposingTab />
|
<ComposingTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
:full-width="true"
|
:label="$t('settings.posts')"
|
||||||
:label="$t('settings.layout')"
|
icon="message"
|
||||||
icon="table-columns"
|
data-tab-name="posts"
|
||||||
data-tab-name="layout"
|
|
||||||
:delay-render="true"
|
:delay-render="true"
|
||||||
>
|
>
|
||||||
<LayoutTab />
|
<PostsTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
:full-width="true"
|
:full-width="true"
|
||||||
|
|
@ -52,39 +49,26 @@
|
||||||
<AppearanceTab />
|
<AppearanceTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="isLoggedIn"
|
:full-width="true"
|
||||||
:label="$t('settings.profile_tab')"
|
:label="$t('settings.layout')"
|
||||||
icon="user"
|
icon="table-columns"
|
||||||
data-tab-name="profile"
|
data-tab-name="layout"
|
||||||
|
:delay-render="true"
|
||||||
>
|
>
|
||||||
<ProfileTab />
|
<LayoutTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="isLoggedIn"
|
v-if="isLoggedIn"
|
||||||
|
:full-width="true"
|
||||||
:label="$t('settings.notifications')"
|
:label="$t('settings.notifications')"
|
||||||
icon="bell"
|
icon="bell"
|
||||||
data-tab-name="notifications"
|
data-tab-name="notifications"
|
||||||
>
|
>
|
||||||
<NotificationsTab />
|
<NotificationsTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
v-if="isLoggedIn"
|
|
||||||
:label="$t('settings.security_tab')"
|
|
||||||
icon="lock"
|
|
||||||
data-tab-name="security"
|
|
||||||
>
|
|
||||||
<SecurityTab />
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
:label="$t('settings.clutter')"
|
|
||||||
:fullHeight="true"
|
|
||||||
icon="broom"
|
|
||||||
data-tab-name="mutesAndBlocks"
|
|
||||||
>
|
|
||||||
<ClutterTab />
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
:label="$t('settings.filtering')"
|
:label="$t('settings.filtering')"
|
||||||
|
:full-width="true"
|
||||||
icon="filter"
|
icon="filter"
|
||||||
data-tab-name="filtering"
|
data-tab-name="filtering"
|
||||||
>
|
>
|
||||||
|
|
@ -99,6 +83,22 @@
|
||||||
>
|
>
|
||||||
<MutesAndBlocksTab />
|
<MutesAndBlocksTab />
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
:label="$t('settings.clutter')"
|
||||||
|
:fullHeight="true"
|
||||||
|
icon="broom"
|
||||||
|
data-tab-name="clutter"
|
||||||
|
>
|
||||||
|
<ClutterTab />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isLoggedIn"
|
||||||
|
:label="$t('settings.security_tab')"
|
||||||
|
icon="lock"
|
||||||
|
data-tab-name="security"
|
||||||
|
>
|
||||||
|
<SecurityTab />
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="isLoggedIn"
|
v-if="isLoggedIn"
|
||||||
:label="$t('settings.data_import_export_tab')"
|
:label="$t('settings.data_import_export_tab')"
|
||||||
|
|
@ -123,7 +123,7 @@
|
||||||
data-tab-name="theme"
|
data-tab-name="theme"
|
||||||
:delay-render="true"
|
:delay-render="true"
|
||||||
>
|
>
|
||||||
<ThemeTab />
|
<OldThemeTab />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="expertLevel > 0"
|
v-if="expertLevel > 0"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
.appearance-tab {
|
.appearance-tab {
|
||||||
|
h3 {
|
||||||
|
border: none
|
||||||
|
}
|
||||||
|
|
||||||
.palette,
|
.palette,
|
||||||
.theme-notice {
|
.theme-notice {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
|
@ -10,14 +14,6 @@
|
||||||
padding-bottom: 0.5em;
|
padding-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin: 2em 0;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="file"] {
|
input[type="file"] {
|
||||||
padding: 0.25em;
|
padding: 0.25em;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
.data-import-export-tab {
|
||||||
|
h3 {
|
||||||
|
margin-right: -2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
class="data-import-export-tab"
|
||||||
:label="$t('settings.data_import_export_tab')"
|
:label="$t('settings.data_import_export_tab')"
|
||||||
>
|
>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.follow_import') }}</h2>
|
<h3>{{ $t('settings.follow_import') }}</h3>
|
||||||
<p>{{ $t('settings.import_followers_from_a_csv_file') }}</p>
|
<p>{{ $t('settings.import_followers_from_a_csv_file') }}</p>
|
||||||
<Importer
|
<Importer
|
||||||
:submit-handler="importFollows"
|
:submit-handler="importFollows"
|
||||||
|
|
@ -12,7 +13,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.follow_export') }}</h2>
|
<h3>{{ $t('settings.follow_export') }}</h3>
|
||||||
<Exporter
|
<Exporter
|
||||||
:get-content="getFollowsContent"
|
:get-content="getFollowsContent"
|
||||||
filename="friends.csv"
|
filename="friends.csv"
|
||||||
|
|
@ -20,7 +21,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.block_import') }}</h2>
|
<h3>{{ $t('settings.block_import') }}</h3>
|
||||||
<p>{{ $t('settings.import_blocks_from_a_csv_file') }}</p>
|
<p>{{ $t('settings.import_blocks_from_a_csv_file') }}</p>
|
||||||
<Importer
|
<Importer
|
||||||
:submit-handler="importBlocks"
|
:submit-handler="importBlocks"
|
||||||
|
|
@ -29,7 +30,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.block_export') }}</h2>
|
<h3>{{ $t('settings.block_export') }}</h3>
|
||||||
<Exporter
|
<Exporter
|
||||||
:get-content="getBlocksContent"
|
:get-content="getBlocksContent"
|
||||||
filename="blocks.csv"
|
filename="blocks.csv"
|
||||||
|
|
@ -37,7 +38,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.mute_import') }}</h2>
|
<h3>{{ $t('settings.mute_import') }}</h3>
|
||||||
<p>{{ $t('settings.import_mutes_from_a_csv_file') }}</p>
|
<p>{{ $t('settings.import_mutes_from_a_csv_file') }}</p>
|
||||||
<Importer
|
<Importer
|
||||||
:submit-handler="importMutes"
|
:submit-handler="importMutes"
|
||||||
|
|
@ -46,7 +47,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.mute_export') }}</h2>
|
<h3>{{ $t('settings.mute_export') }}</h3>
|
||||||
<Exporter
|
<Exporter
|
||||||
:get-content="getMutesContent"
|
:get-content="getMutesContent"
|
||||||
filename="mutes.csv"
|
filename="mutes.csv"
|
||||||
|
|
@ -54,7 +55,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.account_backup') }}</h2>
|
<h3>{{ $t('settings.account_backup') }}</h3>
|
||||||
<p>{{ $t('settings.account_backup_description') }}</p>
|
<p>{{ $t('settings.account_backup_description') }}</p>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
|
@ -128,4 +129,4 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./data_import_export_tab.js"></script>
|
<script src="./data_import_export_tab.js"></script>
|
||||||
<!-- <style lang="scss" src="./profile.scss"></style> -->
|
<style lang="scss" src="./data_import_export_tab.scss"></style>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
import BooleanSetting from '../helpers/boolean_setting.vue'
|
||||||
|
|
||||||
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
|
|
||||||
|
import { clearCache, cacheKey, emojiCacheKey } from 'src/services/sw/sw.js'
|
||||||
|
|
||||||
const pleromaFeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma-fe/commit/'
|
const pleromaFeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma-fe/commit/'
|
||||||
|
|
||||||
const VersionTab = {
|
const VersionTab = {
|
||||||
|
|
@ -9,10 +15,14 @@ const VersionTab = {
|
||||||
frontendVersion: instance.frontendVersion
|
frontendVersion: instance.frontendVersion
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
BooleanSetting
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
frontendVersionLink () {
|
frontendVersionLink () {
|
||||||
return pleromaFeCommitUrl + this.frontendVersion
|
return pleromaFeCommitUrl + this.frontendVersion
|
||||||
}
|
},
|
||||||
|
...SharedComputedObject(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
src/components/settings_modal/tabs/developer_tab.scss
Normal file
10
src/components/settings_modal/tabs/developer_tab.scss
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
.developer-tab {
|
||||||
|
dt {
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,32 +1,31 @@
|
||||||
<template>
|
<template>
|
||||||
<div :label="$t('settings.developer')">
|
<div
|
||||||
<div class="setting-item">
|
:label="$t('settings.developer')"
|
||||||
<ul class="setting-list">
|
class="developer-tab"
|
||||||
<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">
|
<div class="setting-item">
|
||||||
|
<h3>{{ $t('settings.version.title')}}</h3>
|
||||||
|
<dl class="setting-list">
|
||||||
|
<dt>{{ $t('settings.version.backend_version') }}</dt>
|
||||||
|
<dd>
|
||||||
|
<a
|
||||||
|
:href="backendRepository"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{{ backendVersion }}
|
||||||
|
</a>
|
||||||
|
</dd>
|
||||||
|
<dt>{{ $t('settings.version.frontend_version') }}</dt>
|
||||||
|
<dd>
|
||||||
|
<a
|
||||||
|
:href="frontendVersionLink"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{{ frontendVersion }}
|
||||||
|
</a>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h3>{{ $t('settings.debug')}}</h3>
|
||||||
<ul class="setting-list">
|
<ul class="setting-list">
|
||||||
<li>
|
<li>
|
||||||
<BooleanSetting path="virtualScrolling">
|
<BooleanSetting path="virtualScrolling">
|
||||||
|
|
@ -70,3 +69,4 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script src="./developer_tab.js" />
|
<script src="./developer_tab.js" />
|
||||||
|
<style lang="scss" src="./developer_tab.scss"></style>
|
||||||
|
|
|
||||||
|
|
@ -233,9 +233,11 @@
|
||||||
{{ $t('settings.use_contain_fit') }}
|
{{ $t('settings.use_contain_fit') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
<h3 v-if="expertLevel > 0">
|
</ul>
|
||||||
{{ $t('settings.fun') }}
|
<h3 v-if="expertLevel > 0">
|
||||||
</h3>
|
{{ $t('settings.fun') }}
|
||||||
|
</h3>
|
||||||
|
<ul class="setting-list">
|
||||||
<li v-if="user">
|
<li v-if="user">
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
path="mentionLinkShowYous"
|
path="mentionLinkShowYous"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="profile-tab">
|
<div class="profile-tab">
|
||||||
<div class="setting-item profile-edit">
|
<div class="setting-item profile-edit">
|
||||||
<h2>{{ $t('settings.account_profile_edit') }}</h2>
|
<h3>{{ $t('settings.account_profile_edit') }}</h3>
|
||||||
<UserCard
|
<UserCard
|
||||||
:user-id="user.id"
|
:user-id="user.id"
|
||||||
:editable="true"
|
:editable="true"
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.account_privacy') }}</h2>
|
<h3>{{ $t('settings.account_privacy') }}</h3>
|
||||||
<ul class="setting-list">
|
<ul class="setting-list">
|
||||||
<li>
|
<li>
|
||||||
<Checkbox v-model="locked">
|
<Checkbox v-model="locked">
|
||||||
|
|
|
||||||
|
|
@ -37,19 +37,13 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: null
|
default: null
|
||||||
},
|
|
||||||
hideHeader: {
|
|
||||||
required: false,
|
|
||||||
type: Boolean,
|
|
||||||
default: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
active: findFirstUsable(this.slots()),
|
active: findFirstUsable(this.slots()),
|
||||||
resizeHandler: null,
|
resizeHandler: null,
|
||||||
navMode: false,
|
navSide: 'tabs'
|
||||||
navSide: 'content'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -71,16 +65,6 @@ export default {
|
||||||
mobileLayout: store => store.layoutType === 'mobile'
|
mobileLayout: store => store.layoutType === 'mobile'
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
created () {
|
|
||||||
this.resizeHandler = throttle(this.onResize, 200)
|
|
||||||
window.addEventListener('resize', this.resizeHandler)
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
this.resizeHandler()
|
|
||||||
},
|
|
||||||
unmounted () {
|
|
||||||
window.removeEventListener('resize', this.resizeHandler)
|
|
||||||
},
|
|
||||||
beforeUpdate () {
|
beforeUpdate () {
|
||||||
const currentSlot = this.slots()[this.active]
|
const currentSlot = this.slots()[this.active]
|
||||||
if (!currentSlot.props) {
|
if (!currentSlot.props) {
|
||||||
|
|
@ -92,7 +76,6 @@ export default {
|
||||||
return (e) => {
|
return (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.setTab(index)
|
this.setTab(index)
|
||||||
this.onResize()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setTab (index) {
|
setTab (index) {
|
||||||
|
|
@ -105,30 +88,6 @@ export default {
|
||||||
changeNavSide (side) {
|
changeNavSide (side) {
|
||||||
if (this.navSide !== side) {
|
if (this.navSide !== side) {
|
||||||
this.navSide = side
|
this.navSide = side
|
||||||
this.onResize()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getNavMode () {
|
|
||||||
return this.navMode
|
|
||||||
},
|
|
||||||
onResize () {
|
|
||||||
// All other tabs are hidden and their width is most likely 0
|
|
||||||
const activeTab = this.$refs.root.querySelector('.tab-content-wrapper.-active')
|
|
||||||
const tabContent = activeTab.querySelector('.tab-content')
|
|
||||||
const tabContentWidth = tabContent.clientWidth
|
|
||||||
|
|
||||||
const rootWidth = this.$refs.root.clientWidth
|
|
||||||
const navWidth = this.$refs.nav.clientWidth
|
|
||||||
const contentsWidth = rootWidth - navWidth
|
|
||||||
|
|
||||||
// if contents takes more space than its container
|
|
||||||
if (contentsWidth < tabContentWidth) {
|
|
||||||
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
|
|
||||||
this.showNav()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// DO NOT put it to computed, it doesn't work (caching?)
|
// DO NOT put it to computed, it doesn't work (caching?)
|
||||||
|
|
@ -145,7 +104,7 @@ export default {
|
||||||
const props = slot.props
|
const props = slot.props
|
||||||
if (!props) return
|
if (!props) return
|
||||||
const classesTab = ['vertical-tab', 'menu-item']
|
const classesTab = ['vertical-tab', 'menu-item']
|
||||||
if (this.activeIndex === index) {
|
if (this.activeIndex === index && useInterfaceStore().layoutType !== 'mobile') {
|
||||||
classesTab.push('-active')
|
classesTab.push('-active')
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
@ -183,14 +142,21 @@ export default {
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
const headerClasses = ['tab-content-label']
|
const headerClasses = ['tab-content-label']
|
||||||
if (this.hideHeader === true) {
|
|
||||||
headerClasses.push('-hidden')
|
|
||||||
}
|
|
||||||
const header = (
|
const header = (
|
||||||
<h1 class={headerClasses}>
|
<h2 class={headerClasses}>
|
||||||
<button type="button" onClick={() => this.changeNavSide('tabs')}>LOL</button>
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => this.changeNavSide('tabs')}
|
||||||
|
class="button-unstyled"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
size="lg"
|
||||||
|
class="back-button-icon"
|
||||||
|
icon="chevron-left"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
{props.label}
|
{props.label}
|
||||||
</h1>
|
</h2>
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -204,13 +170,14 @@ export default {
|
||||||
})
|
})
|
||||||
|
|
||||||
const rootClasses = ['vertical-tab-switcher']
|
const rootClasses = ['vertical-tab-switcher']
|
||||||
if (this.navMode) {
|
if (useInterfaceStore().layoutType === 'mobile') {
|
||||||
rootClasses.push('-nav-mode')
|
rootClasses.push('-mobile')
|
||||||
if (this.navSide === 'content') {
|
}
|
||||||
rootClasses.push('-nav-content')
|
|
||||||
} else {
|
if (this.navSide === 'tabs') {
|
||||||
rootClasses.push('-nav-tabs')
|
rootClasses.push('-nav-tabs')
|
||||||
}
|
} else {
|
||||||
|
rootClasses.push('-nav-contents')
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
.vertical-tab-switcher {
|
.vertical-tab-switcher {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
container-type: inline-size;
|
||||||
|
|
||||||
> .tabs {
|
> .tabs {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 15em;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden auto;
|
overflow: hidden auto;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
width: 15em;
|
width: 15em;
|
||||||
|
min-width: 15em;
|
||||||
border-right: 1px solid;
|
border-right: 1px solid;
|
||||||
border-right-color: var(--border);
|
border-right-color: var(--border);
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
> .menu-item {
|
> .menu-item {
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
|
|
@ -23,18 +26,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
> .contents {
|
> .contents {
|
||||||
flex: 1 1 auto;
|
flex: 1 0 35em;
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
.tab-content-label {
|
|
||||||
display: none
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
|
||||||
&:not(.-full-width) {
|
&:not(.-full-width) {
|
||||||
width: 30em;
|
max-width: 40em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.-full-width {
|
&.-full-width {
|
||||||
|
|
@ -42,16 +40,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-content-label {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
button {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tab-content-wrapper {
|
.tab-content-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow-y: auto;
|
||||||
.tab-content-label {
|
height: 100%;
|
||||||
font-size: 1.5em;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
margin: 0;
|
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.-hidden {
|
&.-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -69,38 +74,104 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.-nav-mode {
|
&.-mobile {
|
||||||
&.-nav-tabs {
|
> .contents {
|
||||||
> .tabs {
|
.tab-content-label {
|
||||||
width: 100%;
|
display: block
|
||||||
}
|
|
||||||
|
|
||||||
> .nav-content {
|
|
||||||
width: 0%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.-nav-content {
|
&.-nav-contents {
|
||||||
> .contents {
|
> .contents {
|
||||||
> .tab-content-wrapper {
|
display: block;
|
||||||
> .tab-content-label {
|
flex-grow: 1;
|
||||||
display: block;
|
}
|
||||||
|
|
||||||
&.-hidden {
|
> .tabs {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.-nav-tabs {
|
||||||
|
> .tabs {
|
||||||
|
display: block;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .contents {
|
||||||
|
display: none;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (container-type: inline-size) {
|
||||||
|
&,
|
||||||
|
&.-mobile {
|
||||||
|
&.-nav-contents,
|
||||||
|
&.-nav-tabs {
|
||||||
|
/* I THINK it's a false positive and eslint doesn't understand the @-rule */
|
||||||
|
/* stylelint-disable no-descending-specificity */
|
||||||
|
> .contents {
|
||||||
|
display: block;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .tabs {
|
||||||
|
display: block;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
/* stylelint-enable no-descending-specificity */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@container (width < 50em) {
|
||||||
|
> .contents {
|
||||||
|
.tab-content-label {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.-mobile {
|
||||||
|
> .contents {
|
||||||
|
.tab-content-label {
|
||||||
|
display: block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .tabs {
|
&,
|
||||||
position: absolute;
|
&.-mobile {
|
||||||
pointer-events: none;
|
&.-nav-contents {
|
||||||
opacity: 0;
|
> .contents {
|
||||||
}
|
display: block;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
> .nav-content {
|
> .tabs {
|
||||||
width: 100%;
|
display: none;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.-nav-tabs {
|
||||||
|
/* stylelint-disable no-descending-specificity */
|
||||||
|
> .tabs {
|
||||||
|
display: block;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .contents {
|
||||||
|
display: none;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
/* stylelint-enable no-descending-specificity */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,7 @@
|
||||||
"post_look_feel": "Posts Look & Feel",
|
"post_look_feel": "Posts Look & Feel",
|
||||||
"posts": "Posts",
|
"posts": "Posts",
|
||||||
"developer": "Developer",
|
"developer": "Developer",
|
||||||
|
"debug": "Debug",
|
||||||
"mention_links": "Mention links",
|
"mention_links": "Mention links",
|
||||||
"appearance": "Appearance",
|
"appearance": "Appearance",
|
||||||
"confirm_new_setting": "Confirm new setting?",
|
"confirm_new_setting": "Confirm new setting?",
|
||||||
|
|
@ -418,7 +419,7 @@
|
||||||
"navbar_size": "Top bar size",
|
"navbar_size": "Top bar size",
|
||||||
"panel_header_size": "Panel header size",
|
"panel_header_size": "Panel header size",
|
||||||
"visual_tweaks": "Minor visual tweaks",
|
"visual_tweaks": "Minor visual tweaks",
|
||||||
"theme_debug": "Show what background theme engine assumes when dealing with transparancy (DEBUG)",
|
"theme_debug": "Show what background theme engine assumes when dealing with transparancy",
|
||||||
"scale_and_layout": "Interface scale and layout",
|
"scale_and_layout": "Interface scale and layout",
|
||||||
"timelines": "Timelines",
|
"timelines": "Timelines",
|
||||||
"format_and_language": "Format and Language",
|
"format_and_language": "Format and Language",
|
||||||
|
|
@ -753,7 +754,7 @@
|
||||||
"subject_line_email": "Like email: \"re: subject\"",
|
"subject_line_email": "Like email: \"re: subject\"",
|
||||||
"subject_line_mastodon": "Like mastodon: copy as is",
|
"subject_line_mastodon": "Like mastodon: copy as is",
|
||||||
"subject_line_noop": "Do not copy",
|
"subject_line_noop": "Do not copy",
|
||||||
"force_theme_recompilation_debug": "Disable theme cahe, force recompile on each boot (DEBUG)",
|
"force_theme_recompilation_debug": "Disable theme cahe, force recompile on each boot",
|
||||||
"conversation_display": "Conversation display style",
|
"conversation_display": "Conversation display style",
|
||||||
"conversation_display_tree": "Tree-style",
|
"conversation_display_tree": "Tree-style",
|
||||||
"conversation_display_tree_quick": "Tree view",
|
"conversation_display_tree_quick": "Tree view",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue