Skip to content

Commit

Permalink
File based settings (#1679)
Browse files Browse the repository at this point in the history
* Rename GlobalStateContext to SettingsAuthContext

* Naive initial impl of settings persistence to file system

* Update app identifier in tauri config

* Add "show in folder" tauri command

* Load from and save to file system in Tauri app

* Add documents drive to tauri permission scope

* Add recursive prop to default dir selection dialog

* Add success toast to web restore defaults action

* Add a way to validate read-in settings

* Update imports to use separate settings lib file

* Validate localStorage-loaded settings, combine error message

* Add a e2e test for validation

* Clean up state state bugs

* Reverse validation looping so new users don't error

* update settingsMachine typegen to remove conflicts

* Fmt

* Fix TS errors

* Fix import paths, etc post-merge

* Make default length units `mm` and 'metric'

* Rename to SettingsAuth*

* cargo fmt

* Revert Tauri config identifier change

* Update clientSideInfra's baseUnits from settings

* Break apart CommandBar and CommandBarProvider

* Bugfix: don't validate defaultValue when it's not configured

* Allow some TauriFS functions to no-op from browser

* Sidestep circular deps by loading context and kclManager only from React-land

* Update broken import paths

* Separate loaders from Router, load settings on every route

* Break apart settings types, utils, and constants

* Fix Jest tests by decoupling reliance on useLoaderData from SettingsAuthProvider

* Fix up Router loader data with "layout routes"
https://reactrouter.com/en/main/route/route#layout-routes

* Move settings validation and toast to custom hook so the toast renders

* fmt

* Use forks for Vitest
https://vitest.dev/guide/common-errors.html#failed-to-terminate-worker

* $APPCONFIG !== $APPDATA only on Linux
+ change the identifier back since it really doesn't seem to affect app signing

* Debugging on Linux

* Better directory validation, fix reset settings button

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* defaultDirectory can be empty in browser

* fmt

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* re-trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
franknoirot and github-actions[bot] committed Mar 14, 2024
1 parent 13cd3e1 commit f40cdab
Show file tree
Hide file tree
Showing 30 changed files with 836 additions and 383 deletions.
51 changes: 50 additions & 1 deletion e2e/playwright/flow-tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { secrets } from './secrets'
import { getUtils } from './test-utils'
import waitOn from 'wait-on'
import { Themes } from '../../src/lib/theme'
import { initialSettings } from '../../src/lib/settings/initialSettings'
import { roundOff } from 'lib/utils'
import { platform } from 'node:os'

/*
debug helper: unfortunately we do rely on exact coord mouse clicks in a few places
Expand Down Expand Up @@ -516,6 +516,55 @@ test('Auto complete works', async ({ page }) => {
|> xLine(5, %) // lin`)
})

// Stored settings validation test
test('Stored settings are validated and fall back to defaults', async ({
page,
context,
}) => {
// Override beforeEach test setup
// with corrupted settings
await context.addInitScript(async () => {
const storedSettings = JSON.parse(
localStorage.getItem('SETTINGS_PERSIST_KEY') || '{}'
)

// Corrupt the settings
storedSettings.baseUnit = 'invalid'
storedSettings.cameraControls = `() => alert('hack the planet')`
storedSettings.defaultDirectory = 123
storedSettings.defaultProjectName = false

localStorage.setItem('SETTINGS_PERSIST_KEY', JSON.stringify(storedSettings))
})

await page.setViewportSize({ width: 1200, height: 500 })
await page.goto('/', { waitUntil: 'domcontentloaded' })

// Check the toast appeared
await expect(
page.getByText(`Error validating persisted settings:`, {
exact: false,
})
).toBeVisible()

// Check the settings were reset
const storedSettings = JSON.parse(
await page.evaluate(
() => localStorage.getItem('SETTINGS_PERSIST_KEY') || '{}'
)
)
await expect(storedSettings.baseUnit).toBe(initialSettings.baseUnit)
await expect(storedSettings.cameraControls).toBe(
initialSettings.cameraControls
)
await expect(storedSettings.defaultDirectory).toBe(
initialSettings.defaultDirectory
)
await expect(storedSettings.defaultProjectName).toBe(
initialSettings.defaultProjectName
)
})

// Onboarding tests
test('Onboarding redirects and code updating', async ({ page, context }) => {
const u = getUtils(page)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 22 additions & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::io::Read;

use anyhow::Result;
use oauth2::TokenResponse;
use std::process::Command;
use tauri::{InvokeError, Manager};
const DEFAULT_HOST: &str = "https://api.kittycad.io";

Expand Down Expand Up @@ -142,6 +143,25 @@ async fn get_user(
Ok(user_info)
}

/// Open the selected path in the system file manager.
/// From this GitHub comment: https://github.com/tauri-apps/tauri/issues/4062#issuecomment-1338048169
/// But with the Linux support removed since we don't need it for now.
#[tauri::command]
fn show_in_folder(path: String) {
#[cfg(target_os = "windows")]
{
Command::new("explorer")
.args(["/select,", &path]) // The comma after select is not a typo
.spawn()
.unwrap();
}

#[cfg(target_os = "macos")]
{
Command::new("open").args(["-R", &path]).spawn().unwrap();
}
}

fn main() {
tauri::Builder::default()
.setup(|_app| {
Expand All @@ -158,7 +178,8 @@ fn main() {
get_user,
login,
read_toml,
read_txt_file
read_txt_file,
show_in_folder,
])
.plugin(tauri_plugin_fs_extra::init())
.run(tauri::generate_context!())
Expand Down
7 changes: 5 additions & 2 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
"fs": {
"scope": [
"$HOME/**/*",
"$APPDATA/**/*"
"$APPCONFIG",
"$APPCONFIG/**/*",
"$DOCUMENT",
"$DOCUMENT/**/*"
],
"all": true
},
Expand Down Expand Up @@ -60,7 +63,7 @@
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "io.kittycad.modeling-app",
"identifier": "dev.zoo.modeling-app",
"longDescription": "",
"macOS": {
"entitlements": null,
Expand Down
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ import { useModelingContext } from 'hooks/useModelingContext'
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
import { isTauri } from 'lib/isTauri'
import { useLspContext } from 'components/LspProvider'
import { useValidateSettings } from 'hooks/useValidateSettings'

export function App() {
useValidateSettings()
const { project, file } = useLoaderData() as IndexLoaderData
const navigate = useNavigate()
const filePath = useAbsoluteFilePath()
Expand Down
Loading

0 comments on commit f40cdab

Please sign in to comment.