diff --git a/src/components/scenery-loaded-dialog/SceneryLoadedDialog.css b/src/components/scenery-loaded-dialog/SceneryLoadedDialog.css
new file mode 100644
index 0000000..09c0e35
--- /dev/null
+++ b/src/components/scenery-loaded-dialog/SceneryLoadedDialog.css
@@ -0,0 +1,14 @@
+.scenery-loaded-dialog-content {
+ display: flex;
+ flex-direction: column;
+ gap: 1em;
+}
+
+.scenery-loaded-dialog-content .main-message {
+ padding: 0.5em;
+}
+
+.scenery-loaded-dialog-content .scenery-parser-log-view {
+ max-height: 30vh;
+ overflow-y: auto;
+}
diff --git a/src/components/scenery-loaded-dialog/SceneryLoadedDialog.js b/src/components/scenery-loaded-dialog/SceneryLoadedDialog.js
new file mode 100644
index 0000000..97dc1b5
--- /dev/null
+++ b/src/components/scenery-loaded-dialog/SceneryLoadedDialog.js
@@ -0,0 +1,46 @@
+import { forwardRef, useImperativeHandle } from 'react';
+import SceneryParserLog from '../../model/scenery-parser-log';
+import SceneryParserLogView from '../scenery-loaded-dialog/SceneryParserLogView';
+import '../dialog/Dialog.css';
+import './SceneryLoadedDialog.css'
+import Constants from '../../helpers/constants';
+
+const SceneryLoadedDialog = forwardRef((props, ref) => {
+ const {onClose, loadingError} = props;
+
+ const onBgClick = () => {
+ onClose();
+ }
+
+ useImperativeHandle(ref, () => ({
+ onBgClick: onBgClick
+ }));
+
+ const warningsOrError = SceneryParserLog.hasWarnings || !!loadingError;
+ const showLog = Constants.parser.alwaysShowLogDialog || warningsOrError;
+
+ const message = loadingError ? "An error occurred while loading the scenery"
+ :( SceneryParserLog.hasWarnings ? "Scenery loaded with warnings"
+ : "Scenery loaded successfully" );
+
+ const additionalErr = (loadingError && !SceneryParserLog.hasErrors) ?
+ loadingError.message : undefined;
+
+ return (
+
+
+
+ {message}
+
+ {showLog &&
}
+
+
+
+
+
+ );
+});
+
+export default SceneryLoadedDialog;
diff --git a/src/components/scenery-loaded-dialog/SceneryParserLogView.css b/src/components/scenery-loaded-dialog/SceneryParserLogView.css
new file mode 100644
index 0000000..baef0ae
--- /dev/null
+++ b/src/components/scenery-loaded-dialog/SceneryParserLogView.css
@@ -0,0 +1,22 @@
+.scenery-parser-log-view {
+ padding: 1em;
+ border-radius: 8px;
+ border: 2px solid #444;
+ background-color: #0004;
+}
+
+.scenery-parser-log-view ul {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+ text-indent: -1em;
+ padding-left: 1em;
+}
+
+.scenery-parser-log-view .log-entry.warn {
+ color: #aa4;
+}
+
+.scenery-parser-log-view .log-entry.error {
+ color: #f44;
+}
\ No newline at end of file
diff --git a/src/components/scenery-loaded-dialog/SceneryParserLogView.js b/src/components/scenery-loaded-dialog/SceneryParserLogView.js
new file mode 100644
index 0000000..3226daf
--- /dev/null
+++ b/src/components/scenery-loaded-dialog/SceneryParserLogView.js
@@ -0,0 +1,27 @@
+import './SceneryParserLogView.css';
+
+export default function SceneryParserLogView({ log, additionalErr }) {
+ const extendedLog = additionalErr ? [...log, { logType: 'error', message: additionalErr }] : log;
+
+ return (
+
+ {extendedLog.length === 0 ? (
+
No log entries.
+ ) : (
+
+ {extendedLog.map((entry, index) => )}
+
+ )}
+
+ );
+}
+
+function LogEntry({ entry }) {
+ const { logType, message } = entry;
+
+ return (
+
+ {message}
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/toolbar/FileSelect.js b/src/components/toolbar/FileSelect.js
index e1b79a3..6159860 100644
--- a/src/components/toolbar/FileSelect.js
+++ b/src/components/toolbar/FileSelect.js
@@ -1,6 +1,9 @@
import { useContext } from "react";
import MainContext from "../../contexts/MainContext";
import Scenery from "../../model/scenery";
+import { showCustomDialog } from "../../services/dialogService";
+import SceneryLoadedDialog from "../scenery-loaded-dialog/SceneryLoadedDialog";
+import SceneryParserLog from "../../model/scenery-parser-log";
export default function FileSelect() {
const {setScenery, setIsLoading} = useContext(MainContext);
@@ -9,17 +12,22 @@ export default function FileSelect() {
const file = event.target.files[0];
if (!file) return;
+ SceneryParserLog.clear();
setIsLoading(true);
const reader = new FileReader();
reader.readAsText(file);
reader.onload = (e) => {
- setIsLoading(false);
- if(!e.target || !e.target.result) {
- console.error("File reading failed or no content found.");
- }
+ let loadingError = null;
+ try {
+ const scenery = Scenery.fromText(e.target?.result);
+ setScenery(scenery);
+ } catch (error) {
+ loadingError = error;
+ setScenery(null);
+ }
- const scenery = Scenery.fromText(e.target.result);
- setScenery(scenery);
+ setIsLoading(false);
+ showCustomDialog();
}
};
diff --git a/src/helpers/constants.js b/src/helpers/constants.js
index 37b77b8..0a85c17 100644
--- a/src/helpers/constants.js
+++ b/src/helpers/constants.js
@@ -6,7 +6,8 @@ const Constants = {
parser: {
forceAutoSwitches: false,
logNewAutoSwitches: true,
- sceneryInfoVersion: 29
+ sceneryInfoVersion: 29,
+ alwaysShowLogDialog: false
},
warnings: {
all: false, // enable all warnings
diff --git a/src/model/scenery-parser-log.js b/src/model/scenery-parser-log.js
index cd631c6..7990931 100644
--- a/src/model/scenery-parser-log.js
+++ b/src/model/scenery-parser-log.js
@@ -1,13 +1,32 @@
import Constants from "../helpers/constants";
export default class SceneryParserLog {
+ static log = [];
+ static hasWarnings = false;
+ static hasErrors = false;
+
+ static clear() {
+ SceneryParserLog.log = [];
+ SceneryParserLog.hasWarnings = false;
+ SceneryParserLog.hasErrors = false;
+ }
+
static warn(type, message) {
if(!Constants.warnings[type] && !Constants.warnings.all) return;
+ SceneryParserLog.hasWarnings = true;
+ SceneryParserLog.log.push({logType: 'warn', type, message});
console.warn(`[SceneryParserLog] ${message}`);
}
static error(type, message) {
+ SceneryParserLog.hasErrors = true;
+ SceneryParserLog.log.push({logType: 'error', type, message});
+
throw new Error(`[SceneryParserLog] ${message}`);
}
+
+ static getLog() {
+ return [...SceneryParserLog.log];
+ }
}
diff --git a/src/model/switch.js b/src/model/switch.js
index 73c0403..97ee7bb 100644
--- a/src/model/switch.js
+++ b/src/model/switch.js
@@ -63,7 +63,7 @@ export default class Switch extends SceneryObject {
let def = DefinedSwitches[this.bare_model] || null;
if(!def && !Constants.parser.forceAutoSwitches) {
- SceneryParserLog.warn('switchUndefinedModel', `Switch ${this.id} has undefined model "${this.bare_model}", trying to generate auto model definition`);
+ SceneryParserLog.warn('switchUndefinedModel', `Switch ${this.id} has an undefined model "${this.bare_model}", trying to generate auto model definition`);
}
if(!def || Constants.parser.forceAutoSwitches) {