From 419fcc7c6d8aacdf882b288303adf05789ef50e6 Mon Sep 17 00:00:00 2001 From: izawartka <59137928+izawartka@users.noreply.github.com> Date: Wed, 29 Jul 2026 19:49:44 +0200 Subject: [PATCH] Implement embedded mode - Implemented embedded mode hiding unnecessary UI elements and tweaking scenery loading process --- src/components/App.js | 6 ++++-- src/components/SceneryManager.js | 29 ++++++++++++++++++++--------- src/components/toolbar/Toolbar.js | 6 +++++- src/helpers/constants.js | 1 + 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/components/App.js b/src/components/App.js index fe6e8aa..b19fb34 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -10,7 +10,7 @@ import {GradientsManager} from "./GradientsManager"; import SideMenuContext from '../contexts/SideMenuContext'; import SceneryManager from './SceneryManager'; import ThemeManager from './ThemeManager'; -import {EmbeddedContextProvider} from '../contexts/EmbeddedContext'; +import {EmbeddedContextProvider, useEmbeddedContext} from '../contexts/EmbeddedContext'; import './Themes.css'; import './App.css'; @@ -38,6 +38,8 @@ function App() { } function AppContent() { + const { isEmbedded } = useEmbeddedContext(); + return (
@@ -45,7 +47,7 @@ function AppContent() {
- + { !isEmbedded && } ); diff --git a/src/components/SceneryManager.js b/src/components/SceneryManager.js index b9605a1..a10a243 100644 --- a/src/components/SceneryManager.js +++ b/src/components/SceneryManager.js @@ -9,6 +9,7 @@ import SceneryLoadedDialog from './scenery-loaded-dialog/SceneryLoadedDialog'; import Constants from '../helpers/constants'; import MiscHelper from '../helpers/miscHelper'; import ElectrificationResolver from '../model/parsing/electrification-resolver'; +import { useEmbeddedContext } from '../contexts/EmbeddedContext'; export default function SceneryManager(props) { const [isLoading, setIsLoading] = useState(false); @@ -16,6 +17,7 @@ export default function SceneryManager(props) { const [sceneryListData, setSceneryListData] = useState(null); const urlParamsLoaded = useRef(false); const { setCamera } = useZoomPanEmitter(); + const { isEmbedded } = useEmbeddedContext(); const myFetch = useCallback(async (url, toJson) => { const response = await fetch(url); @@ -39,14 +41,15 @@ export default function SceneryManager(props) { }, [myFetch]); const updateViewAfterSceneryLoaded = useCallback((scenery) => { + const targetZoom = isEmbedded ? Constants.map.zoomDefaultEmbedded : Constants.map.zoomDefault; const mainSignalBox = scenery.getMainSignalBox(); if(mainSignalBox) { const sbPos = mainSignalBox.pos.toSVGCoords(); const sbRot = -mainSignalBox.getFinalRotation(); - setCamera(...sbPos, sbRot, Constants.map.zoomDefault); + setCamera(...sbPos, sbRot, targetZoom); } - else setCamera(0, 0, 0, Constants.map.zoomDefault); - }, [setCamera]); + else setCamera(0, 0, 0, targetZoom); + }, [setCamera, isEmbedded]); const loadCustomScenery = useCallback((file) => { return new Promise((resolve, reject) => { @@ -64,10 +67,12 @@ export default function SceneryManager(props) { setScenery(null); SceneryParserLog.clear(); - const urlParams = new URLSearchParams(window.location.search); - urlParams.delete('scenery'); - urlParams.delete('pos'); - window.history.replaceState({}, '', urlParams.size ? `${window.location.pathname}?${urlParams.toString()}` : window.location.pathname); + if (!isEmbedded) { + const urlParams = new URLSearchParams(window.location.search); + urlParams.delete('scenery'); + urlParams.delete('pos'); + window.history.replaceState({}, '', urlParams.size ? `${window.location.pathname}?${urlParams.toString()}` : window.location.pathname); + } const reader = new FileReader(); reader.readAsText(file); @@ -83,13 +88,17 @@ export default function SceneryManager(props) { console.error(error); } - showCustomDialog(); + if (isEmbedded && loadingError) { + showDialog('Failed to load scenery'); + } else if (!isEmbedded) { + showCustomDialog(); + } setScenery(scenery); setIsLoading(false); resolve(scenery); } }); - }, [updateViewAfterSceneryLoaded]); + }, [updateViewAfterSceneryLoaded, isEmbedded]); const loadScenery = useCallback(async (sceneryName) => { let file; @@ -130,6 +139,7 @@ export default function SceneryManager(props) { const sceneryName = findSceneryInList(sceneryQuery); if (!sceneryName) { console.warn(`Scenery "${sceneryQuery}" not found in the list.`); + showDialog(`Scenery "${sceneryQuery}" not found in the list.`); return; } @@ -140,6 +150,7 @@ export default function SceneryManager(props) { if(!posQuery) return; if (!pos) { console.warn(`Invalid position query "${posQuery}"`); + showDialog("Invalid position query in URL."); return; } diff --git a/src/components/toolbar/Toolbar.js b/src/components/toolbar/Toolbar.js index b625437..a7ec4d0 100644 --- a/src/components/toolbar/Toolbar.js +++ b/src/components/toolbar/Toolbar.js @@ -5,11 +5,14 @@ import SideMenuToggle from './SideMenuToggle'; import SceneryList from './SceneryList'; import ElectrificationStepMode from './ElectrificationStepMode'; import ThemeToggle from './ThemeToggle'; +import { useEmbeddedContext } from '../../contexts/EmbeddedContext'; export default function Toolbar() { + const { isEmbedded } = useEmbeddedContext(); + return (
-
+ {!isEmbedded &&
or @@ -18,6 +21,7 @@ export default function Toolbar() {
+ }
diff --git a/src/helpers/constants.js b/src/helpers/constants.js index 421d05e..0cf8d20 100644 --- a/src/helpers/constants.js +++ b/src/helpers/constants.js @@ -5,6 +5,7 @@ const Constants = { zoomMin: 0.03, zoomMax: 200.0, zoomDefault: 5, + zoomDefaultEmbeded: 2.5, rotationSensitivity: 0.2, forcePointerEvents: false, platformMaxTilt: 0.5,