Lots of little QOL style fixes, remove minimized event panels
This commit is contained in:
parent
2b9dff2983
commit
a6aded4e8e
9 changed files with 203 additions and 198 deletions
73
README.md
73
README.md
|
@ -1,3 +1,74 @@
|
|||
# EventMapper
|
||||
|
||||
TODO: Readme
|
||||
EventMapper, an easily-deployable, nearly-static digital guide application made in JavaScript.
|
||||
|
||||
## Specifications
|
||||
|
||||
### Data Folder Structure
|
||||
```
|
||||
/events
|
||||
[FLOOR].json
|
||||
/rooms
|
||||
[FLOOR].json
|
||||
floors.json
|
||||
```
|
||||
|
||||
### Floor
|
||||
Used to represent a floor in a building. It is a parent to both its [Rooms](#room) and [Events](#events).
|
||||
This object gets represented in the app as a map poly, and in a set of buttons among other floors.
|
||||
```json
|
||||
{
|
||||
"id": "[FLOOR ID]",
|
||||
"poly": [
|
||||
[x, y], // An array of vertex positions.
|
||||
...
|
||||
],
|
||||
"lang": {
|
||||
"[IETF LANGUAGE TAG]": {
|
||||
"name": "[SHORT SINGLE-LINE STRING]",
|
||||
"description": "[SINGLE-LINE STRING]"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
This will be stored in an array in `floors.json` to be accessed by clients.
|
||||
|
||||
### Room
|
||||
Used to represent a space in which events can happen. It is a child to a [Floor](#floor), and a parent to [Events](#event).
|
||||
This object gets represented in the app as a map poly.
|
||||
```json
|
||||
{
|
||||
"id": "[FLOOR]_[ROOM ID]",
|
||||
"poly": [
|
||||
[x, y], // An array of vertex positions.
|
||||
...
|
||||
],
|
||||
"lang": {
|
||||
"[IETF LANGUAGE TAG]": {
|
||||
"name": "[SINGLE-LINE STRING]",
|
||||
"description": "[SINGLE-LINE STRING]"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
This will be stored in an array in `rooms/[FLOOR].json` to be accessed by clients.
|
||||
|
||||
### Event
|
||||
Used to represent a point in time when an activity or festivity happens. It is a child to both a [Floor](#floor) and a [Room](#room), reflected in its ID.
|
||||
```json
|
||||
{
|
||||
"id": "[FLOOR]_[ROOM]_[EVENT ID]",
|
||||
"when": {
|
||||
"start": "[ISO 8601 DATE]",
|
||||
"end": "[ISO 8601 DATE]"
|
||||
},
|
||||
"lang": {
|
||||
"[IETF LANGUAGE TAG]": {
|
||||
"name": "[SINGLE-LINE STRING]",
|
||||
"description": "[MULTI-LINE STRING]",
|
||||
"url": "[URL]"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
This will be stored in an array in `events/[FLOOR].json` to be accessed by clients.
|
|
@ -1,8 +1,4 @@
|
|||
export class GameObjManager {
|
||||
opts = {
|
||||
floorMinZoom: 1,
|
||||
roomMinZoom: 2,
|
||||
};
|
||||
map;
|
||||
|
||||
mainmanager;
|
||||
|
@ -10,12 +6,8 @@ export class GameObjManager {
|
|||
floorObject;
|
||||
roomObjects = new Map([]);
|
||||
|
||||
constructor(map, opts) {
|
||||
constructor(map) {
|
||||
this.map = map;
|
||||
this.opts = {
|
||||
...this.opts,
|
||||
opts,
|
||||
};
|
||||
}
|
||||
|
||||
generateFloor() {
|
||||
|
@ -58,13 +50,32 @@ export class GameObjManager {
|
|||
this.map.kp.add(this.floorObject);
|
||||
}
|
||||
|
||||
zoomToBounds(boundingBox) {
|
||||
// Get screen size
|
||||
const width = this.map.kp.width();
|
||||
const height = this.map.kp.height();
|
||||
|
||||
// Get bbox size
|
||||
const bBoxWidth = boundingBox.width * 1.5;
|
||||
const bBoxHeight = boundingBox.height * 1.5;
|
||||
|
||||
// Compare bounds
|
||||
const scaledWidth = width / bBoxWidth;
|
||||
const scaledHeight = height / bBoxHeight;
|
||||
|
||||
// Whichever one is biggest
|
||||
const scale = Math.min(scaledWidth, scaledHeight);
|
||||
|
||||
this.map.zoomToAbs(
|
||||
Math.log2(scale), // log scale
|
||||
boundingBox.center()
|
||||
);
|
||||
}
|
||||
|
||||
zoomToFloor() {
|
||||
const objectBounds = this.floorObject.renderArea().bbox();
|
||||
|
||||
this.map.zoomToAbs(
|
||||
this.map.opts.minZoomLevel + this.opts.floorMinZoom,
|
||||
objectBounds.center()
|
||||
);
|
||||
this.zoomToBounds(objectBounds);
|
||||
}
|
||||
|
||||
zoomToRoom(id) {
|
||||
|
@ -73,10 +84,7 @@ export class GameObjManager {
|
|||
|
||||
const objectBounds = selectedObject.renderArea().bbox();
|
||||
|
||||
this.map.zoomToAbs(
|
||||
this.map.opts.minZoomLevel + this.opts.roomMinZoom,
|
||||
objectBounds.center()
|
||||
);
|
||||
this.zoomToBounds(objectBounds);
|
||||
}
|
||||
|
||||
generateRooms() {
|
||||
|
|
|
@ -15,12 +15,10 @@ export default new Map([
|
|||
events_in: (name) => `Events (${name})`,
|
||||
event_in: (location) => `In ${location}`,
|
||||
view_events_in: (name) => `Return to events in ${name}`,
|
||||
minimize: "Hide events panel",
|
||||
maximize: "Show events panel",
|
||||
minimize: "Toggle event panel docking",
|
||||
event_inspector_header: (name) => `Event ${name}`,
|
||||
event_inspector_back: "Return to events panel",
|
||||
event_inspector_minimize: "Hide event inspector",
|
||||
event_inspector_maximize: "Show event inspector",
|
||||
event_inspector_minimize: "Toggle event inspector docking",
|
||||
},
|
||||
],
|
||||
]);
|
||||
|
|
|
@ -2,7 +2,7 @@ export class KaplayMap {
|
|||
kp;
|
||||
opts = {
|
||||
minZoomLevel: 1,
|
||||
maxZoomLevel: 5,
|
||||
maxZoomLevel: 6,
|
||||
dblClickDuration: 0.2, // s
|
||||
dblClickForgiveness: 100, // px
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ export class EventMapperManager {
|
|||
this.uimanager = new UIManager(mapUi);
|
||||
this.uimanager.mainmanager = this;
|
||||
|
||||
this.gameobjmanager = new GameObjManager(this.map, {});
|
||||
this.gameobjmanager = new GameObjManager(this.map);
|
||||
this.gameobjmanager.mainmanager = this;
|
||||
}
|
||||
|
||||
|
@ -60,17 +60,24 @@ export class EventMapperManager {
|
|||
|
||||
let hash = location.hash;
|
||||
if (hash.includes("#")) hash = hash.replace("#", "");
|
||||
else return;
|
||||
|
||||
const floorFocus = this.convertIdFocus(hash, "floor");
|
||||
const roomFocus = this.convertIdFocus(hash, "room");
|
||||
const eventFocus = this.convertIdFocus(hash, "event");
|
||||
|
||||
this.uimanager.setLoading(true);
|
||||
if (floorFocus != this.convertFocus(prevID, "floor"))
|
||||
await this.selectFloor(floorFocus);
|
||||
this.uimanager.setLoading(true);
|
||||
this.uimanager.setLoading(false);
|
||||
if (roomFocus != this.convertFocus(prevID, "room"))
|
||||
await this.selectRoom(roomFocus);
|
||||
this.uimanager.setLoading(true);
|
||||
this.uimanager.setLoading(false);
|
||||
if (eventFocus != this.convertFocus(prevID, "event"))
|
||||
await this.selectEvent(eventFocus);
|
||||
this.uimanager.setLoading(false);
|
||||
}
|
||||
|
||||
async selectFloor(id) {
|
||||
|
|
|
@ -49,7 +49,9 @@ export class UIManager {
|
|||
}
|
||||
|
||||
setEventsMinimized(state) {
|
||||
if (state) {
|
||||
if (state == null) {
|
||||
this.uiElements.eventsContainer.classList.toggle("minimized");
|
||||
} else if (state) {
|
||||
this.uiElements.eventsContainer.classList.add("minimized");
|
||||
} else {
|
||||
this.uiElements.eventsContainer.classList.remove("minimized");
|
||||
|
@ -57,7 +59,10 @@ export class UIManager {
|
|||
}
|
||||
|
||||
setEventsInspector(state) {
|
||||
this.setEventsMinimized(false);
|
||||
if (
|
||||
state != this.uiElements.eventsContainer.classList.contains("inspector")
|
||||
)
|
||||
this.setEventsMinimized(false);
|
||||
if (state) {
|
||||
this.uiElements.eventsContainer.classList.add("inspector");
|
||||
} else {
|
||||
|
@ -81,9 +86,6 @@ export class UIManager {
|
|||
|
||||
// Floors
|
||||
this.uiElements.floors = this.ui.querySelector("#floors");
|
||||
this.uiElements.floorsHeading = this.ui.querySelector(
|
||||
"#floors .widget-heading"
|
||||
);
|
||||
this.uiElements.floorButtons =
|
||||
this.uiElements.floors.querySelector("#floor-buttons");
|
||||
|
||||
|
@ -102,10 +104,6 @@ export class UIManager {
|
|||
this.uiElements.events.querySelector("#events-header #room-description");
|
||||
this.uiElements.eventList =
|
||||
this.uiElements.events.querySelector("#event-list");
|
||||
this.uiElements.eventsMinimized =
|
||||
this.uiElements.eventsContainer.querySelector("#events-minimized");
|
||||
this.uiElements.eventsMinimizedBackButton =
|
||||
this.uiElements.eventsMinimized.querySelector("#back");
|
||||
|
||||
this.uiElements.eventsInspector =
|
||||
this.uiElements.eventsContainer.querySelector("#events-inspector");
|
||||
|
@ -117,29 +115,16 @@ export class UIManager {
|
|||
this.uiElements.eventsInspectorHeader.querySelector("#event-length");
|
||||
this.uiElements.eventsInspectorRoomTime =
|
||||
this.uiElements.eventsInspector.querySelector("#room-time");
|
||||
this.uiElements.eventsInspectorMinimized =
|
||||
this.uiElements.eventsContainer.querySelector(
|
||||
"#events-inspector-minimized"
|
||||
);
|
||||
this.uiElements.eventsInspectorBackButton =
|
||||
this.uiElements.eventsInspector.querySelector("#back");
|
||||
this.uiElements.eventsInspectorBody =
|
||||
this.uiElements.eventsInspector.querySelector("#event-body");
|
||||
this.uiElements.eventsInspectorMinimizedBackButton =
|
||||
this.uiElements.eventsInspectorMinimized.querySelector("#back");
|
||||
|
||||
this.uiElements.minimizeButton = this.uiElements.events.querySelector(
|
||||
"#footer #footer-buttons #minimize"
|
||||
);
|
||||
this.uiElements.maximizeButton =
|
||||
this.uiElements.eventsMinimized.querySelector("#maximize");
|
||||
this.uiElements.minimizeButton =
|
||||
this.uiElements.events.querySelector("#minimize");
|
||||
|
||||
this.uiElements.eventsInspectorMinimizeButton =
|
||||
this.uiElements.eventsInspector.querySelector(
|
||||
"#footer #footer-buttons #minimize"
|
||||
);
|
||||
this.uiElements.eventsInspectorMaximizeButton =
|
||||
this.uiElements.eventsInspectorMinimized.querySelector("#maximize");
|
||||
this.uiElements.eventsInspector.querySelector("#minimize");
|
||||
|
||||
// Loading
|
||||
this.uiElements.loading = this.ui.querySelector("#loading");
|
||||
|
@ -166,21 +151,11 @@ export class UIManager {
|
|||
__initInspector() {
|
||||
this.uiElements.eventsInspectorMinimizeButton.addEventListener(
|
||||
"click",
|
||||
() => this.setEventsMinimized(true)
|
||||
);
|
||||
this.uiElements.eventsInspectorMaximizeButton.addEventListener(
|
||||
"click",
|
||||
() => this.setEventsMinimized(false)
|
||||
() => this.setEventsMinimized()
|
||||
);
|
||||
this.uiElements.eventsInspectorBackButton.addEventListener("click", () => {
|
||||
window.location.hash = this.mainmanager.getCurrentFocus("room");
|
||||
});
|
||||
this.uiElements.eventsInspectorMinimizedBackButton.addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
window.location.hash = this.mainmanager.getCurrentFocus("room");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateInspector() {
|
||||
|
@ -191,12 +166,8 @@ export class UIManager {
|
|||
|
||||
this.uiElements.eventsInspectorBackButton.title =
|
||||
currentLocalization.event_inspector_back;
|
||||
this.uiElements.eventsInspectorMinimizedBackButton.title =
|
||||
currentLocalization.event_inspector_back;
|
||||
this.uiElements.eventsInspectorMinimizeButton.title =
|
||||
currentLocalization.event_inspector_minimize;
|
||||
this.uiElements.eventsInspectorMaximizeButton.title =
|
||||
currentLocalization.event_inspector_maximize;
|
||||
|
||||
const currentDate = new Date();
|
||||
const eventDateStart = new Date(currentEvent.when.start);
|
||||
|
@ -283,16 +254,10 @@ export class UIManager {
|
|||
this.uiElements.eventsBackButton.addEventListener("click", () => {
|
||||
window.location.hash = this.mainmanager.getCurrentFocus("floor");
|
||||
});
|
||||
this.uiElements.eventsMinimizedBackButton.addEventListener("click", () => {
|
||||
window.location.hash = this.mainmanager.getCurrentFocus("floor");
|
||||
});
|
||||
|
||||
this.uiElements.minimizeButton.addEventListener("click", () => {
|
||||
this.uiElements.eventsContainer.classList.add("minimized");
|
||||
});
|
||||
this.uiElements.maximizeButton.addEventListener("click", () => {
|
||||
this.uiElements.eventsContainer.classList.remove("minimized");
|
||||
});
|
||||
this.uiElements.minimizeButton.addEventListener("click", () =>
|
||||
this.setEventsMinimized()
|
||||
);
|
||||
}
|
||||
|
||||
__updateEventsSoft() {
|
||||
|
@ -314,7 +279,6 @@ export class UIManager {
|
|||
const focusedRoom = this.mainmanager.getCurrentFocusObject("room");
|
||||
|
||||
this.uiElements.minimizeButton.title = currentLocalization.minimize;
|
||||
this.uiElements.maximizeButton.title = currentLocalization.maximize;
|
||||
// Figure out header
|
||||
|
||||
if (this.mainmanager.getIsFocused("room")) {
|
||||
|
@ -329,9 +293,6 @@ export class UIManager {
|
|||
this.uiElements.eventsBackButton.disabled = false;
|
||||
this.uiElements.eventsBackButton.title =
|
||||
currentLocalization.view_events_in(focusedFloor.name);
|
||||
this.uiElements.eventsMinimizedBackButton.disabled = false;
|
||||
this.uiElements.eventsMinimizedBackButton.title =
|
||||
currentLocalization.view_events_in(focusedFloor.name);
|
||||
} else {
|
||||
if (currentEvents.size < 1) {
|
||||
this.uiElements.eventsRoomName.textContent = focusedFloor.name;
|
||||
|
@ -343,8 +304,6 @@ export class UIManager {
|
|||
focusedFloor.description;
|
||||
this.uiElements.eventsBackButton.disabled = true;
|
||||
this.uiElements.eventsBackButton.title = "";
|
||||
this.uiElements.eventsMinimizedBackButton.disabled = true;
|
||||
this.uiElements.eventsMinimizedBackButton.title = "";
|
||||
}
|
||||
|
||||
// Remove all children
|
||||
|
@ -455,8 +414,6 @@ export class UIManager {
|
|||
const mainFocus = this.mainmanager.getCurrentFocus("floor");
|
||||
// Remove all children
|
||||
this.uiElements.floorButtons.replaceChildren();
|
||||
this.uiElements.floorsHeading.textContent =
|
||||
currentLocalization.floors_header;
|
||||
|
||||
// Put them back
|
||||
currentFloors.forEach(({ name }, id) => {
|
||||
|
@ -486,9 +443,6 @@ export class UIManager {
|
|||
const currentFloors = this.mainmanager.getAllFocusObject("floor");
|
||||
const mainFocus = this.mainmanager.getCurrentFocus("floor");
|
||||
|
||||
this.uiElements.floorsHeading.textContent =
|
||||
currentLocalization.floors_header;
|
||||
|
||||
currentFloors.forEach((_, id) => {
|
||||
const child = this.uiElements.floorButtons.querySelector("#floor-" + id);
|
||||
if (id === mainFocus) child.classList.add("selected");
|
||||
|
|
|
@ -15,7 +15,7 @@ h1.widget-heading {
|
|||
margin: 0;
|
||||
margin-bottom: 4px;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.25em;
|
||||
/* letter-spacing: 0.25em; */
|
||||
text-transform: uppercase;
|
||||
/* border-bottom: 1px solid currentColor;
|
||||
padding-bottom: 2px; */
|
||||
|
@ -136,15 +136,13 @@ a {
|
|||
}
|
||||
|
||||
#map-ui #floors #floor-buttons .floor-button {
|
||||
text-align: left;
|
||||
width: 200px;
|
||||
padding: 12px;
|
||||
height: unset;
|
||||
display: inline-block;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
padding: 4px;
|
||||
}
|
||||
#map-ui #floors #floor-buttons .floor-button.selected {
|
||||
padding-left: 9px;
|
||||
border: 1px solid #fff;
|
||||
border-left: 4px solid #fff;
|
||||
}
|
||||
|
||||
#map-ui #events-container {
|
||||
|
@ -156,51 +154,57 @@ a {
|
|||
}
|
||||
|
||||
#map-ui #events-container #events,
|
||||
#map-ui #events-container #events-minimized,
|
||||
#map-ui #events-container #events-inspector,
|
||||
#map-ui #events-container #events-inspector-minimized {
|
||||
#map-ui #events-container #events-inspector {
|
||||
pointer-events: all;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
position: absolute;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
left: 16px;
|
||||
bottom: 16px;
|
||||
border-radius: 4px;
|
||||
left: -100%;
|
||||
translate: 0 calc(100% + 32px);
|
||||
background-color: #202020;
|
||||
color: #fff;
|
||||
box-shadow: 0 0 8px 0 #0008;
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
#map-ui #events-container #events,
|
||||
#map-ui #events-container #events-inspector {
|
||||
transition: translate 0.25s, bottom 0.25s, width 0.25s, border-radius 0.25s;
|
||||
max-height: calc(50vh - 16px);
|
||||
flex-direction: column;
|
||||
width: 400px;
|
||||
max-width: calc(100% - 32px);
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
#map-ui #events-container:not(.empty):not(.inspector):not(.minimized) #events {
|
||||
left: 16px;
|
||||
#map-ui #events-container:not(.inspector) #events,
|
||||
#map-ui #events-container.inspector #events-inspector {
|
||||
translate: 0;
|
||||
}
|
||||
|
||||
#map-ui #events-container:not(.empty):not(.inspector).minimized #events-minimized {
|
||||
left: 16px;
|
||||
#map-ui #events-container:not(.inspector) #events,
|
||||
#map-ui #events-container.inspector #events-inspector {
|
||||
translate: 0;
|
||||
}
|
||||
|
||||
#map-ui #events-container:not(.empty):not(.minimized).inspector #events-inspector {
|
||||
left: 16px;
|
||||
#map-ui #events-container:not(.inspector).minimized #events,
|
||||
#map-ui #events-container.inspector.minimized #events-inspector {
|
||||
bottom: 0;
|
||||
translate: 0 calc(100% - 52px);
|
||||
}
|
||||
|
||||
#map-ui #events-container:not(.empty).minimized.inspector #events-inspector-minimized {
|
||||
left: 16px;
|
||||
#map-ui #events-container.empty #events,
|
||||
#map-ui #events-container.empty #events-inspector {
|
||||
translate: 0 calc(100% + 32px);
|
||||
}
|
||||
|
||||
/* #map-ui #floors.empty ~ #events-container #events,
|
||||
#map-ui #floors.empty ~ #events-container #events-inspector,
|
||||
#map-ui #floors.empty ~ #events-container #events-minimized,
|
||||
#map-ui #floors.empty ~ #events-container #events-inspector-minimized {
|
||||
left: -100% !important;
|
||||
} */
|
||||
#map-ui #events-container.minimized #events #room-description,
|
||||
#map-ui #events-container.minimized #events-inspector #event-length {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#map-ui #events-container.minimized #room-name {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#map-ui #events-container #events #footer #footer-buttons,
|
||||
#map-ui #events-container #events-inspector #footer #footer-buttons {
|
||||
|
@ -214,28 +218,15 @@ a {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#map-ui #events-container #events #events-header,
|
||||
#map-ui #events-container #events-inspector #events-header {
|
||||
#map-ui #events-container #events-header {
|
||||
display: grid;
|
||||
grid-template-columns: 36px auto;
|
||||
align-items: start;
|
||||
grid-template-columns: 36px auto 36px;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
/* align-items: center; */
|
||||
}
|
||||
|
||||
#map-ui #events-container #events #event-list {
|
||||
/* min-height: 100px; */
|
||||
max-height: calc(50% - 16px);
|
||||
margin: 8px 0;
|
||||
padding: 8px;
|
||||
background-color: #0002;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
/* transition: height 0.25s,
|
||||
min-height 0.25s,
|
||||
padding 0.25s,
|
||||
margin 0.25s; */
|
||||
#map-ui #events-container.minimized #events-header {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#map-ui #events-container #events.empty #event-list {
|
||||
|
@ -248,19 +239,23 @@ a {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
#map-ui #events-container #events #event-list,
|
||||
#map-ui #events-container #events-inspector #event-body {
|
||||
/* min-height: 100px; */
|
||||
max-height: calc(50% - 16px);
|
||||
margin: 8px 0;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
background-color: #0002;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#map-ui #events-container #events #events-header button,
|
||||
#map-ui #events-container #footer #footer-buttons button,
|
||||
#map-ui #events-container #events-inspector #events-header button:not(.link),
|
||||
#map-ui #events-container #events-minimized button,
|
||||
#map-ui #events-container #events-inspector-minimized button {
|
||||
#map-ui #events-container #events-inspector #events-header button:not(.link) {
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
|
@ -292,4 +287,14 @@ a {
|
|||
-webkit-mask-image: radial-gradient(circle, #fff0 0%, #fff0 33%, #ffff 33%, #ffff 66%, #fff0 66%, #fff0 100%);
|
||||
mask-image: radial-gradient(circle, #fff0 0%, #fff0 33%, #ffff 33%, #ffff 66%, #fff0 66%, #fff0 100%);
|
||||
animation: load 0.5s linear infinite;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
#map-ui #events-container #events,
|
||||
#map-ui #events-container #events-inspector {
|
||||
bottom: 0;
|
||||
border-radius: 4px 4px 0 0;
|
||||
width: 100%;
|
||||
max-height: 33vh;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
<button class="zoom-button" id="zoom-out" disabled>-</button>
|
||||
</div>
|
||||
<div id="floors" class="empty">
|
||||
<h1 class="widget-heading"></h1>
|
||||
<div id="floor-buttons">
|
||||
|
||||
</div>
|
||||
|
@ -32,19 +31,11 @@
|
|||
<h1 class="widget-heading" id="room-name"></h1>
|
||||
<p class="widget-description" id="room-description"></p>
|
||||
</div>
|
||||
<button id="minimize">_</button>
|
||||
</div>
|
||||
<div id="event-list">
|
||||
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-buttons">
|
||||
<button id="minimize">_</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="events-minimized">
|
||||
<button id="maximize">‾</button>
|
||||
<button id="back" disabled>↑</button>
|
||||
</div>
|
||||
<div id="events-inspector">
|
||||
<div id="events-header">
|
||||
|
@ -53,19 +44,11 @@
|
|||
<h1 class="widget-heading" id="room-name"></h1>
|
||||
<p class="widget-description subtitle" id="event-length"></p>
|
||||
</div>
|
||||
<button id="minimize">_</button>
|
||||
</div>
|
||||
<p class="widget-description" id="room-time"></p>
|
||||
<div id="event-body">
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-buttons">
|
||||
<button id="minimize">_</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="events-inspector-minimized">
|
||||
<button id="maximize">‾</button>
|
||||
<button id="back">←</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loading">
|
||||
|
|
|
@ -19,21 +19,14 @@ app.get('/data/:lang/events/:floor', async (req, res) => {
|
|||
else
|
||||
return res.status(400).send("Bad Request");
|
||||
|
||||
// Get localization
|
||||
let l10nReq = await fetch(new URL(`localization/${req.params.lang}.json`, config.data_url));
|
||||
let l10n;
|
||||
if (l10nReq.ok)
|
||||
l10n = await l10nReq.json();
|
||||
else
|
||||
return res.status(404).send("Localization not found!");
|
||||
|
||||
// Merge events and localization
|
||||
const lang = req.params.lang;
|
||||
const merged = events.map(event => {
|
||||
const localizationKey = l10n.__events[event.id];
|
||||
return {
|
||||
...event,
|
||||
...localizationKey
|
||||
};
|
||||
event.name = event.lang[lang]?.name ?? "";
|
||||
event.description = event.lang[lang]?.description ?? "";
|
||||
event.url = event.lang[lang]?.url ?? "";
|
||||
delete event.lang;
|
||||
return event;
|
||||
});
|
||||
|
||||
return res.send(merged);
|
||||
|
@ -48,21 +41,13 @@ app.get('/data/:lang/floors', async (req, res) => {
|
|||
else
|
||||
return res.status(400).send("Bad Request");
|
||||
|
||||
// Get localization
|
||||
let l10nReq = await fetch(new URL(`localization/${req.params.lang}.json`, config.data_url));
|
||||
let l10n;
|
||||
if (l10nReq.ok)
|
||||
l10n = await l10nReq.json();
|
||||
else
|
||||
return res.status(404).send("Localization not found!");
|
||||
|
||||
// Merge layers and localization
|
||||
const lang = req.params.lang;
|
||||
const merged = layers.map(layer => {
|
||||
const localizationKey = l10n.__layers[layer.id];
|
||||
return {
|
||||
...layer,
|
||||
...localizationKey
|
||||
};
|
||||
layer.name = layer.lang[lang]?.name ?? "";
|
||||
layer.description = layer.lang[lang]?.description ?? "";
|
||||
delete layer.lang;
|
||||
return layer;
|
||||
});
|
||||
|
||||
return res.send(merged);
|
||||
|
@ -77,21 +62,13 @@ app.get('/data/:lang/rooms/:floor', async (req, res) => {
|
|||
else
|
||||
return res.status(400).send("Bad Request");
|
||||
|
||||
// Get localization
|
||||
let l10nReq = await fetch(new URL(`localization/${req.params.lang}.json`, config.data_url));
|
||||
let l10n;
|
||||
if (l10nReq.ok)
|
||||
l10n = await l10nReq.json();
|
||||
else
|
||||
return res.status(404).send("Localization not found!");
|
||||
|
||||
// Merge rooms and localization
|
||||
const lang = req.params.lang;
|
||||
const merged = rooms.map(room => {
|
||||
const localizationKey = l10n.__rooms[room.id];
|
||||
return {
|
||||
...room,
|
||||
...localizationKey
|
||||
};
|
||||
room.name = room.lang[lang]?.name ?? "";
|
||||
room.description = room.lang[lang]?.description ?? "";
|
||||
delete room.lang;
|
||||
return room;
|
||||
});
|
||||
|
||||
return res.send(merged);
|
||||
|
@ -101,4 +78,6 @@ app.listen(config.port, () => {
|
|||
const listeningURL = new URL("http://localhost/");
|
||||
listeningURL.port = config.port;
|
||||
console.log(`Example app listening on ${listeningURL.toString()}`)
|
||||
})
|
||||
})
|
||||
|
||||
export default app;
|
Loading…
Reference in a new issue