pleroma-fe/src/components/settings_modal/tabs/appearance_tab.js

195 lines
5.6 KiB
JavaScript
Raw Normal View History

import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue'
import IntegerSetting from '../helpers/integer_setting.vue'
import FloatSetting from '../helpers/float_setting.vue'
2024-06-13 02:22:47 +03:00
import UnitSetting, { defaultHorizontalUnits } from '../helpers/unit_setting.vue'
2024-06-27 00:59:24 +03:00
import FontControl from 'src/components/font_control/font_control.vue'
2024-07-17 17:19:57 +03:00
import { normalizeThemeData } from 'src/modules/interface'
import {
getThemes
} from 'src/services/style_setter/style_setter.js'
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
import { init } from 'src/services/theme_data/theme_data_3.service.js'
import {
getCssRules,
getScopedVersion
} from 'src/services/theme_data/css_utils.js'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
} from '@fortawesome/free-solid-svg-icons'
2024-07-17 17:19:57 +03:00
import Preview from './theme_tab/preview.vue'
library.add(
faGlobe
)
const AppearanceTab = {
data () {
2024-06-13 02:22:47 +03:00
return {
2024-07-17 17:19:57 +03:00
availableStyles: [],
2024-07-17 19:58:04 +03:00
intersectionObserver: null,
2024-06-13 02:22:47 +03:00
thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({
key: mode,
value: mode,
label: this.$t(`settings.third_column_mode_${mode}`)
2024-06-21 22:46:01 +03:00
})),
forcedRoundnessOptions: ['disabled', 'sharp', 'nonsharp', 'round'].map((mode, i) => ({
key: mode,
value: i - 1,
label: this.$t(`settings.style.themes3.hacks.forced_roundness_mode_${mode}`)
})),
underlayOverrideModes: ['none', 'opaque', 'transparent'].map((mode, i) => ({
key: mode,
value: mode,
label: this.$t(`settings.style.themes3.hacks.underlay_override_mode_${mode}`)
2024-06-13 02:22:47 +03:00
}))
}
},
components: {
BooleanSetting,
ChoiceSetting,
IntegerSetting,
FloatSetting,
UnitSetting,
2024-06-27 00:59:24 +03:00
ProfileSettingIndicator,
2024-07-17 17:19:57 +03:00
FontControl,
Preview
},
2024-07-17 19:58:04 +03:00
mounted () {
2024-07-17 17:19:57 +03:00
getThemes()
.then((promises) => {
return Promise.all(
Object.entries(promises)
.map(([k, v]) => v.then(res => [k, res]))
)
})
.then(themes => themes.reduce((acc, [k, v]) => {
if (v) {
2024-07-17 19:58:04 +03:00
return [
2024-07-17 17:19:57 +03:00
...acc,
2024-07-17 19:58:04 +03:00
{
name: v.name || v[0],
key: k,
data: v
}
]
2024-07-17 17:19:57 +03:00
} else {
return acc
}
2024-07-17 19:58:04 +03:00
}, []))
2024-07-17 17:19:57 +03:00
.then((themesComplete) => {
2024-07-17 19:58:04 +03:00
this.availableStyles = themesComplete
})
if (window.IntersectionObserver) {
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(({ target, isIntersecting }) => {
if (!isIntersecting) return
const theme = this.availableStyles.find(x => x.key === target.dataset.themeKey)
this.$nextTick(() => {
2024-07-17 22:10:11 +03:00
if (theme) theme.ready = true
2024-07-17 19:58:04 +03:00
})
observer.unobserve(target)
})
}, {
root: this.$refs.themeList
})
}
},
updated () {
this.$nextTick(() => {
this.$refs.themeList.querySelectorAll('.theme-preview').forEach(node => {
this.intersectionObserver.observe(node)
2024-07-17 17:19:57 +03:00
})
2024-07-17 19:58:04 +03:00
})
},
computed: {
2024-07-17 19:58:04 +03:00
noIntersectionObserver () {
return !window.IntersectionObserver
},
2024-06-13 02:22:47 +03:00
horizontalUnits () {
return defaultHorizontalUnits
},
2024-06-27 00:59:24 +03:00
fontsOverride () {
return this.$store.getters.mergedConfig.fontsOverride
},
2024-06-13 02:22:47 +03:00
columns () {
const mode = this.$store.getters.mergedConfig.thirdColumnMode
const notif = mode === 'none' ? [] : ['notifs']
if (this.$store.getters.mergedConfig.sidebarRight || mode === 'postform') {
return [...notif, 'content', 'sidebar']
} else {
return ['sidebar', 'content', ...notif]
}
},
instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel },
instanceWallpaperUsed () {
return this.$store.state.instance.background &&
!this.$store.state.users.currentUser.background_image
},
2024-06-13 02:22:47 +03:00
instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable },
language: {
get: function () { return this.$store.getters.mergedConfig.interfaceLanguage },
set: function (val) {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
}
},
2024-07-17 22:10:11 +03:00
isCustomThemeUsed () {
const { theme } = this.mergedConfig
return theme === 'custom' || theme === null
},
...SharedComputedObject()
2024-07-17 17:19:57 +03:00
},
methods: {
updateFont (key, value) {
console.log(key, value)
this.$store.dispatch('setOption', {
name: 'theme3hacks',
value: {
...this.mergedConfig.theme3hacks,
fonts: {
...this.mergedConfig.theme3hacks.fonts,
[key]: value
}
}
})
},
2024-07-17 22:10:11 +03:00
isThemeActive (key) {
const { theme } = this.mergedConfig
return key === theme
},
setTheme (name) {
this.$store.dispatch('setTheme', { themeName: name, saveData: true, recompile: true })
2024-07-17 19:58:04 +03:00
},
previewTheme (key, input) {
2024-07-17 17:19:57 +03:00
const style = normalizeThemeData(input)
const x = 2
if (x === 1) return
const theme2 = convertTheme2To3(style)
const theme3 = init({
inputRuleset: theme2,
ultimateBackgroundColor: '#000000',
liteMode: true,
2024-07-17 19:58:04 +03:00
debug: true,
2024-07-17 17:19:57 +03:00
onlyNormalState: true
})
return getScopedVersion(
getCssRules(theme3.eager),
2024-07-17 19:58:04 +03:00
'#theme-preview-' + key
2024-07-17 17:19:57 +03:00
).join('\n')
}
}
}
export default AppearanceTab