-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1799d55
commit f2e10b4
Showing
14 changed files
with
390 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
-- CreateTable | ||
CREATE TABLE `Door` ( | ||
`map_id` INTEGER UNSIGNED NOT NULL, | ||
`room1_id` INTEGER UNSIGNED NOT NULL, | ||
`room2_id` INTEGER UNSIGNED NOT NULL, | ||
|
||
PRIMARY KEY (`map_id`, `room1_id`, `room2_id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `Door` ADD CONSTRAINT `Door_map_id_fkey` FOREIGN KEY (`map_id`) REFERENCES `Map`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `Door` ADD CONSTRAINT `Door_map_id_room1_id_fkey` FOREIGN KEY (`map_id`, `room1_id`) REFERENCES `Room`(`map_id`, `id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `Door` ADD CONSTRAINT `Door_map_id_room2_id_fkey` FOREIGN KEY (`map_id`, `room2_id`) REFERENCES `Room`(`map_id`, `id`) ON DELETE RESTRICT ON UPDATE CASCADE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
<script lang="ts"> | ||
import { onMount } from "svelte"; | ||
import { ICON_SIZE, SVG_NS } from "$lib/constants"; | ||
let container: HTMLElement; | ||
let svg: SVGSVGElement; | ||
export function getSVG() { | ||
return svg; | ||
} | ||
export function getElmWhere( | ||
dataName: string, | ||
dataValue: number, | ||
): SVGGraphicsElement | null { | ||
return svg.querySelector(`[data-${dataName}='${dataValue}']`); | ||
} | ||
export function getRoom(id: number): SVGGraphicsElement | null { | ||
return getElmWhere("room", id) as SVGGraphicsElement; | ||
} | ||
export function getLabelsFor(roomId: number): IterableIterator<HTMLElement> | null { | ||
return svg | ||
.querySelectorAll(`[data-label-for='${roomId}']`) | ||
.values() as IterableIterator<HTMLElement>; | ||
} | ||
export function removeIcon(icon: SVGImageElement) { | ||
if (icon.parentElement && icon.parentElement.childElementCount === 1) { | ||
const labels = getLabelsFor(Number(icon.parentElement.dataset.iconFor)); | ||
if (labels) { | ||
for (const label of labels) { | ||
label.style.display = "block"; | ||
} | ||
} | ||
} | ||
icon.remove(); | ||
} | ||
export function getCenterOf(roomId: number) { | ||
const room = getRoom(roomId); | ||
if (!room) return; | ||
const roomBBox = room.getBBox(); | ||
let center = new DOMPoint( | ||
roomBBox.x + roomBBox.width / 2, | ||
roomBBox.y + roomBBox.height / 2, | ||
); | ||
const roomCTM = room.getCTM(); | ||
const svgCTM = svg.getCTM(); | ||
if (roomCTM && svgCTM) { | ||
center = center.matrixTransform(svgCTM.inverse().multiply(roomCTM)); | ||
} | ||
return center; | ||
} | ||
export function addIconTo(roomId: number, iconSrc: string) { | ||
const center = getCenterOf(roomId); | ||
if (!center) return; | ||
const labels = getLabelsFor(roomId); | ||
if (labels) { | ||
for (const label of labels) { | ||
label.style.display = "none"; | ||
} | ||
} | ||
let iconContainer = getElmWhere("icon-for", roomId); | ||
if (!iconContainer) { | ||
iconContainer = svg.appendChild(document.createElementNS(SVG_NS, "g")); | ||
iconContainer.dataset.iconFor = roomId.toString(); | ||
} | ||
const icon = document.createElementNS(SVG_NS, "image"); | ||
icon.href.baseVal = iconSrc; | ||
icon.setAttribute("width", ICON_SIZE.toString()); | ||
icon.setAttribute("height", ICON_SIZE.toString()); | ||
iconContainer.appendChild(icon); | ||
const iconContainerBBox = iconContainer.getBBox(); | ||
center.x -= iconContainerBBox.width / 2; | ||
center.y -= iconContainerBBox.height / 2; | ||
iconContainer.setAttribute( | ||
"transform", | ||
`translate(${center.x}, ${center.y})`, | ||
); | ||
return icon; | ||
} | ||
export let mapData: string | undefined; | ||
export let onSuccess = () => {}; | ||
export let onError = (message: string) => { | ||
(container || document.body).appendChild( | ||
document.createTextNode("Error: "+message), | ||
); | ||
}; | ||
export let onClickRoom: ((clickedRoom: number) => void) | undefined | ||
onMount(() => { | ||
if (mapData) { | ||
const tempMapContainer = document.getElementById("map-container"); | ||
if (!tempMapContainer) onError("Failed to get map container"); | ||
container = tempMapContainer!; | ||
const tempMapElm = new DOMParser().parseFromString( | ||
mapData, | ||
"image/svg+xml", | ||
).documentElement; | ||
if (tempMapElm instanceof SVGSVGElement) { | ||
svg = container.appendChild(tempMapElm); | ||
svg.addEventListener("click", event => { | ||
if (onClickRoom && event.target instanceof SVGElement) { | ||
let clickedRoom = event.target.dataset.room || event.target.parentElement?.dataset.room; | ||
if (clickedRoom) onClickRoom(+clickedRoom); | ||
} | ||
}); | ||
onSuccess(); | ||
} else { | ||
onError("Invalid map! Must be SVG."); | ||
} | ||
} else { | ||
onError("Not given any map data"); | ||
} | ||
}); | ||
</script> | ||
|
||
<div id="map-container"></div> | ||
|
||
<svelte:head> | ||
<style> | ||
body { | ||
margin: 0; | ||
} | ||
#map-container { | ||
height: 100vh; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
[data-room]:hover { | ||
filter: brightness(1.5); | ||
cursor: pointer; | ||
} | ||
[data-label-for], | ||
[data-icon-for] { | ||
pointer-events: none; | ||
} | ||
</style> | ||
</svelte:head> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
export const SESSION_COOKIE_KEY = "session"; | ||
export const SESSION_DURATION_DAYS = 7; | ||
export const ICON_SIZE = 16; | ||
export const SVG_NS = "http://www.w3.org/2000/svg"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import prisma from "$lib/prisma"; | ||
|
||
export function getMapFor(user: { school_id: number }) { | ||
return prisma.map.findFirst({ | ||
where: { | ||
creator: { | ||
school_id: user.school_id, | ||
}, | ||
}, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,20 @@ | ||
import type { LayoutServerLoad } from "./$types"; | ||
import type { User } from "@prisma/client"; | ||
import { getMapFor } from "$lib/get-map-for"; | ||
|
||
type props = { | ||
user: User; | ||
map_id?: number; | ||
map?: string; | ||
}; | ||
export const load: LayoutServerLoad = async ({ locals }) => { | ||
return { | ||
const data: props = { | ||
user: locals.user, | ||
}; | ||
const map = await getMapFor(locals.user); | ||
if (map) { | ||
data.map_id = map.id; | ||
data.map = await (await fetch(map.img_url)).text(); | ||
} | ||
return data; | ||
}; |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.