search
This commit is contained in:
parent
2850588b58
commit
91235defd8
10 changed files with 736 additions and 57 deletions
|
@ -5,6 +5,19 @@ export class EventManager {
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
async getAllEvents() {
|
||||||
|
// DO NOT use this function for general use - may overload the server(s). get ONCE and then cache!
|
||||||
|
const currentLocalization = this.mainmanager.getCurrentLangCode();
|
||||||
|
|
||||||
|
let allEventsReqSend = fetch(`/data/${currentLocalization}/events/`);
|
||||||
|
|
||||||
|
let allEventsReq = await allEventsReqSend;
|
||||||
|
let allEvents;
|
||||||
|
if (allEventsReq.ok) allEvents = await allEventsReq.json();
|
||||||
|
|
||||||
|
return allEvents;
|
||||||
|
}
|
||||||
|
|
||||||
async getEvents() {
|
async getEvents() {
|
||||||
const currentLocalization = this.mainmanager.getCurrentLangCode();
|
const currentLocalization = this.mainmanager.getCurrentLangCode();
|
||||||
const currentFloor = this.mainmanager.getCurrentFocus("floor");
|
const currentFloor = this.mainmanager.getCurrentFocus("floor");
|
||||||
|
|
|
@ -12,6 +12,8 @@ export class GameObjManager {
|
||||||
font: "monospace",
|
font: "monospace",
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
maxFontWidth: 16,
|
maxFontWidth: 16,
|
||||||
|
floorOpacity: 0.75,
|
||||||
|
roomOpacity: 0.75,
|
||||||
};
|
};
|
||||||
|
|
||||||
mainmanager;
|
mainmanager;
|
||||||
|
@ -38,8 +40,8 @@ export class GameObjManager {
|
||||||
|
|
||||||
this.floorObject = this.map.kp.make([
|
this.floorObject = this.map.kp.make([
|
||||||
this.map.kp.polygon(polygon.pts),
|
this.map.kp.polygon(polygon.pts),
|
||||||
this.map.kp.outline(1, this.map.kp.BLACK),
|
|
||||||
this.map.kp.color(this.map.kp.Color.fromHex("303030")),
|
this.map.kp.color(this.map.kp.Color.fromHex("303030")),
|
||||||
|
this.map.kp.opacity(this.opts.floorOpacity),
|
||||||
this.map.kp.pos(),
|
this.map.kp.pos(),
|
||||||
this.map.kp.z(5),
|
this.map.kp.z(5),
|
||||||
]);
|
]);
|
||||||
|
@ -48,13 +50,19 @@ export class GameObjManager {
|
||||||
|
|
||||||
this.map.camBounds = bounds;
|
this.map.camBounds = bounds;
|
||||||
|
|
||||||
this.floorObject.onUpdate(() => {
|
|
||||||
const camScale = 1 / this.map.kp.camScale().y;
|
|
||||||
this.floorObject.outline.width = 8 * camScale;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.floorObject.onDraw(() => {
|
this.floorObject.onDraw(() => {
|
||||||
const camScale = 1 / this.map.kp.camScale().y;
|
const camScale = 1 / this.map.kp.camScale().y;
|
||||||
|
|
||||||
|
this.map.kp.drawPolygon({
|
||||||
|
pts: polygon.pts,
|
||||||
|
pos: this.map.kp.vec2(0),
|
||||||
|
fill: false,
|
||||||
|
outline: {
|
||||||
|
color: this.map.kp.Color.fromHex(this.opts.borderColor),
|
||||||
|
width: 8 * camScale,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
this.map.kp.drawText({
|
this.map.kp.drawText({
|
||||||
text: currentFloor.name,
|
text: currentFloor.name,
|
||||||
size: 24 * camScale,
|
size: 24 * camScale,
|
||||||
|
@ -120,7 +128,7 @@ export class GameObjManager {
|
||||||
const obj = this.map.kp.make([
|
const obj = this.map.kp.make([
|
||||||
this.map.kp.polygon(polygon.pts),
|
this.map.kp.polygon(polygon.pts),
|
||||||
this.map.kp.color(this.map.kp.Color.fromHex(this.opts.bgColor)),
|
this.map.kp.color(this.map.kp.Color.fromHex(this.opts.bgColor)),
|
||||||
this.map.kp.opacity(0.5),
|
this.map.kp.opacity(this.opts.roomOpacity),
|
||||||
this.map.kp.area(),
|
this.map.kp.area(),
|
||||||
this.map.kp.pos(),
|
this.map.kp.pos(),
|
||||||
this.map.kp.z(6),
|
this.map.kp.z(6),
|
||||||
|
@ -133,8 +141,6 @@ export class GameObjManager {
|
||||||
this.roomObjects.set(room.id, obj);
|
this.roomObjects.set(room.id, obj);
|
||||||
|
|
||||||
obj.onUpdate(() => {
|
obj.onUpdate(() => {
|
||||||
const camScale = 1 / this.map.kp.camScale().y;
|
|
||||||
|
|
||||||
const roomFocused = this.mainmanager.getCurrentFocus("room") == room.id;
|
const roomFocused = this.mainmanager.getCurrentFocus("room") == room.id;
|
||||||
|
|
||||||
if (roomFocused) {
|
if (roomFocused) {
|
||||||
|
|
|
@ -6,7 +6,10 @@ export default new Map([
|
||||||
date_starting: "Starting",
|
date_starting: "Starting",
|
||||||
date_started: "Started",
|
date_started: "Started",
|
||||||
date_summary: (prefix, time) => `${prefix} ${time}`,
|
date_summary: (prefix, time) => `${prefix} ${time}`,
|
||||||
|
list_index: (index) => `, ${index}`,
|
||||||
parenthesis: (content) => `(${content})`,
|
parenthesis: (content) => `(${content})`,
|
||||||
|
openParenthesis: "(",
|
||||||
|
closeParenthesis: ")",
|
||||||
separator: (p1, p2) => `${p1} - ${p2}`,
|
separator: (p1, p2) => `${p1} - ${p2}`,
|
||||||
hours_long: (hours) =>
|
hours_long: (hours) =>
|
||||||
hours == 1 ? `${hours} hour long` : `${hours} hours long`,
|
hours == 1 ? `${hours} hour long` : `${hours} hours long`,
|
||||||
|
@ -19,6 +22,22 @@ export default new Map([
|
||||||
event_inspector_header: (name) => `Event ${name}`,
|
event_inspector_header: (name) => `Event ${name}`,
|
||||||
event_inspector_back: "Return to events panel",
|
event_inspector_back: "Return to events panel",
|
||||||
event_inspector_minimize: "Toggle event inspector docking",
|
event_inspector_minimize: "Toggle event inspector docking",
|
||||||
|
zoom_in_button: "Zoom in",
|
||||||
|
zoom_out_button: "Zoom out",
|
||||||
|
menu_search_button: "Search events",
|
||||||
|
menu_language_button: "Change language",
|
||||||
|
menu_about_button: "About EventMapper",
|
||||||
|
search_dialog_close_button: "Close search",
|
||||||
|
search_dialog_search_button: "Run search",
|
||||||
|
search_dialog_header_title: "Search Events",
|
||||||
|
search_filters: {
|
||||||
|
name: ({ src }) => `Found by title`,
|
||||||
|
description: ({ src }) => `Found by description`,
|
||||||
|
url: ({ src }) => `Found by URL ${src}`,
|
||||||
|
floor: ({ src }) => `Found by floor ${src}`,
|
||||||
|
room: ({ src }) => `Found by room ${src}`,
|
||||||
|
},
|
||||||
|
regexAnyWordCharacter: /[^\w]/g,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { EventManager } from "./events.js";
|
||||||
import { FloorManager } from "./floors.js";
|
import { FloorManager } from "./floors.js";
|
||||||
import { GameObjManager } from "./gameobj.js";
|
import { GameObjManager } from "./gameobj.js";
|
||||||
import { LangManager } from "./lang.js";
|
import { LangManager } from "./lang.js";
|
||||||
|
import { TagManager } from "./tags.js";
|
||||||
import { UIManager } from "./ui.js";
|
import { UIManager } from "./ui.js";
|
||||||
|
|
||||||
export class EventMapperManager {
|
export class EventMapperManager {
|
||||||
|
@ -32,6 +33,9 @@ export class EventMapperManager {
|
||||||
this.floormanager = new FloorManager();
|
this.floormanager = new FloorManager();
|
||||||
this.floormanager.mainmanager = this;
|
this.floormanager.mainmanager = this;
|
||||||
|
|
||||||
|
this.tagmanager = new TagManager();
|
||||||
|
this.tagmanager.mainmanager = this;
|
||||||
|
|
||||||
this.uimanager = new UIManager(mapUi);
|
this.uimanager = new UIManager(mapUi);
|
||||||
this.uimanager.mainmanager = this;
|
this.uimanager.mainmanager = this;
|
||||||
|
|
||||||
|
@ -54,6 +58,14 @@ export class EventMapperManager {
|
||||||
|
|
||||||
this.uimanager.setLoading(true);
|
this.uimanager.setLoading(true);
|
||||||
|
|
||||||
|
await this.tagmanager.getTags();
|
||||||
|
|
||||||
|
this.uimanager.__updateSearchUI();
|
||||||
|
|
||||||
|
this.uimanager.setLoading(false);
|
||||||
|
|
||||||
|
this.uimanager.setLoading(true);
|
||||||
|
|
||||||
window.addEventListener("hashchange", () => this.hashchange());
|
window.addEventListener("hashchange", () => this.hashchange());
|
||||||
|
|
||||||
await this.hashchange();
|
await this.hashchange();
|
||||||
|
@ -113,6 +125,8 @@ export class EventMapperManager {
|
||||||
|
|
||||||
if (!this.uimanager.getEventsEmpty())
|
if (!this.uimanager.getEventsEmpty())
|
||||||
this.uimanager.setEventsMinimized(false);
|
this.uimanager.setEventsMinimized(false);
|
||||||
|
// this.uimanager.setSearchDialogOpen(false);
|
||||||
|
await this.uimanager.__updateSearch();
|
||||||
|
|
||||||
this.uimanager.setLoading(false);
|
this.uimanager.setLoading(false);
|
||||||
}
|
}
|
||||||
|
@ -127,6 +141,9 @@ export class EventMapperManager {
|
||||||
|
|
||||||
if (!this.uimanager.getEventsEmpty())
|
if (!this.uimanager.getEventsEmpty())
|
||||||
this.uimanager.setEventsMinimized(false);
|
this.uimanager.setEventsMinimized(false);
|
||||||
|
if (id != null) {
|
||||||
|
this.uimanager.setSearchDialogOpen(false);
|
||||||
|
}
|
||||||
this.uimanager.setEventsInspector(false);
|
this.uimanager.setEventsInspector(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +154,7 @@ export class EventMapperManager {
|
||||||
this.gameobjmanager.zoomToRoom(this.convertIdFocus(id, "room"));
|
this.gameobjmanager.zoomToRoom(this.convertIdFocus(id, "room"));
|
||||||
|
|
||||||
this.uimanager.updateInspector();
|
this.uimanager.updateInspector();
|
||||||
|
this.uimanager.setSearchDialogOpen(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.uimanager.setEventsInspector(id != null);
|
this.uimanager.setEventsInspector(id != null);
|
||||||
|
@ -294,6 +312,8 @@ export class EventMapperManager {
|
||||||
return this.eventmanager[func](...args);
|
return this.eventmanager[func](...args);
|
||||||
case "floor":
|
case "floor":
|
||||||
return this.floormanager[func](...args);
|
return this.floormanager[func](...args);
|
||||||
|
case "tag":
|
||||||
|
return this.tagmanager[func](...args);
|
||||||
case "ui":
|
case "ui":
|
||||||
return this.uimanager[func](...args);
|
return this.uimanager[func](...args);
|
||||||
case "gameobj":
|
case "gameobj":
|
||||||
|
@ -311,6 +331,8 @@ export class EventMapperManager {
|
||||||
return this.eventmanager[variable];
|
return this.eventmanager[variable];
|
||||||
case "floor":
|
case "floor":
|
||||||
return this.floormanager[variable];
|
return this.floormanager[variable];
|
||||||
|
case "tag":
|
||||||
|
return this.tagmanager[variable];
|
||||||
case "ui":
|
case "ui":
|
||||||
return this.uimanager[variable];
|
return this.uimanager[variable];
|
||||||
case "gameobj":
|
case "gameobj":
|
||||||
|
|
25
assets/scripts/KaplayMap/tags.js
Normal file
25
assets/scripts/KaplayMap/tags.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
export class TagManager {
|
||||||
|
mainmanager;
|
||||||
|
|
||||||
|
#tags = new Map([]);
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
async getTags() {
|
||||||
|
const currentLocalization = this.mainmanager.getCurrentLangCode();
|
||||||
|
|
||||||
|
let allTagsReqSend = fetch(`/data/${currentLocalization}/tags`);
|
||||||
|
|
||||||
|
let allTagsReq = await allTagsReqSend;
|
||||||
|
let allTags;
|
||||||
|
if (allTagsReq.ok) allTags = await allTagsReq.json();
|
||||||
|
|
||||||
|
this.#tags.clear();
|
||||||
|
|
||||||
|
allTags.forEach((tag) => this.#tags.set(tag.id, tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
get allTags() {
|
||||||
|
return this.#tags;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,10 @@ export class UIManager {
|
||||||
|
|
||||||
this.__initZoom();
|
this.__initZoom();
|
||||||
|
|
||||||
|
this.__initMenu();
|
||||||
|
|
||||||
|
this.__initSearchUI();
|
||||||
|
|
||||||
this.__initEvents();
|
this.__initEvents();
|
||||||
|
|
||||||
this.__initInspector();
|
this.__initInspector();
|
||||||
|
@ -61,8 +65,10 @@ export class UIManager {
|
||||||
setEventsInspector(state) {
|
setEventsInspector(state) {
|
||||||
if (
|
if (
|
||||||
state != this.uiElements.eventsContainer.classList.contains("inspector")
|
state != this.uiElements.eventsContainer.classList.contains("inspector")
|
||||||
)
|
) {
|
||||||
this.setEventsMinimized(false);
|
this.setEventsMinimized(false);
|
||||||
|
this.setSearchDialogOpen(false);
|
||||||
|
}
|
||||||
if (state) {
|
if (state) {
|
||||||
this.uiElements.eventsContainer.classList.add("inspector");
|
this.uiElements.eventsContainer.classList.add("inspector");
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,6 +76,15 @@ export class UIManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSearchDialogOpen(state) {
|
||||||
|
if (state) {
|
||||||
|
this.uiElements.searchDialogScrim.classList.add("open");
|
||||||
|
this.__updateSearch();
|
||||||
|
} else {
|
||||||
|
this.uiElements.searchDialogScrim.classList.remove("open");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getEventsEmpty() {
|
getEventsEmpty() {
|
||||||
return this.uiElements.events.classList.contains("empty");
|
return this.uiElements.events.classList.contains("empty");
|
||||||
}
|
}
|
||||||
|
@ -77,6 +92,8 @@ export class UIManager {
|
||||||
// Init
|
// Init
|
||||||
|
|
||||||
__initUIElements() {
|
__initUIElements() {
|
||||||
|
this.uiElements.controls = this.ui.querySelector("#controls");
|
||||||
|
|
||||||
// Zoom
|
// Zoom
|
||||||
this.uiElements.zoomButtons = this.ui.querySelector("#zoom");
|
this.uiElements.zoomButtons = this.ui.querySelector("#zoom");
|
||||||
this.uiElements.zoomIn =
|
this.uiElements.zoomIn =
|
||||||
|
@ -89,6 +106,12 @@ export class UIManager {
|
||||||
this.uiElements.floorButtons =
|
this.uiElements.floorButtons =
|
||||||
this.uiElements.floors.querySelector("#floor-buttons");
|
this.uiElements.floors.querySelector("#floor-buttons");
|
||||||
|
|
||||||
|
// Menu Bar
|
||||||
|
this.uiElements.menuBar = this.ui.querySelector("#menu-bar");
|
||||||
|
this.uiElements.menuBarSearch = this.ui.querySelector("#menu-search");
|
||||||
|
this.uiElements.menuBarLang = this.ui.querySelector("#menu-lang");
|
||||||
|
this.uiElements.menuBarAbout = this.ui.querySelector("#menu-about");
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
this.uiElements.eventsContainer =
|
this.uiElements.eventsContainer =
|
||||||
this.ui.querySelector("#events-container");
|
this.ui.querySelector("#events-container");
|
||||||
|
@ -126,11 +149,34 @@ export class UIManager {
|
||||||
this.uiElements.eventsInspectorMinimizeButton =
|
this.uiElements.eventsInspectorMinimizeButton =
|
||||||
this.uiElements.eventsInspector.querySelector("#minimize");
|
this.uiElements.eventsInspector.querySelector("#minimize");
|
||||||
|
|
||||||
|
// Search Dialog
|
||||||
|
this.uiElements.searchDialogScrim = this.ui.querySelector(
|
||||||
|
"#search-dialog-scrim"
|
||||||
|
);
|
||||||
|
this.uiElements.searchDialog =
|
||||||
|
this.uiElements.searchDialogScrim.querySelector("#search-dialog");
|
||||||
|
this.uiElements.searchDialogHeader =
|
||||||
|
this.uiElements.searchDialog.querySelector("#search-dialog-header");
|
||||||
|
this.uiElements.searchDialogHeaderClose =
|
||||||
|
this.uiElements.searchDialogHeader.querySelector("#close");
|
||||||
|
this.uiElements.searchDialogHeaderTitle =
|
||||||
|
this.uiElements.searchDialogHeader.querySelector("#search-dialog-title");
|
||||||
|
this.uiElements.searchDialogBar =
|
||||||
|
this.uiElements.searchDialog.querySelector("#search-dialog-bar");
|
||||||
|
this.uiElements.searchDialogBarInput =
|
||||||
|
this.uiElements.searchDialogBar.querySelector("#search-dialog-input");
|
||||||
|
this.uiElements.searchDialogTags =
|
||||||
|
this.uiElements.searchDialog.querySelector("#search-dialog-tags");
|
||||||
|
this.uiElements.searchDialogList =
|
||||||
|
this.uiElements.searchDialog.querySelector("#search-list");
|
||||||
|
|
||||||
// Loading
|
// Loading
|
||||||
this.uiElements.loading = this.ui.querySelector("#loading");
|
this.uiElements.loading = this.ui.querySelector("#loading");
|
||||||
}
|
}
|
||||||
|
|
||||||
__initZoom() {
|
__initZoom() {
|
||||||
|
const currentLocalization = this.mainmanager.getCurrentLocalization();
|
||||||
|
|
||||||
this.uiElements.zoomIn.addEventListener("click", () =>
|
this.uiElements.zoomIn.addEventListener("click", () =>
|
||||||
this.mainmanager.callManagerFunction("map", "zoomIn")
|
this.mainmanager.callManagerFunction("map", "zoomIn")
|
||||||
);
|
);
|
||||||
|
@ -146,6 +192,320 @@ export class UIManager {
|
||||||
this.mainmanager.addManagerEventListener("map", "zoom", () => {
|
this.mainmanager.addManagerEventListener("map", "zoom", () => {
|
||||||
this.setZoomDisabled(0);
|
this.setZoomDisabled(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.uiElements.zoomIn.title = currentLocalization.zoom_in_button;
|
||||||
|
this.uiElements.zoomOut.title = currentLocalization.zoom_out_button;
|
||||||
|
}
|
||||||
|
|
||||||
|
__initMenu() {
|
||||||
|
this.uiElements.menuBarSearch.addEventListener("click", () => {
|
||||||
|
this.setSearchDialogOpen(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.__updateMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
__updateMenu() {
|
||||||
|
const currentLocalization = this.mainmanager.getCurrentLocalization();
|
||||||
|
|
||||||
|
this.uiElements.menuBarSearch.title =
|
||||||
|
currentLocalization.menu_search_button;
|
||||||
|
this.uiElements.menuBarLang.title =
|
||||||
|
currentLocalization.menu_language_button;
|
||||||
|
this.uiElements.menuBarAbout.title = currentLocalization.menu_about_button;
|
||||||
|
}
|
||||||
|
|
||||||
|
__initSearchUI() {
|
||||||
|
this.uiElements.searchDialogHeaderClose.addEventListener("click", () => {
|
||||||
|
this.setSearchDialogOpen(false);
|
||||||
|
});
|
||||||
|
this.uiElements.searchDialogScrim.addEventListener("click", () => {
|
||||||
|
this.setSearchDialogOpen(false);
|
||||||
|
});
|
||||||
|
this.uiElements.searchDialog.addEventListener("click", (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
this.uiElements.searchDialogBarInput.addEventListener("input", () => {
|
||||||
|
this.__updateSearch();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#Search__selectedTags = [];
|
||||||
|
#Search__allEvents = null;
|
||||||
|
|
||||||
|
__updateSearchUI() {
|
||||||
|
const currentLocalization = this.mainmanager.getCurrentLocalization();
|
||||||
|
|
||||||
|
this.uiElements.searchDialogHeaderClose.title =
|
||||||
|
currentLocalization.search_dialog_close_button;
|
||||||
|
this.uiElements.searchDialogHeaderTitle.textContent =
|
||||||
|
currentLocalization.search_dialog_header_title;
|
||||||
|
|
||||||
|
const tags = this.mainmanager.getManagerVariable("tag", "allTags");
|
||||||
|
|
||||||
|
this.uiElements.searchDialogTags.replaceChildren();
|
||||||
|
|
||||||
|
tags.forEach((value, id) => {
|
||||||
|
const tagButton = document.createElement("button");
|
||||||
|
tagButton.classList.add("search-tag");
|
||||||
|
tagButton.textContent = value.name;
|
||||||
|
tagButton.title = value.description;
|
||||||
|
tagButton.id = "tag-" + id;
|
||||||
|
tagButton.addEventListener("click", () => this.__updateTagState(id));
|
||||||
|
|
||||||
|
this.uiElements.searchDialogTags.appendChild(tagButton);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
__updateTagState(tag) {
|
||||||
|
const tags = this.mainmanager.getManagerVariable("tag", "allTags");
|
||||||
|
|
||||||
|
const tagPos = this.#Search__selectedTags.indexOf(tag);
|
||||||
|
if (tagPos >= 0) this.#Search__selectedTags.splice(tagPos, 1);
|
||||||
|
else this.#Search__selectedTags.push(tag);
|
||||||
|
|
||||||
|
this.#Search__selectedTags = this.#Search__selectedTags.filter(
|
||||||
|
(val) =>
|
||||||
|
val == tag || tags.get(val).radiogroup != tags.get(tag).radiogroup
|
||||||
|
);
|
||||||
|
|
||||||
|
this.__updateSearchUISoft();
|
||||||
|
this.__updateSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
__updateSearchUISoft() {
|
||||||
|
const tags = this.mainmanager.getManagerVariable("tag", "allTags");
|
||||||
|
|
||||||
|
tags.forEach((_, id) => {
|
||||||
|
const child = this.uiElements.searchDialogTags.querySelector(
|
||||||
|
"#tag-" + id
|
||||||
|
);
|
||||||
|
if (this.#Search__selectedTags.includes(id))
|
||||||
|
child.classList.add("selected");
|
||||||
|
else child.classList.remove("selected");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async __initSearch() {
|
||||||
|
// Runs on first search, as to not make the client wait too long when starting EventMapper (loading the same thing twice)
|
||||||
|
this.setLoading(true);
|
||||||
|
this.#Search__allEvents = await this.mainmanager.callManagerFunction(
|
||||||
|
"event",
|
||||||
|
"getAllEvents"
|
||||||
|
);
|
||||||
|
this.setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
async __updateSearch() {
|
||||||
|
const currentLocalization = this.mainmanager.getCurrentLocalization();
|
||||||
|
if (this.#Search__allEvents == null) await this.__initSearch();
|
||||||
|
|
||||||
|
const searchTransform = (x) =>
|
||||||
|
x.toLowerCase().replace(currentLocalization.regexAnyWordCharacter, "");
|
||||||
|
|
||||||
|
const searchValue = searchTransform(
|
||||||
|
this.uiElements.searchDialogBarInput.value
|
||||||
|
);
|
||||||
|
|
||||||
|
let whatFilter = [];
|
||||||
|
let filteredEvents = this.#Search__allEvents.filter((event) => {
|
||||||
|
if (searchValue.length < 1) {
|
||||||
|
whatFilter.push(null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// First, filter by text
|
||||||
|
if (searchTransform(event.name).includes(searchValue)) {
|
||||||
|
whatFilter.push({
|
||||||
|
type: "name",
|
||||||
|
src: event.name,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (searchTransform(event.description).includes(searchValue)) {
|
||||||
|
whatFilter.push({
|
||||||
|
type: "description",
|
||||||
|
src: event.description,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (searchTransform(event.url).includes(searchValue)) {
|
||||||
|
whatFilter.push({
|
||||||
|
type: "url",
|
||||||
|
src: event.url,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Filter by room/floor
|
||||||
|
const eventFloorId = this.mainmanager.convertIdFocus(event.id, "floor");
|
||||||
|
const eventFloor = this.mainmanager
|
||||||
|
.getAllFocusObject("floor")
|
||||||
|
.get(eventFloorId);
|
||||||
|
|
||||||
|
if (eventFloor != null) {
|
||||||
|
if (searchTransform(eventFloor.name).includes(searchValue)) {
|
||||||
|
whatFilter.push({
|
||||||
|
type: "floor",
|
||||||
|
src: eventFloor.name,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (searchTransform(eventFloorId).includes(searchValue)) {
|
||||||
|
whatFilter.push({
|
||||||
|
type: "floor",
|
||||||
|
src: eventFloorId,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventRoomId = this.mainmanager.convertIdFocus(event.id, "room");
|
||||||
|
const eventRoom = this.mainmanager
|
||||||
|
.getAllFocusObject("room")
|
||||||
|
.get(eventRoomId);
|
||||||
|
|
||||||
|
if (eventRoom != null) {
|
||||||
|
if (searchTransform(eventRoom.name).includes(searchValue)) {
|
||||||
|
whatFilter.push({
|
||||||
|
type: "room",
|
||||||
|
src: eventRoom.name,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (searchTransform(eventRoomId).includes(searchValue)) {
|
||||||
|
whatFilter.push({
|
||||||
|
type: "room",
|
||||||
|
src: eventRoomId,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.#Search__selectedTags.length > 0)
|
||||||
|
filteredEvents = filteredEvents.filter((event, idx) => {
|
||||||
|
return this.#Search__selectedTags.every((tag) =>
|
||||||
|
event.tags.includes(tag)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.uiElements.searchDialogList.replaceChildren();
|
||||||
|
const currentDate = new Date();
|
||||||
|
filteredEvents.forEach((event, idx) => {
|
||||||
|
const eventFloorId = this.mainmanager.convertIdFocus(event.id, "floor");
|
||||||
|
const eventDateStart = new Date(event.when.start);
|
||||||
|
const eventDateEnd = new Date(event.when.end);
|
||||||
|
|
||||||
|
const filterReason = whatFilter[idx];
|
||||||
|
|
||||||
|
const eventStarted = currentDate > eventDateStart;
|
||||||
|
const eventEnded = currentDate > eventDateEnd;
|
||||||
|
|
||||||
|
let datePrefix;
|
||||||
|
|
||||||
|
if (eventEnded) {
|
||||||
|
return; // Don't display this event
|
||||||
|
} else if (eventStarted) {
|
||||||
|
datePrefix = currentLocalization.date_started;
|
||||||
|
} else {
|
||||||
|
datePrefix = currentLocalization.date_starting;
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventListContainer = document.createElement("div");
|
||||||
|
eventListContainer.classList.add("event-list-container");
|
||||||
|
eventListContainer.id = "event-" + event.id;
|
||||||
|
|
||||||
|
const eventListContainerSummary = document.createElement("p");
|
||||||
|
|
||||||
|
if (filterReason != null) {
|
||||||
|
const eventListContainerSummaryReason = document.createElement("small");
|
||||||
|
eventListContainerSummaryReason.textContent =
|
||||||
|
currentLocalization.search_filters[filterReason.type](filterReason);
|
||||||
|
eventListContainerSummaryReason.classList.add("reason");
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(eventListContainerSummaryReason);
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(document.createElement("br"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventListContainerSummaryName = document.createElement("a");
|
||||||
|
eventListContainerSummaryName.href = "#" + event.id;
|
||||||
|
eventListContainerSummaryName.textContent = event.name;
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(eventListContainerSummaryName);
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(document.createTextNode(" "));
|
||||||
|
|
||||||
|
if (this.mainmanager.getCurrentFocus("floor") != eventFloorId) {
|
||||||
|
const eventFloor = this.mainmanager
|
||||||
|
.getAllFocusObject("floor")
|
||||||
|
.get(eventFloorId);
|
||||||
|
|
||||||
|
const eventListContainerSummaryFloor = document.createElement("a");
|
||||||
|
eventListContainerSummaryFloor.href = "#" + eventFloorId;
|
||||||
|
eventListContainerSummaryFloor.textContent =
|
||||||
|
currentLocalization.parenthesis(eventFloor?.name ?? eventFloorId);
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(eventListContainerSummaryFloor);
|
||||||
|
} else {
|
||||||
|
const eventRoomId = this.mainmanager.convertIdFocus(event.id, "room");
|
||||||
|
const eventRoom = this.mainmanager
|
||||||
|
.getAllFocusObject("room")
|
||||||
|
.get(eventRoomId);
|
||||||
|
|
||||||
|
const eventListContainerSummaryRoom = document.createElement("a");
|
||||||
|
eventListContainerSummaryRoom.href = "#" + eventRoomId;
|
||||||
|
eventListContainerSummaryRoom.textContent =
|
||||||
|
currentLocalization.parenthesis(eventRoom?.name ?? eventRoomId);
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(eventListContainerSummaryRoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(document.createElement("br"));
|
||||||
|
|
||||||
|
const eventListContainerSummarySmall = document.createElement("small");
|
||||||
|
|
||||||
|
const eventListContainerSummaryTime = document.createElement("span");
|
||||||
|
eventListContainerSummaryTime.classList.add("clarification");
|
||||||
|
eventListContainerSummaryTime.title = eventDateStart.toLocaleString(
|
||||||
|
this.mainmanager.getCurrentLangCode(),
|
||||||
|
{
|
||||||
|
dateStyle: "short",
|
||||||
|
timeStyle: "short",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
eventListContainerSummaryTime.textContent =
|
||||||
|
currentLocalization.date_summary(
|
||||||
|
datePrefix,
|
||||||
|
getRelativeTime(
|
||||||
|
eventDateStart,
|
||||||
|
currentDate,
|
||||||
|
this.mainmanager.getCurrentLangCode()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
eventListContainerSummarySmall.appendChild(eventListContainerSummaryTime);
|
||||||
|
|
||||||
|
eventListContainerSummarySmall.appendChild(document.createTextNode(" "));
|
||||||
|
|
||||||
|
const eventListContainerSummaryLength = document.createElement("span");
|
||||||
|
eventListContainerSummaryLength.textContent =
|
||||||
|
currentLocalization.parenthesis(
|
||||||
|
currentLocalization.minutes_long(
|
||||||
|
getMinutesDifference(eventDateStart, eventDateEnd)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
eventListContainerSummarySmall.appendChild(
|
||||||
|
eventListContainerSummaryLength
|
||||||
|
);
|
||||||
|
|
||||||
|
eventListContainerSummary.appendChild(eventListContainerSummarySmall);
|
||||||
|
|
||||||
|
eventListContainer.appendChild(eventListContainerSummary);
|
||||||
|
|
||||||
|
this.uiElements.searchDialogList.appendChild(eventListContainer);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
__initInspector() {
|
__initInspector() {
|
||||||
|
@ -213,8 +573,7 @@ export class UIManager {
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
const eventWhere = document.createElement("a");
|
const eventWhere = document.createElement("span");
|
||||||
eventWhere.href = "#" + eventRoom.id;
|
|
||||||
eventWhere.textContent = eventRoom.name;
|
eventWhere.textContent = eventRoom.name;
|
||||||
|
|
||||||
this.uiElements.eventsInspectorEventLength.appendChild(eventWhere);
|
this.uiElements.eventsInspectorEventLength.appendChild(eventWhere);
|
||||||
|
@ -416,9 +775,10 @@ export class UIManager {
|
||||||
this.uiElements.floorButtons.replaceChildren();
|
this.uiElements.floorButtons.replaceChildren();
|
||||||
|
|
||||||
// Put them back
|
// Put them back
|
||||||
currentFloors.forEach(({ name }, id) => {
|
currentFloors.forEach(({ name, shortName }, id) => {
|
||||||
const floorButton = document.createElement("button");
|
const floorButton = document.createElement("button");
|
||||||
floorButton.textContent = name;
|
floorButton.textContent = shortName;
|
||||||
|
floorButton.title = name;
|
||||||
floorButton.classList.add("floor-button");
|
floorButton.classList.add("floor-button");
|
||||||
floorButton.id = "floor-" + id;
|
floorButton.id = "floor-" + id;
|
||||||
if (id === mainFocus) floorButton.classList.add("selected");
|
if (id === mainFocus) floorButton.classList.add("selected");
|
||||||
|
@ -430,16 +790,15 @@ export class UIManager {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (currentFloors.size < 1) {
|
if (currentFloors.size < 1) {
|
||||||
this.uiElements.floors.classList.add("empty");
|
this.uiElements.controls.classList.add("empty");
|
||||||
this.floorsEmpty = true;
|
this.floorsEmpty = true;
|
||||||
} else {
|
} else {
|
||||||
this.uiElements.floors.classList.remove("empty");
|
this.uiElements.controls.classList.remove("empty");
|
||||||
this.floorsEmpty = false;
|
this.floorsEmpty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__updateFloorsSoft() {
|
__updateFloorsSoft() {
|
||||||
const currentLocalization = this.mainmanager.getCurrentLocalization();
|
|
||||||
const currentFloors = this.mainmanager.getAllFocusObject("floor");
|
const currentFloors = this.mainmanager.getAllFocusObject("floor");
|
||||||
const mainFocus = this.mainmanager.getCurrentFocus("floor");
|
const mainFocus = this.mainmanager.getCurrentFocus("floor");
|
||||||
|
|
||||||
|
|
90
assets/styles/dialog.css
Normal file
90
assets/styles/dialog.css
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/* I fell into a burning ring of fire / Went down down down / And the flames went higher */
|
||||||
|
#search-dialog-scrim {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #0008;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: opacity 0.125s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog-scrim.open {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: all;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #202020;
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: 0 0 8px 0 #0008;
|
||||||
|
flex-direction: column;
|
||||||
|
width: calc(100% - 16px);
|
||||||
|
max-width: 624px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-dialog-header {
|
||||||
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
|
grid-template-columns: auto 36px;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-dialog-bar {
|
||||||
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-dialog-tags {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-dialog-tags .search-tag {
|
||||||
|
white-space: nowrap;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-dialog-tags .search-tag.selected {
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-list {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-list .event-list-container p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-dialog #search-list .event-list-container p .reason {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
body, html {
|
body, html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -42,6 +42,7 @@ button:not(.link) {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border: 1px solid #0008;
|
border: 1px solid #0008;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:not(.link):hover {
|
button:not(.link):hover {
|
||||||
|
@ -68,6 +69,23 @@ button.link {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button:not(.link):focus,
|
||||||
|
input:focus {
|
||||||
|
outline: 1px solid #808080;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background-color: #0004;
|
||||||
|
border: none;
|
||||||
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 36px;
|
||||||
|
border: 1px solid #0008;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: currentColor;
|
color: currentColor;
|
||||||
}
|
}
|
||||||
|
@ -85,25 +103,39 @@ a {
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#map-ui #controls {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #fff4;
|
||||||
|
border-radius: 0 0 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#map-ui #controls.empty {
|
||||||
|
right: -100%;
|
||||||
|
}
|
||||||
|
|
||||||
#map-ui #zoom {
|
#map-ui #zoom {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
position: absolute;
|
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
top: 16px;
|
|
||||||
left: 16px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: #202020;
|
background-color: #202020;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: 0 0 8px 0 #0008;
|
box-shadow: 0 0 8px 0 #0008;
|
||||||
|
transition: left 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#map-ui #zoom .zoom-button {
|
#map-ui #zoom .zoom-button {
|
||||||
|
@ -114,19 +146,12 @@ a {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: absolute;
|
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
top: 16px;
|
|
||||||
right: 16px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: #202020;
|
background-color: #202020;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: 0 0 8px 0 #0008;
|
box-shadow: 0 0 8px 0 #0008;
|
||||||
transition: right 0.5s;
|
transition: left 0.5s;
|
||||||
}
|
|
||||||
|
|
||||||
#map-ui #floors.empty {
|
|
||||||
right: -100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#map-ui #floors #floor-buttons {
|
#map-ui #floors #floor-buttons {
|
||||||
|
@ -145,6 +170,27 @@ a {
|
||||||
border: 1px solid #fff;
|
border: 1px solid #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#map-ui #menu-bar {
|
||||||
|
position: absolute;
|
||||||
|
left: 8px;
|
||||||
|
top: 8px;
|
||||||
|
pointer-events: all;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #202020;
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: 0 0 8px 0 #0008;
|
||||||
|
transition: left 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#map-ui #menu-bar .menu-button {
|
||||||
|
width: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
#map-ui #events-container {
|
#map-ui #events-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -156,13 +202,14 @@ a {
|
||||||
#map-ui #events-container #events,
|
#map-ui #events-container #events,
|
||||||
#map-ui #events-container #events-inspector {
|
#map-ui #events-container #events-inspector {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
/* user-select: text; */
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
left: 16px;
|
left: 8px;
|
||||||
bottom: 16px;
|
bottom: 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
translate: 0 calc(100% + 32px);
|
translate: 0 calc(100% + 32px);
|
||||||
background-color: #202020;
|
background-color: #202020;
|
||||||
|
@ -172,7 +219,7 @@ a {
|
||||||
max-height: calc(50vh - 16px);
|
max-height: calc(50vh - 16px);
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
max-width: calc(100% - 32px);
|
max-width: calc(100% - 16px);
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +316,7 @@ a {
|
||||||
background-color: #2228;
|
background-color: #2228;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
z-index: 1000;
|
||||||
transition: opacity 0.25s;
|
transition: opacity 0.25s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,18 +10,29 @@
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="/assets/styles/style.css"
|
href="/assets/styles/style.css"
|
||||||
/>
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="/assets/styles/dialog.css"
|
||||||
|
/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="map"></canvas>
|
<canvas id="map"></canvas>
|
||||||
<div id="map-ui" class="loading">
|
<div id="map-ui" class="loading">
|
||||||
<div id="zoom">
|
<div id="controls" class="empty">
|
||||||
<button class="zoom-button" id="zoom-in">+</button>
|
<div id="zoom">
|
||||||
<button class="zoom-button" id="zoom-out" disabled>-</button>
|
<button class="zoom-button" id="zoom-in">+</button>
|
||||||
</div>
|
<button class="zoom-button" id="zoom-out" disabled>-</button>
|
||||||
<div id="floors" class="empty">
|
|
||||||
<div id="floor-buttons">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div id="floors">
|
||||||
|
<div id="floor-buttons">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="menu-bar">
|
||||||
|
<button class="menu-button" id="menu-search">Sc</button>
|
||||||
|
<button class="menu-button" id="menu-lang">Ln</button>
|
||||||
|
<button class="menu-button" id="menu-about">(i)</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="events-container" class="empty">
|
<div id="events-container" class="empty">
|
||||||
<div id="events">
|
<div id="events">
|
||||||
|
@ -51,6 +62,24 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="search-dialog-scrim">
|
||||||
|
<div id="search-dialog">
|
||||||
|
<div id="search-dialog-header">
|
||||||
|
<div>
|
||||||
|
<h1 class="widget-heading" id="search-dialog-title"></h1>
|
||||||
|
</div>
|
||||||
|
<button id="close">X</button>
|
||||||
|
</div>
|
||||||
|
<div id="search-dialog-bar">
|
||||||
|
<input type="text" id="search-dialog-input" />
|
||||||
|
</div>
|
||||||
|
<div id="search-dialog-tags">
|
||||||
|
</div>
|
||||||
|
<div id="search-list">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
<div id="loading-circle">
|
<div id="loading-circle">
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,48 @@ app.get('/data/:lang/events/:floor', async (req, res) => {
|
||||||
// Merge events and localization
|
// Merge events and localization
|
||||||
const lang = req.params.lang;
|
const lang = req.params.lang;
|
||||||
const merged = events.map(event => {
|
const merged = events.map(event => {
|
||||||
event.name = event.lang[lang]?.name ?? "";
|
const curLang = event.lang[lang] ?? event.lang[config.default_language];
|
||||||
event.description = event.lang[lang]?.description ?? "";
|
|
||||||
event.url = event.lang[lang]?.url ?? "";
|
event.name = curLang.name ?? "";
|
||||||
|
event.description = curLang.description ?? "";
|
||||||
|
event.url = curLang.url ?? "";
|
||||||
|
delete event.lang;
|
||||||
|
return event;
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.send(merged);
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get('/data/:lang/events/', async (req, res) => {
|
||||||
|
// Get floors
|
||||||
|
let floorsReq = await fetch(new URL("floors.json", config.data_url));
|
||||||
|
let floors;
|
||||||
|
if (floorsReq.ok)
|
||||||
|
floors = await floorsReq.json();
|
||||||
|
else
|
||||||
|
return res.status(400).send("Bad Request");
|
||||||
|
|
||||||
|
let allEvents = [];
|
||||||
|
|
||||||
|
await Promise.allSettled(floors.map(async (curFloor) => {
|
||||||
|
let eventsReq = await fetch(new URL(`events/${curFloor.id}.json`, config.data_url));
|
||||||
|
let events;
|
||||||
|
if (eventsReq.ok)
|
||||||
|
events = await eventsReq.json();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
|
||||||
|
allEvents = allEvents.concat(events);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Merge events and localization
|
||||||
|
const lang = req.params.lang;
|
||||||
|
const merged = allEvents.map(event => {
|
||||||
|
const curLang = event.lang[lang] ?? event.lang[config.default_language];
|
||||||
|
|
||||||
|
event.name = curLang.name ?? "";
|
||||||
|
event.description = curLang.description ?? "";
|
||||||
|
event.url = curLang.url ?? "";
|
||||||
delete event.lang;
|
delete event.lang;
|
||||||
return event;
|
return event;
|
||||||
});
|
});
|
||||||
|
@ -33,21 +72,48 @@ app.get('/data/:lang/events/:floor', async (req, res) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get('/data/:lang/floors', async (req, res) => {
|
app.get('/data/:lang/floors', async (req, res) => {
|
||||||
// Get layers
|
// Get floors
|
||||||
let layersReq = await fetch(new URL("floors.json", config.data_url));
|
let floorsReq = await fetch(new URL("floors.json", config.data_url));
|
||||||
let layers;
|
let floors;
|
||||||
if (layersReq.ok)
|
if (floorsReq.ok)
|
||||||
layers = await layersReq.json();
|
floors = await floorsReq.json();
|
||||||
else
|
else
|
||||||
return res.status(400).send("Bad Request");
|
return res.status(400).send("Bad Request");
|
||||||
|
|
||||||
// Merge layers and localization
|
// Merge floors and localization
|
||||||
const lang = req.params.lang;
|
const lang = req.params.lang;
|
||||||
const merged = layers.map(layer => {
|
const merged = floors.map(floor => {
|
||||||
layer.name = layer.lang[lang]?.name ?? "";
|
const curLang = floor.lang[lang] ?? floor.lang[config.default_language];
|
||||||
layer.description = layer.lang[lang]?.description ?? "";
|
|
||||||
delete layer.lang;
|
floor.name = curLang.name ?? "";
|
||||||
return layer;
|
floor.shortName = curLang.shortName ?? "";
|
||||||
|
floor.description = curLang.description ?? "";
|
||||||
|
delete floor.lang;
|
||||||
|
return floor;
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.send(merged);
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get('/data/:lang/tags', async (req, res) => {
|
||||||
|
// Get tags
|
||||||
|
let tagsReq = await fetch(new URL("tags.json", config.data_url));
|
||||||
|
let tags;
|
||||||
|
if (tagsReq.ok)
|
||||||
|
tags = await tagsReq.json();
|
||||||
|
else
|
||||||
|
return res.status(400).send("Bad Request");
|
||||||
|
|
||||||
|
// Merge floors and localization
|
||||||
|
const lang = req.params.lang;
|
||||||
|
const merged = tags.map(tag => {
|
||||||
|
const curLang = tag.lang[lang] ?? tag.lang[config.default_language];
|
||||||
|
|
||||||
|
tag.name = curLang.name ?? "";
|
||||||
|
tag.shortName = curLang.shortName ?? "";
|
||||||
|
tag.description = curLang.description ?? "";
|
||||||
|
delete tag.lang;
|
||||||
|
return tag;
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.send(merged);
|
return res.send(merged);
|
||||||
|
@ -65,9 +131,11 @@ app.get('/data/:lang/rooms/:floor', async (req, res) => {
|
||||||
// Merge rooms and localization
|
// Merge rooms and localization
|
||||||
const lang = req.params.lang;
|
const lang = req.params.lang;
|
||||||
const merged = rooms.map(room => {
|
const merged = rooms.map(room => {
|
||||||
room.name = room.lang[lang]?.name ?? "";
|
const curLang = room.lang[lang] ?? room.lang[config.default_language];
|
||||||
room.shortName = room.lang[lang]?.shortName ?? "";
|
|
||||||
room.description = room.lang[lang]?.description ?? "";
|
room.name = curLang.name ?? "";
|
||||||
|
room.shortName = curLang.shortName ?? "";
|
||||||
|
room.description = curLang.description ?? "";
|
||||||
delete room.lang;
|
delete room.lang;
|
||||||
return room;
|
return room;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue