Rearchitect settings system to be scoped (#1956)
* BROKEN: start of scopes for each setting * Clean up later: mostly-functional scoped settings! Broken command bar, unimplemented generated settings components * Working persisted project settings in-folder * Start working toward automatic commands and settings UI * Relatively stable, settings-menu-editable * Settings persistence tweaks after merge * Custom settings UI working properly, cleaner types * Allow boolean command types, create Settings UI for them * Add support for option and string Settings input types * Proof of concept settings from command bar * Add all settings to command bar * Allow settings to be hidden on a level * Better command titles for settings * Hide the settings the settings from the commands bar * Derive command defaultValue from *current* settingsMachine context * Fix generated settings UI for 'options' type settings * Pretty settings modal 💅 * Allow for rollback to parent level setting * fmt * Fix tsc errors not related to loading from localStorage * Better setting descriptions, better buttons * Make displayName searchable in command bar * Consolidate constants, get working in browser * Start fixing tests, better types for saved settings payloads * Fix playwright tests * Add a test for the settings modal * Add AtLeast to codespell ignore list * Goofed merge of codespellrc * Try fixing linux E2E tests * Make codespellrc word lowercase * fmt * Fix data-testid in Tauri test * Don't set text settings if nothing changed * Turn off unimplemented settings * Allow for multiple "execution-done" messages to have appeared in snapshot tests * Try fixing up snapshot tests * Switch from .json to .toml settings file format * Use a different method for overriding the default units * Try to force using the new common storage state in snapshot tests * Update tests to use TOML * fmt and remove console logs * Restore units to export * tsc errors, make snapshot tests use TOML * Ensure that snapshot tests use the basicStorageState * Re-organize use of test.use() * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Update snapshots one more time since lighting changed * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Fix broken "Show in folder" for project-level settings * Fire all relevant actions after settings reset * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Properly reset the default directory * Hide settings by platform * Actually honor showDebugPanel * Unify settings hiding logic * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * fix first extrusion snapshot * another attempt to fix extrustion snapshot * Rerun test suite * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * trigger CI * more extrusion stuff * Replace resetSettings console log with comment --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
This commit is contained in:
@ -10,25 +10,17 @@ import { appConfigDir, documentDir, homeDir, sep } from '@tauri-apps/api/path'
|
||||
import { isTauri } from './isTauri'
|
||||
import { type ProjectWithEntryPointMetadata } from 'lib/types'
|
||||
import { metadata } from 'tauri-plugin-fs-extra-api'
|
||||
import { settingsMachine } from 'machines/settingsMachine'
|
||||
import { ContextFrom } from 'xstate'
|
||||
import { SETTINGS_FILE_NAME } from 'lib/constants'
|
||||
|
||||
const PROJECT_FOLDER = 'zoo-modeling-app-projects'
|
||||
export const FILE_EXT = '.kcl'
|
||||
export const PROJECT_ENTRYPOINT = 'main' + FILE_EXT
|
||||
const INDEX_IDENTIFIER = '$n' // $nn.. will pad the number with 0s
|
||||
export const MAX_PADDING = 7
|
||||
const RELEVANT_FILE_TYPES = [
|
||||
'kcl',
|
||||
'fbx',
|
||||
'gltf',
|
||||
'glb',
|
||||
'obj',
|
||||
'ply',
|
||||
'step',
|
||||
'stl',
|
||||
]
|
||||
import {
|
||||
FILE_EXT,
|
||||
INDEX_IDENTIFIER,
|
||||
MAX_PADDING,
|
||||
PROJECT_ENTRYPOINT,
|
||||
PROJECT_FOLDER,
|
||||
RELEVANT_FILE_TYPES,
|
||||
SETTINGS_FILE_EXT,
|
||||
} from 'lib/constants'
|
||||
import { SaveSettingsPayload, SettingsLevel } from './settings/settingsTypes'
|
||||
import * as TOML from '@iarna/toml'
|
||||
|
||||
type PathWithPossibleError = {
|
||||
path: string | null
|
||||
@ -375,25 +367,18 @@ function getPaddedIdentifierRegExp() {
|
||||
return new RegExp(`${escapedIdentifier}(${escapedIdentifier.slice(-1)}*)`)
|
||||
}
|
||||
|
||||
export async function getSettingsFilePath() {
|
||||
const dir = await appConfigDir()
|
||||
return dir + SETTINGS_FILE_NAME
|
||||
}
|
||||
|
||||
export async function writeToSettingsFile(
|
||||
settings: ContextFrom<typeof settingsMachine>
|
||||
export async function getUserSettingsFilePath(
|
||||
filename: string = SETTINGS_FILE_EXT
|
||||
) {
|
||||
return writeTextFile(
|
||||
await getSettingsFilePath(),
|
||||
JSON.stringify(settings, null, 2)
|
||||
)
|
||||
const dir = await appConfigDir()
|
||||
return dir + filename
|
||||
}
|
||||
|
||||
export async function readSettingsFile(): Promise<ContextFrom<
|
||||
typeof settingsMachine
|
||||
> | null> {
|
||||
const dir = await appConfigDir()
|
||||
const path = dir + SETTINGS_FILE_NAME
|
||||
export async function readSettingsFile(
|
||||
path: string
|
||||
): Promise<Partial<SaveSettingsPayload>> {
|
||||
const dir = path.slice(0, path.lastIndexOf(sep))
|
||||
|
||||
const dirExists = await exists(dir)
|
||||
if (!dirExists) {
|
||||
await createDir(dir, { recursive: true })
|
||||
@ -403,15 +388,39 @@ export async function readSettingsFile(): Promise<ContextFrom<
|
||||
|
||||
if (!settingsExist) {
|
||||
console.log(`Settings file does not exist at ${path}`)
|
||||
await writeToSettingsFile(settingsMachine.initialState.context)
|
||||
return null
|
||||
return {}
|
||||
}
|
||||
|
||||
try {
|
||||
const settings = await readTextFile(path)
|
||||
return JSON.parse(settings)
|
||||
// We expect the settings to be under a top-level [settings] key
|
||||
return TOML.parse(settings).settings as Partial<SaveSettingsPayload>
|
||||
} catch (e) {
|
||||
console.error('Error reading settings file:', e)
|
||||
return null
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSettingsFilePaths(
|
||||
projectPath?: string
|
||||
): Promise<Partial<Record<SettingsLevel, string>>> {
|
||||
const { user, project } = await getSettingsFolderPaths(projectPath)
|
||||
|
||||
return {
|
||||
user: user + 'user' + SETTINGS_FILE_EXT,
|
||||
project:
|
||||
project !== undefined
|
||||
? project + (isTauri() ? sep : '/') + 'project' + SETTINGS_FILE_EXT
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSettingsFolderPaths(projectPath?: string) {
|
||||
const user = isTauri() ? await appConfigDir() : '/'
|
||||
const project = projectPath !== undefined ? projectPath : undefined
|
||||
|
||||
return {
|
||||
user,
|
||||
project,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user