Compare commits
41
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b75eb16b3d | ||
|
|
f8a570d0d5 | ||
|
|
e7ee7bbe8e | ||
|
|
2f4f66cc94 | ||
|
|
4afbc046ff | ||
|
|
79bd5b98d5 | ||
|
|
c1cdeba1d3 | ||
|
|
255168ffb6 | ||
|
|
ca0b8da733 | ||
|
|
34206cac12 | ||
|
|
47a2f15fc5 | ||
|
|
17658f70ba | ||
|
|
500ec958cb | ||
|
|
d2fa2050ac | ||
|
|
e8be433ee6 | ||
|
|
506072017c | ||
|
|
4561c825a4 | ||
|
|
693bddbcf0 | ||
|
|
eae7cefae1 | ||
|
|
212728e138 | ||
|
|
0d627f297e | ||
|
|
f07ae979a2 | ||
|
|
8bdbbafcff | ||
|
|
3856ccb576 | ||
|
|
9f839d3f5d | ||
|
|
721b611cdb | ||
|
|
70fb30f673 | ||
|
|
e200dab2a4 | ||
|
|
e8c246f002 | ||
|
|
251bf1be3d | ||
|
|
0be20a6097 | ||
|
|
d5d3563ddc | ||
|
|
19aa4098e5 | ||
|
|
394c8b8830 | ||
|
|
dc4ba4b5a4 | ||
|
|
eda4e00378 | ||
|
|
dfc74375d7 | ||
|
|
dc1aedd28f | ||
|
|
787427b211 | ||
|
|
05b1a84168 | ||
|
|
e2a0da3dd2 |
No files matched your search
@@ -14,3 +14,4 @@ MAIL_HOST=mail
|
||||
MAIL_PORT=2500
|
||||
GOOGLE_OAUTH_CLIENT_ID=your_google_oauth_client_id
|
||||
GOOGLE_OAUTH_CLIENT_SECRET=your_google_oauth_client_secret
|
||||
GOOGLE_ANALITICS_ID=your_google_analytics_id
|
||||
@@ -1,3 +1,4 @@
|
||||
.env
|
||||
installed
|
||||
unit_test_results.xml
|
||||
vendor
|
||||
@@ -0,0 +1,15 @@
|
||||
image: php:7.4.7-cli-buster
|
||||
|
||||
pipelines:
|
||||
default:
|
||||
- step:
|
||||
name: Unit Testing
|
||||
caches:
|
||||
- composer
|
||||
artifacts:
|
||||
- unit_test_results.xml
|
||||
script:
|
||||
- apt-get update && apt-get install -y unzip
|
||||
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
- composer install
|
||||
- vendor/bin/phpunit --log-junit unit_test_results.xml --testdox tests
|
||||
+3
-1
@@ -8,7 +8,9 @@
|
||||
"symfony/console": "^5.1",
|
||||
"phpmailer/phpmailer": "^6.1"
|
||||
},
|
||||
"require-dev": {},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MapGuesser\\": "src"
|
||||
|
||||
Generated
+1701
-2
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -4,8 +4,8 @@ ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
# Install Nginx, PHP and further necessary packages
|
||||
RUN apt update --fix-missing
|
||||
RUN apt install -y curl git mariadb-client nginx \
|
||||
php-apcu php-xdebug php7.4-cli php7.4-curl php7.4-fpm php7.4-mbstring php7.4-mysql php7.4-zip
|
||||
RUN apt install -y curl git unzip mariadb-client nginx \
|
||||
php-apcu php-xdebug php7.4-cli php7.4-curl php7.4-fpm php7.4-mbstring php7.4-mysql php7.4-zip php7.4-xml
|
||||
|
||||
# Configure Nginx with PHP
|
||||
RUN mkdir -p /run/php
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#panorama {
|
||||
width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#guessCover {
|
||||
#panoCover {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
@@ -111,7 +114,7 @@
|
||||
z-index: 2;
|
||||
}
|
||||
#guess {
|
||||
top: 50px;
|
||||
top: 10px;
|
||||
left: 20px;
|
||||
opacity: 0.95;
|
||||
visibility: hidden;
|
||||
@@ -157,7 +160,7 @@
|
||||
#guess.result {
|
||||
width: initial;
|
||||
height: initial;
|
||||
top: 50px;
|
||||
top: 10px;
|
||||
left: 50px;
|
||||
right: 50px;
|
||||
bottom: 50px;
|
||||
@@ -167,11 +170,11 @@
|
||||
}
|
||||
@media screen and (max-height: 424px) {
|
||||
#guess {
|
||||
top: 50px;
|
||||
top: 10px;
|
||||
height: initial;
|
||||
}
|
||||
#guess.adapt:hover {
|
||||
top: 50px;
|
||||
top: 10px;
|
||||
height: initial;
|
||||
}
|
||||
#guess.result {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#map {
|
||||
width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* modify the cursor for the Leaflet map */
|
||||
.leaflet-container {
|
||||
cursor: crosshair;
|
||||
}
|
||||
@@ -16,6 +20,8 @@
|
||||
|
||||
#noPano {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
visibility: hidden;
|
||||
@@ -23,12 +29,12 @@
|
||||
}
|
||||
|
||||
#noPano>p {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#control {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
width: 125px;
|
||||
z-index: 3;
|
||||
@@ -48,31 +54,34 @@
|
||||
|
||||
@media screen and (max-width: 999px) and (min-height: 600px) {
|
||||
#map.selected {
|
||||
height: calc(50% - 20px);
|
||||
height: 50%;
|
||||
}
|
||||
#panorama, #noPano {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: calc(50% - 20px);
|
||||
height: 50%;
|
||||
}
|
||||
#placeControl {
|
||||
top: calc(50% + 30px);
|
||||
top: calc(50% + 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1000px), (max-height: 599px) {
|
||||
#map.selected {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 50%;
|
||||
}
|
||||
#panorama, #noPano {
|
||||
top: 40px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 50%;
|
||||
}
|
||||
#placeControl {
|
||||
top: 50px;
|
||||
top: 10px;
|
||||
}
|
||||
#modified.selected {
|
||||
right: calc(50% + 10px);
|
||||
|
||||
@@ -84,7 +84,7 @@ hr {
|
||||
}
|
||||
|
||||
p.small, span.small {
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.justify {
|
||||
@@ -148,6 +148,13 @@ button, a.button {
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
button.small {
|
||||
font-size: 14px;
|
||||
padding: 0 12px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
button:enabled:hover, button:enabled:focus, a.button:hover, a.button:focus {
|
||||
background-color: #29457f;
|
||||
outline: none;
|
||||
@@ -317,6 +324,12 @@ main {
|
||||
padding: 6px 12px;
|
||||
}
|
||||
|
||||
div.full {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: #444444;
|
||||
padding: 6px 12px;
|
||||
@@ -336,6 +349,12 @@ div.buttonContainer>button {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#cookiesNotice {
|
||||
background-color: #eeeeee;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: fixed;
|
||||
width: 64px;
|
||||
|
||||
@@ -29,17 +29,16 @@ div.mapItem>div.title>p.title {
|
||||
div.mapItem>div.imgContainer {
|
||||
width: 100%;
|
||||
padding-top: 50%;
|
||||
background: #cccccc;
|
||||
}
|
||||
|
||||
div.mapItem>div.imgContainer>img {
|
||||
width: 100%;
|
||||
margin-top: -50%
|
||||
background-color: #cccccc;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
div.mapItem>div.inner {
|
||||
background-color: #eeeeee;
|
||||
padding: 10px 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.mapItem>div.inner>div.info {
|
||||
@@ -47,6 +46,12 @@ div.mapItem>div.inner>div.info {
|
||||
grid-template-columns: auto auto;
|
||||
}
|
||||
|
||||
div.mapItem>div.inner>div.description {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.mapItem>div.inner>div.info>p:nth-child(1) {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
initialize: function () {
|
||||
document.getElementById('loading').style.visibility = 'visible';
|
||||
document.getElementById('guessCover').style.visibility = 'visible';
|
||||
document.getElementById('panoCover').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('guessCover').style.visibility = 'hidden';
|
||||
document.getElementById('panoCover').style.visibility = 'hidden';
|
||||
|
||||
if (this.response.error) {
|
||||
//TODO: handle this error
|
||||
@@ -98,7 +98,7 @@
|
||||
lastRound.line.setVisible(false);
|
||||
}
|
||||
|
||||
document.getElementById('guessCover').style.visibility = 'hidden';
|
||||
document.getElementById('panoCover').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('guessCover').style.visibility = 'visible';
|
||||
document.getElementById('panoCover').style.visibility = 'visible';
|
||||
|
||||
var data = new FormData();
|
||||
data.append('lat', String(guessPosition.lat));
|
||||
@@ -370,6 +370,14 @@
|
||||
}
|
||||
};
|
||||
|
||||
MapGuesser.sessionAvailableHooks.reinitializeGame = function () {
|
||||
MapGuesser.httpRequest('GET', '/game/' + mapId + '/json', function () {
|
||||
mapBounds = this.response.bounds;
|
||||
|
||||
Game.initialize();
|
||||
});
|
||||
};
|
||||
|
||||
if (!('ontouchstart' in document.documentElement)) {
|
||||
Game.adaptGuess = true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,49 @@
|
||||
var MapGuesser = {
|
||||
cookiesAgreed: false,
|
||||
sessionAvailableHooks: {},
|
||||
|
||||
initGoogleAnalitics: function () {
|
||||
if (typeof GOOGLE_ANALITICS_ID === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Global site tag (gtag.js) - Google Analytics
|
||||
var script = document.createElement('script');
|
||||
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + GOOGLE_ANALITICS_ID;
|
||||
script.async = true;
|
||||
|
||||
document.head.appendChild(script);
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', GOOGLE_ANALITICS_ID);
|
||||
},
|
||||
|
||||
agreeCookies: function () {
|
||||
if (MapGuesser.cookiesAgreed) {
|
||||
return;
|
||||
}
|
||||
|
||||
var expirationDate = new Date(new Date().getTime() + 20 * 365 * 24 * 60 * 60 * 1000).toUTCString();
|
||||
document.cookie = 'COOKIES_CONSENT=1; expires=' + expirationDate + '; path=/';
|
||||
|
||||
MapGuesser.initGoogleAnalitics();
|
||||
MapGuesser.httpRequest('GET', '/startSession.json', function () {
|
||||
ANTI_CSRF_TOKEN = this.response.antiCsrfToken;
|
||||
|
||||
for (var hookId in MapGuesser.sessionAvailableHooks) {
|
||||
if (!MapGuesser.sessionAvailableHooks.hasOwnProperty(hookId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MapGuesser.sessionAvailableHooks[hookId]();
|
||||
}
|
||||
});
|
||||
|
||||
MapGuesser.cookiesAgreed = true;
|
||||
},
|
||||
|
||||
httpRequest: function (method, url, callback, data) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ ROOT_DIR=$(dirname $(readlink -f "$0"))/..
|
||||
. ${ROOT_DIR}/.env
|
||||
|
||||
echo "Installing Composer packages..."
|
||||
(cd ${ROOT_DIR} && composer install)
|
||||
(cd ${ROOT_DIR} && composer install --no-dev)
|
||||
|
||||
echo "Installing Yarn packages..."
|
||||
(cd ${ROOT_DIR}/public/static && yarn install)
|
||||
|
||||
@@ -1,12 +1,30 @@
|
||||
<?php namespace MapGuesser\Controller;
|
||||
|
||||
use MapGuesser\Interfaces\Request\IRequest;
|
||||
use MapGuesser\Interfaces\Response\IContent;
|
||||
use MapGuesser\Interfaces\Response\IRedirect;
|
||||
use MapGuesser\Response\JsonContent;
|
||||
use MapGuesser\Response\Redirect;
|
||||
|
||||
class HomeController
|
||||
{
|
||||
private IRequest $request;
|
||||
|
||||
public function __construct(IRequest $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function getIndex(): IRedirect
|
||||
{
|
||||
return new Redirect(\Container::$routeCollection->getRoute('maps')->generateLink(), IRedirect::TEMPORARY);
|
||||
}
|
||||
|
||||
public function startSession(): IContent
|
||||
{
|
||||
// session starts with the request, this method just sends valid data to the client
|
||||
|
||||
$data = ['antiCsrfToken' => $this->request->session()->get('anti_csrf_token')];
|
||||
return new JsonContent($data);
|
||||
}
|
||||
}
|
||||
@@ -65,8 +65,8 @@ class Mail
|
||||
$mailer->Mailer = 'mail';
|
||||
}
|
||||
|
||||
$mailer->setFrom($_ENV['MAIL_FROM'], 'MapGuesser');
|
||||
$mailer->addReplyTo($_ENV['MAIL_FROM'], 'MapGuesser');
|
||||
$mailer->setFrom($_ENV['MAIL_FROM'], $_ENV['APP_NAME']);
|
||||
$mailer->addReplyTo($_ENV['MAIL_FROM'], $_ENV['APP_NAME']);
|
||||
|
||||
$mailer->Sender = !empty($_ENV['MAIL_BOUNCE']) ? $_ENV['MAIL_BOUNCE'] : $_ENV['MAIL_FROM'];
|
||||
$mailer->Subject = $this->subject;
|
||||
|
||||
@@ -45,6 +45,11 @@ class RouteCollection
|
||||
{
|
||||
$groupNumber = count($uri);
|
||||
|
||||
// response to HEAD request with the GET content
|
||||
if ($method === 'head') {
|
||||
$method = 'get';
|
||||
}
|
||||
|
||||
if (!isset($this->searchTable[$method][$groupNumber])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php namespace MapGuesser\Tests\Util\Geo;
|
||||
|
||||
use MapGuesser\Util\Geo\Bounds;
|
||||
use MapGuesser\Util\Geo\Position;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class BoundsTest extends TestCase
|
||||
{
|
||||
public function testCanBeCreatedEmpty(): void
|
||||
{
|
||||
$bounds = new Bounds();
|
||||
|
||||
$this->assertEquals(90.0, $bounds->getSouthLat());
|
||||
$this->assertEquals(180.0, $bounds->getWestLng());
|
||||
$this->assertEquals(-90.0, $bounds->getNorthLat());
|
||||
$this->assertEquals(-180.0, $bounds->getEastLng());
|
||||
}
|
||||
|
||||
public function testCanBeCreatedWithPosition(): void
|
||||
{
|
||||
$position = new Position(45.25, 18.12);
|
||||
|
||||
$bounds = new Bounds($position);
|
||||
|
||||
$this->assertEquals($position->getLat(), $bounds->getSouthLat());
|
||||
$this->assertEquals($position->getLng(), $bounds->getWestLng());
|
||||
$this->assertEquals($position->getLat(), $bounds->getNorthLat());
|
||||
$this->assertEquals($position->getLng(), $bounds->getEastLng());
|
||||
}
|
||||
|
||||
public function testCanBeCreatedDirectly(): void
|
||||
{
|
||||
$bounds = Bounds::createDirectly(44.12, 7.33, 50.12, 15.11);
|
||||
|
||||
$this->assertEquals(44.12, $bounds->getSouthLat());
|
||||
$this->assertEquals(7.33, $bounds->getWestLng());
|
||||
$this->assertEquals(50.12, $bounds->getNorthLat());
|
||||
$this->assertEquals(15.11, $bounds->getEastLng());
|
||||
}
|
||||
|
||||
public function testExtendingWithOnePositionIsTheSameAsCreatingWithPosition(): void
|
||||
{
|
||||
$position = new Position(45.25, 18.12);
|
||||
|
||||
$bounds1 = new Bounds();
|
||||
$bounds1->extend($position);
|
||||
|
||||
$bounds2 = new Bounds($position);
|
||||
|
||||
$this->assertEquals($bounds1, $bounds2);
|
||||
}
|
||||
|
||||
public function testCanBeExtendedWithTwoPositions(): void
|
||||
{
|
||||
$bounds = new Bounds();
|
||||
|
||||
$position1 = new Position(45.25, 18.12);
|
||||
$position2 = new Position(43.15, 19.28);
|
||||
|
||||
$bounds->extend($position1);
|
||||
$bounds->extend($position2);
|
||||
|
||||
$this->assertEquals($position2->getLat(), $bounds->getSouthLat());
|
||||
$this->assertEquals($position1->getLng(), $bounds->getWestLng());
|
||||
$this->assertEquals($position1->getLat(), $bounds->getNorthLat());
|
||||
$this->assertEquals($position2->getLng(), $bounds->getEastLng());
|
||||
|
||||
$bounds = new Bounds();
|
||||
|
||||
$position1 = new Position(43.15, 18.12);
|
||||
$position2 = new Position(45.25, 19.28);
|
||||
|
||||
$bounds->extend($position1);
|
||||
$bounds->extend($position2);
|
||||
|
||||
$this->assertEquals($position1->getLat(), $bounds->getSouthLat());
|
||||
$this->assertEquals($position1->getLng(), $bounds->getWestLng());
|
||||
$this->assertEquals($position2->getLat(), $bounds->getNorthLat());
|
||||
$this->assertEquals($position2->getLng(), $bounds->getEastLng());
|
||||
}
|
||||
|
||||
public function testCanCalculateApproximateArea(): void
|
||||
{
|
||||
$bounds = Bounds::createDirectly(44.12, 7.33, 50.12, 15.11);
|
||||
|
||||
$this->assertEqualsWithDelta(391766.09, $bounds->calculateApproximateArea(), 0.01);
|
||||
}
|
||||
|
||||
public function testCanBeConvertedToArray(): void
|
||||
{
|
||||
$bounds = Bounds::createDirectly(44.12, 7.33, 50.12, 15.11);
|
||||
|
||||
$this->assertEquals(
|
||||
['south' => 44.12, 'west' => 7.33, 'north' => 50.12, 'east' => 15.11],
|
||||
$bounds->toArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php namespace MapGuesser\Tests\Util\Geo;
|
||||
|
||||
use MapGuesser\Util\Geo\Position;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class PositionTest extends TestCase
|
||||
{
|
||||
public function testCanBeCreatedWithLatAndLng(): void
|
||||
{
|
||||
$position = new Position(45.25, 18.12);
|
||||
|
||||
$this->assertEquals(45.25, $position->getLat());
|
||||
$this->assertEquals(18.12, $position->getLng());
|
||||
}
|
||||
|
||||
public function testCanCalculateDistanceToAnotherPosition(): void
|
||||
{
|
||||
$position1 = new Position(44.12, 7.33);
|
||||
$position2 = new Position(50.12, 15.11);
|
||||
|
||||
$this->assertEqualsWithDelta(888785.73, $position1->calculateDistanceTo($position2), 0.01);
|
||||
}
|
||||
|
||||
public function testCanBeConvertedToArray(): void
|
||||
{
|
||||
$position = new Position(45.25, 18.12);
|
||||
|
||||
$this->assertEquals(
|
||||
['lat' => 45.25, 'lng' => 18.12],
|
||||
$position->toArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ $jsFiles = [
|
||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||
<header class="small">
|
||||
<h1>
|
||||
<a href="/maps" title="Back to playable maps">
|
||||
<a href="/" title="<?= $_ENV['APP_NAME'] ?>">
|
||||
<img class="inline" width="1em" height="1em" src="<?= $_ENV['STATIC_ROOT'] ?>/img/icon.svg?rev=<?= REVISION ?>"><!--
|
||||
--><span><?= $_ENV['APP_NAME'] ?></span>
|
||||
</a>
|
||||
@@ -59,19 +59,21 @@ $jsFiles = [
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="full">
|
||||
<div id="map"></div>
|
||||
<div id="control">
|
||||
<button id="saveButton" class="fullWidth" disabled>Save</button>
|
||||
</div>
|
||||
<div id="panorama"></div>
|
||||
<div id="noPano">
|
||||
<p class="bold">No panorama is available for this location.</p>
|
||||
</div>
|
||||
<div id="control">
|
||||
<button id="saveButton" class="fullWidth" disabled>Save</button>
|
||||
</div>
|
||||
<div id="placeControl">
|
||||
<button id="applyButton" class="fullWidth">Apply</button>
|
||||
<button id="closeButton" class="gray fullWidth marginTop">Close</button>
|
||||
<button id="deleteButton" class="red fullWidth marginTop">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var tileUrl = '<?= $_ENV['LEAFLET_TILESERVER_URL'] ?>';
|
||||
var tileAttribution = '<?= $_ENV['LEAFLET_TILESERVER_ATTRIBUTION'] ?>';
|
||||
|
||||
+4
-2
@@ -10,7 +10,7 @@ $jsFiles = [
|
||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||
<header class="small">
|
||||
<h1>
|
||||
<a href="/maps" title="Back to playable maps">
|
||||
<a href="/" title="<?= $_ENV['APP_NAME'] ?>">
|
||||
<img class="inline" width="1em" height="1em" src="<?= $_ENV['STATIC_ROOT'] ?>/img/icon.svg?rev=<?= REVISION ?>"><!--
|
||||
--><span><?= $_ENV['APP_NAME'] ?></span>
|
||||
</a>
|
||||
@@ -21,7 +21,8 @@ $jsFiles = [
|
||||
--><span>Score <span id="currentScoreSum" class="bold"></span></span>
|
||||
</p>
|
||||
</header>
|
||||
<div id="guessCover"></div>
|
||||
<div class="full">
|
||||
<div id="panoCover"></div>
|
||||
<div id="panorama"></div>
|
||||
<div id="showGuessButtonContainer">
|
||||
<button id="showGuessButton" class="fullWidth">Show guess map</button>
|
||||
@@ -55,6 +56,7 @@ $jsFiles = [
|
||||
<button id="startNewGameButton" class="fullWidth">Play this map again</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var mapId = <?= $mapId ?>;
|
||||
var mapBounds = <?= json_encode($bounds) ?>;
|
||||
|
||||
+67
-7
@@ -5,7 +5,6 @@ $cssFiles = [
|
||||
?>
|
||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||
<h2>Playable maps</h2>
|
||||
<div id="mapContainer">
|
||||
<?php foreach ($maps as $map): ?>
|
||||
<div class="mapItem">
|
||||
@@ -31,7 +30,9 @@ $cssFiles = [
|
||||
-->~ <?= $map['area'][0] ?> <?= $map['area'][1] ?><sup>2</sup>
|
||||
</p>
|
||||
</div>
|
||||
<p class="small justify marginTop"><?= $map['description'] ?></p>
|
||||
<div class="description marginTop">
|
||||
<p class="small center"><?= $map['description'] ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($isAdmin): ?>
|
||||
<div class="buttonContainer">
|
||||
@@ -64,21 +65,80 @@ $cssFiles = [
|
||||
(function () {
|
||||
const GOOGLE_MAPS_JS_API_KEY = '<?= $_ENV['GOOGLE_MAPS_JS_API_KEY'] ?>';
|
||||
|
||||
var Maps = {
|
||||
descriptionDivs: null,
|
||||
|
||||
addStaticMaps: function () {
|
||||
var imgContainers = document.getElementById('mapContainer').getElementsByClassName('imgContainer');
|
||||
for (var i = 0; i < imgContainers.length; i++) {
|
||||
var imgContainer = imgContainers[i];
|
||||
|
||||
var img = document.createElement('img');
|
||||
|
||||
img.src = 'https://maps.googleapis.com/maps/api/staticmap?size=350x175&' +
|
||||
var imgSrc = 'https://maps.googleapis.com/maps/api/staticmap?size=350x175&' +
|
||||
'scale=' + (window.devicePixelRatio >= 2 ? 2 : 1) + '&' +
|
||||
'visible=' + imgContainer.dataset.boundSouthLat + ',' + imgContainer.dataset.boundWestLng + '|' +
|
||||
imgContainer.dataset.boundNorthLat + ',' + imgContainer.dataset.boundEastLng +
|
||||
'&key=' + GOOGLE_MAPS_JS_API_KEY;
|
||||
img.alt = 'Map area';
|
||||
|
||||
imgContainer.appendChild(img);
|
||||
imgContainer.style.backgroundImage = 'url("' + imgSrc + '")';
|
||||
}
|
||||
},
|
||||
|
||||
initializeDescriptionDivs: function () {
|
||||
Maps.descriptionDivs = document.getElementById('mapContainer').getElementsByClassName('description');
|
||||
|
||||
for (var i = 0; i < Maps.descriptionDivs.length; i++) {
|
||||
var description = Maps.descriptionDivs[i];
|
||||
var boundingClientRect = description.getBoundingClientRect();
|
||||
|
||||
description.defaultHeight = boundingClientRect.height;
|
||||
}
|
||||
},
|
||||
|
||||
calculateDescriptionDivHeights: function () {
|
||||
var currentY;
|
||||
var rows = [];
|
||||
for (var i = 0; i < Maps.descriptionDivs.length; i++) {
|
||||
var description = Maps.descriptionDivs[i];
|
||||
var boundingClientRect = description.getBoundingClientRect();
|
||||
|
||||
if (currentY !== boundingClientRect.y) {
|
||||
rows.push([]);
|
||||
}
|
||||
|
||||
rows[rows.length - 1].push(description);
|
||||
|
||||
currentY = boundingClientRect.y;
|
||||
}
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var row = rows[i];
|
||||
|
||||
var maxHeight = 0;
|
||||
for (var j = 0; j < row.length; j++) {
|
||||
var description = row[j];
|
||||
|
||||
if (description.defaultHeight > maxHeight) {
|
||||
maxHeight = description.defaultHeight;
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < row.length; j++) {
|
||||
var description = row[j];
|
||||
|
||||
description.style.height = maxHeight + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Maps.addStaticMaps();
|
||||
|
||||
Maps.initializeDescriptionDivs();
|
||||
Maps.calculateDescriptionDivHeights();
|
||||
|
||||
window.onresize = function () {
|
||||
Maps.calculateDescriptionDivHeights();
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
<?php if ($isAdmin): ?>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<script>
|
||||
const STATIC_ROOT = '<?= $_ENV['STATIC_ROOT'] ?>';
|
||||
const REVISION = '<?= REVISION ?>';
|
||||
const ANTI_CSRF_TOKEN = '<?= $_SESSION['anti_csrf_token'] ?>';
|
||||
var ANTI_CSRF_TOKEN = '<?= \Container::$request->session()->get('anti_csrf_token') ?>';
|
||||
<?php if (!empty($_ENV['GOOGLE_ANALITICS_ID'])): ?>
|
||||
const GOOGLE_ANALITICS_ID = '<?= $_ENV['GOOGLE_ANALITICS_ID'] ?>';
|
||||
<?php endif; ?>
|
||||
</script>
|
||||
<script src="<?= $_ENV['STATIC_ROOT'] ?>/js/mapguesser.js?rev=<?= REVISION ?>"></script>
|
||||
<?php if (isset($jsFiles)) : ?>
|
||||
@@ -14,5 +17,33 @@
|
||||
<script src="<?= $jsFile ?>"></script>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!isset($_COOKIE['COOKIES_CONSENT'])): ?>
|
||||
<script>
|
||||
(function () {
|
||||
// we don't want user to agree cookies when clicking on the notice itself
|
||||
document.getElementById('cookiesNotice').onclick = function (e) {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
document.getElementById('agreeCookiesButton').onclick = function () {
|
||||
MapGuesser.agreeCookies();
|
||||
|
||||
document.getElementById('cookiesNotice').style.display = 'none';
|
||||
};
|
||||
|
||||
window.onclick = function () {
|
||||
MapGuesser.agreeCookies();
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
<?php else: ?>
|
||||
<?php if (!empty($_ENV['GOOGLE_ANALITICS_ID'])): ?>
|
||||
<script>
|
||||
(function () {
|
||||
MapGuesser.initGoogleAnalitics();
|
||||
})();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -22,6 +22,14 @@
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<?= $_ENV['STATIC_ROOT'] ?>/img/favicon/16x16.png?rev=<?= REVISION ?>">
|
||||
</head>
|
||||
<body>
|
||||
<?php if (!isset($_COOKIE['COOKIES_CONSENT'])): ?>
|
||||
<div id="cookiesNotice">
|
||||
<p class="small">
|
||||
<?= $_ENV['APP_NAME'] ?> uses cookies to improve user experience. By using the app or clicking 'Agree', you consent to our use of cookies.
|
||||
</p>
|
||||
<button id="agreeCookiesButton" class="small marginTop">Agree</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div id="loading">
|
||||
<img src="<?= $_ENV['STATIC_ROOT'] ?>/img/loading.svg?rev=<?= REVISION ?>" width="64" height="64">
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,8 @@ if (!empty($_ENV['DEV'])) {
|
||||
|
||||
Container::$routeCollection = new MapGuesser\Routing\RouteCollection();
|
||||
|
||||
Container::$routeCollection->get('index', '', [MapGuesser\Controller\HomeController::class, 'getIndex']);
|
||||
Container::$routeCollection->get('index', '', [MapGuesser\Controller\MapsController::class, 'getMaps']);
|
||||
Container::$routeCollection->get('startSession', 'startSession.json', [MapGuesser\Controller\HomeController::class, 'startSession']);
|
||||
Container::$routeCollection->group('login', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||
$routeCollection->get('login', '', [MapGuesser\Controller\LoginController::class, 'getLoginForm']);
|
||||
$routeCollection->post('login-action', '', [MapGuesser\Controller\LoginController::class, 'login']);
|
||||
@@ -35,7 +36,7 @@ Container::$routeCollection->group('profile', function (MapGuesser\Routing\Route
|
||||
$routeCollection->get('profile', '', [MapGuesser\Controller\UserController::class, 'getProfile']);
|
||||
$routeCollection->post('profile-action', '', [MapGuesser\Controller\UserController::class, 'saveProfile']);
|
||||
});
|
||||
Container::$routeCollection->get('maps', 'maps', [MapGuesser\Controller\MapsController::class, 'getMaps']);
|
||||
//Container::$routeCollection->get('maps', 'maps', [MapGuesser\Controller\MapsController::class, 'getMaps']);
|
||||
Container::$routeCollection->group('game', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||
$routeCollection->get('game', '{mapId}', [MapGuesser\Controller\GameController::class, 'getGame']);
|
||||
$routeCollection->get('game-json', '{mapId}/json', [MapGuesser\Controller\GameController::class, 'getGameJson']);
|
||||
@@ -49,6 +50,7 @@ Container::$routeCollection->group('admin', function (MapGuesser\Routing\RouteCo
|
||||
$routeCollection->post('admin.deleteMap', 'deleteMap/{mapId}', [MapGuesser\Controller\MapAdminController::class, 'deleteMap']);
|
||||
});
|
||||
|
||||
if (isset($_COOKIE['COOKIES_CONSENT'])) {
|
||||
Container::$sessionHandler = new MapGuesser\Session\DatabaseSessionHandler();
|
||||
|
||||
session_set_save_handler(Container::$sessionHandler, true);
|
||||
@@ -58,6 +60,9 @@ session_start([
|
||||
'cookie_httponly' => true,
|
||||
'cookie_samesite' => 'Lax'
|
||||
]);
|
||||
} else {
|
||||
$_SESSION = [];
|
||||
}
|
||||
|
||||
Container::$request = new MapGuesser\Request\Request($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'], $_GET, $_POST, $_SESSION);
|
||||
|
||||
|
||||
Reference in new issue
Block a user