diff --git a/src/Router.tsx b/src/Router.tsx index 06f7bd1df..4846bdcbe 100644 --- a/src/Router.tsx +++ b/src/Router.tsx @@ -40,9 +40,9 @@ import * as Sentry from '@sentry/react' import ModelingMachineProvider from 'components/ModelingMachineProvider' import { KclContextProvider, kclManager } from 'lang/KclSingleton' import FileMachineProvider from 'components/FileMachineProvider' -import { sep } from '@tauri-apps/api/path' +import { join, sep } from '@tauri-apps/api/path' import { paths } from 'lib/paths' -import { IndexLoaderData, HomeLoaderData, FileEntry } from 'lib/types' +import type { IndexLoaderData, HomeLoaderData, FileEntry } from 'lib/types' import { fileSystemManager } from 'lang/std/fileSystemManager' import { invoke } from '@tauri-apps/api/core' @@ -157,20 +157,20 @@ const router = createBrowserRouter( const projectAndFile = decodedId.replace(defaultDir + sep(), '') const firstSlashIndex = projectAndFile.indexOf(sep()) const projectName = projectAndFile.slice(0, firstSlashIndex) - const projectPath = defaultDir + sep() + projectName + const projectPath = await join(defaultDir, projectName) const currentFileName = projectAndFile.slice(firstSlashIndex + 1) if (firstSlashIndex === -1 || !currentFileName) return redirect( `${paths.FILE}/${encodeURIComponent( - `${params.id}${sep()}${PROJECT_ENTRYPOINT}` + await join(params.id, PROJECT_ENTRYPOINT) )}` ) // Note that PROJECT_ENTRYPOINT is hardcoded until we support multiple files const code = await readTextFile(decodedId) const entrypointMetadata = await stat( - projectPath + sep() + PROJECT_ENTRYPOINT + await join(projectPath, PROJECT_ENTRYPOINT) ) const children = await invoke('read_dir_recursive', { path: projectPath, diff --git a/src/components/FileMachineProvider.tsx b/src/components/FileMachineProvider.tsx index 0777ab92d..b8be26d0e 100644 --- a/src/components/FileMachineProvider.tsx +++ b/src/components/FileMachineProvider.tsx @@ -17,7 +17,7 @@ import { DEFAULT_FILE_NAME, fileMachine } from 'machines/fileMachine' import { mkdir, remove, rename, create } from '@tauri-apps/plugin-fs' import { FILE_EXT, readProject } from 'lib/tauriFS' import { isTauri } from 'lib/isTauri' -import { sep } from '@tauri-apps/api/path' +import { join, sep } from '@tauri-apps/api/path' type MachineContext = { state: StateFrom @@ -78,7 +78,7 @@ export const FileMachineProvider = ({ let name = event.data.name.trim() || DEFAULT_FILE_NAME if (event.data.makeDir) { - await mkdir(context.selectedDirectory.path + sep() + name) + await mkdir(await join(context.selectedDirectory.path, name)) } else { await create( context.selectedDirectory.path + @@ -98,10 +98,8 @@ export const FileMachineProvider = ({ let name = newName ? newName : DEFAULT_FILE_NAME await rename( - context.selectedDirectory.path + sep() + oldName, - context.selectedDirectory.path + - sep() + - name + + await join(context.selectedDirectory.path, oldName), + (await join(context.selectedDirectory.path, name)) + (name.endsWith(FILE_EXT) || isDir ? '' : FILE_EXT), {} ) diff --git a/src/components/FileTree.tsx b/src/components/FileTree.tsx index 72e112949..80e29e0fd 100644 --- a/src/components/FileTree.tsx +++ b/src/components/FileTree.tsx @@ -1,4 +1,4 @@ -import { FileEntry, type IndexLoaderData } from 'lib/types' +import type { FileEntry, IndexLoaderData } from 'lib/types' import { paths } from 'lib/paths' import { ActionButton } from './ActionButton' import Tooltip from './Tooltip' diff --git a/src/lib/exportSave.ts b/src/lib/exportSave.ts index 621127d54..7234a3f49 100644 --- a/src/lib/exportSave.ts +++ b/src/lib/exportSave.ts @@ -25,6 +25,7 @@ export async function exportSave(data: ArrayBuffer) { } // Write the file. + // TODO: check if this is still value with the uint8 instance await writeFile(filePath, new Uint8Array(file.contents)) } else { // Download the file to the user's computer. diff --git a/src/lib/tauriFS.test.ts b/src/lib/tauriFS.test.ts index 76d5434a6..8e0425ee5 100644 --- a/src/lib/tauriFS.test.ts +++ b/src/lib/tauriFS.test.ts @@ -6,7 +6,7 @@ import { interpolateProjectNameWithIndex, isRelevantFileOrDir, } from './tauriFS' -import { FileEntry } from './types' +import type { FileEntry } from './types' describe('Test project name utility functions', () => { it('interpolates a project name without an index', () => { diff --git a/src/lib/tauriFS.ts b/src/lib/tauriFS.ts index 4ce37a440..a049701b5 100644 --- a/src/lib/tauriFS.ts +++ b/src/lib/tauriFS.ts @@ -1,14 +1,8 @@ -import { - mkdir, - exists, - readDir, - writeTextFile, - stat, -} from '@tauri-apps/plugin-fs' +import { mkdir, exists, writeTextFile, stat } from '@tauri-apps/plugin-fs' import { invoke } from '@tauri-apps/api/core' import { documentDir, homeDir, join, sep } from '@tauri-apps/api/path' import { isTauri } from './isTauri' -import { FileEntry, type ProjectWithEntryPointMetadata } from 'lib/types' +import type { FileEntry, ProjectWithEntryPointMetadata } from 'lib/types' const PROJECT_FOLDER = 'zoo-modeling-app-projects' export const FILE_EXT = '.kcl' @@ -38,10 +32,10 @@ export async function initializeProjectDirectory(directory: string) { docDirectory = await documentDir() } catch (e) { console.log('error', e) - docDirectory = `${await homeDir()}Documents` // for headless Linux (eg. Github Actions) + docDirectory = await join(await homeDir(), 'Documents') // for headless Linux (eg. Github Actions) } - const INITIAL_DEFAULT_DIR = docDirectory + sep() + PROJECT_FOLDER + const INITIAL_DEFAULT_DIR = await join(docDirectory, PROJECT_FOLDER) const defaultDirExists = await exists(INITIAL_DEFAULT_DIR) @@ -65,7 +59,6 @@ export async function getProjectsInDir(projectDir: string) { const readProjects = ( await invoke('read_dir_recursive', { path: projectDir }) ).filter(isProjectDirectory) - console.log('read_dir_recursive + isProjectDirectory', readProjects) const projectsWithMetadata = await Promise.all( readProjects.map(async (p) => ({ @@ -73,7 +66,6 @@ export async function getProjectsInDir(projectDir: string) { ...p, })) ) - console.log('projectsWithMetadata', projectsWithMetadata) return projectsWithMetadata } @@ -133,7 +125,6 @@ export async function readProject(projectDir: string) { const readFiles = await invoke('read_dir_recursive', { path: projectDir, }) - console.log('read_dir_recursive', readFiles) return deepFileFilter(readFiles, isRelevantFileOrDir) } @@ -226,7 +217,7 @@ export async function createNewProject( }) } - await writeTextFile(path + sep() + PROJECT_ENTRYPOINT, initCode).catch( + await writeTextFile(await join(path, PROJECT_ENTRYPOINT), initCode).catch( (err) => { console.error('Error creating new file:', err) throw err @@ -242,7 +233,7 @@ export async function createNewProject( children: [ { name: PROJECT_ENTRYPOINT, - path: path + sep() + PROJECT_ENTRYPOINT, + path: await join(path, PROJECT_ENTRYPOINT), children: [], }, ], diff --git a/src/machines/fileMachine.ts b/src/machines/fileMachine.ts index b84ddfbab..1f4f971ab 100644 --- a/src/machines/fileMachine.ts +++ b/src/machines/fileMachine.ts @@ -1,5 +1,5 @@ import { assign, createMachine } from 'xstate' -import { FileEntry, type ProjectWithEntryPointMetadata } from 'lib/types' +import type { FileEntry, ProjectWithEntryPointMetadata } from 'lib/types' export const FILE_PERSIST_KEY = 'Last opened KCL files' export const DEFAULT_FILE_NAME = 'Untitled' diff --git a/src/routes/Home.tsx b/src/routes/Home.tsx index 40494d79b..49e8f940b 100644 --- a/src/routes/Home.tsx +++ b/src/routes/Home.tsx @@ -32,7 +32,7 @@ import useStateMachineCommands from '../hooks/useStateMachineCommands' import { useGlobalStateContext } from 'hooks/useGlobalStateContext' import { useCommandsContext } from 'hooks/useCommandsContext' import { DEFAULT_PROJECT_NAME } from 'machines/settingsMachine' -import { sep } from '@tauri-apps/api/path' +import { join, sep } from '@tauri-apps/api/path' import { homeCommandBarConfig } from 'lib/commandBarConfigs/homeCommandConfig' import { useHotkeys } from 'react-hotkeys-hook' import { isTauri } from 'lib/isTauri' @@ -120,7 +120,7 @@ const Home = () => { name = interpolateProjectNameWithIndex(name, nextIndex) } - await createNewProject(context.defaultDirectory + sep() + name) + await createNewProject(await join(context.defaultDirectory, name)) if (shouldUpdateDefaultProjectName) { sendToSettings({ @@ -143,8 +143,8 @@ const Home = () => { } await rename( - context.defaultDirectory + sep() + oldName, - context.defaultDirectory + sep() + name, + await join(context.defaultDirectory, oldName), + await join(context.defaultDirectory, name), {} ) return `Successfully renamed "${oldName}" to "${name}"` @@ -153,7 +153,7 @@ const Home = () => { context: ContextFrom, event: EventFrom ) => { - await remove(context.defaultDirectory + sep() + event.data.name, { + await remove(await join(context.defaultDirectory, event.data.name), { recursive: true, }) return `Successfully deleted "${event.data.name}"` diff --git a/src/routes/Onboarding/Introduction.tsx b/src/routes/Onboarding/Introduction.tsx index d8202e2cc..c5925e355 100644 --- a/src/routes/Onboarding/Introduction.tsx +++ b/src/routes/Onboarding/Introduction.tsx @@ -20,7 +20,7 @@ import { useNavigate } from 'react-router-dom' import { paths } from 'lib/paths' import { useEffect } from 'react' import { kclManager } from 'lang/KclSingleton' -import { sep } from '@tauri-apps/api/path' +import { join, sep } from '@tauri-apps/api/path' import { APP_NAME } from 'lib/constants' function OnboardingWithNewFile() { @@ -44,12 +44,12 @@ function OnboardingWithNewFile() { nextIndex ) const newFile = await createNewProject( - defaultDirectory + sep() + name, + await join(defaultDirectory, name), bracket ) navigate( `${paths.FILE}/${encodeURIComponent( - newFile.path + sep() + PROJECT_ENTRYPOINT + await join(newFile.path, PROJECT_ENTRYPOINT) )}${paths.ONBOARDING.INDEX}` ) } diff --git a/src/routes/Settings.tsx b/src/routes/Settings.tsx index aae5fb152..394de28bf 100644 --- a/src/routes/Settings.tsx +++ b/src/routes/Settings.tsx @@ -28,7 +28,7 @@ import { interpolateProjectNameWithIndex, } from 'lib/tauriFS' import { ONBOARDING_PROJECT_NAME } from './Onboarding' -import { sep } from '@tauri-apps/api/path' +import { join, sep } from '@tauri-apps/api/path' import { bracket } from 'lib/exampleKcl' export const Settings = () => { @@ -96,7 +96,7 @@ export const Settings = () => { nextIndex ) const newFile = await createNewProject( - defaultDirectory + sep() + name, + await join(defaultDirectory, name), bracket ) navigate(`${paths.FILE}/${encodeURIComponent(newFile.path)}`)