diff --git a/public/static/css/game.css b/public/static/css/game.css index 28f2d7d..4081aa9 100644 --- a/public/static/css/game.css +++ b/public/static/css/game.css @@ -4,7 +4,7 @@ z-index: 1; } -#cover { +#guessCover { position: absolute; top: 40px; left: 0; diff --git a/public/static/css/map_editor.css b/public/static/css/map_editor.css index b173251..46338ec 100644 --- a/public/static/css/map_editor.css +++ b/public/static/css/map_editor.css @@ -1,17 +1,3 @@ -#metadata { - position: absolute; - top: 50px; - left: 10px; - padding: 10px; - background-color: #eeeeee; - border: solid 1px #555555; - border-radius: 3px; - box-sizing: border-box; - opacity: 0.95; - z-index: 2; - visibility: hidden; -} - #map { width: 100%; height: calc(100% - 40px); @@ -61,9 +47,6 @@ } @media screen and (max-width: 999px) and (min-height: 600px) { - #metadata { - width: calc(100% - 155px); - } #map.selected { height: calc(50% - 20px); } @@ -79,12 +62,6 @@ } @media screen and (min-width: 1000px), (max-height: 599px) { - #metadata { - width: calc(50% - 20px); - } - #metadata.selected { - top: 95px; - } #map.selected { width: 50%; } diff --git a/public/static/css/mapguesser.css b/public/static/css/mapguesser.css index bddb9f4..1fec7b8 100644 --- a/public/static/css/mapguesser.css +++ b/public/static/css/mapguesser.css @@ -89,10 +89,18 @@ sub { margin-top: 10px; } +.marginLeft { + margin-left: 10px; +} + .marginBottom { margin-bottom: 10px; } +.marginRight { + margin-right: 10px; +} + .right { text-align: right; } @@ -230,6 +238,29 @@ input.big:focus, select.big:focus, textarea.big:focus { padding: 4px; } +div.modal { + position: fixed; + top: 100px; + background-color: #ffffff; + border-radius: 3px; + padding: 20px; + box-sizing: border-box; + z-index: 3; + visibility: hidden; +} + +#cover { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + background-color: #000000; + opacity: 0.5; + z-index: 2; + visibility: hidden; +} + p.formError { color: #7f2929; font-weight: 500; @@ -313,7 +344,19 @@ div.box { padding: 0; width: 100%; } + div.modal { + left: 20px; + right: 20px; + } div.box { width: initial; } } + +@media screen and (min-width: 600px) { + div.modal { + width: 540px; + left: 50%; + margin-left: -270px; + } +} diff --git a/public/static/js/game.js b/public/static/js/game.js index baac16b..8a835c0 100644 --- a/public/static/js/game.js +++ b/public/static/js/game.js @@ -16,7 +16,7 @@ initialize: function () { document.getElementById('loading').style.visibility = 'visible'; - document.getElementById('cover').style.visibility = 'visible'; + document.getElementById('guessCover').style.visibility = 'visible'; document.getElementById('currentRound').innerHTML = '1/' + String(Game.NUMBER_OF_ROUNDS); document.getElementById('currentScoreSum').innerHTML = '0/0'; @@ -27,7 +27,7 @@ MapGuesser.httpRequest('GET', '/game/' + mapId + '/newPlace.json', function () { document.getElementById('loading').style.visibility = 'hidden'; - document.getElementById('cover').style.visibility = 'hidden'; + document.getElementById('guessCover').style.visibility = 'hidden'; if (this.response.error) { //TODO: handle this error @@ -98,7 +98,7 @@ lastRound.line.setVisible(false); } - document.getElementById('cover').style.visibility = 'hidden'; + document.getElementById('guessCover').style.visibility = 'hidden'; document.getElementById('showGuessButton').style.visibility = null; document.getElementById('guess').style.visibility = null; document.getElementById('guess').classList.remove('result') @@ -152,7 +152,7 @@ document.getElementById('guess').classList.remove('adapt'); } document.getElementById('loading').style.visibility = 'visible'; - document.getElementById('cover').style.visibility = 'visible'; + document.getElementById('guessCover').style.visibility = 'visible'; var data = new FormData(); data.append('lat', String(guessPosition.lat)); diff --git a/public/static/js/map_editor.js b/public/static/js/map_editor.js index 59c664a..83f950a 100644 --- a/public/static/js/map_editor.js +++ b/public/static/js/map_editor.js @@ -22,7 +22,7 @@ document.getElementById('mapName').innerHTML = form.elements.name.value ? form.elements.name.value : '[unnamed map]'; - document.getElementById('metadata').style.visibility = 'hidden'; + MapGuesser.hideModal(); document.getElementById('saveButton').disabled = false; }, @@ -109,7 +109,6 @@ return; } - document.getElementById('metadata').classList.add('selected'); document.getElementById('map').classList.add('selected'); document.getElementById('control').classList.add('selected'); document.getElementById('noPano').style.visibility = 'hidden'; @@ -215,7 +214,6 @@ }, closePlace: function (del) { - document.getElementById('metadata').classList.remove('selected') document.getElementById('map').classList.remove('selected'); document.getElementById('control').classList.remove('selected'); document.getElementById('noPano').style.visibility = 'hidden'; @@ -413,14 +411,7 @@ document.getElementById('mapName').onclick = function (e) { e.preventDefault(); - var metadata = document.getElementById('metadata'); - - if (metadata.style.visibility === 'visible') { - metadata.style.visibility = 'hidden'; - } else { - metadata.style.visibility = 'visible'; - document.getElementById('metadataForm').elements.name.select(); - } + MapGuesser.showModal('metadata'); }; document.getElementById('metadataForm').onsubmit = function (e) { @@ -430,7 +421,7 @@ }; document.getElementById('closeMetadataButton').onclick = function () { - document.getElementById('metadata').style.visibility = 'hidden'; + MapGuesser.hideModal(); }; document.getElementById('saveButton').onclick = function () { diff --git a/public/static/js/mapguesser.js b/public/static/js/mapguesser.js index 06cbc89..92fef9e 100644 --- a/public/static/js/mapguesser.js +++ b/public/static/js/mapguesser.js @@ -18,6 +18,75 @@ var MapGuesser = { } else { xhr.send(); } + }, + + showModal: function (id) { + document.getElementById(id).style.visibility = 'visible'; + document.getElementById('cover').style.visibility = 'visible'; + }, + + showModalWithContent: function (title, body, extraButtons) { + if (typeof extraButtons === 'undefined') { + extraButtons = []; + } + + MapGuesser.showModal('modal'); + + document.getElementById('modalTitle').textContent = title; + + if (typeof body === 'object') { + document.getElementById('modalText').appendChild(body); + } else { + document.getElementById('modalText').textContent = body; + } + + var buttons = document.getElementById('modalButtons'); + buttons.textContent = ''; + + for (extraButton of extraButtons) { + var button = document.createElement(extraButton.type); + + if (extraButton.type === 'a') { + button.classList.add('button'); + } + + for (className of extraButton.classNames) { + button.classList.add(className); + } + + button.classList.add('marginTop'); + button.classList.add('marginRight'); + button.textContent = extraButton.text; + + if (extraButton.type === 'a') { + button.href = extraButton.href; + } else if (extraButton.type === 'button') { + button.onclick = extraButton.onclick; + } + + buttons.appendChild(button); + } + + var closeButton = document.createElement('button'); + + closeButton.classList.add('gray'); + closeButton.classList.add('marginTop'); + closeButton.textContent = 'Cancel'; + closeButton.onclick = function () { + MapGuesser.hideModal(); + }; + + buttons.appendChild(closeButton); + }, + + hideModal: function () { + var modals = document.getElementsByClassName('modal'); + + for (modal of modals) { + modal.style.visibility = 'hidden'; + } + + document.getElementById('cover').style.visibility = 'hidden'; } }; @@ -31,4 +100,8 @@ var MapGuesser = { } } } + + document.getElementById('cover').onclick = function () { + MapGuesser.hideModal(); + }; })(); diff --git a/src/Controller/MapAdminController.php b/src/Controller/MapAdminController.php index 7a49d41..075017a 100644 --- a/src/Controller/MapAdminController.php +++ b/src/Controller/MapAdminController.php @@ -74,6 +74,8 @@ class MapAdminController implements ISecured { $mapId = (int) $this->request->query('mapId'); + \Container::$dbConnection->startTransaction(); + if (!$mapId) { $mapId = $this->addNewMap(); } @@ -131,10 +133,44 @@ class MapAdminController implements ISecured $this->saveMapData($mapId, $map); + \Container::$dbConnection->commit(); + $data = ['mapId' => $mapId, 'added' => $addedIds]; return new JsonContent($data); } + public function deleteMap() { + $mapId = (int) $this->request->query('mapId'); + + \Container::$dbConnection->startTransaction(); + + $this->deletePlaces($mapId); + + $modify = new Modify(\Container::$dbConnection, 'maps'); + $modify->setId($mapId); + $modify->delete(); + + \Container::$dbConnection->commit(); + + $data = ['success' => true]; + return new JsonContent($data); + } + + private function deletePlaces(int $mapId): void + { + $select = new Select(\Container::$dbConnection, 'places'); + $select->columns(['id']); + $select->where('map_id', '=', $mapId); + + $result = $select->execute(); + + while ($place = $result->fetch(IResultSet::FETCH_ASSOC)) { + $modify = new Modify(\Container::$dbConnection, 'places'); + $modify->setId($place['id']); + $modify->delete(); + } + } + private function calculateMapBounds(int $mapId): Bounds { $select = new Select(\Container::$dbConnection, 'places'); diff --git a/src/Database/Query/Modify.php b/src/Database/Query/Modify.php index f731461..5554409 100755 --- a/src/Database/Query/Modify.php +++ b/src/Database/Query/Modify.php @@ -116,11 +116,14 @@ class Modify private function update(): void { - $diff = $this->generateDiff(); + /*$diff = $this->generateDiff(); if (count($diff) === 0) { return; - } + }*/ + + $diff = $this->attributes; + unset($diff[$this->idName]); $set = $this->generateColumnsWithBinding(array_keys($diff)); diff --git a/views/admin/map_editor.php b/views/admin/map_editor.php index ffc2be6..12c9a09 100644 --- a/views/admin/map_editor.php +++ b/views/admin/map_editor.php @@ -22,7 +22,7 @@ $jsFiles = [

- @@ -50,13 +50,14 @@ $jsFiles = [

-
-
+
-
+
diff --git a/views/maps.php b/views/maps.php index e438b5e..9740011 100644 --- a/views/maps.php +++ b/views/maps.php @@ -8,7 +8,7 @@ $cssFiles = [

Playable maps

- +

@@ -36,18 +36,18 @@ $cssFiles = [
- Play this map - Edit - + Play this map + Edit +
- Play this map + Play this map
@@ -61,4 +61,40 @@ $cssFiles = [
+ + + \ No newline at end of file diff --git a/views/templates/main_header.php b/views/templates/main_header.php index a487f11..6c2bb17 100644 --- a/views/templates/main_header.php +++ b/views/templates/main_header.php @@ -24,4 +24,10 @@
+
+
+ \ No newline at end of file diff --git a/web.php b/web.php index 27aa54b..e00c293 100644 --- a/web.php +++ b/web.php @@ -27,6 +27,7 @@ Container::$routeCollection->group('admin', function (MapGuesser\Routing\RouteCo $routeCollection->get('admin.mapEditor', 'mapEditor/{mapId?}', [MapGuesser\Controller\MapAdminController::class, 'getMapEditor']); $routeCollection->get('admin.place', 'place.json/{placeId}', [MapGuesser\Controller\MapAdminController::class, 'getPlace']); $routeCollection->post('admin.saveMap', 'saveMap/{mapId}/json', [MapGuesser\Controller\MapAdminController::class, 'saveMap']); + $routeCollection->post('admin.deleteMap', 'deleteMap/{mapId}', [MapGuesser\Controller\MapAdminController::class, 'deleteMap']); }); Container::$sessionHandler = new MapGuesser\Session\DatabaseSessionHandler();