Implement embedded mode
- Implemented embedded mode hiding unnecessary UI elements and tweaking scenery loading process
This commit is contained in:
parent
b68d4e76c0
commit
419fcc7c6d
@ -10,7 +10,7 @@ import {GradientsManager} from "./GradientsManager";
|
|||||||
import SideMenuContext from '../contexts/SideMenuContext';
|
import SideMenuContext from '../contexts/SideMenuContext';
|
||||||
import SceneryManager from './SceneryManager';
|
import SceneryManager from './SceneryManager';
|
||||||
import ThemeManager from './ThemeManager';
|
import ThemeManager from './ThemeManager';
|
||||||
import {EmbeddedContextProvider} from '../contexts/EmbeddedContext';
|
import {EmbeddedContextProvider, useEmbeddedContext} from '../contexts/EmbeddedContext';
|
||||||
import './Themes.css';
|
import './Themes.css';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
@ -38,6 +38,8 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function AppContent() {
|
function AppContent() {
|
||||||
|
const { isEmbedded } = useEmbeddedContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<Toolbar />
|
<Toolbar />
|
||||||
@ -45,7 +47,7 @@ function AppContent() {
|
|||||||
<Map />
|
<Map />
|
||||||
<SideMenu />
|
<SideMenu />
|
||||||
</div>
|
</div>
|
||||||
<LocList />
|
{ !isEmbedded && <LocList /> }
|
||||||
<DialogManager />
|
<DialogManager />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import SceneryLoadedDialog from './scenery-loaded-dialog/SceneryLoadedDialog';
|
|||||||
import Constants from '../helpers/constants';
|
import Constants from '../helpers/constants';
|
||||||
import MiscHelper from '../helpers/miscHelper';
|
import MiscHelper from '../helpers/miscHelper';
|
||||||
import ElectrificationResolver from '../model/parsing/electrification-resolver';
|
import ElectrificationResolver from '../model/parsing/electrification-resolver';
|
||||||
|
import { useEmbeddedContext } from '../contexts/EmbeddedContext';
|
||||||
|
|
||||||
export default function SceneryManager(props) {
|
export default function SceneryManager(props) {
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
@ -16,6 +17,7 @@ export default function SceneryManager(props) {
|
|||||||
const [sceneryListData, setSceneryListData] = useState(null);
|
const [sceneryListData, setSceneryListData] = useState(null);
|
||||||
const urlParamsLoaded = useRef(false);
|
const urlParamsLoaded = useRef(false);
|
||||||
const { setCamera } = useZoomPanEmitter();
|
const { setCamera } = useZoomPanEmitter();
|
||||||
|
const { isEmbedded } = useEmbeddedContext();
|
||||||
|
|
||||||
const myFetch = useCallback(async (url, toJson) => {
|
const myFetch = useCallback(async (url, toJson) => {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
@ -39,14 +41,15 @@ export default function SceneryManager(props) {
|
|||||||
}, [myFetch]);
|
}, [myFetch]);
|
||||||
|
|
||||||
const updateViewAfterSceneryLoaded = useCallback((scenery) => {
|
const updateViewAfterSceneryLoaded = useCallback((scenery) => {
|
||||||
|
const targetZoom = isEmbedded ? Constants.map.zoomDefaultEmbedded : Constants.map.zoomDefault;
|
||||||
const mainSignalBox = scenery.getMainSignalBox();
|
const mainSignalBox = scenery.getMainSignalBox();
|
||||||
if(mainSignalBox) {
|
if(mainSignalBox) {
|
||||||
const sbPos = mainSignalBox.pos.toSVGCoords();
|
const sbPos = mainSignalBox.pos.toSVGCoords();
|
||||||
const sbRot = -mainSignalBox.getFinalRotation();
|
const sbRot = -mainSignalBox.getFinalRotation();
|
||||||
setCamera(...sbPos, sbRot, Constants.map.zoomDefault);
|
setCamera(...sbPos, sbRot, targetZoom);
|
||||||
}
|
}
|
||||||
else setCamera(0, 0, 0, Constants.map.zoomDefault);
|
else setCamera(0, 0, 0, targetZoom);
|
||||||
}, [setCamera]);
|
}, [setCamera, isEmbedded]);
|
||||||
|
|
||||||
const loadCustomScenery = useCallback((file) => {
|
const loadCustomScenery = useCallback((file) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -64,10 +67,12 @@ export default function SceneryManager(props) {
|
|||||||
setScenery(null);
|
setScenery(null);
|
||||||
SceneryParserLog.clear();
|
SceneryParserLog.clear();
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
if (!isEmbedded) {
|
||||||
urlParams.delete('scenery');
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
urlParams.delete('pos');
|
urlParams.delete('scenery');
|
||||||
window.history.replaceState({}, '', urlParams.size ? `${window.location.pathname}?${urlParams.toString()}` : window.location.pathname);
|
urlParams.delete('pos');
|
||||||
|
window.history.replaceState({}, '', urlParams.size ? `${window.location.pathname}?${urlParams.toString()}` : window.location.pathname);
|
||||||
|
}
|
||||||
|
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
@ -83,13 +88,17 @@ export default function SceneryManager(props) {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
showCustomDialog(<SceneryLoadedDialog loadingError={loadingError} />);
|
if (isEmbedded && loadingError) {
|
||||||
|
showDialog('Failed to load scenery');
|
||||||
|
} else if (!isEmbedded) {
|
||||||
|
showCustomDialog(<SceneryLoadedDialog loadingError={loadingError} />);
|
||||||
|
}
|
||||||
setScenery(scenery);
|
setScenery(scenery);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
resolve(scenery);
|
resolve(scenery);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [updateViewAfterSceneryLoaded]);
|
}, [updateViewAfterSceneryLoaded, isEmbedded]);
|
||||||
|
|
||||||
const loadScenery = useCallback(async (sceneryName) => {
|
const loadScenery = useCallback(async (sceneryName) => {
|
||||||
let file;
|
let file;
|
||||||
@ -130,6 +139,7 @@ export default function SceneryManager(props) {
|
|||||||
const sceneryName = findSceneryInList(sceneryQuery);
|
const sceneryName = findSceneryInList(sceneryQuery);
|
||||||
if (!sceneryName) {
|
if (!sceneryName) {
|
||||||
console.warn(`Scenery "${sceneryQuery}" not found in the list.`);
|
console.warn(`Scenery "${sceneryQuery}" not found in the list.`);
|
||||||
|
showDialog(`Scenery "${sceneryQuery}" not found in the list.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +150,7 @@ export default function SceneryManager(props) {
|
|||||||
if(!posQuery) return;
|
if(!posQuery) return;
|
||||||
if (!pos) {
|
if (!pos) {
|
||||||
console.warn(`Invalid position query "${posQuery}"`);
|
console.warn(`Invalid position query "${posQuery}"`);
|
||||||
|
showDialog("Invalid position query in URL.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,11 +5,14 @@ import SideMenuToggle from './SideMenuToggle';
|
|||||||
import SceneryList from './SceneryList';
|
import SceneryList from './SceneryList';
|
||||||
import ElectrificationStepMode from './ElectrificationStepMode';
|
import ElectrificationStepMode from './ElectrificationStepMode';
|
||||||
import ThemeToggle from './ThemeToggle';
|
import ThemeToggle from './ThemeToggle';
|
||||||
|
import { useEmbeddedContext } from '../../contexts/EmbeddedContext';
|
||||||
|
|
||||||
export default function Toolbar() {
|
export default function Toolbar() {
|
||||||
|
const { isEmbedded } = useEmbeddedContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='toolbar-cont'>
|
<div className='toolbar-cont'>
|
||||||
<div className='toolbar'>
|
{!isEmbedded && <div className='toolbar'>
|
||||||
<SceneryList />
|
<SceneryList />
|
||||||
or
|
or
|
||||||
<CustomFileSelect />
|
<CustomFileSelect />
|
||||||
@ -18,6 +21,7 @@ export default function Toolbar() {
|
|||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
<SideMenuToggle />
|
<SideMenuToggle />
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
<div className='loading-indicator-cont'>
|
<div className='loading-indicator-cont'>
|
||||||
<LoadingIndicator />
|
<LoadingIndicator />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ const Constants = {
|
|||||||
zoomMin: 0.03,
|
zoomMin: 0.03,
|
||||||
zoomMax: 200.0,
|
zoomMax: 200.0,
|
||||||
zoomDefault: 5,
|
zoomDefault: 5,
|
||||||
|
zoomDefaultEmbeded: 2.5,
|
||||||
rotationSensitivity: 0.2,
|
rotationSensitivity: 0.2,
|
||||||
forcePointerEvents: false,
|
forcePointerEvents: false,
|
||||||
platformMaxTilt: 0.5,
|
platformMaxTilt: 0.5,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user