remove rust bw compatible settings (#6085)

regenerate the settings docs



cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2025-04-30 12:00:37 -07:00
committed by GitHub
parent 820082d7f2
commit dee77e814a
15 changed files with 268 additions and 600 deletions

View File

@ -55,20 +55,6 @@ This setting has further nested options. See the schema for full details.
The onboarding status of the app. The onboarding status of the app.
**Default:** None
##### theme_color
The hue of the primary theme color for the app.
**Default:** None
##### enable_ssao
Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
**Default:** None **Default:** None
##### dismiss_web_banner ##### dismiss_web_banner
@ -128,13 +114,6 @@ The default unit to use in modeling dimensions.
Highlight edges of 3D objects? Highlight edges of 3D objects?
**Default:** None
##### show_debug_panel
Whether to show the debug panel, which lets you see various states of the app to aid in development. Remove this when we remove backwards compatibility with the old settings file.
**Default:** None **Default:** None
##### enable_ssao ##### enable_ssao

View File

@ -57,34 +57,6 @@ This setting has further nested options. See the schema for full details.
The onboarding status of the app. The onboarding status of the app.
**Default:** None
##### project_directory
Backwards compatible project directory setting.
**Default:** None
##### theme
Backwards compatible theme setting.
**Default:** None
##### theme_color
The hue of the primary theme color for the app.
**Default:** None
##### enable_ssao
Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
**Default:** None **Default:** None
##### dismiss_web_banner ##### dismiss_web_banner
@ -103,7 +75,7 @@ When the user is idle, teardown the stream after some time.
##### allow_orbit_in_sketch_mode ##### allow_orbit_in_sketch_mode
When the user is idle, and this is true, the stream will be torn down. Allow orbiting in sketch mode.
**Default:** None **Default:** None
@ -159,13 +131,6 @@ The controls for how to navigate the 3D view.
Highlight edges of 3D objects? Highlight edges of 3D objects?
**Default:** None
##### show_debug_panel
Whether to show the debug panel, which lets you see various states of the app to aid in development. Remove this when we remove backwards compatibility with the old settings file.
**Default:** None **Default:** None
##### enable_ssao ##### enable_ssao

View File

@ -21,6 +21,7 @@ import {
executorInputPath, executorInputPath,
getUtils, getUtils,
networkingMasks, networkingMasks,
settingsToToml,
tomlToSettings, tomlToSettings,
} from '@e2e/playwright/test-utils' } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test' import { expect, test } from '@e2e/playwright/zoo-test'
@ -510,7 +511,15 @@ test.describe(
) )
await fsp.writeFile( await fsp.writeFile(
tempSettingsFilePath, tempSettingsFilePath,
`[settings.app]\nthemeColor = "${color}"` settingsToToml({
settings: {
app: {
appearance: {
color: parseFloat(color),
},
},
},
})
) )
} }

View File

@ -27,42 +27,8 @@ pub struct Configuration {
} }
impl Configuration { impl Configuration {
// TODO: remove this when we remove backwards compatibility with the old settings file. pub fn parse_and_validate(toml_str: &str) -> Result<Self> {
pub fn backwards_compatible_toml_parse(toml_str: &str) -> Result<Self> { let settings = toml::from_str::<Self>(toml_str)?;
let mut settings = toml::from_str::<Self>(toml_str)?;
if let Some(project_directory) = &settings.settings.app.project_directory {
if settings.settings.project.directory.to_string_lossy().is_empty() {
settings.settings.project.directory.clone_from(project_directory);
settings.settings.app.project_directory = None;
}
}
if let Some(theme) = &settings.settings.app.theme {
if settings.settings.app.appearance.theme == AppTheme::default() {
settings.settings.app.appearance.theme = *theme;
settings.settings.app.theme = None;
}
}
if let Some(theme_color) = &settings.settings.app.theme_color {
if settings.settings.app.appearance.color == AppColor::default() {
settings.settings.app.appearance.color = theme_color.clone().into();
settings.settings.app.theme_color = None;
}
}
if let Some(enable_ssao) = settings.settings.app.enable_ssao {
if settings.settings.modeling.enable_ssao.into() {
settings.settings.modeling.enable_ssao = enable_ssao.into();
settings.settings.app.enable_ssao = None;
}
}
if settings.settings.modeling.show_debug_panel && !settings.settings.app.show_debug_panel {
settings.settings.app.show_debug_panel = settings.settings.modeling.show_debug_panel;
settings.settings.modeling.show_debug_panel = Default::default();
}
settings.validate()?; settings.validate()?;
@ -84,22 +50,20 @@ pub struct Settings {
#[validate(nested)] #[validate(nested)]
pub modeling: ModelingSettings, pub modeling: ModelingSettings,
/// Settings that affect the behavior of the KCL text editor. /// Settings that affect the behavior of the KCL text editor.
#[serde(default, alias = "textEditor", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
#[validate(nested)] #[validate(nested)]
pub text_editor: TextEditorSettings, pub text_editor: TextEditorSettings,
/// Settings that affect the behavior of project management. /// Settings that affect the behavior of project management.
#[serde(default, alias = "projects", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
#[validate(nested)] #[validate(nested)]
pub project: ProjectSettings, pub project: ProjectSettings,
/// Settings that affect the behavior of the command bar. /// Settings that affect the behavior of the command bar.
#[serde(default, alias = "commandBar", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
#[validate(nested)] #[validate(nested)]
pub command_bar: CommandBarSettings, pub command_bar: CommandBarSettings,
} }
/// Application wide settings. /// Application wide settings.
// TODO: When we remove backwards compatibility with the old settings file, we can remove the
// aliases to camelCase (and projects plural) from everywhere.
#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema, ts_rs::TS, PartialEq, Validate)] #[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema, ts_rs::TS, PartialEq, Validate)]
#[ts(export)] #[ts(export)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
@ -109,27 +73,11 @@ pub struct AppSettings {
#[validate(nested)] #[validate(nested)]
pub appearance: AppearanceSettings, pub appearance: AppearanceSettings,
/// The onboarding status of the app. /// The onboarding status of the app.
#[serde(default, alias = "onboardingStatus", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub onboarding_status: OnboardingStatus, pub onboarding_status: OnboardingStatus,
/// Backwards compatible project directory setting.
#[serde(default, alias = "projectDirectory", skip_serializing_if = "Option::is_none")]
#[ts(skip)]
pub project_directory: Option<std::path::PathBuf>,
/// Backwards compatible theme setting.
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(skip)]
pub theme: Option<AppTheme>,
/// The hue of the primary theme color for the app.
#[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
#[ts(skip)]
pub theme_color: Option<FloatOrInt>,
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
#[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
#[ts(skip)]
pub enable_ssao: Option<bool>,
/// Permanently dismiss the banner warning to download the desktop app. /// Permanently dismiss the banner warning to download the desktop app.
/// This setting only applies to the web app. And is temporary until we have Linux support. /// This setting only applies to the web app. And is temporary until we have Linux support.
#[serde(default, alias = "dismissWebBanner", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub dismiss_web_banner: bool, pub dismiss_web_banner: bool,
/// When the user is idle, teardown the stream after some time. /// When the user is idle, teardown the stream after some time.
#[serde( #[serde(
@ -139,12 +87,12 @@ pub struct AppSettings {
skip_serializing_if = "is_default" skip_serializing_if = "is_default"
)] )]
stream_idle_mode: Option<u32>, stream_idle_mode: Option<u32>,
/// When the user is idle, and this is true, the stream will be torn down. /// Allow orbiting in sketch mode.
#[serde(default, alias = "allowOrbitInSketchMode", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub allow_orbit_in_sketch_mode: bool, pub allow_orbit_in_sketch_mode: bool,
/// Whether to show the debug panel, which lets you see various states /// Whether to show the debug panel, which lets you see various states
/// of the app to aid in development. /// of the app to aid in development.
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub show_debug_panel: bool, pub show_debug_panel: bool,
} }
@ -300,31 +248,25 @@ impl From<AppTheme> for kittycad::types::Color {
#[ts(export)] #[ts(export)]
pub struct ModelingSettings { pub struct ModelingSettings {
/// The default unit to use in modeling dimensions. /// The default unit to use in modeling dimensions.
#[serde(default, alias = "defaultUnit", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub base_unit: UnitLength, pub base_unit: UnitLength,
/// The projection mode the camera should use while modeling. /// The projection mode the camera should use while modeling.
#[serde(default, alias = "cameraProjection", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub camera_projection: CameraProjectionType, pub camera_projection: CameraProjectionType,
/// The methodology the camera should use to orbit around the model. /// The methodology the camera should use to orbit around the model.
#[serde(default, alias = "cameraOrbit", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub camera_orbit: CameraOrbitType, pub camera_orbit: CameraOrbitType,
/// The controls for how to navigate the 3D view. /// The controls for how to navigate the 3D view.
#[serde(default, alias = "mouseControls", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub mouse_controls: MouseControlType, pub mouse_controls: MouseControlType,
/// Highlight edges of 3D objects? /// Highlight edges of 3D objects?
#[serde(default, alias = "highlightEdges", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub highlight_edges: DefaultTrue, pub highlight_edges: DefaultTrue,
/// Whether to show the debug panel, which lets you see various states
/// of the app to aid in development.
/// Remove this when we remove backwards compatibility with the old settings file.
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
#[ts(skip)]
pub show_debug_panel: bool,
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled. /// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
#[serde(default, skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub enable_ssao: DefaultTrue, pub enable_ssao: DefaultTrue,
/// Whether or not to show a scale grid in the 3D modeling view /// Whether or not to show a scale grid in the 3D modeling view
#[serde(default, alias = "showScaleGrid", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub show_scale_grid: bool, pub show_scale_grid: bool,
} }
@ -435,21 +377,17 @@ impl From<UnitLength> for kittycad_modeling_cmds::units::UnitLength {
pub enum MouseControlType { pub enum MouseControlType {
#[default] #[default]
#[display("zoo")] #[display("zoo")]
#[serde(rename = "zoo", alias = "Zoo", alias = "KittyCAD")] #[serde(rename = "zoo")]
Zoo, Zoo,
#[display("onshape")] #[display("onshape")]
#[serde(rename = "onshape", alias = "OnShape")] #[serde(rename = "onshape")]
OnShape, OnShape,
#[serde(alias = "Trackpad Friendly")]
TrackpadFriendly, TrackpadFriendly,
#[serde(alias = "Solidworks")]
Solidworks, Solidworks,
#[serde(alias = "NX")]
Nx, Nx,
#[serde(alias = "Creo")]
Creo, Creo,
#[display("autocad")] #[display("autocad")]
#[serde(rename = "autocad", alias = "AutoCAD")] #[serde(rename = "autocad")]
AutoCad, AutoCad,
} }
@ -487,10 +425,10 @@ pub enum CameraOrbitType {
#[ts(export)] #[ts(export)]
pub struct TextEditorSettings { pub struct TextEditorSettings {
/// Whether to wrap text in the editor or overflow with scroll. /// Whether to wrap text in the editor or overflow with scroll.
#[serde(default, alias = "textWrapping", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub text_wrapping: DefaultTrue, pub text_wrapping: DefaultTrue,
/// Whether to make the cursor blink in the editor. /// Whether to make the cursor blink in the editor.
#[serde(default, alias = "blinkingCursor", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub blinking_cursor: DefaultTrue, pub blinking_cursor: DefaultTrue,
} }
@ -503,7 +441,7 @@ pub struct ProjectSettings {
#[serde(default, skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub directory: std::path::PathBuf, pub directory: std::path::PathBuf,
/// The default project name to use when creating a new project. /// The default project name to use when creating a new project.
#[serde(default, alias = "defaultProjectName", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub default_project_name: ProjectNameTemplate, pub default_project_name: ProjectNameTemplate,
} }
@ -536,7 +474,7 @@ impl From<String> for ProjectNameTemplate {
#[ts(export)] #[ts(export)]
pub struct CommandBarSettings { pub struct CommandBarSettings {
/// Whether to include settings in the command bar. /// Whether to include settings in the command bar.
#[serde(default, alias = "includeSettings", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub include_settings: DefaultTrue, pub include_settings: DefaultTrue,
} }
@ -608,305 +546,9 @@ mod tests {
use super::{ use super::{
AppColor, AppSettings, AppTheme, AppearanceSettings, CameraProjectionType, CommandBarSettings, Configuration, AppColor, AppSettings, AppTheme, AppearanceSettings, CameraProjectionType, CommandBarSettings, Configuration,
ModelingSettings, OnboardingStatus, ProjectSettings, Settings, TextEditorSettings, UnitLength, ModelingSettings, MouseControlType, OnboardingStatus, ProjectNameTemplate, ProjectSettings, Settings,
TextEditorSettings, UnitLength,
}; };
use crate::settings::types::CameraOrbitType;
#[test]
// Test that we can deserialize a project file from the old format.
// TODO: We can remove this functionality after a few versions.
fn test_backwards_compatible_project_settings_file_pw() {
let old_project_file = r#"[settings.app]
theme = "dark"
onboardingStatus = "dismissed"
projectDirectory = ""
enableSSAO = false
[settings.modeling]
defaultUnit = "in"
cameraProjection = "orthographic"
mouseControls = "KittyCAD"
showDebugPanel = true
[settings.projects]
defaultProjectName = "untitled"
[settings.textEditor]
textWrapping = true
#"#;
//let parsed = toml::from_str::<Configuration(old_project_file).unwrap();
let parsed = Configuration::backwards_compatible_toml_parse(old_project_file).unwrap();
assert_eq!(
parsed,
Configuration {
settings: Settings {
app: AppSettings {
appearance: AppearanceSettings {
theme: AppTheme::Dark,
color: Default::default()
},
onboarding_status: OnboardingStatus::Dismissed,
project_directory: None,
theme: None,
theme_color: None,
dismiss_web_banner: false,
enable_ssao: None,
stream_idle_mode: None,
allow_orbit_in_sketch_mode: false,
show_debug_panel: true,
},
modeling: ModelingSettings {
base_unit: UnitLength::In,
camera_projection: CameraProjectionType::Orthographic,
camera_orbit: Default::default(),
mouse_controls: Default::default(),
show_debug_panel: Default::default(),
highlight_edges: Default::default(),
enable_ssao: false.into(),
show_scale_grid: false,
},
text_editor: TextEditorSettings {
text_wrapping: true.into(),
blinking_cursor: true.into()
},
project: Default::default(),
command_bar: CommandBarSettings {
include_settings: true.into()
},
}
}
);
}
#[test]
// Test that we can deserialize a project file from the old format.
// TODO: We can remove this functionality after a few versions.
fn test_backwards_compatible_project_settings_file() {
let old_project_file = r#"[settings.app]
theme = "dark"
themeColor = "138"
[settings.modeling]
defaultUnit = "yd"
showDebugPanel = true
[settings.textEditor]
textWrapping = false
blinkingCursor = false
[settings.commandBar]
includeSettings = false
#"#;
//let parsed = toml::from_str::<Configuration(old_project_file).unwrap();
let parsed = Configuration::backwards_compatible_toml_parse(old_project_file).unwrap();
assert_eq!(
parsed,
Configuration {
settings: Settings {
app: AppSettings {
appearance: AppearanceSettings {
theme: AppTheme::Dark,
color: 138.0.into()
},
onboarding_status: Default::default(),
project_directory: None,
theme: None,
theme_color: None,
dismiss_web_banner: false,
enable_ssao: None,
show_debug_panel: true,
stream_idle_mode: None,
allow_orbit_in_sketch_mode: false,
},
modeling: ModelingSettings {
base_unit: UnitLength::Yd,
camera_projection: Default::default(),
camera_orbit: Default::default(),
mouse_controls: Default::default(),
highlight_edges: Default::default(),
enable_ssao: true.into(),
show_scale_grid: false,
show_debug_panel: Default::default(),
},
text_editor: TextEditorSettings {
text_wrapping: false.into(),
blinking_cursor: false.into()
},
project: Default::default(),
command_bar: CommandBarSettings {
include_settings: false.into()
},
}
}
);
}
#[test]
// Test that we can deserialize a app settings file from the old format.
// TODO: We can remove this functionality after a few versions.
fn test_backwards_compatible_app_settings_file() {
let old_app_settings_file = r#"[settings.app]
onboardingStatus = "dismissed"
projectDirectory = "/Users/macinatormax/Documents/kittycad-modeling-projects"
theme = "dark"
themeColor = "138"
[settings.modeling]
defaultUnit = "yd"
showDebugPanel = true
[settings.textEditor]
textWrapping = false
blinkingCursor = false
[settings.commandBar]
includeSettings = false
[settings.projects]
defaultProjectName = "projects-$nnn"
#"#;
//let parsed = toml::from_str::<Configuration>(old_app_settings_file).unwrap();
let parsed = Configuration::backwards_compatible_toml_parse(old_app_settings_file).unwrap();
assert_eq!(
parsed,
Configuration {
settings: Settings {
app: AppSettings {
appearance: AppearanceSettings {
theme: AppTheme::Dark,
color: 138.0.into()
},
onboarding_status: OnboardingStatus::Dismissed,
project_directory: None,
theme: None,
theme_color: None,
dismiss_web_banner: false,
enable_ssao: None,
stream_idle_mode: None,
allow_orbit_in_sketch_mode: false,
show_debug_panel: true,
},
modeling: ModelingSettings {
base_unit: UnitLength::Yd,
camera_projection: Default::default(),
camera_orbit: CameraOrbitType::Spherical,
mouse_controls: Default::default(),
highlight_edges: Default::default(),
show_debug_panel: Default::default(),
enable_ssao: true.into(),
show_scale_grid: false,
},
text_editor: TextEditorSettings {
text_wrapping: false.into(),
blinking_cursor: false.into()
},
project: ProjectSettings {
directory: "/Users/macinatormax/Documents/kittycad-modeling-projects".into(),
default_project_name: "projects-$nnn".to_string().into()
},
command_bar: CommandBarSettings {
include_settings: false.into()
},
}
}
);
// Write the file back out.
let serialized = toml::to_string(&parsed).unwrap();
assert_eq!(
serialized,
r#"[settings.app]
onboarding_status = "dismissed"
show_debug_panel = true
[settings.app.appearance]
theme = "dark"
color = 138.0
[settings.modeling]
base_unit = "yd"
[settings.text_editor]
text_wrapping = false
blinking_cursor = false
[settings.project]
directory = "/Users/macinatormax/Documents/kittycad-modeling-projects"
default_project_name = "projects-$nnn"
[settings.command_bar]
include_settings = false
"#
);
}
#[test]
fn test_settings_backwards_compat_partial() {
let partial_settings_file = r#"[settings.app]
onboardingStatus = "dismissed"
projectDirectory = "/Users/macinatormax/Documents/kittycad-modeling-projects""#;
//let parsed = toml::from_str::<Configuration>(partial_settings_file).unwrap();
let parsed = Configuration::backwards_compatible_toml_parse(partial_settings_file).unwrap();
assert_eq!(
parsed,
Configuration {
settings: Settings {
app: AppSettings {
appearance: AppearanceSettings {
theme: AppTheme::System,
color: Default::default()
},
onboarding_status: OnboardingStatus::Dismissed,
project_directory: None,
theme: None,
theme_color: None,
dismiss_web_banner: false,
enable_ssao: None,
show_debug_panel: false,
stream_idle_mode: None,
allow_orbit_in_sketch_mode: false,
},
modeling: ModelingSettings {
base_unit: UnitLength::Mm,
camera_projection: Default::default(),
camera_orbit: Default::default(),
mouse_controls: Default::default(),
highlight_edges: true.into(),
show_debug_panel: Default::default(),
enable_ssao: true.into(),
show_scale_grid: false,
},
text_editor: TextEditorSettings {
text_wrapping: true.into(),
blinking_cursor: true.into()
},
project: ProjectSettings {
directory: "/Users/macinatormax/Documents/kittycad-modeling-projects".into(),
default_project_name: "untitled".to_string().into()
},
command_bar: CommandBarSettings {
include_settings: true.into()
},
}
}
);
// Write the file back out.
let serialized = toml::to_string(&parsed).unwrap();
assert_eq!(
serialized,
r#"[settings.app]
onboarding_status = "dismissed"
[settings.project]
directory = "/Users/macinatormax/Documents/kittycad-modeling-projects"
"#
);
}
#[test] #[test]
fn test_settings_empty_file_parses() { fn test_settings_empty_file_parses() {
@ -919,10 +561,87 @@ directory = "/Users/macinatormax/Documents/kittycad-modeling-projects"
let serialized = toml::to_string(&parsed).unwrap(); let serialized = toml::to_string(&parsed).unwrap();
assert_eq!(serialized, r#""#); assert_eq!(serialized, r#""#);
let parsed = Configuration::backwards_compatible_toml_parse(empty_settings_file).unwrap(); let parsed = Configuration::parse_and_validate(empty_settings_file).unwrap();
assert_eq!(parsed, Configuration::default()); assert_eq!(parsed, Configuration::default());
} }
#[test]
fn test_settings_parse_basic() {
let settings_file = r#"[settings.app]
default_project_name = "untitled"
directory = ""
onboarding_status = "dismissed"
[settings.app.appearance]
theme = "dark"
[settings.modeling]
enable_ssao = false
base_unit = "in"
mouse_controls = "zoo"
camera_projection = "perspective"
[settings.project]
default_project_name = "untitled"
directory = ""
[settings.text_editor]
text_wrapping = true"#;
let expected = Configuration {
settings: Settings {
app: AppSettings {
onboarding_status: OnboardingStatus::Dismissed,
appearance: AppearanceSettings {
theme: AppTheme::Dark,
color: AppColor(264.5),
},
..Default::default()
},
modeling: ModelingSettings {
enable_ssao: false.into(),
base_unit: UnitLength::In,
mouse_controls: MouseControlType::Zoo,
camera_projection: CameraProjectionType::Perspective,
..Default::default()
},
project: ProjectSettings {
default_project_name: ProjectNameTemplate("untitled".to_string()),
directory: "".into(),
},
text_editor: TextEditorSettings {
text_wrapping: true.into(),
..Default::default()
},
command_bar: CommandBarSettings {
include_settings: true.into(),
},
},
};
let parsed = toml::from_str::<Configuration>(settings_file).unwrap();
assert_eq!(parsed, expected,);
// Write the file back out.
let serialized = toml::to_string(&parsed).unwrap();
assert_eq!(
serialized,
r#"[settings.app]
onboarding_status = "dismissed"
[settings.app.appearance]
theme = "dark"
[settings.modeling]
base_unit = "in"
camera_projection = "perspective"
enable_ssao = false
"#
);
let parsed = Configuration::parse_and_validate(settings_file).unwrap();
assert_eq!(parsed, expected);
}
#[test] #[test]
fn test_color_validation() { fn test_color_validation() {
let color = AppColor(360.0); let color = AppColor(360.0);
@ -957,7 +676,7 @@ directory = "/Users/macinatormax/Documents/kittycad-modeling-projects"
let settings_file = r#"[settings.app.appearance] let settings_file = r#"[settings.app.appearance]
color = 1567.4"#; color = 1567.4"#;
let result = Configuration::backwards_compatible_toml_parse(settings_file); let result = Configuration::parse_and_validate(settings_file);
if let Ok(r) = result { if let Ok(r) = result {
panic!("Expected an error, but got success: {:?}", r); panic!("Expected an error, but got success: {:?}", r);
} }

View File

@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use validator::Validate; use validator::Validate;
use crate::settings::types::{ use crate::settings::types::{
is_default, AppColor, CommandBarSettings, DefaultTrue, FloatOrInt, OnboardingStatus, TextEditorSettings, UnitLength, is_default, AppColor, CommandBarSettings, DefaultTrue, OnboardingStatus, TextEditorSettings, UnitLength,
}; };
/// Project specific settings for the app. /// Project specific settings for the app.
@ -27,27 +27,8 @@ pub struct ProjectConfiguration {
impl ProjectConfiguration { impl ProjectConfiguration {
// TODO: remove this when we remove backwards compatibility with the old settings file. // TODO: remove this when we remove backwards compatibility with the old settings file.
pub fn backwards_compatible_toml_parse(toml_str: &str) -> Result<Self> { pub fn parse_and_validate(toml_str: &str) -> Result<Self> {
let mut settings = toml::from_str::<Self>(toml_str)?; let settings = toml::from_str::<Self>(toml_str)?;
if let Some(theme_color) = &settings.settings.app.theme_color {
if settings.settings.app.appearance.color == AppColor::default() {
settings.settings.app.appearance.color = theme_color.clone().into();
settings.settings.app.theme_color = None;
}
}
if let Some(enable_ssao) = settings.settings.app.enable_ssao {
if settings.settings.modeling.enable_ssao.into() {
settings.settings.modeling.enable_ssao = enable_ssao.into();
settings.settings.app.enable_ssao = None;
}
}
if settings.settings.modeling.show_debug_panel && !settings.settings.app.show_debug_panel {
settings.settings.app.show_debug_panel = settings.settings.modeling.show_debug_panel;
settings.settings.modeling.show_debug_panel = Default::default();
}
settings.validate()?; settings.validate()?;
@ -69,11 +50,11 @@ pub struct PerProjectSettings {
#[validate(nested)] #[validate(nested)]
pub modeling: ProjectModelingSettings, pub modeling: ProjectModelingSettings,
/// Settings that affect the behavior of the KCL text editor. /// Settings that affect the behavior of the KCL text editor.
#[serde(default, alias = "textEditor")] #[serde(default)]
#[validate(nested)] #[validate(nested)]
pub text_editor: TextEditorSettings, pub text_editor: TextEditorSettings,
/// Settings that affect the behavior of the command bar. /// Settings that affect the behavior of the command bar.
#[serde(default, alias = "commandBar")] #[serde(default)]
#[validate(nested)] #[validate(nested)]
pub command_bar: CommandBarSettings, pub command_bar: CommandBarSettings,
} }
@ -90,32 +71,24 @@ pub struct ProjectAppSettings {
#[validate(nested)] #[validate(nested)]
pub appearance: ProjectAppearanceSettings, pub appearance: ProjectAppearanceSettings,
/// The onboarding status of the app. /// The onboarding status of the app.
#[serde(default, alias = "onboardingStatus", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub onboarding_status: OnboardingStatus, pub onboarding_status: OnboardingStatus,
/// The hue of the primary theme color for the app.
#[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
#[ts(skip)]
pub theme_color: Option<FloatOrInt>,
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
#[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
#[ts(skip)]
pub enable_ssao: Option<bool>,
/// Permanently dismiss the banner warning to download the desktop app. /// Permanently dismiss the banner warning to download the desktop app.
/// This setting only applies to the web app. And is temporary until we have Linux support. /// This setting only applies to the web app. And is temporary until we have Linux support.
#[serde(default, alias = "dismissWebBanner", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub dismiss_web_banner: bool, pub dismiss_web_banner: bool,
/// When the user is idle, and this is true, the stream will be torn down. /// When the user is idle, and this is true, the stream will be torn down.
#[serde(default, alias = "streamIdleMode", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub stream_idle_mode: bool, pub stream_idle_mode: bool,
/// When the user is idle, and this is true, the stream will be torn down. /// When the user is idle, and this is true, the stream will be torn down.
#[serde(default, alias = "allowOrbitInSketchMode", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub allow_orbit_in_sketch_mode: bool, pub allow_orbit_in_sketch_mode: bool,
/// Whether to show the debug panel, which lets you see various states /// Whether to show the debug panel, which lets you see various states
/// of the app to aid in development. /// of the app to aid in development.
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub show_debug_panel: bool, pub show_debug_panel: bool,
/// Settings that affect the behavior of the command bar. /// Settings that affect the behavior of the command bar.
#[serde(default, alias = "namedViews", skip_serializing_if = "IndexMap::is_empty")] #[serde(default, skip_serializing_if = "IndexMap::is_empty")]
pub named_views: IndexMap<uuid::Uuid, NamedView>, pub named_views: IndexMap<uuid::Uuid, NamedView>,
} }
@ -136,17 +109,11 @@ pub struct ProjectAppearanceSettings {
#[ts(export)] #[ts(export)]
pub struct ProjectModelingSettings { pub struct ProjectModelingSettings {
/// The default unit to use in modeling dimensions. /// The default unit to use in modeling dimensions.
#[serde(default, alias = "defaultUnit", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub base_unit: UnitLength, pub base_unit: UnitLength,
/// Highlight edges of 3D objects? /// Highlight edges of 3D objects?
#[serde(default, alias = "highlightEdges", skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub highlight_edges: DefaultTrue, pub highlight_edges: DefaultTrue,
/// Whether to show the debug panel, which lets you see various states
/// of the app to aid in development.
/// Remove this when we remove backwards compatibility with the old settings file.
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
#[ts(skip)]
pub show_debug_panel: bool,
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled. /// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
#[serde(default, skip_serializing_if = "is_default")] #[serde(default, skip_serializing_if = "is_default")]
pub enable_ssao: DefaultTrue, pub enable_ssao: DefaultTrue,
@ -161,31 +128,31 @@ fn named_view_point_version_one() -> f64 {
#[ts(export)] #[ts(export)]
pub struct NamedView { pub struct NamedView {
/// User defined name to identify the named view. A label. /// User defined name to identify the named view. A label.
#[serde(default, alias = "name")] #[serde(default)]
pub name: String, pub name: String,
/// Engine camera eye off set /// Engine camera eye off set
#[serde(default, alias = "eyeOffset")] #[serde(default)]
pub eye_offset: f64, pub eye_offset: f64,
/// Engine camera vertical FOV /// Engine camera vertical FOV
#[serde(default, alias = "fovY")] #[serde(default)]
pub fov_y: f64, pub fov_y: f64,
// Engine camera is orthographic or perspective projection // Engine camera is orthographic or perspective projection
#[serde(default, alias = "isOrtho")] #[serde(default)]
pub is_ortho: bool, pub is_ortho: bool,
/// Engine camera is orthographic camera scaling enabled /// Engine camera is orthographic camera scaling enabled
#[serde(default, alias = "orthoScaleEnabled")] #[serde(default)]
pub ortho_scale_enabled: bool, pub ortho_scale_enabled: bool,
/// Engine camera orthographic scaling factor /// Engine camera orthographic scaling factor
#[serde(default, alias = "orthoScaleFactor")] #[serde(default)]
pub ortho_scale_factor: f64, pub ortho_scale_factor: f64,
/// Engine camera position that the camera pivots around /// Engine camera position that the camera pivots around
#[serde(default, alias = "pivotPosition")] #[serde(default)]
pub pivot_position: [f64; 3], pub pivot_position: [f64; 3],
/// Engine camera orientation in relation to the pivot position /// Engine camera orientation in relation to the pivot position
#[serde(default, alias = "pivotRotation")] #[serde(default)]
pub pivot_rotation: [f64; 4], pub pivot_rotation: [f64; 4],
/// Engine camera world coordinate system orientation /// Engine camera world coordinate system orientation
#[serde(default, alias = "worldCoordSystem")] #[serde(default)]
pub world_coord_system: String, pub world_coord_system: String,
/// Version number of the view point if the engine camera API changes /// Version number of the view point if the engine camera API changes
#[serde(default = "named_view_point_version_one")] #[serde(default = "named_view_point_version_one")]
@ -204,80 +171,6 @@ mod tests {
}; };
use crate::settings::types::UnitLength; use crate::settings::types::UnitLength;
#[test]
// Test that we can deserialize a project file from the old format.
// TODO: We can remove this functionality after a few versions.
fn test_backwards_compatible_project_settings_file() {
let old_project_file = r#"[settings.app]
themeColor = "138"
[settings.textEditor]
textWrapping = false
blinkingCursor = false
[settings.modeling]
showDebugPanel = true
[settings.commandBar]
includeSettings = false
#"#;
//let parsed = toml::from_str::<ProjectConfiguration(old_project_file).unwrap();
let parsed = ProjectConfiguration::backwards_compatible_toml_parse(old_project_file).unwrap();
assert_eq!(
parsed,
ProjectConfiguration {
settings: PerProjectSettings {
app: ProjectAppSettings {
appearance: ProjectAppearanceSettings { color: 138.0.into() },
onboarding_status: Default::default(),
theme_color: None,
dismiss_web_banner: false,
enable_ssao: None,
stream_idle_mode: false,
allow_orbit_in_sketch_mode: false,
show_debug_panel: true,
named_views: IndexMap::default()
},
modeling: ProjectModelingSettings {
base_unit: UnitLength::Mm,
highlight_edges: Default::default(),
show_debug_panel: Default::default(),
enable_ssao: true.into(),
},
text_editor: TextEditorSettings {
text_wrapping: false.into(),
blinking_cursor: false.into()
},
command_bar: CommandBarSettings {
include_settings: false.into()
},
}
}
);
// Write the file back out.
let serialized = toml::to_string(&parsed).unwrap();
assert_eq!(
serialized,
r#"[settings.app]
show_debug_panel = true
[settings.app.appearance]
color = 138.0
[settings.modeling]
[settings.text_editor]
text_wrapping = false
blinking_cursor = false
[settings.command_bar]
include_settings = false
"#
);
}
#[test] #[test]
fn test_project_settings_empty_file_parses() { fn test_project_settings_empty_file_parses() {
let empty_settings_file = r#""#; let empty_settings_file = r#""#;
@ -299,7 +192,7 @@ include_settings = false
"# "#
); );
let parsed = ProjectConfiguration::backwards_compatible_toml_parse(empty_settings_file).unwrap(); let parsed = ProjectConfiguration::parse_and_validate(empty_settings_file).unwrap();
assert_eq!(parsed, ProjectConfiguration::default()); assert_eq!(parsed, ProjectConfiguration::default());
} }
@ -308,7 +201,7 @@ include_settings = false
let settings_file = r#"[settings.app.appearance] let settings_file = r#"[settings.app.appearance]
color = 1567.4"#; color = 1567.4"#;
let result = ProjectConfiguration::backwards_compatible_toml_parse(settings_file); let result = ProjectConfiguration::parse_and_validate(settings_file);
if let Ok(r) = result { if let Ok(r) = result {
panic!("Expected an error, but got success: {:?}", r); panic!("Expected an error, but got success: {:?}", r);
} }
@ -376,9 +269,7 @@ color = 1567.4"#;
app: ProjectAppSettings { app: ProjectAppSettings {
appearance: ProjectAppearanceSettings { color: 138.0.into() }, appearance: ProjectAppearanceSettings { color: 138.0.into() },
onboarding_status: Default::default(), onboarding_status: Default::default(),
theme_color: None,
dismiss_web_banner: false, dismiss_web_banner: false,
enable_ssao: None,
stream_idle_mode: false, stream_idle_mode: false,
allow_orbit_in_sketch_mode: false, allow_orbit_in_sketch_mode: false,
show_debug_panel: true, show_debug_panel: true,
@ -418,7 +309,6 @@ color = 1567.4"#;
modeling: ProjectModelingSettings { modeling: ProjectModelingSettings {
base_unit: UnitLength::Yd, base_unit: UnitLength::Yd,
highlight_edges: Default::default(), highlight_edges: Default::default(),
show_debug_panel: Default::default(),
enable_ssao: true.into(), enable_ssao: true.into(),
}, },
text_editor: TextEditorSettings { text_editor: TextEditorSettings {

View File

@ -136,7 +136,7 @@ pub fn default_app_settings() -> Result<JsValue, String> {
pub fn parse_app_settings(toml_str: &str) -> Result<JsValue, String> { pub fn parse_app_settings(toml_str: &str) -> Result<JsValue, String> {
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
let settings = kcl_lib::Configuration::backwards_compatible_toml_parse(toml_str).map_err(|e| e.to_string())?; let settings = kcl_lib::Configuration::parse_and_validate(toml_str).map_err(|e| e.to_string())?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the // The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead. // gloo-serialize crate instead.
@ -160,8 +160,7 @@ pub fn default_project_settings() -> Result<JsValue, String> {
pub fn parse_project_settings(toml_str: &str) -> Result<JsValue, String> { pub fn parse_project_settings(toml_str: &str) -> Result<JsValue, String> {
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
let settings = let settings = kcl_lib::ProjectConfiguration::parse_and_validate(toml_str).map_err(|e| e.to_string())?;
kcl_lib::ProjectConfiguration::backwards_compatible_toml_parse(toml_str).map_err(|e| e.to_string())?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the // The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead. // gloo-serialize crate instead.
@ -176,8 +175,6 @@ pub fn serialize_configuration(val: JsValue) -> Result<JsValue, String> {
let config: kcl_lib::Configuration = val.into_serde().map_err(|e| e.to_string())?; let config: kcl_lib::Configuration = val.into_serde().map_err(|e| e.to_string())?;
let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?; let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?;
let settings = kcl_lib::Configuration::backwards_compatible_toml_parse(&toml_str).map_err(|e| e.to_string())?;
let toml_str = toml::to_string_pretty(&settings).map_err(|e| e.to_string())?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the // The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead. // gloo-serialize crate instead.
@ -192,9 +189,6 @@ pub fn serialize_project_configuration(val: JsValue) -> Result<JsValue, String>
let config: kcl_lib::ProjectConfiguration = val.into_serde().map_err(|e| e.to_string())?; let config: kcl_lib::ProjectConfiguration = val.into_serde().map_err(|e| e.to_string())?;
let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?; let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?;
let settings =
kcl_lib::ProjectConfiguration::backwards_compatible_toml_parse(&toml_str).map_err(|e| e.to_string())?;
let toml_str = toml::to_string_pretty(&settings).map_err(|e| e.to_string())?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the // The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead. // gloo-serialize crate instead.

View File

@ -230,7 +230,7 @@ const FileTreeItem = ({
codeManager.updateCodeStateEditor(code) codeManager.updateCodeStateEditor(code)
} else if (isImportedInCurrentFile && eventType === 'change') { } else if (isImportedInCurrentFile && eventType === 'change') {
await rustContext.clearSceneAndBustCache( await rustContext.clearSceneAndBustCache(
{ settings: await jsAppSettings() }, await jsAppSettings(),
codeManager?.currentFilePath || undefined codeManager?.currentFilePath || undefined
) )
await kclManager.executeAst() await kclManager.executeAst()

View File

@ -324,7 +324,7 @@ export class KclManager {
// the cache and clear the scene. // the cache and clear the scene.
if (this._astParseFailed && this._switchedFiles) { if (this._astParseFailed && this._switchedFiles) {
await this.singletons.rustContext.clearSceneAndBustCache( await this.singletons.rustContext.clearSceneAndBustCache(
{ settings: await jsAppSettings() }, await jsAppSettings(),
this.singletons.codeManager.currentFilePath || undefined this.singletons.codeManager.currentFilePath || undefined
) )
} else if (this._switchedFiles) { } else if (this._switchedFiles) {

View File

@ -65,7 +65,7 @@ export async function executeAst({
path?: string path?: string
}): Promise<ExecutionResult> { }): Promise<ExecutionResult> {
try { try {
const settings = { settings: await jsAppSettings() } const settings = await jsAppSettings()
const execState = await rustContext.execute(ast, settings, path) const execState = await rustContext.execute(ast, settings, path)
await rustContext.waitForAllEngineCommands() await rustContext.waitForAllEngineCommands()
@ -92,7 +92,7 @@ export async function executeAstMock({
usePrevMemory?: boolean usePrevMemory?: boolean
}): Promise<ExecutionResult> { }): Promise<ExecutionResult> {
try { try {
const settings = { settings: await jsAppSettings() } const settings = await jsAppSettings()
const execState = await rustContext.executeMock( const execState = await rustContext.executeMock(
ast, ast,
settings, settings,

View File

@ -1434,7 +1434,7 @@ export class EngineCommandManager extends EventTarget {
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
this.onEngineConnectionOpened = async () => { this.onEngineConnectionOpened = async () => {
await this.rustContext?.clearSceneAndBustCache( await this.rustContext?.clearSceneAndBustCache(
{ settings: await jsAppSettings() }, await jsAppSettings(),
this.codeManager?.currentFilePath || undefined this.codeManager?.currentFilePath || undefined
) )

View File

@ -660,7 +660,9 @@ export function getKclVersion(): string {
/** /**
* Serialize a project configuration to a TOML string. * Serialize a project configuration to a TOML string.
*/ */
export function serializeConfiguration(configuration: any): string | Error { export function serializeConfiguration(
configuration: DeepPartial<Configuration>
): string | Error {
try { try {
return serialize_configuration(configuration) return serialize_configuration(configuration)
} catch (e: any) { } catch (e: any) {
@ -672,7 +674,7 @@ export function serializeConfiguration(configuration: any): string | Error {
* Serialize a project configuration to a TOML string. * Serialize a project configuration to a TOML string.
*/ */
export function serializeProjectConfiguration( export function serializeProjectConfiguration(
configuration: any configuration: DeepPartial<ProjectConfiguration>
): string | Error { ): string | Error {
try { try {
return serialize_project_configuration(configuration) return serialize_project_configuration(configuration)

View File

@ -58,6 +58,29 @@ export function mouseControlsToCameraSystem(
} }
} }
export function cameraSystemToMouseControl(
cameraSystem: CameraSystem
): MouseControlType | undefined {
switch (cameraSystem) {
case 'Zoo':
return 'zoo'
case 'OnShape':
return 'onshape'
case 'Trackpad Friendly':
return 'trackpad_friendly'
case 'Solidworks':
return 'solidworks'
case 'NX':
return 'nx'
case 'Creo':
return 'creo'
case 'AutoCAD':
return 'autocad'
default:
return undefined
}
}
interface MouseGuardHandler { interface MouseGuardHandler {
description: string description: string
callback: (e: MouseEvent) => boolean callback: (e: MouseEvent) => boolean

View File

@ -13,7 +13,10 @@ import {
serializeProjectConfiguration, serializeProjectConfiguration,
} from '@src/lang/wasm' } from '@src/lang/wasm'
import { initPromise } from '@src/lang/wasmUtils' import { initPromise } from '@src/lang/wasmUtils'
import { mouseControlsToCameraSystem } from '@src/lib/cameraControls' import {
cameraSystemToMouseControl,
mouseControlsToCameraSystem,
} from '@src/lib/cameraControls'
import { BROWSER_PROJECT_NAME } from '@src/lib/constants' import { BROWSER_PROJECT_NAME } from '@src/lib/constants'
import { import {
getInitialDefaultDir, getInitialDefaultDir,
@ -86,6 +89,50 @@ export function configurationToSettingsPayload(
} }
} }
export function settingsPayloadToConfiguration(
configuration: DeepPartial<SaveSettingsPayload>
): DeepPartial<Configuration> {
return {
settings: {
app: {
appearance: {
theme: configuration?.app?.theme,
color: configuration?.app?.themeColor
? parseFloat(configuration.app.themeColor)
: undefined,
},
onboarding_status: configuration?.app?.onboardingStatus,
dismiss_web_banner: configuration?.app?.dismissWebBanner,
stream_idle_mode: configuration?.app?.streamIdleMode,
allow_orbit_in_sketch_mode: configuration?.app?.allowOrbitInSketchMode,
show_debug_panel: configuration?.app?.showDebugPanel,
},
modeling: {
base_unit: configuration?.modeling?.defaultUnit,
camera_projection: configuration?.modeling?.cameraProjection,
camera_orbit: configuration?.modeling?.cameraOrbit,
mouse_controls: configuration?.modeling?.mouseControls
? cameraSystemToMouseControl(configuration?.modeling?.mouseControls)
: undefined,
highlight_edges: configuration?.modeling?.highlightEdges,
enable_ssao: configuration?.modeling?.enableSSAO,
show_scale_grid: configuration?.modeling?.showScaleGrid,
},
text_editor: {
text_wrapping: configuration?.textEditor?.textWrapping,
blinking_cursor: configuration?.textEditor?.blinkingCursor,
},
project: {
directory: configuration?.app?.projectDirectory,
default_project_name: configuration?.projects?.defaultProjectName,
},
command_bar: {
include_settings: configuration?.commandBar?.includeSettings,
},
},
}
}
export function isNamedView( export function isNamedView(
namedView: DeepPartial<NamedView> | undefined namedView: DeepPartial<NamedView> | undefined
): namedView is NamedView { ): namedView is NamedView {
@ -156,6 +203,41 @@ export function projectConfigurationToSettingsPayload(
} }
} }
export function settingsPayloadToProjectConfiguration(
configuration: DeepPartial<SaveSettingsPayload>
): DeepPartial<ProjectConfiguration> {
return {
settings: {
app: {
appearance: {
color: configuration?.app?.themeColor
? parseFloat(configuration.app.themeColor)
: undefined,
},
onboarding_status: configuration?.app?.onboardingStatus,
dismiss_web_banner: configuration?.app?.dismissWebBanner,
allow_orbit_in_sketch_mode: configuration?.app?.allowOrbitInSketchMode,
show_debug_panel: configuration?.app?.showDebugPanel,
named_views: deepPartialNamedViewsToNamedViews(
configuration?.app?.namedViews
),
},
modeling: {
base_unit: configuration?.modeling?.defaultUnit,
highlight_edges: configuration?.modeling?.highlightEdges,
enable_ssao: configuration?.modeling?.enableSSAO,
},
text_editor: {
text_wrapping: configuration?.textEditor?.textWrapping,
blinking_cursor: configuration?.textEditor?.blinkingCursor,
},
command_bar: {
include_settings: configuration?.commandBar?.includeSettings,
},
},
}
}
function localStorageAppSettingsPath() { function localStorageAppSettingsPath() {
return '/settings.toml' return '/settings.toml'
} }
@ -204,6 +286,7 @@ export function readLocalStorageProjectSettingsFile():
const projectSettings = parseProjectSettings(stored) const projectSettings = parseProjectSettings(stored)
if (err(projectSettings)) { if (err(projectSettings)) {
const settings = defaultProjectSettings() const settings = defaultProjectSettings()
if (err(settings)) return settings
const tomlStr = serializeProjectConfiguration(settings) const tomlStr = serializeProjectConfiguration(settings)
if (err(tomlStr)) return tomlStr if (err(tomlStr)) return tomlStr
@ -281,7 +364,9 @@ export async function saveSettings(
// Get the user settings. // Get the user settings.
const jsAppSettings = getChangedSettingsAtLevel(allSettings, 'user') const jsAppSettings = getChangedSettingsAtLevel(allSettings, 'user')
const appTomlString = serializeConfiguration({ settings: jsAppSettings }) const appTomlString = serializeConfiguration(
settingsPayloadToConfiguration(jsAppSettings)
)
if (err(appTomlString)) return if (err(appTomlString)) return
// Write the app settings. // Write the app settings.
@ -298,9 +383,9 @@ export async function saveSettings(
// Get the project settings. // Get the project settings.
const jsProjectSettings = getChangedSettingsAtLevel(allSettings, 'project') const jsProjectSettings = getChangedSettingsAtLevel(allSettings, 'project')
const projectTomlString = serializeProjectConfiguration({ const projectTomlString = serializeProjectConfiguration(
settings: jsProjectSettings, settingsPayloadToProjectConfiguration(jsProjectSettings)
}) )
if (err(projectTomlString)) return if (err(projectTomlString)) return
// Write the project settings. // Write the project settings.
@ -453,7 +538,7 @@ export function getSettingInputType(setting: Setting) {
return typeof setting.default as 'string' | 'boolean' return typeof setting.default as 'string' | 'boolean'
} }
export const jsAppSettings = async () => { export const jsAppSettings = async (): Promise<DeepPartial<Configuration>> => {
let jsAppSettings = default_app_settings() let jsAppSettings = default_app_settings()
if (!TEST) { if (!TEST) {
// TODO: https://github.com/KittyCAD/modeling-app/issues/6445 // TODO: https://github.com/KittyCAD/modeling-app/issues/6445
@ -464,5 +549,5 @@ export const jsAppSettings = async () => {
jsAppSettings = getAllCurrentSettings(settings) jsAppSettings = getAllCurrentSettings(settings)
} }
} }
return jsAppSettings return settingsPayloadToConfiguration(jsAppSettings)
} }

View File

@ -9,6 +9,6 @@ export async function enginelessExecutor(
usePrevMemory?: boolean, usePrevMemory?: boolean,
path?: string path?: string
): Promise<ExecState> { ): Promise<ExecState> {
const settings = { settings: await jsAppSettings() } const settings = await jsAppSettings()
return await rustContext.executeMock(ast, settings, path, usePrevMemory) return await rustContext.executeMock(ast, settings, path, usePrevMemory)
} }

View File

@ -307,6 +307,8 @@ export const settingsMachine = setup({
resetSettings: assign(({ context, event }) => { resetSettings: assign(({ context, event }) => {
if (!('level' in event)) return {} if (!('level' in event)) return {}
console.log('Resetting settings at level', event.level)
// Create a new, blank payload // Create a new, blank payload
const newPayload = const newPayload =
event.level === 'user' event.level === 'user'