* Add cameraProjection setting * Add UI to toggle the user-level projection setting. * Make cameraProjection setting respected at startup * Add an E2E test for the perspective toggle * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * Don't force user back into perspective when exiting sketch * Make the projection setting more searchable * Make `current` label apply to the default option if not set * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * Re-run CI * Ohh *cargo fmt* * @lf94 feedback, fix found toggling bug, make command bar instantly toggle setting * Roll back the instant toggling behavior, it breaks the tests * Make ortho the default, keep tests using perspective * Move projection below camera controls setting * Fix up gizmo tests, which broke because the gizmo moved * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * Look at this (photo)Graph *in the voice of Nickelback* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: 49fl <ircsurfer33@gmail.com>
218 lines
6.4 KiB
TypeScript
218 lines
6.4 KiB
TypeScript
import { assign, setup } from 'xstate'
|
|
import { Themes, getSystemTheme, setThemeClass } from 'lib/theme'
|
|
import { createSettings, settings } from 'lib/settings/initialSettings'
|
|
import {
|
|
BaseUnit,
|
|
SetEventTypes,
|
|
SettingsLevel,
|
|
SettingsPaths,
|
|
WildcardSetEvent,
|
|
} from 'lib/settings/settingsTypes'
|
|
import {
|
|
configurationToSettingsPayload,
|
|
projectConfigurationToSettingsPayload,
|
|
setSettingsAtLevel,
|
|
} from 'lib/settings/settingsUtils'
|
|
import { sceneInfra } from 'lib/singletons'
|
|
|
|
export const settingsMachine = setup({
|
|
types: {
|
|
context: {} as ReturnType<typeof createSettings>,
|
|
input: {} as ReturnType<typeof createSettings>,
|
|
events: {} as
|
|
| WildcardSetEvent<SettingsPaths>
|
|
| SetEventTypes
|
|
| {
|
|
type: 'set.app.theme'
|
|
data: { level: SettingsLevel; value: Themes }
|
|
}
|
|
| {
|
|
type: 'set.modeling.units'
|
|
data: { level: SettingsLevel; value: BaseUnit }
|
|
}
|
|
| {
|
|
type: 'Reset settings'
|
|
level: SettingsLevel
|
|
}
|
|
| { type: 'Set all settings'; settings: typeof settings },
|
|
},
|
|
actions: {
|
|
setEngineTheme: () => {},
|
|
setClientTheme: () => {},
|
|
'Execute AST': () => {},
|
|
toastSuccess: () => {},
|
|
setEngineEdges: () => {},
|
|
setEngineScaleGridVisibility: () => {},
|
|
setClientSideSceneUnits: () => {},
|
|
persistSettings: () => {},
|
|
resetSettings: assign(({ context, event }) => {
|
|
if (!('level' in event)) return {}
|
|
|
|
// Create a new, blank payload
|
|
const newPayload =
|
|
event.level === 'user'
|
|
? configurationToSettingsPayload({})
|
|
: projectConfigurationToSettingsPayload({})
|
|
|
|
// Reset the settings at that level
|
|
const newSettings = setSettingsAtLevel(context, event.level, newPayload)
|
|
|
|
return newSettings
|
|
}),
|
|
setAllSettings: assign(({ event }) => {
|
|
if (!('settings' in event)) return {}
|
|
return event.settings
|
|
}),
|
|
setSettingAtLevel: assign(({ context, event }) => {
|
|
if (!('data' in event)) return {}
|
|
const { level, value } = event.data
|
|
const [category, setting] = event.type
|
|
.replace(/^set./, '')
|
|
.split('.') as [keyof typeof settings, string]
|
|
|
|
// @ts-ignore
|
|
context[category][setting][level] = value
|
|
|
|
const newContext = {
|
|
...context,
|
|
[category]: {
|
|
...context[category],
|
|
// @ts-ignore
|
|
[setting]: context[category][setting],
|
|
},
|
|
}
|
|
|
|
return newContext
|
|
}),
|
|
setThemeClass: ({ context }) => {
|
|
const currentTheme = context.app.theme.current ?? Themes.System
|
|
setThemeClass(
|
|
currentTheme === Themes.System ? getSystemTheme() : currentTheme
|
|
)
|
|
},
|
|
setEngineCameraProjection: ({ context }) => {
|
|
const newCurrentProjection = context.modeling.cameraProjection.current
|
|
sceneInfra.camControls.setEngineCameraProjection(newCurrentProjection)
|
|
},
|
|
},
|
|
}).createMachine({
|
|
/** @xstate-layout N4IgpgJg5mDOIC5QGUwBc0EsB2VYDpMIAbMAYlnXwEMAHW-Ae2wCNHqAnCHKZNatAFdYAbQAMAXUShajWJizNpIAB6IALAFYAnPgBMARgDsBsQDY969QGYjmzQBoQAT0SnrADnwePY61r0PAwNtMyMAX3CnVAweAiJSCio6BjQACzAAWzAAYUZiRg5xKSQQWXlFbGU1BD1PfFtfE3UzTUNNaydXBCD1b209PTEPTTMtdQNNSOj0LFx4knJKNHxMxggwYh58DYAzakFiNABVbAVi5XKFTCVSmusxPXx7bRt1DzMxI3UjD3UutwhAz4MyeHxiV5+AYRKIgGJzPCERZJFYpfDpLJgC6lK6VaqIExPMwWGwdGxBPRmAE9PSafCPMQ-EzWbQ6ELTOGzOJIxLLVbrTbbNKYKBpLaitAAUWgcGxMjk11uoBqVmBH0ZLKCrVs-xciCCwLCvhCjyMFhGHPh3IS5AASnB0AACZYI0SSS4KvF3AlafADRl1YZ2IxiRx6hBtIzPb7abQ+DxGaxmYKWrnzHnkGKO6jEYjOtN4OVlT03KrehAtOnm7Qaup6Ixm6mR6OaR4dAwjM1mVOxdM2lH8jZbXD4WBpRgAd2QAGMc2AAOIcIhF3Gl-EIRPA6yGcyh4whSnU0xGJ5GAat0OfFowma9xH9gBUK5LStUiECdMmfx+mg8hmNTY-PgMYQpoZoxh41g9q6+C0GAHDyLACL5nesBkBAzBgIQ2AAG6MAA1lhcEIZgSFWvMz4VGu5YALTbtYwEnj8HhxnooT1mG3QhmY-TmJ82gGCyjzaJEsLYAK8ClOReAelRr41HRJiMZYvysexdjUuohh+poBiGDuXzGKy0HWossmKmWyqIDR3zAZWLSahM2jWJ04YjDxHbDMmmhaYE3wmemxGIchLpxOZXpWQgNEjMB1h6WEYHqK8ZgJk2EL6N8wR1Cy-gJqJ4RAA */
|
|
id: 'Settings',
|
|
initial: 'idle',
|
|
context: ({ input }) => {
|
|
return {
|
|
...createSettings(),
|
|
...input,
|
|
}
|
|
},
|
|
states: {
|
|
idle: {
|
|
entry: ['setThemeClass', 'setClientSideSceneUnits'],
|
|
|
|
on: {
|
|
'*': {
|
|
target: 'persisting settings',
|
|
actions: ['setSettingAtLevel', 'toastSuccess'],
|
|
},
|
|
|
|
'set.app.onboardingStatus': {
|
|
target: 'persisting settings',
|
|
|
|
// No toast
|
|
actions: ['setSettingAtLevel'],
|
|
},
|
|
|
|
'set.app.themeColor': {
|
|
target: 'persisting settings',
|
|
|
|
// No toast
|
|
actions: ['setSettingAtLevel'],
|
|
},
|
|
|
|
'set.modeling.defaultUnit': {
|
|
target: 'persisting settings',
|
|
|
|
actions: [
|
|
'setSettingAtLevel',
|
|
'toastSuccess',
|
|
'setClientSideSceneUnits',
|
|
'Execute AST',
|
|
],
|
|
},
|
|
|
|
'set.app.theme': {
|
|
target: 'persisting settings',
|
|
|
|
actions: [
|
|
'setSettingAtLevel',
|
|
'toastSuccess',
|
|
'setThemeClass',
|
|
'setEngineTheme',
|
|
'setClientTheme',
|
|
],
|
|
},
|
|
|
|
'set.app.streamIdleMode': {
|
|
target: 'persisting settings',
|
|
|
|
actions: ['setSettingAtLevel', 'toastSuccess'],
|
|
},
|
|
|
|
'set.modeling.cameraProjection': {
|
|
target: 'persisting settings',
|
|
|
|
actions: [
|
|
'setSettingAtLevel',
|
|
'toastSuccess',
|
|
'setEngineCameraProjection',
|
|
],
|
|
},
|
|
|
|
'set.modeling.highlightEdges': {
|
|
target: 'persisting settings',
|
|
|
|
actions: ['setSettingAtLevel', 'toastSuccess', 'setEngineEdges'],
|
|
},
|
|
|
|
'Reset settings': {
|
|
target: 'persisting settings',
|
|
|
|
actions: [
|
|
'resetSettings',
|
|
'setThemeClass',
|
|
'setEngineTheme',
|
|
'setClientSideSceneUnits',
|
|
'Execute AST',
|
|
'setClientTheme',
|
|
],
|
|
},
|
|
|
|
'Set all settings': {
|
|
actions: [
|
|
'setAllSettings',
|
|
'setThemeClass',
|
|
'setEngineTheme',
|
|
'setClientSideSceneUnits',
|
|
'Execute AST',
|
|
'setClientTheme',
|
|
],
|
|
},
|
|
|
|
'set.modeling.showScaleGrid': {
|
|
target: 'persisting settings',
|
|
actions: [
|
|
'setSettingAtLevel',
|
|
'toastSuccess',
|
|
'setEngineScaleGridVisibility',
|
|
],
|
|
},
|
|
},
|
|
},
|
|
|
|
'persisting settings': {
|
|
entry: ['persistSettings'],
|
|
always: 'idle',
|
|
},
|
|
},
|
|
})
|