split out react UI
This commit is contained in:
parent
74603cba65
commit
618c0013ee
156
index.html
156
index.html
@ -3,165 +3,11 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport"/>
|
||||
<link href="/styles.css" rel="stylesheet">
|
||||
<link href="/assets/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png">
|
||||
<link href="/assets/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png">
|
||||
<link href="/assets/favicon-96x96.png" rel="icon" sizes="96x96" type="image/png">
|
||||
<title>Deep Diagram</title>
|
||||
<style>
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
aspect-ratio: auto;
|
||||
font-family: Roboto, sans-serif;
|
||||
font-size: large;
|
||||
color: #4444ee;
|
||||
}
|
||||
|
||||
.scene {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
#gameCanvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
|
||||
div.overlay {
|
||||
position: absolute;
|
||||
background: #000;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 12;
|
||||
width: 320px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
div.overlay div {
|
||||
background-color: #000000;
|
||||
color: #FFD700;
|
||||
padding: 15px 25px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.overlay div a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
border-color: #FFD700;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 10px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div.overlay div a:visited, div.overlay div a:link {
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.overlay div a:hover {
|
||||
background-color: #FFD700;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
div.overlay div a {
|
||||
|
||||
}
|
||||
|
||||
div.overlay input {
|
||||
display: inline-block;
|
||||
margin: 10px auto;
|
||||
text-decoration: none;
|
||||
border-color: #FFD700;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 10px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div#create {
|
||||
left: 50%;
|
||||
top: 60%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 12;
|
||||
width: 320px;
|
||||
height: 344px;
|
||||
border: 3px inset #FFD700;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.overlay div a.cancel {
|
||||
font-size: small;
|
||||
font-weight: lighter;
|
||||
font-style: italic;
|
||||
background-color: #222211;
|
||||
color: #EEC755;
|
||||
}
|
||||
|
||||
div.overlay div a.cancel:hover {
|
||||
background-color: #EEC700;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
#download {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#main.mini {
|
||||
left: 100px;
|
||||
top: 200px;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
#main.mini img, #tutorial img {
|
||||
width: 160px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
#main.mini div a, #tutorial div a {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#tutorial h1 {
|
||||
font-size: x-large;
|
||||
font-weight: bolder;
|
||||
text-align: center;
|
||||
color: #F9F9E9;
|
||||
}
|
||||
|
||||
#tutorial {
|
||||
z-index: 15;
|
||||
left: 100px;
|
||||
top: 560px;
|
||||
width: 160px;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
|
||||
#closekey, #closekey a:active, #closekey a:visited, #closekey a:link {
|
||||
position: relative;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#loadingGrid {
|
||||
z-index: -1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<link as="script" href="/newRelic.js" rel="preload">
|
||||
<script src="/newRelic.js"></script>
|
||||
<meta content="width=device-width, initial-scale=1, height=device-height" name="viewport">
|
||||
|
||||
188
public/styles.css
Normal file
188
public/styles.css
Normal file
@ -0,0 +1,188 @@
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
aspect-ratio: auto;
|
||||
font-family: Roboto, sans-serif;
|
||||
font-size: large;
|
||||
color: #4444ee;
|
||||
}
|
||||
|
||||
.scene {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
#gameCanvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
|
||||
div.overlay {
|
||||
position: absolute;
|
||||
background: #000;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 12;
|
||||
width: 320px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
div.overlay div {
|
||||
background-color: #000000;
|
||||
color: #FFD700;
|
||||
padding: 15px 25px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.overlay div a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
border-color: #FFD700;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 10px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div.overlay div a:visited, div.overlay div a:link {
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.overlay div a:hover {
|
||||
background-color: #FFD700;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
div.overlay div a {
|
||||
|
||||
}
|
||||
|
||||
div.overlay input {
|
||||
display: inline-block;
|
||||
margin: 10px auto;
|
||||
text-decoration: none;
|
||||
border-color: #FFD700;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 10px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div#create {
|
||||
left: 600px;
|
||||
top: 400px;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 14;
|
||||
width: 320px;
|
||||
height: 344px;
|
||||
border: 3px inset #FFD700;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.overlay div a.cancel {
|
||||
font-size: small;
|
||||
font-weight: lighter;
|
||||
font-style: italic;
|
||||
background-color: #222211;
|
||||
color: #EEC755;
|
||||
}
|
||||
|
||||
#diagramListContent ul {
|
||||
list-style-type: none;
|
||||
text-align: left;
|
||||
padding: 0;
|
||||
padding-inline-start: 0;
|
||||
|
||||
}
|
||||
|
||||
#diagramList {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#diagramList > h1 {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#diagramListContent li {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
#diagramListContent li a {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
div.overlay div a.cancel:hover {
|
||||
background-color: #EEC700;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
|
||||
#main.mini {
|
||||
left: 100px;
|
||||
top: 200px;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
#main.mini img, #tutorial img {
|
||||
width: 160px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
#main.mini div a, #tutorial div a {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: x-large;
|
||||
font-weight: bolder;
|
||||
text-align: center;
|
||||
color: #F9F9E9;
|
||||
}
|
||||
|
||||
#tutorial {
|
||||
z-index: 15;
|
||||
left: 100px;
|
||||
top: 560px;
|
||||
width: 160px;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
#diagramList {
|
||||
left: 340px;
|
||||
top: 240px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#create {
|
||||
left: 500px;
|
||||
top: 340px;
|
||||
}
|
||||
|
||||
|
||||
#closekey, #closekey a:active, #closekey a:visited, #closekey a:link {
|
||||
position: relative;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#enterXR {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#loadingGrid {
|
||||
z-index: -1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@ -11,11 +11,9 @@ import {
|
||||
import {ControllerEventType, Controllers} from "./controllers";
|
||||
import log from "loglevel";
|
||||
import {DiagramManager} from "../diagram/diagramManager";
|
||||
import {DiagramListingMenu} from "../menus/diagramListingMenu";
|
||||
import {RoundButton} from "../objects/roundButton";
|
||||
|
||||
export class Right extends Base {
|
||||
private listingMenu: DiagramListingMenu;
|
||||
|
||||
private startPosition: Vector3 = null;
|
||||
|
||||
@ -42,7 +40,6 @@ export class Right extends Base {
|
||||
controllers: Controllers,
|
||||
) {
|
||||
super(controller, scene, xr, controllers, diagramManager);
|
||||
this.listingMenu = new DiagramListingMenu(this.scene, xr, this.controllers, diagramManager);
|
||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||
this.initTrigger(init.components['xr-standard-trigger']);
|
||||
if (init.components['a-button']) {
|
||||
|
||||
@ -14,12 +14,11 @@ import {toDiagramEntity} from "./functions/toDiagramEntity";
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
import {buildEntityActionManager} from "./functions/buildEntityActionManager";
|
||||
import {isDiagramEntity} from "./functions/isDiagramEntity";
|
||||
import {DiagramListingEvent} from "./types/diagramListing";
|
||||
|
||||
|
||||
export class DiagramManager {
|
||||
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
|
||||
public readonly onDiagramEventListingObservable: Observable<DiagramListingEvent> = new Observable();
|
||||
|
||||
private readonly logger = log.getLogger('DiagramManager');
|
||||
private readonly toolbox: Toolbox;
|
||||
private readonly scene: Scene;
|
||||
@ -68,12 +67,6 @@ export class DiagramManager {
|
||||
});
|
||||
}
|
||||
|
||||
//@TODO Refactor
|
||||
/*public setPersistenceManager(persistenceManager: IPersistenceManager) {
|
||||
this.persistenceManager = persistenceManager;
|
||||
this._config = new AppConfig(persistenceManager);
|
||||
this.persistenceManager.updateObserver.add(this.onRemoteEvent, -1, true, this);
|
||||
}*/
|
||||
public createCopy(mesh: AbstractMesh, copy: boolean = false): AbstractMesh {
|
||||
let newMesh;
|
||||
if (!mesh.isAnInstance) {
|
||||
@ -97,13 +90,6 @@ export class DiagramManager {
|
||||
if (this.config.current?.physicsEnabled) {
|
||||
applyPhysics(this.sounds, newMesh, this.scene);
|
||||
}
|
||||
//@TODO Refactor
|
||||
/*this.onDiagramEventObservable.notifyObservers({
|
||||
type: DiagramEventType.ADD,
|
||||
entity: toDiagramEntity(newMesh)
|
||||
}, 2);*/
|
||||
//this.persistenceManager.add(toDiagramEntity(newMesh));
|
||||
|
||||
return newMesh;
|
||||
}
|
||||
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
export enum DiagramListingEventType {
|
||||
GET,
|
||||
ADD,
|
||||
REMOVE,
|
||||
MODIFY,
|
||||
GETALL,
|
||||
}
|
||||
|
||||
export type DiagramListingEvent = {
|
||||
type: DiagramListingEventType;
|
||||
listing?: DiagramListing;
|
||||
}
|
||||
export type DiagramListing = {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
sharekey?: string;
|
||||
}
|
||||
@ -6,8 +6,6 @@ import {v4 as uuidv4} from 'uuid';
|
||||
import axios from "axios";
|
||||
import {DiagramManager} from "../diagram/diagramManager";
|
||||
import log, {Logger} from "loglevel";
|
||||
import {DiagramListing, DiagramListingEventType} from "../diagram/types/diagramListing";
|
||||
|
||||
|
||||
export class PouchdbPersistenceManager {
|
||||
configObserver: Observable<AppConfigType> = new Observable<AppConfigType>();
|
||||
@ -16,30 +14,14 @@ export class PouchdbPersistenceManager {
|
||||
//implement IPersistenceManager interface with pouchdb apis
|
||||
private db: PouchDB;
|
||||
private remote: PouchDB;
|
||||
private config: PouchDB;
|
||||
|
||||
private diagramListings: PouchDB;
|
||||
private readonly logger: Logger = log.getLogger('PouchdbPersistenceManager');
|
||||
constructor() {
|
||||
this.config = new PouchDB("config");
|
||||
this.diagramListings = new PouchDB("diagramListings");
|
||||
}
|
||||
|
||||
public async getDiagramListings() {
|
||||
return this.diagramListings.allDocs({include_docs: true});
|
||||
}
|
||||
public setDiagramManager(diagramManager: DiagramManager) {
|
||||
diagramManager.onDiagramEventListingObservable.add((evt) => {
|
||||
if (evt.type == DiagramListingEventType.GETALL) {
|
||||
this.diagramListings.allDocs({include_docs: true}).then((all) => {
|
||||
for (const entity of all.rows) {
|
||||
diagramManager.onDiagramEventListingObservable.notifyObservers({
|
||||
type: DiagramListingEventType.ADD,
|
||||
listing: {id: entity.doc._id, name: entity.doc.name}
|
||||
}, -1, false, this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, -1, false, this);
|
||||
diagramManager.onDiagramEventObservable.add((evt) => {
|
||||
switch (evt.type) {
|
||||
case DiagramEventType.CHANGECOLOR:
|
||||
@ -125,34 +107,6 @@ export class PouchdbPersistenceManager {
|
||||
this.logger.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async addDiagram(diagram: DiagramListing) {
|
||||
try {
|
||||
const doc = await this.diagramListings.get(diagram.id);
|
||||
|
||||
} catch (err) {
|
||||
this.diagramListings.put({...diagram, _id: diagram.id});
|
||||
}
|
||||
}
|
||||
|
||||
public async removeDiagram(diagram: DiagramListing) {
|
||||
try {
|
||||
this.diagramListings.delete(diagram.id);
|
||||
} catch (err) {
|
||||
this.logger.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async modifyDiagram(diagram: DiagramListing) {
|
||||
try {
|
||||
const doc = await this.db.get(diagram.id);
|
||||
this.db.put({...doc, ...diagram});
|
||||
} catch (err) {
|
||||
this.logger.error(err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async getNewRelicData(): Promise<any[]> {
|
||||
return [];
|
||||
}
|
||||
@ -161,25 +115,23 @@ export class PouchdbPersistenceManager {
|
||||
return data;
|
||||
}
|
||||
|
||||
public async setConfig(config: any, initial: boolean = false): Promise<any> {
|
||||
public async setConfig(config: AppConfigType, initial: boolean = false) {
|
||||
if (!initial) {
|
||||
const doc = await this.config.get('1');
|
||||
const newConf = {...config, _id: '1', _rev: doc._rev};
|
||||
return this.config.put(newConf);
|
||||
localStorage.setItem('config', JSON.stringify(config));
|
||||
} else {
|
||||
const newConf = {...config, _id: '1'};
|
||||
return this.config.put(newConf);
|
||||
localStorage.setItem('config', JSON.stringify(config));
|
||||
}
|
||||
}
|
||||
|
||||
public async getConfig(): Promise<any> {
|
||||
return this.config.get('1');
|
||||
public getConfig(): AppConfigType {
|
||||
return JSON.parse(localStorage.getItem('config')) as AppConfigType;
|
||||
}
|
||||
|
||||
public async initialize() {
|
||||
try {
|
||||
let current = this.getPath();
|
||||
const config = await this.config.get('1');
|
||||
const configString = localStorage.getItem('config');
|
||||
const config = JSON.parse(configString) as AppConfigType;
|
||||
|
||||
if (!current && config.currentDiagramId) {
|
||||
this.db = new PouchDB(config.currentDiagramId);
|
||||
@ -192,7 +144,7 @@ export class PouchdbPersistenceManager {
|
||||
}
|
||||
this.db = new PouchDB(config.currentDiagramId);
|
||||
await this.beginSync(config.currentDiagramId);
|
||||
await this.config.put(config);
|
||||
localStorage.setItem('config', JSON.stringify(config));
|
||||
}
|
||||
this.configObserver.notifyObservers(config);
|
||||
} catch (err) {
|
||||
@ -264,10 +216,6 @@ export class PouchdbPersistenceManager {
|
||||
}
|
||||
}
|
||||
|
||||
setCurrentDiagram(diagram: DiagramListing) {
|
||||
this.currentDiagramId = diagram.id;
|
||||
}
|
||||
|
||||
sync() {
|
||||
|
||||
}
|
||||
|
||||
@ -1,94 +0,0 @@
|
||||
import {AbstractMesh, MeshBuilder, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||
import {AbstractMenu} from "./abstractMenu";
|
||||
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||
import {AdvancedDynamicTexture, Button, Control, ScrollViewer, StackPanel, TextBlock} from "@babylonjs/gui";
|
||||
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
||||
import {DiagramManager} from "../diagram/diagramManager";
|
||||
import {DiagramListingEvent, DiagramListingEventType} from "../diagram/types/diagramListing";
|
||||
import {DiagramEventType} from "../diagram/types/diagramEntity";
|
||||
|
||||
|
||||
export class DiagramListingMenu extends AbstractMenu {
|
||||
private mesh: AbstractMesh;
|
||||
private panel: StackPanel;
|
||||
private readonly diagramManager: DiagramManager;
|
||||
|
||||
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers, diagramManager: DiagramManager) {
|
||||
super(scene, xr, controllers);
|
||||
this.diagramManager = diagramManager;
|
||||
this.buildMenu();
|
||||
this.controllers.controllerObserver.add((event) => {
|
||||
if (event.type == ControllerEventType.B_BUTTON) {
|
||||
this.toggle();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public toggle() {
|
||||
setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0));
|
||||
this.mesh.isVisible = !this.mesh.isVisible;
|
||||
this.populateData();
|
||||
(this.mesh.parent as AbstractMesh).isVisible = this.mesh.isVisible;
|
||||
}
|
||||
|
||||
public populateData() {
|
||||
this.panel.clearControls();
|
||||
this.diagramManager.onDiagramEventListingObservable.notifyObservers({type: DiagramListingEventType.GETALL}, -1);
|
||||
}
|
||||
|
||||
private buildMenu() {
|
||||
const configPlane = MeshBuilder
|
||||
.CreatePlane("gridSizePlane",
|
||||
{
|
||||
width: 1,
|
||||
height: .5
|
||||
}, this.scene);
|
||||
this.mesh = configPlane;
|
||||
this.createHandle(this.mesh);
|
||||
this.mesh.position = new Vector3(0, .32, 0);
|
||||
const configTexture = AdvancedDynamicTexture.CreateForMesh(configPlane, 2048, 1024);
|
||||
|
||||
configTexture.background = "white";
|
||||
const scrollViewer = new ScrollViewer('diagramListingScroll');
|
||||
configTexture.addControl(scrollViewer);
|
||||
this.panel = new StackPanel('diagramListingStack');
|
||||
scrollViewer.addControl(this.panel);
|
||||
|
||||
//configPlane.position.y = .5;
|
||||
setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0));
|
||||
this.mesh.isVisible = false;
|
||||
(this.mesh.parent as AbstractMesh).isVisible = false;
|
||||
this.diagramManager.onDiagramEventListingObservable.add((event: DiagramListingEvent) => {
|
||||
if (event.type == DiagramListingEventType.ADD) {
|
||||
this.addRow(event.listing.id, event.listing.name);
|
||||
}
|
||||
}, -1, false, this);
|
||||
|
||||
}
|
||||
|
||||
private addRow(id: string, name: string) {
|
||||
const row = new StackPanel('diagramListingRow ' + id);
|
||||
row.isVertical = false;
|
||||
row.height = "68px";
|
||||
row.width = 1;
|
||||
this.panel.addControl(row);
|
||||
const selectButton = Button.CreateSimpleButton('diagramListingText ' + id, id);
|
||||
selectButton.height = "64px";
|
||||
selectButton.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
|
||||
selectButton.width = "220px";
|
||||
selectButton.color = "white";
|
||||
selectButton.fontSize = "48px";
|
||||
selectButton.background = "#333333";
|
||||
selectButton.onPointerClickObservable.add(() => {
|
||||
this.diagramManager.onDiagramEventObservable.notifyObservers({type: DiagramEventType.RESET});
|
||||
console.log(id);
|
||||
}, -1, false, this);
|
||||
const textBlock = new TextBlock('diagramListingText ' + name, 'Diagram ' + name);
|
||||
textBlock.width = "1000px";
|
||||
textBlock.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
|
||||
textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
|
||||
textBlock.fontSize = "48px";
|
||||
row.addControl(selectButton);
|
||||
row.addControl(textBlock);
|
||||
}
|
||||
}
|
||||
@ -1,26 +1,34 @@
|
||||
import {useState} from "react";
|
||||
import {useEffect, useState} from "react";
|
||||
|
||||
function MainMenu({onClick}) {
|
||||
return (
|
||||
<div className="overlay mini" id="main" onClick={onClick}>
|
||||
<div className="overlay mini" id="main">
|
||||
<img height="120" src="/assets/ddd.svg" width="320"/>
|
||||
<div id="startCreate"><a href="#" id="startCreateLink">Start</a></div>
|
||||
<div id="diagrams"><a href="#" id="diagramsLink" onClick={onClick}>Diagrams</a></div>
|
||||
<div id="enterXR"><a href="#" id="enterVRLink">Enter VR</a></div>
|
||||
<div id="download"><a href="#" id="downloadLink">Download Model</a></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CreateMenu({display}) {
|
||||
function CreateMenu({display, toggleCreateMenu}) {
|
||||
const onCreateClick = (evt) => {
|
||||
evt.preventDefault();
|
||||
const name = (document.querySelector('#createName') as HTMLInputElement).value;
|
||||
if (name && name.length > 4) {
|
||||
document.location.href = '/db/' + name;
|
||||
} else {
|
||||
window.alert('Name must be longer than 4 characters');
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div className="overlay" id="create" style={{'display': display}}>
|
||||
|
||||
<div>
|
||||
<div><input id="createName" placeholder="Enter a name for your diagram" type="text"/></div>
|
||||
<div><input id="createPassword" placeholder="Enter a password (optional)" type="text"/></div>
|
||||
<div><a href="#" id="createActionLink">Create</a></div>
|
||||
<div><a className="cancel" href="#" id="cancelCreateLink">Cancel</a></div>
|
||||
<div><a href="#" id="createActionLink" onClick={onCreateClick}>Create</a></div>
|
||||
<div><a className="cancel" onClick={toggleCreateMenu} href="#" id="cancelCreateLink">Cancel</a></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -30,7 +38,6 @@ function TutorialMenu({onClick}) {
|
||||
<div className="overlay" id="tutorial">
|
||||
<h1>Help</h1>
|
||||
<div id="desktopTutorial"><a href="#" id="desktopLink" onClick={onClick}>Desktop</a></div>
|
||||
<div id="questTutorial"><a href="#" id="questLink">Quest</a></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -45,15 +52,26 @@ function KeyboardHelp({display, onClick}) {
|
||||
)
|
||||
}
|
||||
|
||||
function DiagramList() {
|
||||
function DiagramList({display, onClick}) {
|
||||
const [dbList, setDbList] = useState([]);
|
||||
useEffect(() => {
|
||||
const listDb = async () => {
|
||||
const data = await indexedDB.databases();
|
||||
setDbList(data.filter((item) => item.name.indexOf('_pouch_') > -1).map((item) => {
|
||||
return {name: item.name.replace('_pouch_', '')}
|
||||
}));
|
||||
};
|
||||
listDb();
|
||||
}, []);
|
||||
|
||||
|
||||
return (
|
||||
<div className="overlay" id="diagramList" style={{'left': '500px'}}>
|
||||
<h1>Existing Diagrams</h1>
|
||||
<div className="overlay" id="diagramList" style={{'display': display}}>
|
||||
<h1>Diagrams</h1>
|
||||
<div id="startCreate"><a href="#" id="startCreateLink" onClick={onClick}>New</a></div>
|
||||
<div id="diagramListContent">
|
||||
<ul>
|
||||
<li><a href="/db/ddd">ddd</a></li>
|
||||
<li><a href="/db/ddd2">ddd2</a></li>
|
||||
<li><a href="/db/ddd3">ddd3</a></li>
|
||||
{dbList.map((item) => <li><a href={`/db/${item.name}`}>{item.name}</a></li>)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -64,21 +82,30 @@ function Menu() {
|
||||
|
||||
const [createState, setCreateState] = useState('none');
|
||||
const [desktopTutorialState, setDesktopTutorialState] = useState('none');
|
||||
const [diagramListState, setDiagramListState] = useState('none');
|
||||
|
||||
function handleCreateClick() {
|
||||
function handleCreateClick(evt: React.MouseEvent<HTMLAnchorElement>) {
|
||||
evt.preventDefault();
|
||||
setCreateState(createState == 'none' ? 'block' : 'none');
|
||||
}
|
||||
|
||||
function handleDesktopTutorialClick() {
|
||||
function handleDesktopTutorialClick(evt: React.MouseEvent<HTMLAnchorElement>) {
|
||||
evt.preventDefault();
|
||||
setDesktopTutorialState(desktopTutorialState == 'none' ? 'block' : 'none');
|
||||
}
|
||||
|
||||
function handleDiagramListClick(evt: React.MouseEvent<HTMLAnchorElement>) {
|
||||
evt.preventDefault();
|
||||
setDiagramListState(diagramListState == 'none' ? 'block' : 'none');
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<MainMenu onClick={handleCreateClick}/>
|
||||
<MainMenu onClick={handleDiagramListClick}/>
|
||||
<TutorialMenu onClick={handleDesktopTutorialClick}/>
|
||||
<CreateMenu display={createState}/>
|
||||
<CreateMenu display={createState} toggleCreateMenu={handleCreateClick}/>
|
||||
<KeyboardHelp display={desktopTutorialState} onClick={handleDesktopTutorialClick}/>
|
||||
<DiagramList onClick={handleCreateClick} display={diagramListState}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -89,8 +116,6 @@ export default function WebApp() {
|
||||
<Menu/>
|
||||
</div>
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
const create = document.querySelector('#startCreateLink');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user