mirror of https://github.com/FreeTubeApp/FreeTube
Compare commits
16 Commits
6e3988b072
...
2b7d95497d
Author | SHA1 | Date |
---|---|---|
Jason | 2b7d95497d | |
Jason Henriquez | a2f346e977 | |
Jason Henriquez | 1d88d647be | |
Jason Henriquez | 938b40d194 | |
Jason Henriquez | 02567db33b | |
Jason Henriquez | 9097768d85 | |
Jason Henriquez | 5eaf46923e | |
Jason Henriquez | 5bbc41a946 | |
Jason Henriquez | e16b37264e | |
Jason Henriquez | e9c527a5d3 | |
Jason Henriquez | 8135ff2dd0 | |
Jason Henriquez | f4d8648607 | |
Jason Henriquez | 97a5c7362c | |
Jason Henriquez | edafe33a22 | |
Jason Henriquez | 569f561591 | |
Jason Henriquez | 9a75cd0dda |
|
@ -73,6 +73,9 @@ const SyncEvents = {
|
|||
}
|
||||
}
|
||||
|
||||
// Settings
|
||||
const ACTIVE_CLASS_NAME = 'active'
|
||||
|
||||
// Utils
|
||||
const MAIN_PROFILE_ID = 'allChannels'
|
||||
|
||||
|
@ -80,5 +83,6 @@ export {
|
|||
IpcChannels,
|
||||
DBActions,
|
||||
SyncEvents,
|
||||
ACTIVE_CLASS_NAME,
|
||||
MAIN_PROFILE_ID
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
.settingsMenu {
|
||||
position: sticky;
|
||||
inset-block-start: 120px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 22px;
|
||||
padding-inline-start: 0;
|
||||
block-size: fit-content;
|
||||
}
|
||||
|
||||
.header {
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-decoration: none;
|
||||
color: var(--tertiary-text-color);
|
||||
inline-size: 220px;
|
||||
padding-block: 3px;
|
||||
}
|
||||
|
||||
/* prevent hover styling from showing on title click for mobile */
|
||||
@media (hover: hover) {
|
||||
.title:hover {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
.titleContent {
|
||||
inline-size: fit-content;
|
||||
max-inline-size: 100%;
|
||||
}
|
||||
|
||||
|
||||
.iconAndTitleText {
|
||||
overflow-x: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
/* needed to have underline poke out */
|
||||
margin-inline-start: 3px;
|
||||
}
|
||||
|
||||
.titleUnderline {
|
||||
/* have underline poke out */
|
||||
inline-size: calc(100% + 6px);
|
||||
|
||||
/* prevent "active" border from visibly pushing the content up */
|
||||
border-block-end: 4px solid transparent;
|
||||
}
|
||||
|
||||
.title.active {
|
||||
color: var(--primary-text-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.title.active .titleUnderline {
|
||||
border-block-end: 4px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.titleIcon {
|
||||
inline-size: 22px;
|
||||
block-size: 22px;
|
||||
}
|
||||
|
||||
@media only screen and (width <= 950px) {
|
||||
.settingsMenu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: integrate settings menu into mobile view
|
||||
|
||||
.header {
|
||||
display: none;
|
||||
}
|
||||
.settingsMenu {
|
||||
position: fixed;
|
||||
flex-direction: row;
|
||||
gap: 5px;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.title {
|
||||
inline-size: 100%;
|
||||
} */
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FtSettingsMenu',
|
||||
props: {
|
||||
settingsSections: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getTitleForSection: function(settingsSection) {
|
||||
return settingsSection.shortTitle !== '' ? settingsSection.shortTitle : settingsSection.title
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<menu
|
||||
class="settingsMenu"
|
||||
>
|
||||
<h2 class="header">
|
||||
{{ $t('Settings.Settings') }}
|
||||
</h2>
|
||||
<a
|
||||
v-for="(settingsSection) in settingsSections"
|
||||
:id="settingsSection.type + '-link'"
|
||||
:key="settingsSection.type + '-link'"
|
||||
:href="'#' + settingsSection.type"
|
||||
class="title"
|
||||
>
|
||||
<div class="titleContent">
|
||||
<div class="iconAndTitleText">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', settingsSection.icon]"
|
||||
class="titleIcon"
|
||||
/>
|
||||
{{ getTitleForSection(settingsSection) }}
|
||||
</div>
|
||||
<div class="titleUnderline" />
|
||||
</div>
|
||||
</a>
|
||||
</menu>
|
||||
</template>
|
||||
|
||||
<script src="./ft-settings-menu.js" />
|
||||
<style scoped src="./ft-settings-menu.css" />
|
|
@ -7,10 +7,5 @@ export default defineComponent({
|
|||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
allSettingsSectionsExpandedByDefault: function () {
|
||||
return this.$store.getters.getAllSettingsSectionsExpandedByDefault
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
.settingsSection {
|
||||
background-color: var(--card-bg-color);
|
||||
margin-block: 0;
|
||||
margin-inline: auto;
|
||||
inline-size: 85%;
|
||||
|
||||
@media only screen and (width <= 800px) {
|
||||
inline-size: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&[open] {
|
||||
padding-block-end: 15px;
|
||||
}
|
||||
.sectionHeader {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.sectionBody {
|
||||
background-color: var(--card-bg-color);
|
||||
border-radius: 20px;
|
||||
padding-block: 10px;
|
||||
|
||||
> div {
|
||||
box-sizing: border-box;
|
||||
|
@ -26,19 +31,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.sectionLine {
|
||||
border: 0;
|
||||
border-block-start: 2px solid var(--primary-color);
|
||||
margin-block-start: -1px;
|
||||
inline-size: 100%;
|
||||
}
|
||||
|
||||
.sectionHeader {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.sectionTitle {
|
||||
user-select: none;
|
||||
margin-inline-start: 2%;
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
<template>
|
||||
<details
|
||||
:open="allSettingsSectionsExpandedByDefault"
|
||||
<div
|
||||
class="settingsSection"
|
||||
>
|
||||
<summary class="sectionHeader">
|
||||
<h3 class="sectionTitle">
|
||||
{{ title }}
|
||||
</h3>
|
||||
</summary>
|
||||
<hr class="sectionLine">
|
||||
<slot />
|
||||
</details>
|
||||
<h3 class="sectionTitle">
|
||||
{{ title }}
|
||||
</h3>
|
||||
<div class="sectionBody">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./ft-settings-section.js" />
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
:select-names="protocolNames"
|
||||
:select-values="protocolValues"
|
||||
class="protocol-dropdown"
|
||||
:icon="['fas', 'microchip']"
|
||||
:icon="['fas', 'network-wired']"
|
||||
@change="handleUpdateProxyProtocol"
|
||||
/>
|
||||
</ft-flex-box>
|
||||
|
|
|
@ -20,14 +20,19 @@ import {
|
|||
faArrowRight,
|
||||
faArrowUp,
|
||||
faBars,
|
||||
faBorderAll,
|
||||
faBookmark,
|
||||
faCheck,
|
||||
faChevronRight,
|
||||
faCirclePlay,
|
||||
faCircleUser,
|
||||
faClapperboard,
|
||||
faClone,
|
||||
faComment,
|
||||
faCommentDots,
|
||||
faCopy,
|
||||
faDatabase,
|
||||
faDisplay,
|
||||
faDownload,
|
||||
faEdit,
|
||||
faEllipsisH,
|
||||
|
@ -42,6 +47,7 @@ import {
|
|||
faFileImage,
|
||||
faFileVideo,
|
||||
faFilter,
|
||||
faFlask,
|
||||
faFire,
|
||||
faForward,
|
||||
faGauge,
|
||||
|
@ -52,12 +58,14 @@ import {
|
|||
faHistory,
|
||||
faImages,
|
||||
faInfoCircle,
|
||||
faKey,
|
||||
faLanguage,
|
||||
faLink,
|
||||
faLinkSlash,
|
||||
faList,
|
||||
faLocationDot,
|
||||
faMicrochip,
|
||||
faLock,
|
||||
faNetworkWired,
|
||||
faNewspaper,
|
||||
faPalette,
|
||||
faPause,
|
||||
|
@ -73,6 +81,7 @@ import {
|
|||
faSearch,
|
||||
faServer,
|
||||
faShareAlt,
|
||||
faShield,
|
||||
faSlidersH,
|
||||
faSortAlphaDown,
|
||||
faSortAlphaDownAlt,
|
||||
|
@ -86,7 +95,8 @@ import {
|
|||
faTimes,
|
||||
faTimesCircle,
|
||||
faTrash,
|
||||
faUsers,
|
||||
faUserLock,
|
||||
faUsers
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
faBitcoin,
|
||||
|
@ -113,14 +123,19 @@ library.add(
|
|||
faArrowRight,
|
||||
faArrowUp,
|
||||
faBars,
|
||||
faBorderAll,
|
||||
faBookmark,
|
||||
faCheck,
|
||||
faChevronRight,
|
||||
faCirclePlay,
|
||||
faCircleUser,
|
||||
faClapperboard,
|
||||
faClone,
|
||||
faComment,
|
||||
faCommentDots,
|
||||
faCopy,
|
||||
faDatabase,
|
||||
faDisplay,
|
||||
faDownload,
|
||||
faEdit,
|
||||
faEllipsisH,
|
||||
|
@ -135,6 +150,7 @@ library.add(
|
|||
faFileImage,
|
||||
faFileVideo,
|
||||
faFilter,
|
||||
faFlask,
|
||||
faFire,
|
||||
faForward,
|
||||
faGauge,
|
||||
|
@ -145,12 +161,14 @@ library.add(
|
|||
faHistory,
|
||||
faImages,
|
||||
faInfoCircle,
|
||||
faKey,
|
||||
faLanguage,
|
||||
faLink,
|
||||
faLinkSlash,
|
||||
faList,
|
||||
faLocationDot,
|
||||
faMicrochip,
|
||||
faLock,
|
||||
faNetworkWired,
|
||||
faNewspaper,
|
||||
faPalette,
|
||||
faPause,
|
||||
|
@ -167,6 +185,7 @@ library.add(
|
|||
faSearch,
|
||||
faServer,
|
||||
faShareAlt,
|
||||
faShield,
|
||||
faSlidersH,
|
||||
faSortAlphaDown,
|
||||
faSortAlphaDownAlt,
|
||||
|
@ -180,6 +199,7 @@ library.add(
|
|||
faTimes,
|
||||
faTimesCircle,
|
||||
faTrash,
|
||||
faUserLock,
|
||||
faUsers,
|
||||
|
||||
// brand icons
|
||||
|
|
|
@ -162,7 +162,6 @@ const defaultSideEffectsTriggerId = settingId =>
|
|||
/*****/
|
||||
|
||||
const state = {
|
||||
allSettingsSectionsExpandedByDefault: false,
|
||||
autoplayPlaylists: true,
|
||||
autoplayVideos: true,
|
||||
backendFallback: process.env.SUPPORTS_LOCAL_API,
|
||||
|
|
|
@ -232,17 +232,6 @@
|
|||
--accent-color-opacity4: rgb(255 255 255 / 24%) !important;
|
||||
}
|
||||
|
||||
/* Given that the Hot Pink theme does not need link underlining due to meeting
|
||||
WCAG 2 Level AA (https://webaim.org/resources/linkcontrastchecker/?fcolor=FFFFFF&bcolor=DE1C85&lcolor=000000),
|
||||
it can be safely elided. This looks quite pleasant on this theme. */
|
||||
.hotPink a:not(:hover, :focus), .hotPink .navOption:hover, .hotPink .navOption:focus, .hotPink *:not(:hover, :focus) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hotPink a:hover, .hotPink a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.nordic {
|
||||
--primary-text-color: #EEE;
|
||||
--secondary-text-color: #ddd;
|
||||
|
|
|
@ -1,24 +1,47 @@
|
|||
hr {
|
||||
inline-size: 85%;
|
||||
margin-block: 0;
|
||||
margin-inline: auto;
|
||||
border: 0;
|
||||
border-block-start: 2px solid var(--scrollbar-color-hover);
|
||||
.settingsPage {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
@media only screen and (width <= 800px) {
|
||||
hr {
|
||||
inline-size: 100%;
|
||||
}
|
||||
.settingsSections {
|
||||
overflow-x: hidden;
|
||||
max-inline-size: 90%;
|
||||
}
|
||||
|
||||
.settingsSections:last-child {
|
||||
/* Add enough blank space to have the last setting section be active on the FtSettingsMenu when scrolled to */
|
||||
margin-block-end: calc(76vh - 150px)
|
||||
}
|
||||
|
||||
.switchRow {
|
||||
inline-size: 85%;
|
||||
margin-inline: auto;
|
||||
display: flex;
|
||||
margin-inline-end: auto;
|
||||
}
|
||||
|
||||
.settingsToggle {
|
||||
padding-block: 0;
|
||||
margin-block: 10px 5px;
|
||||
margin-block: 0;
|
||||
}
|
||||
|
||||
.section {
|
||||
/* enables anchor link clicks to land with the section title in the top quarter of the page */
|
||||
scroll-margin-top: 24vh;
|
||||
}
|
||||
|
||||
.section + .section {
|
||||
padding-block-start: 20px;
|
||||
}
|
||||
|
||||
@media only screen and (width <= 950px) {
|
||||
.settingsPage {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.switchRow, .settingsSections {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.settingsSections:last-child {
|
||||
margin-block-end: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ import ExperimentalSettings from '../../components/experimental-settings/experim
|
|||
import PasswordSettings from '../../components/password-settings/password-settings.vue'
|
||||
import PasswordDialog from '../../components/password-dialog/password-dialog.vue'
|
||||
import FtToggleSwitch from '../../components/ft-toggle-switch/ft-toggle-switch.vue'
|
||||
import FtSettingsMenu from '../../components/ft-settings-menu/ft-settings-menu.vue'
|
||||
import { ACTIVE_CLASS_NAME } from '../../../constants'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Settings',
|
||||
|
@ -35,73 +37,12 @@ export default defineComponent({
|
|||
'experimental-settings': ExperimentalSettings,
|
||||
'password-settings': PasswordSettings,
|
||||
'password-dialog': PasswordDialog,
|
||||
'ft-toggle-switch': FtToggleSwitch
|
||||
'ft-toggle-switch': FtToggleSwitch,
|
||||
'ft-settings-menu': FtSettingsMenu,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
unlocked: false,
|
||||
settingsComponentsData: [
|
||||
{
|
||||
type: 'general-settings',
|
||||
title: this.$t('Settings.General Settings.General Settings')
|
||||
},
|
||||
{
|
||||
type: 'theme-settings',
|
||||
title: this.$t('Settings.Theme Settings.Theme Settings')
|
||||
},
|
||||
{
|
||||
type: 'player-settings',
|
||||
title: this.$t('Settings.Player Settings.Player Settings')
|
||||
},
|
||||
{
|
||||
type: 'external-player-settings',
|
||||
title: this.$t('Settings.External Player Settings.External Player Settings'),
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'subscription-settings',
|
||||
title: this.$t('Settings.Subscription Settings.Subscription Settings')
|
||||
},
|
||||
{
|
||||
type: 'distraction-settings',
|
||||
title: this.$t('Settings.Distraction Free Settings.Distraction Free Settings')
|
||||
},
|
||||
{
|
||||
type: 'privacy-settings',
|
||||
title: this.$t('Settings.Privacy Settings.Privacy Settings')
|
||||
},
|
||||
{
|
||||
type: 'data-settings',
|
||||
title: this.$t('Settings.Data Settings.Data Settings')
|
||||
},
|
||||
{
|
||||
type: 'proxy-settings',
|
||||
title: this.$t('Settings.Proxy Settings.Proxy Settings'),
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'download-settings',
|
||||
title: this.$t('Settings.Download Settings.Download Settings'),
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'parental-control-settings',
|
||||
title: this.$t('Settings.Parental Control Settings.Parental Control Settings')
|
||||
},
|
||||
{
|
||||
type: 'sponsor-block-settings',
|
||||
title: this.$t('Settings.SponsorBlock Settings.SponsorBlock Settings'),
|
||||
},
|
||||
{
|
||||
type: 'experimental-settings',
|
||||
title: this.$t('Settings.Experimental Settings.Experimental Settings'),
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'password-settings',
|
||||
title: this.$t('Settings.Password Settings.Password Settings')
|
||||
},
|
||||
]
|
||||
unlocked: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -113,14 +54,98 @@ export default defineComponent({
|
|||
return this.$store.getters.getSettingsPassword
|
||||
},
|
||||
|
||||
allSettingsSectionsExpandedByDefault: function () {
|
||||
return this.$store.getters.getAllSettingsSectionsExpandedByDefault
|
||||
},
|
||||
|
||||
settingsSectionSortEnabled: function () {
|
||||
return this.$store.getters.getSettingsSectionSortEnabled
|
||||
},
|
||||
|
||||
settingsComponentsData: function () {
|
||||
return [
|
||||
{
|
||||
type: 'theme-settings',
|
||||
title: this.$t('Settings.Theme Settings.Theme Settings'),
|
||||
shortTitle: this.$te('Settings.Theme Settings.Theme Settings Short Label') ? this.$t('Settings.Theme Settings.Theme Settings Short Label') : '',
|
||||
icon: 'display'
|
||||
},
|
||||
{
|
||||
type: 'player-settings',
|
||||
title: this.$t('Settings.Player Settings.Player Settings'),
|
||||
shortTitle: this.$te('Settings.Player Settings.Player Settings Short Label') ? this.$t('Settings.Player Settings.Player Settings Short Label') : '',
|
||||
icon: 'circle-play'
|
||||
},
|
||||
{
|
||||
type: 'external-player-settings',
|
||||
title: this.$t('Settings.External Player Settings.External Player Settings'),
|
||||
shortTitle: this.$te('Settings.External Player Settings.External Player') ? this.$t('Settings.External Player Settings.External Player') : '',
|
||||
icon: 'clapperboard',
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'subscription-settings',
|
||||
title: this.$t('Settings.Subscription Settings.Subscription Settings'),
|
||||
shortTitle: this.$te('Settings.Subscription Settings.Subscription Settings Short Label') ? this.$t('Settings.Subscription Settings.Subscription Settings Short Label') : '',
|
||||
icon: 'play'
|
||||
},
|
||||
{
|
||||
type: 'distraction-settings',
|
||||
title: this.$t('Settings.Distraction Free Settings.Distraction Free Settings'),
|
||||
shortTitle: this.$te('Settings.Distraction Free Settings.Distraction Free Settings Short Label') ? this.$t('Settings.Distraction Free Settings.Distraction Free Settings Short Label') : '',
|
||||
icon: 'eye-slash'
|
||||
},
|
||||
{
|
||||
type: 'privacy-settings',
|
||||
title: this.$t('Settings.Privacy Settings.Privacy Settings'),
|
||||
shortTitle: this.$te('Settings.Privacy Settings.Privacy Settings Short Label') ? this.$t('Settings.Privacy Settings.Privacy Settings Short Label') : '',
|
||||
icon: 'lock'
|
||||
},
|
||||
{
|
||||
type: 'data-settings',
|
||||
title: this.$t('Settings.Data Settings.Data Settings'),
|
||||
shortTitle: this.$te('Settings.Data Settings.Data Settings Short Label') ? this.$t('Settings.Data Settings.Data Settings Short Label') : '',
|
||||
icon: 'database'
|
||||
},
|
||||
{
|
||||
type: 'proxy-settings',
|
||||
title: this.$t('Settings.Proxy Settings.Proxy Settings'),
|
||||
shortTitle: this.$te('Settings.Proxy Settings.Proxy Settings Short Label') ? this.$t('Settings.Proxy Settings.Proxy Settings Short Label') : '',
|
||||
icon: 'network-wired',
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'download-settings',
|
||||
title: this.$t('Settings.Download Settings.Download Settings'),
|
||||
shortTitle: this.$te('Settings.Download Settings.Download Settings Short Label') ? this.$t('Settings.Download Settings.Download Settings Short Label') : '',
|
||||
icon: 'download',
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'parental-control-settings',
|
||||
title: this.$t('Settings.Parental Control Settings.Parental Control Settings'),
|
||||
shortTitle: this.$te('Settings.Parental Control Settings.Parental Control Settings Short Label') ? this.$t('Settings.Parental Control Settings.Parental Control Settings Short Label') : '',
|
||||
icon: 'user-lock'
|
||||
},
|
||||
{
|
||||
type: 'sponsor-block-settings',
|
||||
title: this.$t('Settings.SponsorBlock Settings.SponsorBlock Settings'),
|
||||
shortTitle: this.$te('Settings.SponsorBlock Settings.SponsorBlock Settings Short Label') ? this.$t('Settings.SponsorBlock Settings.SponsorBlock Settings Short Label') : '',
|
||||
// TODO: replace with SponsorBlock icon
|
||||
icon: 'shield'
|
||||
},
|
||||
{
|
||||
type: 'experimental-settings',
|
||||
title: this.$t('Settings.Experimental Settings.Experimental Settings'),
|
||||
shortTitle: this.$te('Settings.Experimental Settings.Experimental Settings Short Label') ? this.$t('Settings.Experimental Settings.Experimental Settings Short Label') : '',
|
||||
icon: 'flask',
|
||||
usingElectron: true
|
||||
},
|
||||
{
|
||||
type: 'password-settings',
|
||||
title: this.$t('Settings.Password Settings.Password Settings'),
|
||||
shortTitle: this.$te('Settings.Password Settings.Password Settings Short Label') ? this.$t('Settings.Password Settings.Password Settings Short Label') : '',
|
||||
icon: 'key'
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
settingsSectionComponents: function () {
|
||||
let settingsSections
|
||||
if (!process.env.IS_ELECTRON) {
|
||||
|
@ -130,12 +155,22 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
if (this.settingsSectionSortEnabled) {
|
||||
return settingsSections.toSorted((a, b) =>
|
||||
a.title.toLowerCase().localeCompare(b.title.toLowerCase(), this.locale)
|
||||
)
|
||||
settingsSections = settingsSections.toSorted((a, b) => {
|
||||
const aTitle = a.shortTitle !== '' ? a.shortTitle : a.title
|
||||
const bTitle = b.shortTitle !== '' ? b.shortTitle : b.title
|
||||
return aTitle.toLowerCase().localeCompare(bTitle.toLowerCase(), this.locale)
|
||||
})
|
||||
}
|
||||
|
||||
return settingsSections
|
||||
// ensure General Settings is placed first regardless of sorting
|
||||
const generalSettingsEntry = {
|
||||
type: 'general-settings',
|
||||
title: this.$t('Settings.General Settings.General Settings'),
|
||||
shortTitle: this.$te('Settings.General Settings.General Settings Short Label') ? this.$t('Settings.General Settings.General Settings Short Label') : '',
|
||||
icon: 'border-all'
|
||||
}
|
||||
|
||||
return [generalSettingsEntry, ...settingsSections]
|
||||
},
|
||||
},
|
||||
created: function () {
|
||||
|
@ -143,9 +178,38 @@ export default defineComponent({
|
|||
this.unlocked = true
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
document.addEventListener('scroll', this.markScrolledToSectionAsActive)
|
||||
|
||||
// mark first section as active before any scrolling has taken place
|
||||
if (this.settingsSectionComponents.length > 0) {
|
||||
const firstSection = document.getElementById(`${this.settingsSectionComponents[0].type}-link`)
|
||||
firstSection.classList.add(ACTIVE_CLASS_NAME)
|
||||
}
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
document.removeEventListener('scroll', this.markScrolledToSectionAsActive)
|
||||
},
|
||||
methods: {
|
||||
/* Set the current section to be shown as active in the Settings Menu
|
||||
* if it is the lowest section within the top quarter of the viewport (25vh) */
|
||||
markScrolledToSectionAsActive: function() {
|
||||
const scrollY = window.scrollY + innerHeight / 4
|
||||
this.settingsSectionComponents.forEach((section) => {
|
||||
const sectionElement = document.getElementById(section.type)
|
||||
const sectionHeight = sectionElement.offsetHeight
|
||||
const sectionTop = sectionElement.offsetTop
|
||||
const correspondingMenuLink = document.getElementById(`${section.type}-link`)
|
||||
|
||||
if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) {
|
||||
correspondingMenuLink.classList.add(ACTIVE_CLASS_NAME)
|
||||
} else {
|
||||
correspondingMenuLink.classList.remove(ACTIVE_CLASS_NAME)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'updateAllSettingsSectionsExpandedByDefault',
|
||||
'updateSettingsSectionSortEnabled'
|
||||
])
|
||||
}
|
||||
|
|
|
@ -1,34 +1,33 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="settingsPage">
|
||||
<template v-if="unlocked">
|
||||
<div class="switchRow">
|
||||
<ft-toggle-switch
|
||||
class="settingsToggle"
|
||||
:label="$t('Settings.Expand All Settings Sections')"
|
||||
:default-value="allSettingsSectionsExpandedByDefault"
|
||||
:compact="false"
|
||||
@change="updateAllSettingsSectionsExpandedByDefault"
|
||||
/>
|
||||
<ft-toggle-switch
|
||||
class="settingsToggle"
|
||||
:label="$t('Settings.Sort Settings Sections (A-Z)')"
|
||||
:default-value="settingsSectionSortEnabled"
|
||||
:compact="false"
|
||||
@change="updateSettingsSectionSortEnabled"
|
||||
/>
|
||||
<ft-settings-menu
|
||||
:settings-sections="settingsSectionComponents"
|
||||
/>
|
||||
<div class="settingsContent">
|
||||
<div class="switchRow">
|
||||
<ft-toggle-switch
|
||||
class="settingsToggle"
|
||||
:label="$t('Settings.Sort Settings Sections (A-Z)')"
|
||||
:default-value="settingsSectionSortEnabled"
|
||||
:compact="false"
|
||||
@change="updateSettingsSectionSortEnabled"
|
||||
/>
|
||||
</div>
|
||||
<div class="settingsSections">
|
||||
<template
|
||||
v-for="(settingsComponent) in settingsSectionComponents"
|
||||
ref=""
|
||||
>
|
||||
<component
|
||||
:is="settingsComponent.type"
|
||||
:id="settingsComponent.type"
|
||||
:key="settingsComponent.type + '-component'"
|
||||
class="section"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<template
|
||||
v-for="(settingsComponent, i) in settingsSectionComponents"
|
||||
>
|
||||
<hr
|
||||
v-if="i !== 0"
|
||||
:key="settingsComponent.type + 'hr'"
|
||||
>
|
||||
<component
|
||||
:is="settingsComponent.type"
|
||||
:key="settingsComponent.type + 'component'"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<password-dialog
|
||||
v-else
|
||||
|
|
|
@ -247,6 +247,7 @@ Settings:
|
|||
app needs to restart for changes to take effect. Restart and apply change?
|
||||
General Settings:
|
||||
General Settings: General Settings
|
||||
General Settings Short Label: General
|
||||
Check for Updates: Check for Updates
|
||||
Check for Latest Blog Posts: Check for Latest Blog Posts
|
||||
Fallback to Non-Preferred Backend on Failure: Fallback to Non-Preferred Backend
|
||||
|
@ -290,6 +291,7 @@ Settings:
|
|||
No Action: No Action
|
||||
Theme Settings:
|
||||
Theme Settings: Theme Settings
|
||||
Theme Settings Short Label: Theme
|
||||
Match Top Bar with Main Color: Match Top Bar with Main Color
|
||||
Expand Side Bar by Default: Expand Side Bar by Default
|
||||
Disable Smooth Scrolling: Disable Smooth Scrolling
|
||||
|
@ -350,6 +352,7 @@ Settings:
|
|||
#* Main Color Theme
|
||||
Player Settings:
|
||||
Player Settings: Player Settings
|
||||
Player Settings Short Label: Player
|
||||
Force Local Backend for Legacy Formats: Force Local Backend for Legacy Formats
|
||||
Play Next Video: Play Next Video
|
||||
Turn on Subtitles by Default: Turn on Subtitles by Default
|
||||
|
@ -412,6 +415,7 @@ Settings:
|
|||
Name: None
|
||||
Privacy Settings:
|
||||
Privacy Settings: Privacy Settings
|
||||
Privacy Settings Short Label: Privacy
|
||||
Remember History: Remember History
|
||||
Save Watched Progress: Save Watched Progress
|
||||
Save Watched Videos With Last Viewed Playlist: Save Watched Videos With Last Viewed Playlist
|
||||
|
@ -432,6 +436,7 @@ Settings:
|
|||
Are you sure you want to remove all your playlists?: Are you sure you want to remove all your playlists?
|
||||
Subscription Settings:
|
||||
Subscription Settings: Subscription Settings
|
||||
Subscription Settings Short Label: Subscription
|
||||
Hide Videos on Watch: Hide Videos on Watch
|
||||
Fetch Feeds from RSS: Fetch Feeds from RSS
|
||||
Manage Subscriptions: Manage Subscriptions
|
||||
|
@ -439,6 +444,7 @@ Settings:
|
|||
Only Show Latest Video for Each Channel: Only Show Latest Video for Each Channel
|
||||
Distraction Free Settings:
|
||||
Distraction Free Settings: Distraction Free Settings
|
||||
Distraction Free Settings Short Label: Distraction Free
|
||||
Sections:
|
||||
Side Bar: Side Bar
|
||||
Subscriptions Page: Subscriptions Page
|
||||
|
@ -483,6 +489,7 @@ Settings:
|
|||
Hide Subscriptions Community: Hide Subscriptions Community
|
||||
Data Settings:
|
||||
Data Settings: Data Settings
|
||||
Data Settings Short Label: Data
|
||||
Select Import Type: Select Import Type
|
||||
Select Export Type: Select Export Type
|
||||
Import Subscriptions: Import Subscriptions
|
||||
|
@ -538,6 +545,7 @@ Settings:
|
|||
Manage Subscriptions: Manage Subscriptions
|
||||
Proxy Settings:
|
||||
Proxy Settings: Proxy Settings
|
||||
Proxy Settings Short Label: Proxy
|
||||
Enable Tor / Proxy: Enable Tor / Proxy
|
||||
Proxy Protocol: Proxy Protocol
|
||||
Proxy Host: Proxy Host
|
||||
|
@ -552,6 +560,7 @@ Settings:
|
|||
Error getting network information. Is your proxy configured properly?: Error getting network information. Is your proxy configured properly?
|
||||
SponsorBlock Settings:
|
||||
SponsorBlock Settings: SponsorBlock Settings
|
||||
SponsorBlock Settings Short Label: SponsorBlock
|
||||
Enable SponsorBlock: Enable SponsorBlock
|
||||
'SponsorBlock API Url (Default is https://sponsor.ajay.app)': SponsorBlock API Url (Default is https://sponsor.ajay.app)
|
||||
Notify when sponsor segment is skipped: Notify when sponsor segment is skipped
|
||||
|
@ -567,11 +576,13 @@ Settings:
|
|||
Category Color: Category Color
|
||||
Parental Control Settings:
|
||||
Parental Control Settings: Parental Control Settings
|
||||
Parental Control Settings Short Label: Parental Control
|
||||
Hide Unsubscribe Button: Hide Unsubscribe Button
|
||||
Show Family Friendly Only: Show Family Friendly Only
|
||||
Hide Search Bar: Hide Search Bar
|
||||
Download Settings:
|
||||
Download Settings: Download Settings
|
||||
Download Settings Short Label: Download
|
||||
Ask Download Path: Ask for download path
|
||||
Choose Path: Choose Path
|
||||
Download Behavior: Download Behavior
|
||||
|
@ -579,6 +590,7 @@ Settings:
|
|||
Open in web browser: Open in web browser
|
||||
Experimental Settings:
|
||||
Experimental Settings: Experimental Settings
|
||||
Experimental Settings Short Label: Experimental
|
||||
Warning: These settings are experimental, they may cause crashes while enabled. Making backups is highly recommended. Use at your own risk!
|
||||
Replace HTTP Cache: Replace HTTP Cache
|
||||
Password Dialog:
|
||||
|
@ -588,6 +600,7 @@ Settings:
|
|||
Unlock: Unlock
|
||||
Password Settings:
|
||||
Password Settings: Password Settings
|
||||
Password Settings Short Label: Password
|
||||
Set Password To Prevent Access: Set a password to prevent access to settings
|
||||
Set Password: Set Password
|
||||
Remove Password: Remove Password
|
||||
|
@ -622,6 +635,7 @@ About:
|
|||
|
||||
Profile:
|
||||
Profile Settings: Profile Settings
|
||||
Profile Settings Short Label: Profile
|
||||
Toggle Profile List: Toggle Profile List
|
||||
Profile Select: Profile Select
|
||||
Profile Filter: Profile Filter
|
||||
|
|
Loading…
Reference in New Issue