diff --git a/src/machines/settingsMachine.ts b/src/machines/settingsMachine.ts index 250427692..37aa3fa39 100644 --- a/src/machines/settingsMachine.ts +++ b/src/machines/settingsMachine.ts @@ -1,13 +1,25 @@ import { assign, createMachine } from 'xstate' -import { BaseUnit, baseUnitsUnion } from '../useStore' import { CommandBarMeta } from '../lib/commands' import { Themes, getSystemTheme, setThemeClass } from '../lib/theme' +export const DEFAULT_PROJECT_NAME = 'project-$nnn' + export enum UnitSystem { Imperial = 'imperial', Metric = 'metric', } +export const baseUnits = { + imperial: ['in', 'ft'], + metric: ['mm', 'cm', 'm'], +} as const + +export type BaseUnit = 'in' | 'ft' | 'mm' | 'cm' | 'm' + +export const baseUnitsUnion = Object.values(baseUnits).flatMap((v) => v) + +export type Toggle = 'On' | 'Off' + export const SETTINGS_PERSIST_KEY = 'SETTINGS_PERSIST_KEY' export const settingsCommandBarMeta: CommandBarMeta = { @@ -85,11 +97,11 @@ export const settingsMachine = createMachine( predictableActionArguments: true, context: { theme: Themes.System, - defaultProjectName: '', + defaultProjectName: DEFAULT_PROJECT_NAME, unitSystem: UnitSystem.Imperial, baseUnit: 'in' as BaseUnit, defaultDirectory: '', - textWrapping: 'On' as 'On' | 'Off', + textWrapping: 'On' as Toggle, showDebugPanel: false, onboardingStatus: '', }, @@ -113,7 +125,8 @@ export const settingsMachine = createMachine( 'Set Default Project Name': { actions: [ assign({ - defaultProjectName: (_, event) => event.data.defaultProjectName, + defaultProjectName: (_, event) => + event.data.defaultProjectName.trim() || DEFAULT_PROJECT_NAME, }), 'persistSettings', 'toastSuccess', @@ -205,7 +218,7 @@ export const settingsMachine = createMachine( data: { unitSystem: UnitSystem } } | { type: 'Set Base Unit'; data: { baseUnit: BaseUnit } } - | { type: 'Set Text Wrapping'; data: { textWrapping: 'On' | 'Off' } } + | { type: 'Set Text Wrapping'; data: { textWrapping: Toggle } } | { type: 'Set Onboarding Status'; data: { onboardingStatus: string } } | { type: 'Toggle Debug Panel' }, }, diff --git a/src/routes/Home.tsx b/src/routes/Home.tsx index 4175b0520..bbc14a728 100644 --- a/src/routes/Home.tsx +++ b/src/routes/Home.tsx @@ -28,6 +28,7 @@ import { import useStateMachineCommands from '../hooks/useStateMachineCommands' import { useGlobalStateContext } from 'hooks/useGlobalStateContext' import { useCommandsContext } from 'hooks/useCommandsContext' +import { DEFAULT_PROJECT_NAME } from 'machines/settingsMachine' // This route only opens in the Tauri desktop context for now, // as defined in Router.tsx, so we can use the Tauri APIs and types. @@ -38,6 +39,7 @@ const Home = () => { const { settings: { context: { defaultDirectory, defaultProjectName }, + send: sendToSettings, }, } = useGlobalStateContext() @@ -71,16 +73,33 @@ const Home = () => { context: ContextFrom, event: EventFrom ) => { - let name = + let name = ( event.data && 'name' in event.data ? event.data.name : defaultProjectName + ).trim() + let shouldUpdateDefaultProjectName = false + + // If there is no default project name, flag it to be set to the default + if (!name) { + name = DEFAULT_PROJECT_NAME + shouldUpdateDefaultProjectName = true + } + if (doesProjectNameNeedInterpolated(name)) { const nextIndex = await getNextProjectIndex(name, projects) name = interpolateProjectNameWithIndex(name, nextIndex) } await createNewProject(context.defaultDirectory + '/' + name) + + if (shouldUpdateDefaultProjectName) { + sendToSettings({ + type: 'Set Default Project Name', + data: { defaultProjectName: DEFAULT_PROJECT_NAME }, + }) + } + return `Successfully created "${name}"` }, renameProject: async ( diff --git a/src/routes/Onboarding/Units.tsx b/src/routes/Onboarding/Units.tsx index cdeced5ce..feb169843 100644 --- a/src/routes/Onboarding/Units.tsx +++ b/src/routes/Onboarding/Units.tsx @@ -1,5 +1,5 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons' -import { BaseUnit, baseUnits } from '../../useStore' +import { BaseUnit, baseUnits } from '../../machines/settingsMachine' import { ActionButton } from '../../components/ActionButton' import { SettingsSection } from '../Settings' import { Toggle } from '../../components/Toggle/Toggle' diff --git a/src/routes/Settings.tsx b/src/routes/Settings.tsx index 133473b60..de1bd8b7a 100644 --- a/src/routes/Settings.tsx +++ b/src/routes/Settings.tsx @@ -6,7 +6,11 @@ import { import { ActionButton } from '../components/ActionButton' import { AppHeader } from '../components/AppHeader' import { open } from '@tauri-apps/api/dialog' -import { BaseUnit, baseUnits } from '../useStore' +import { + BaseUnit, + DEFAULT_PROJECT_NAME, + baseUnits, +} from '../machines/settingsMachine' import { Toggle } from '../components/Toggle/Toggle' import { useLocation, useNavigate, useRouteLoaderData } from 'react-router-dom' import { useHotkeys } from 'react-hotkeys-hook' @@ -118,10 +122,14 @@ export const Settings = () => { className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent" defaultValue={defaultProjectName} onBlur={(e) => { + const newValue = e.target.value.trim() || DEFAULT_PROJECT_NAME send({ type: 'Set Default Project Name', - data: { defaultProjectName: e.target.value }, + data: { + defaultProjectName: newValue, + }, }) + e.target.value = newValue }} autoCapitalize="off" autoComplete="off" diff --git a/src/useStore.ts b/src/useStore.ts index 697790d53..4b1b97fb1 100644 --- a/src/useStore.ts +++ b/src/useStore.ts @@ -94,15 +94,6 @@ export type GuiModes = position: Position } -export const baseUnits = { - imperial: ['in', 'ft'], - metric: ['mm', 'cm', 'm'], -} as const - -export type BaseUnit = 'in' | 'ft' | 'mm' | 'cm' | 'm' - -export const baseUnitsUnion = Object.values(baseUnits).flatMap((v) => v) - export type PaneType = | 'code' | 'variables'