diff --git a/index.html b/index.html index 727d947..fbdac0e 100644 --- a/index.html +++ b/index.html @@ -8,12 +8,24 @@ <%- reactDevTools -%> <%- reduxDevToolsPatch -%> -
-
+
+
Loading...
-
+ diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 5ed5791..1837896 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1580,7 +1580,7 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[package]] name = "nh-editor" -version = "0.6.0" +version = "0.6.1" dependencies = [ "base64", "fs_extra", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4bbeab5..52b1b0d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -41,7 +41,7 @@ "relaunch": true }, "shell": { - "open": ".*?" + "open": ".+" }, "window": { "all": true diff --git a/src/Common/Spinner/CenteredSpinner.tsx b/src/Common/Spinner/CenteredSpinner.tsx index eb6e08b..e7a72b3 100644 --- a/src/Common/Spinner/CenteredSpinner.tsx +++ b/src/Common/Spinner/CenteredSpinner.tsx @@ -2,7 +2,7 @@ import Spinner from "./Spinner"; function CenteredSpinner() { return ( -
+
); diff --git a/src/Common/Utils.ts b/src/Common/Utils.ts index cafe6c7..248f771 100644 --- a/src/Common/Utils.ts +++ b/src/Common/Utils.ts @@ -1,10 +1,17 @@ -export function camelToTitleCase(s: string) { - return !s || s.indexOf(" ") >= 0 - ? s - : (s.charAt(0).toUpperCase() + s.substring(1)) - .split(/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g) - .map((x: string) => x.replace(/(\d+)/g, "$1 ")) - .join(" "); +export function camelToTitleCase(str: string) { + const result = str + .replace(/(_)+/g, " ") + .replace(/([a-z])([A-Z][a-z])/g, "$1 $2") + .replace(/([A-Z][a-z])([A-Z])/g, "$1 $2") + .replace(/([a-z])([A-Z]+[a-z])/g, "$1 $2") + .replace(/([A-Z]+)([A-Z][a-z][a-z])/g, "$1 $2") + .replace(/([a-z]+)([A-Z0-9]+)/g, "$1 $2") + .replace(/([A-Z]+)([A-Z][a-rt-z][a-z]*)/g, "$1 $2") + .replace(/([0-9])([A-Z][a-z]+)/g, "$1 $2") + .replace(/([A-Z]{2,})([0-9]{2,})/g, "$1 $2") + .replace(/([0-9]{2,})([A-Z]{2,})/g, "$1 $2") + .trim(); + return result.charAt(0).toUpperCase() + result.slice(1); } export function prettyErrorMessage(message: string) { diff --git a/src/MainWindow/MainWindow.tsx b/src/MainWindow/MainWindow.tsx index 75f319f..bee0502 100644 --- a/src/MainWindow/MainWindow.tsx +++ b/src/MainWindow/MainWindow.tsx @@ -37,6 +37,10 @@ function MainWindow(props: { testStore?: EnhancedStore }) { }); }, []); + if (schemaStore === null) { + return <>; + } + return ( @@ -48,16 +52,14 @@ function MainWindow(props: { testStore?: EnhancedStore }) { - {project.path !== "" && ( - - )} + - {schemaStore && } + diff --git a/src/MainWindow/Panels/ProjectView/ProjectView.tsx b/src/MainWindow/Panels/ProjectView/ProjectView.tsx index 35eabc5..e86c85c 100644 --- a/src/MainWindow/Panels/ProjectView/ProjectView.tsx +++ b/src/MainWindow/Panels/ProjectView/ProjectView.tsx @@ -24,7 +24,6 @@ function ProjectView(props: ProjectViewProps) { useEffect(() => { if (status === "idle") { - console.debug("Loading project", props.projectPath); dispatch(loadProject(props.projectPath)); } }, [status, dispatch]); diff --git a/src/MainWindow/Store/FileUtils.tsx b/src/MainWindow/Store/FileUtils.tsx index 7669892..0b4db48 100644 --- a/src/MainWindow/Store/FileUtils.tsx +++ b/src/MainWindow/Store/FileUtils.tsx @@ -188,7 +188,9 @@ const inspectorRootDirectories = ["planets", "systems", "translations"]; export const usesInspector = (file: ProjectFile | OpenFile): boolean => { const rootDir = getRootDirectory(file.relativePath); return ( - (rootDir !== null && inspectorRootDirectories.includes(rootDir.toLowerCase())) || + (file.extension === "json" && + rootDir !== null && + inspectorRootDirectories.includes(rootDir.toLowerCase())) || file.name === "addon-manifest.json" || file.name === "manifest.json" ); diff --git a/src/MainWindow/Validation/GenericRules.ts b/src/MainWindow/Validation/GenericRules.ts index 0ed7da2..22e6683 100644 --- a/src/MainWindow/Validation/GenericRules.ts +++ b/src/MainWindow/Validation/GenericRules.ts @@ -3,12 +3,14 @@ import { JSONPath } from "jsonpath-plus"; import { tauriCommands } from "../../Common/TauriCommands"; import { ValidationContext, ValidationError, ValidationRule } from "./Validator"; +type JSONPathResult = { value: number; path: string }[]; + export const fileMustExistRule = ( propPath: string, folders: "allow" | "disallow" | "force" = "disallow" ): ValidationRule => ({ perform: async (config: T, context: ValidationContext) => { - const hits = JSONPath<{ value: string; path: string }[]>({ + const hits = JSONPath({ path: propPath, json: config, resultType: "all" @@ -48,12 +50,12 @@ export const fileMustExistRule = ( export const minMaxRule = (minPath: string, maxPath: string) => { return { perform: async (config: T) => { - const minHits = JSONPath<{ value: number; path: string }[]>({ + const minHits = JSONPath({ path: minPath, json: config, resultType: "all" }); - const maxHits = JSONPath<{ value: number; path: string }[]>({ + const maxHits = JSONPath({ path: maxPath, json: config, resultType: "all" diff --git a/src/MainWindow/Validation/PlanetValidator.ts b/src/MainWindow/Validation/PlanetValidator.ts index 3d1cc68..0388fe8 100644 --- a/src/MainWindow/Validation/PlanetValidator.ts +++ b/src/MainWindow/Validation/PlanetValidator.ts @@ -67,7 +67,7 @@ const minMaxRules = minMaxPaths.map(([minPath, maxPath]) => minMaxRule(m const quantumGroupRule = { perform: async (config: Planet) => { - if (config.Props.details === undefined) { + if (config.Props?.details === undefined) { return { valid: true, errors: [] }; } const ids = (config.Props.quantumGroups ?? []).map((group) => group.id); diff --git a/src/MainWindow/Validation/SystemValidator.ts b/src/MainWindow/Validation/SystemValidator.ts new file mode 100644 index 0000000..f1a7a79 --- /dev/null +++ b/src/MainWindow/Validation/SystemValidator.ts @@ -0,0 +1,14 @@ +import { fileMustExistRule } from "./GenericRules"; + +const filePaths = [ + "$.Skybox.rightPath", + "$.Skybox.leftPath", + "$.Skybox.topPath", + "$.Skybox.bottomPath", + "$.Skybox.frontPath", + "$.Skybox.backPath" +]; + +const fileRules = filePaths.map((filePath) => fileMustExistRule>(filePath)); + +export default fileRules; diff --git a/src/MainWindow/Validation/Validator.ts b/src/MainWindow/Validation/Validator.ts index 8601c90..195deaa 100644 --- a/src/MainWindow/Validation/Validator.ts +++ b/src/MainWindow/Validation/Validator.ts @@ -2,6 +2,7 @@ import { getFileName, getRootDirectory } from "../Store/FileUtils"; import { OpenFile } from "../Store/OpenFilesSlice"; import manifestRules from "./ManifestValidator"; import planetRules from "./PlanetValidator"; +import systemRules from "./SystemValidator"; export type ValidationResult = { valid: boolean; @@ -31,6 +32,9 @@ const determineValidationRules = (configPath: string): ValidationRule[] => if (rootDir === "planets") { return planetRules; } + if (rootDir === "systems") { + return systemRules; + } return []; }; diff --git a/src/Wrapper.tsx b/src/Wrapper.tsx index 63f3090..18931e3 100644 --- a/src/Wrapper.tsx +++ b/src/Wrapper.tsx @@ -1,3 +1,4 @@ +import { dialog } from "@tauri-apps/api"; import { Event, listen } from "@tauri-apps/api/event"; import React, { useEffect } from "react"; import { useHotkeys } from "react-hotkeys-hook"; @@ -32,7 +33,14 @@ function Wrapper() { }); useEffect(() => { - SettingsManager.get().then(setSettings); + SettingsManager.get() + .then(setSettings) + .catch((e) => { + dialog.message(`Error loading settings: ${e}`, { + type: "error", + title: "Error" + }); + }); }, []); if (settings === null) { diff --git a/vite.config.ts b/vite.config.ts index 104a53f..298153b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -43,6 +43,9 @@ export default defineConfig({ }) ], envPrefix: "NODE_", + // Im going gorbo mode + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore test: { setupFiles: ["./test/Setup.ts"], environment: "jsdom",