Add option to generate random themes

masks
Warinyourself 4 years ago
parent 6defc7fa60
commit b2659e635a

@ -1,8 +1,8 @@
import { Component, Vue } from 'vue-property-decorator'
import { Component, Vue, Watch } from 'vue-property-decorator'
import Mousetrap from 'mousetrap'
import { AppModule } from '@/store/app'
import { PageModule } from './store/page'
import { focusInputPassword } from './utils/helper'
import { Debounce, focusInputPassword } from './utils/helper'
import { hotkeys } from '@/utils/hotkeys'
@Component
@ -11,6 +11,17 @@ export default class MainApp extends Vue {
return AppModule.bodyClass
}
get getMainSettings() {
return AppModule.getMainSettings
}
@Debounce(100)
@Watch('getMainSettings', { deep: true })
handleSettingsThemes() {
console.log('Update Settings')
AppModule.syncSettingsWithCache()
}
created() {
AppModule.setUpSettings()
this.initKeybinds()

@ -2,8 +2,6 @@ import { Component, Prop, Vue } from 'vue-property-decorator'
import AppIcon from '@/components/app/AppIcon.vue'
import { Route } from 'vue-router'
import { CreateElement, VNode, VNodeData } from 'vue'
import { RenderContext } from 'vue/types/umd'
import { spawn } from 'child_process'
const prefix = 'app-button'
@ -52,9 +50,7 @@ export default class AppButton extends Vue implements AppButtonPropsInterface {
classes[`${prefix}--${property}`] = !!this[property]
})
return {
...classes
}
return classes
}
get isLink() {

@ -5,13 +5,20 @@ import AppIcon from '@/components/app/AppIcon.vue'
components: { AppIcon }
})
export default class AppCheckbox extends Vue {
@Prop({ type: Boolean, default: false }) value!: boolean
@Prop({ default: false }) value!: boolean
@Prop({ default: '' }) label!: string
get isActive() {
return this.value
}
get classes() {
return {
checkbox: true,
'checkbox--active': this.value
}
}
get idCheckbox() {
return `input-${(this as any)._uid}`
}
@ -21,7 +28,7 @@ export default class AppCheckbox extends Vue {
}
render() {
return <label class={['checkbox', this.value ? 'checkbox--active' : '']}>
return <label class={ this.classes }>
<div class="checkbox-control">
<div class="checkbox-control-box">
<AppIcon name="checkbox"></AppIcon>

@ -23,6 +23,10 @@ export default class SettingsCheckboxes extends Vue {
/>
}
generateRandomTheme(value: boolean) {
AppModule.SET_STATE_APP({ key: 'generateRandomThemes', value })
}
render() {
return <div class="grid-two">
<h2 class="title"> { this.$t('settings.performance') } </h2>
@ -30,6 +34,13 @@ export default class SettingsCheckboxes extends Vue {
{ this.buildCheckbox('show-framerate') }
{ this.buildCheckbox('no-transition') }
{ this.buildCheckbox('only-ui') }
<AppCheckbox
inline={ true }
label={ this.$t('settings.generate-random-theme') }
value={ AppModule.generateRandomThemes }
onInput={ this.generateRandomTheme }
/>
</div>
}
}

@ -5,8 +5,8 @@ import AppIcon from '@/components/app/AppIcon.vue'
import AppButton from '@/components/app/AppButton'
import SettingsUsers from './SettingsUsers'
import SettingsHotkeys from './SettingsHotkeys'
import SettingsCheckboxes from './SettingsCheckboxes'
import SettingsSelectors from './SettingsSelectors'
import SettingsCheckboxes from './SettingsCheckboxes'
@Component({
components: {

@ -55,6 +55,7 @@
"performance": "performance",
"choice-desktop": "Choice desktop",
"choice-language": "Choice language",
"generate-random-theme": "Generate random theme",
"keyboard": {
"title": "Hotkeys",
"open-themes": "Open theme",

@ -45,17 +45,20 @@
},
"settings": {
"title": "Настройки",
"blur": "Прозрачность",
"blur": "Размытие",
"users": "Пользователи",
"no-transition": "Отключить анимацию",
"show-framerate": "Показывать частоту кадров",
"only-ui": "Показывать только настройки",
"performance": "производительность",
"generate-random-theme": "Генерировать случайную тему",
"keyboard": {
"title": "Горячие клавишы",
"open-themes": "Открыть темы",
"open-custom": "Открыть настройки темы",
"open-settings": "Открыть общие настройки",
"hide-windows": "Закрыть окна",
"show-password": "Показать пароль",
"randomize-theme": "Выбрать случайные настройки темы",
"poweroff": "Выключить",
"restart": "Перезагрузить",

@ -6,6 +6,7 @@ export interface AppSettings {
username: string;
desktop: string;
defaultColor: string;
generateRandomThemes: boolean;
bodyClass: Record<string, boolean>;
themes: AppTheme[];
}
@ -304,6 +305,7 @@ export const AppThemes: AppTheme[] = [
},
settings: [
pxratio(),
hueInput(),
buildInputSlider({ value: 10, max: 15 }),
buildInputSlider({ value: 1, max: 2.8, min: 0.2, name: 'size' }),
randomButton
@ -318,12 +320,13 @@ export const AppThemes: AppTheme[] = [
type: 'palette',
label: 'input.slider-amount',
value: 0,
// TODO: Add more colors
values: [
['#fcb2bf', '#cf56a1', '#8b2f97', '#511e78'],
['#e3fdfd', '#cbf1f5', '#a6e3e9', '#71c9ce'],
['#e8f79a', '#49d292', '#3b445b', '#383746'],
['#f5f5f5', '#fc5185', '#3fc1c9', '#364f6b']
['#f5f5f5', '#fc5185', '#3fc1c9', '#364f6b'],
['#00A8CC', '#0C7B93', '#27496D', '#142850'],
['#F9F7F7', '#DBE2EF', '#3F72AF', '#112D4E'],
['#ABEDD8', '#46CDCF', '#3D84A8', '#48466D']
]
},
{

@ -20,7 +20,7 @@ import {
defaultTheme
} from '@/models/app'
import { appWindow, LightdmSession, LightdmUsers } from '@/models/lightdm'
import { generateRandomColor, generateRandomSliderValue, parseQueryValue, randomize } from '@/utils/helper'
import { generateRandomColor, generateRandomSliderValue, isDifferentRoute, parseQueryValue, randomize, randomizeSettingsTheme } from '@/utils/helper'
export interface AppState extends AppSettings {
themes: AppTheme[];
@ -43,7 +43,8 @@ class App extends VuexModule implements AppState {
users = appWindow?.lightdm?.users || []
desktops = appWindow?.lightdm?.sessions || []
showPassword = false
generateRandomThemes = false
themes = AppThemes
bodyClass: Record<string, boolean> = {
@ -62,7 +63,8 @@ class App extends VuexModule implements AppState {
bodyClass,
currentOs,
currentTheme,
defaultColor
defaultColor,
generateRandomThemes
} = this
return {
@ -72,7 +74,8 @@ class App extends VuexModule implements AppState {
bodyClass,
currentOs,
currentTheme,
defaultColor
defaultColor,
generateRandomThemes
}
}
@ -158,24 +161,8 @@ class App extends VuexModule implements AppState {
@Action
randomizeSettingsTheme() {
const theme = this.activeTheme
const generateValueObject: Record<string, (input: AppInputThemeSlider) => AppInputThemeValue> = {
slider: (input: AppInputThemeSlider) => generateRandomSliderValue(input),
checkbox: () => Math.random() > 0.5,
color: () => generateRandomColor(),
palette: (input: AppInputThemeGeneral) => Math.floor(randomize(0, (input.values?.length || 2) - 1))
}
theme.settings = theme.settings?.map(input => {
const changeValueFunction = generateValueObject[input.type]
if (changeValueFunction) {
input.value = changeValueFunction(input as AppInputThemeSlider)
}
return input
})
theme.settings = randomizeSettingsTheme(theme)
this.syncSettingsWithCache()
this.syncStoreWithQuery()
}
@ -193,7 +180,6 @@ class App extends VuexModule implements AppState {
this.syncThemeColor()
this.syncStoreWithQuery()
this.syncSettingsWithCache()
}
@Action
@ -210,11 +196,14 @@ class App extends VuexModule implements AppState {
if (input) {
this.CHANGE_THEME_INPUT({ input, value })
this.syncSettingsWithCache()
}
}
@Action
toggleShowPassword() {
this.SET_STATE_APP({ key: 'showPassword', value: !this.showPassword })
}
@Action
syncSettingsWithCache() {
localStorage.setItem('settings', JSON.stringify(this.getMainSettings))
@ -249,29 +238,47 @@ class App extends VuexModule implements AppState {
return query
}, {})
$router.push({ name: $route.name || '/', query: { ...inputQuery, ...bodyClassQuery, themeName: this.currentTheme } })
const query = { ...inputQuery, ...bodyClassQuery, themeName: this.currentTheme }
const routeTo = { name: $route.name || '/', query }
const mayReplace = isDifferentRoute(routeTo)
if (mayReplace) {
$router.replace(routeTo)
}
}
@Action
syncThemeWithStore({ settings, query }: { settings: AppSettings; query: Route['query'] }) {
const themeName = query.themeName as string || settings.currentTheme
let themeName = query.themeName as string || settings.currentTheme
const { generateRandomThemes } = settings
const indexTheme = Math.floor(randomize(0, this.themes.length - 1))
const syncTheme = this.themes.reduce((themes: AppTheme[], theme) => {
const syncTheme = this.themes.reduce((themes: AppTheme[], theme, index) => {
const cachedTheme = settings.themes.find(({ name }) => name === theme.name)
const isActiveTheme = theme.name === themeName
if (cachedTheme && cachedTheme?.settings) {
theme.settings = theme.settings?.map(input => {
const cachedThemeInput = this.getThemeInput(input.name, cachedTheme)
let value = cachedThemeInput?.value ?? input.value
if (isActiveTheme) {
const queryThemeInput = input.name in query ? parseQueryValue(query[input.name] as string) : null
value = queryThemeInput ?? value
}
return Object.assign(input, { value })
})
const isActiveTheme = generateRandomThemes ? indexTheme === index : theme.name === themeName
const hasCachedTheme = cachedTheme && cachedTheme?.settings
if (hasCachedTheme) {
const randomSettings = isActiveTheme && generateRandomThemes
console.log({ indexTheme, index, randomSettings })
if (randomSettings) {
themeName = theme.name
}
theme.settings = randomSettings
? randomizeSettingsTheme(theme)
: theme.settings?.map(input => {
const cachedThemeInput = this.getThemeInput(input.name, cachedTheme)
let value = cachedThemeInput?.value ?? input.value
if (isActiveTheme) {
const queryThemeInput = input.name in query ? parseQueryValue(query[input.name] as string) : null
value = queryThemeInput ?? value
}
return Object.assign(input, { value })
})
}
themes.push(theme)
@ -302,6 +309,7 @@ class App extends VuexModule implements AppState {
try {
const settings: AppSettings = JSON.parse(localStorage.getItem('settings') || '{}')
this.SET_STATE_APP({ key: 'generateRandomThemes', value: settings.generateRandomThemes || false })
if (settings.themes) {
this.syncThemeWithStore({ settings, query })
@ -324,9 +332,7 @@ class App extends VuexModule implements AppState {
this.SET_STATE_APP({ key: 'currentOs', value: settings.currentOs || 'arch-linux' })
this.SET_STATE_APP({ key: 'desktop', value: settings.desktop })
this.SET_STATE_APP({ key: 'username', value: settings.username })
this.syncSettingsWithCache()
} catch (error) {
this.syncSettingsWithCache()
this.setUpSettings()
}
}

@ -2,7 +2,8 @@
font-size 1.5rem
line-height 1.2
font-weight 300
text-transform capitalize
&:first-letter
text-transform uppercase
.position-center
position absolute

@ -1,8 +1,10 @@
import { AppInputThemeSlider } from '@/models/app'
import { AppInputThemeGeneral, AppInputThemeSlider, AppInputThemeValue, AppTheme } from '@/models/app'
import { appWindow } from '@/models/lightdm'
import { AppModule } from '@/store/app'
import { PageModule } from '@/store/page'
import { debounce, DebounceSettings } from 'lodash'
import { RawLocation } from 'vue-router'
import router from '../router'
const isFinalBuild = process.env.VUE_APP_VIEW === 'build'
export const modKey = 'ctrl'
@ -14,6 +16,13 @@ export const languageMap: Record<string, string> = {
es: 'Español'
}
export function isDifferentRoute(to: RawLocation) {
const { app: { $route, $router } } = router
const resolve = $router.resolve(to)
return $route.fullPath !== resolve.href
}
export function Debounce(time = 500, options?: DebounceSettings): MethodDecorator {
const map = new Map<number, any>()
@ -151,3 +160,22 @@ export function stopPropagation(event: Event, callback?: Function) {
export function hasSomeParentClass(element: HTMLElement, tag: string): boolean {
return !!element.closest(tag)
}
export function randomizeSettingsTheme(theme: AppTheme) {
const generateValueObject: Record<string, (input: AppInputThemeSlider) => AppInputThemeValue> = {
slider: (input: AppInputThemeSlider) => generateRandomSliderValue(input),
checkbox: () => Math.random() > 0.5,
color: () => generateRandomColor(),
palette: (input: AppInputThemeGeneral) => Math.floor(randomize(0, (input.values?.length || 2) - 1))
}
return theme.settings?.map(input => {
const changeValueFunction = generateValueObject[input.type]
if (changeValueFunction) {
input.value = changeValueFunction(input as AppInputThemeSlider)
}
return input
})
}

Loading…
Cancel
Save