Compare commits
57
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 | ||
|
|
e751fdaa3e | ||
|
|
675d7e60d0 | ||
|
|
0d097aacb5 | ||
|
|
98cd15e91f | ||
|
|
4f680db8f3 | ||
|
|
ea98af0681 | ||
|
|
05934d6245 | ||
|
|
3ab8ac5fe6 | ||
|
|
94e60e4ac5 | ||
|
|
9df5028c20 | ||
|
|
49bd03f303 | ||
|
|
7210e12656 | ||
|
|
8320b94210 | ||
|
|
28aa762153 | ||
|
|
33eb154112 | ||
|
|
a2ca7888f4 |
No files matched your search
@@ -1,3 +1,4 @@
|
|||||||
|
APP_NAME=MapQuiz
|
||||||
DEV=1
|
DEV=1
|
||||||
DB_HOST=mariadb
|
DB_HOST=mariadb
|
||||||
DB_USER=mapguesser
|
DB_USER=mapguesser
|
||||||
@@ -13,3 +14,4 @@ MAIL_HOST=mail
|
|||||||
MAIL_PORT=2500
|
MAIL_PORT=2500
|
||||||
GOOGLE_OAUTH_CLIENT_ID=your_google_oauth_client_id
|
GOOGLE_OAUTH_CLIENT_ID=your_google_oauth_client_id
|
||||||
GOOGLE_OAUTH_CLIENT_SECRET=your_google_oauth_client_secret
|
GOOGLE_OAUTH_CLIENT_SECRET=your_google_oauth_client_secret
|
||||||
|
GOOGLE_ANALITICS_ID=your_google_analytics_id
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
.env
|
.env
|
||||||
installed
|
installed
|
||||||
|
unit_test_results.xml
|
||||||
vendor
|
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",
|
"symfony/console": "^5.1",
|
||||||
"phpmailer/phpmailer": "^6.1"
|
"phpmailer/phpmailer": "^6.1"
|
||||||
},
|
},
|
||||||
"require-dev": {},
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^9"
|
||||||
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"MapGuesser\\": "src"
|
"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
|
# Install Nginx, PHP and further necessary packages
|
||||||
RUN apt update --fix-missing
|
RUN apt update --fix-missing
|
||||||
RUN apt install -y curl git mariadb-client nginx \
|
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
|
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
|
# Configure Nginx with PHP
|
||||||
RUN mkdir -p /run/php
|
RUN mkdir -p /run/php
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
Hi,
|
Hi,
|
||||||
<br><br>
|
<br><br>
|
||||||
You recently signed up on MapGuesser with this Google account ({{EMAIL}}).
|
You recently signed up on {{APP_NAME}} with this Google account ({{EMAIL}}).
|
||||||
<br><br>
|
<br><br>
|
||||||
Have fun on MapGuesser!
|
Have fun on {{APP_NAME}}!
|
||||||
<br><br>
|
<br><br>
|
||||||
Regards,<br>
|
Regards,<br>
|
||||||
MapGuesser<br>
|
{{APP_NAME}}<br>
|
||||||
<a href="{{BASE_URL}}" title="MapGuesser">{{BASE_URL}}</a>
|
<a href="{{BASE_URL}}" title="{{APP_NAME}}">{{BASE_URL}}</a>
|
||||||
+5
-5
@@ -1,14 +1,14 @@
|
|||||||
Hi,
|
Hi,
|
||||||
<br><br>
|
<br><br>
|
||||||
You recently signed up on MapGuesser with this email address ({{EMAIL}}). To activate your account, please click on the following link:<br>
|
You recently signed up on {{APP_NAME}} with this email address ({{EMAIL}}). To activate your account, please click on the following link:<br>
|
||||||
<a href="{{ACTIVATE_LINK}}" title="Account activation">{{ACTIVATE_LINK}}</a>
|
<a href="{{ACTIVATE_LINK}}" title="Account activation">{{ACTIVATE_LINK}}</a>
|
||||||
<br><br>
|
<br><br>
|
||||||
If you did not sign up on MapGuesser or changed your mind, no further action is required, your email address will be deleted soon.<br>
|
If you did not sign up on {{APP_NAME}} or changed your mind, no further action is required, your email address will be deleted soon.<br>
|
||||||
However if you want to immediately delete it, please click on the following link:<br>
|
However if you want to immediately delete it, please click on the following link:<br>
|
||||||
<a href="{{CANCEL_LINK}}" title="Sign up cancellation">{{CANCEL_LINK}}</a>
|
<a href="{{CANCEL_LINK}}" title="Sign up cancellation">{{CANCEL_LINK}}</a>
|
||||||
<br><br>
|
<br><br>
|
||||||
Have fun on MapGuesser!
|
Have fun on {{APP_NAME}}!
|
||||||
<br><br>
|
<br><br>
|
||||||
Regards,<br>
|
Regards,<br>
|
||||||
MapGuesser<br>
|
{{APP_NAME}}<br>
|
||||||
<a href="{{BASE_URL}}" title="MapGuesser">{{BASE_URL}}</a>
|
<a href="{{BASE_URL}}" title="{{APP_NAME}}">{{BASE_URL}}</a>
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
#panorama {
|
#panorama {
|
||||||
width: 100%;
|
position: absolute;
|
||||||
height: calc(100% - 40px);
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#guessCover {
|
#panoCover {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 40px;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@@ -111,7 +114,7 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
#guess {
|
#guess {
|
||||||
top: 50px;
|
top: 10px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
opacity: 0.95;
|
opacity: 0.95;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@@ -157,7 +160,7 @@
|
|||||||
#guess.result {
|
#guess.result {
|
||||||
width: initial;
|
width: initial;
|
||||||
height: initial;
|
height: initial;
|
||||||
top: 50px;
|
top: 10px;
|
||||||
left: 50px;
|
left: 50px;
|
||||||
right: 50px;
|
right: 50px;
|
||||||
bottom: 50px;
|
bottom: 50px;
|
||||||
@@ -167,11 +170,11 @@
|
|||||||
}
|
}
|
||||||
@media screen and (max-height: 424px) {
|
@media screen and (max-height: 424px) {
|
||||||
#guess {
|
#guess {
|
||||||
top: 50px;
|
top: 10px;
|
||||||
height: initial;
|
height: initial;
|
||||||
}
|
}
|
||||||
#guess.adapt:hover {
|
#guess.adapt:hover {
|
||||||
top: 50px;
|
top: 10px;
|
||||||
height: initial;
|
height: initial;
|
||||||
}
|
}
|
||||||
#guess.result {
|
#guess.result {
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
#map {
|
#map {
|
||||||
width: 100%;
|
position: absolute;
|
||||||
height: calc(100% - 40px);
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* modify the cursor for the Leaflet map */
|
||||||
.leaflet-container {
|
.leaflet-container {
|
||||||
cursor: crosshair;
|
cursor: crosshair;
|
||||||
}
|
}
|
||||||
@@ -16,6 +20,8 @@
|
|||||||
|
|
||||||
#noPano {
|
#noPano {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@@ -23,12 +29,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#noPano>p {
|
#noPano>p {
|
||||||
margin: auto;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#control {
|
#control {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
width: 125px;
|
width: 125px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
@@ -48,31 +54,34 @@
|
|||||||
|
|
||||||
@media screen and (max-width: 999px) and (min-height: 600px) {
|
@media screen and (max-width: 999px) and (min-height: 600px) {
|
||||||
#map.selected {
|
#map.selected {
|
||||||
height: calc(50% - 20px);
|
height: 50%;
|
||||||
}
|
}
|
||||||
#panorama, #noPano {
|
#panorama, #noPano {
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: calc(50% - 20px);
|
height: 50%;
|
||||||
}
|
}
|
||||||
#placeControl {
|
#placeControl {
|
||||||
top: calc(50% + 30px);
|
top: calc(50% + 10px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1000px), (max-height: 599px) {
|
@media screen and (min-width: 1000px), (max-height: 599px) {
|
||||||
#map.selected {
|
#map.selected {
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
#panorama, #noPano {
|
#panorama, #noPano {
|
||||||
top: 40px;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
#placeControl {
|
#placeControl {
|
||||||
top: 50px;
|
top: 10px;
|
||||||
}
|
}
|
||||||
#modified.selected {
|
#modified.selected {
|
||||||
right: calc(50% + 10px);
|
right: calc(50% + 10px);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ h1>a:hover, h1>a:focus {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2, div.header.small h1 {
|
h2, header.small h1 {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +83,8 @@ hr {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.small {
|
p.small, span.small {
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.justify {
|
.justify {
|
||||||
@@ -119,6 +119,7 @@ svg.inline, img.inline {
|
|||||||
display: inline;
|
display: inline;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
|
margin-right: 0.3em;
|
||||||
vertical-align: -0.15em;
|
vertical-align: -0.15em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +148,13 @@ button, a.button {
|
|||||||
line-height: 35px;
|
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 {
|
button:enabled:hover, button:enabled:focus, a.button:hover, a.button:focus {
|
||||||
background-color: #29457f;
|
background-color: #29457f;
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -250,11 +258,10 @@ input.big:focus, select.big:focus, textarea.big:focus {
|
|||||||
|
|
||||||
div.modal {
|
div.modal {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 100px;
|
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 20px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
@@ -280,7 +287,7 @@ p.formError {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header {
|
header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto auto;
|
grid-template-columns: auto auto;
|
||||||
background-color: #333333;
|
background-color: #333333;
|
||||||
@@ -290,33 +297,50 @@ div.header {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header.small {
|
header.small {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header>p.header {
|
header>p {
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header>p.header>span {
|
header>p>span {
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header>p.header>span>a:link, div.header>p.header>span>a:visited {
|
header>p>span>a:link, header>p>span>a:visited {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header>p.header>span:not(:last-child) {
|
header>p>span:not(:last-child) {
|
||||||
border-right: solid white 1px;
|
border-right: solid white 1px;
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.main {
|
main {
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.full {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
background-color: #444444;
|
||||||
|
padding: 6px 12px;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer>p {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
div.buttonContainer {
|
div.buttonContainer {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
}
|
}
|
||||||
@@ -325,6 +349,12 @@ div.buttonContainer>button {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cookiesNotice {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
#loading {
|
#loading {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 64px;
|
width: 64px;
|
||||||
@@ -347,9 +377,12 @@ div.box {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 599px) {
|
@media screen and (max-width: 599px) {
|
||||||
div.header h1 span {
|
header h1 span {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
footer>p:not(:first-child) {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
button, a.button {
|
button, a.button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -363,6 +396,8 @@ div.box {
|
|||||||
div.modal {
|
div.modal {
|
||||||
left: 20px;
|
left: 20px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
}
|
}
|
||||||
div.box {
|
div.box {
|
||||||
width: initial;
|
width: initial;
|
||||||
@@ -370,9 +405,48 @@ div.box {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 600px) {
|
@media screen and (min-width: 600px) {
|
||||||
|
footer>p {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
footer>p:not(:first-child) {
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
footer>p:not(:last-child) {
|
||||||
|
border-right: solid white 1px;
|
||||||
|
padding-right: 6px;
|
||||||
|
}
|
||||||
div.modal {
|
div.modal {
|
||||||
width: 540px;
|
width: 540px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -270px;
|
margin-left: -270px;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-height: 399px) {
|
||||||
|
div.modal {
|
||||||
|
top: 20px;
|
||||||
|
max-height: calc(100% - 40px);
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-height: 400px) and (max-height: 499px) {
|
||||||
|
div.modal {
|
||||||
|
top: 50px;
|
||||||
|
max-height: calc(100% - 100px);
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-height: 500px) {
|
||||||
|
div.modal {
|
||||||
|
top: 75px;
|
||||||
|
max-height: calc(100% - 150px);
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,17 +29,16 @@ div.mapItem>div.title>p.title {
|
|||||||
div.mapItem>div.imgContainer {
|
div.mapItem>div.imgContainer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: 50%;
|
padding-top: 50%;
|
||||||
background: #cccccc;
|
background-color: #cccccc;
|
||||||
}
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
div.mapItem>div.imgContainer>img {
|
background-size: cover;
|
||||||
width: 100%;
|
|
||||||
margin-top: -50%
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.mapItem>div.inner {
|
div.mapItem>div.inner {
|
||||||
background-color: #eeeeee;
|
background-color: #eeeeee;
|
||||||
padding: 10px 8px;
|
padding: 10px 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.mapItem>div.inner>div.info {
|
div.mapItem>div.inner>div.info {
|
||||||
@@ -47,6 +46,12 @@ div.mapItem>div.inner>div.info {
|
|||||||
grid-template-columns: auto auto;
|
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) {
|
div.mapItem>div.inner>div.info>p:nth-child(1) {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
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('currentRound').innerHTML = '1/' + String(Game.NUMBER_OF_ROUNDS);
|
||||||
document.getElementById('currentScoreSum').innerHTML = '0/0';
|
document.getElementById('currentScoreSum').innerHTML = '0/0';
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
MapGuesser.httpRequest('GET', '/game/' + mapId + '/newPlace.json', function () {
|
MapGuesser.httpRequest('GET', '/game/' + mapId + '/newPlace.json', function () {
|
||||||
document.getElementById('loading').style.visibility = 'hidden';
|
document.getElementById('loading').style.visibility = 'hidden';
|
||||||
document.getElementById('guessCover').style.visibility = 'hidden';
|
document.getElementById('panoCover').style.visibility = 'hidden';
|
||||||
|
|
||||||
if (this.response.error) {
|
if (this.response.error) {
|
||||||
//TODO: handle this error
|
//TODO: handle this error
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
lastRound.line.setVisible(false);
|
lastRound.line.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('guessCover').style.visibility = 'hidden';
|
document.getElementById('panoCover').style.visibility = 'hidden';
|
||||||
document.getElementById('showGuessButton').style.visibility = null;
|
document.getElementById('showGuessButton').style.visibility = null;
|
||||||
document.getElementById('guess').style.visibility = null;
|
document.getElementById('guess').style.visibility = null;
|
||||||
document.getElementById('guess').classList.remove('result')
|
document.getElementById('guess').classList.remove('result')
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
document.getElementById('guess').classList.remove('adapt');
|
document.getElementById('guess').classList.remove('adapt');
|
||||||
}
|
}
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
document.getElementById('loading').style.visibility = 'visible';
|
||||||
document.getElementById('guessCover').style.visibility = 'visible';
|
document.getElementById('panoCover').style.visibility = 'visible';
|
||||||
|
|
||||||
var data = new FormData();
|
var data = new FormData();
|
||||||
data.append('lat', String(guessPosition.lat));
|
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)) {
|
if (!('ontouchstart' in document.documentElement)) {
|
||||||
Game.adaptGuess = true;
|
Game.adaptGuess = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,49 @@
|
|||||||
var MapGuesser = {
|
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) {
|
httpRequest: function (method, url, callback, data) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
|||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ "$#" -lt 1 ]; then
|
||||||
|
echo "Usage: $0 <sql_file>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SQL_FILE=$1
|
||||||
|
|
||||||
|
ROOT_DIR=$(dirname $(readlink -f "$0"))/..
|
||||||
|
|
||||||
|
. ${ROOT_DIR}/.env
|
||||||
|
|
||||||
|
if [ -z "${DEV}" ] || [ "${DEV}" -eq "0" ]; then
|
||||||
|
echo "This script can only be used in DEV mode!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running SQL on DB..."
|
||||||
|
mysql --host=${DB_HOST} --user=${DB_USER} --password=${DB_PASSWORD} ${DB_NAME} < ${SQL_FILE}
|
||||||
+1
-1
@@ -5,7 +5,7 @@ ROOT_DIR=$(dirname $(readlink -f "$0"))/..
|
|||||||
. ${ROOT_DIR}/.env
|
. ${ROOT_DIR}/.env
|
||||||
|
|
||||||
echo "Installing Composer packages..."
|
echo "Installing Composer packages..."
|
||||||
(cd ${ROOT_DIR} && composer install)
|
(cd ${ROOT_DIR} && composer install --no-dev)
|
||||||
|
|
||||||
echo "Installing Yarn packages..."
|
echo "Installing Yarn packages..."
|
||||||
(cd ${ROOT_DIR}/public/static && yarn install)
|
(cd ${ROOT_DIR}/public/static && yarn install)
|
||||||
|
|||||||
@@ -1,12 +1,30 @@
|
|||||||
<?php namespace MapGuesser\Controller;
|
<?php namespace MapGuesser\Controller;
|
||||||
|
|
||||||
|
use MapGuesser\Interfaces\Request\IRequest;
|
||||||
|
use MapGuesser\Interfaces\Response\IContent;
|
||||||
use MapGuesser\Interfaces\Response\IRedirect;
|
use MapGuesser\Interfaces\Response\IRedirect;
|
||||||
|
use MapGuesser\Response\JsonContent;
|
||||||
use MapGuesser\Response\Redirect;
|
use MapGuesser\Response\Redirect;
|
||||||
|
|
||||||
class HomeController
|
class HomeController
|
||||||
{
|
{
|
||||||
|
private IRequest $request;
|
||||||
|
|
||||||
|
public function __construct(IRequest $request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
}
|
||||||
|
|
||||||
public function getIndex(): IRedirect
|
public function getIndex(): IRedirect
|
||||||
{
|
{
|
||||||
return new Redirect(\Container::$routeCollection->getRoute('maps')->generateLink(), IRedirect::TEMPORARY);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -373,12 +373,11 @@ class LoginController
|
|||||||
{
|
{
|
||||||
$mail = new Mail();
|
$mail = new Mail();
|
||||||
$mail->addRecipient($email);
|
$mail->addRecipient($email);
|
||||||
$mail->setSubject('Welcome to MapGuesser - Activate your account');
|
$mail->setSubject('Welcome to ' . $_ENV['APP_NAME'] . ' - Activate your account');
|
||||||
$mail->setBodyFromTemplate('signup', [
|
$mail->setBodyFromTemplate('signup', [
|
||||||
'EMAIL' => $email,
|
'EMAIL' => $email,
|
||||||
'ACTIVATE_LINK' => $this->request->getBase() . '/'. \Container::$routeCollection->getRoute('signup.activate')->generateLink(['token' => $token]),
|
'ACTIVATE_LINK' => $this->request->getBase() . '/'. \Container::$routeCollection->getRoute('signup.activate')->generateLink(['token' => $token]),
|
||||||
'CANCEL_LINK' => $this->request->getBase() . '/' . \Container::$routeCollection->getRoute('signup.cancel')->generateLink(['token' => $token]),
|
'CANCEL_LINK' => $this->request->getBase() . '/' . \Container::$routeCollection->getRoute('signup.cancel')->generateLink(['token' => $token]),
|
||||||
'BASE_URL' => $this->request->getBase(),
|
|
||||||
]);
|
]);
|
||||||
$mail->send();
|
$mail->send();
|
||||||
}
|
}
|
||||||
@@ -387,10 +386,9 @@ class LoginController
|
|||||||
{
|
{
|
||||||
$mail = new Mail();
|
$mail = new Mail();
|
||||||
$mail->addRecipient($email);
|
$mail->addRecipient($email);
|
||||||
$mail->setSubject('Welcome to MapGuesser');
|
$mail->setSubject('Welcome to ' . $_ENV['APP_NAME']);
|
||||||
$mail->setBodyFromTemplate('signup-noconfirm', [
|
$mail->setBodyFromTemplate('signup-noconfirm', [
|
||||||
'EMAIL' => $email,
|
'EMAIL' => $email,
|
||||||
'BASE_URL' => $this->request->getBase(),
|
|
||||||
]);
|
]);
|
||||||
$mail->send();
|
$mail->send();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ class Mail
|
|||||||
{
|
{
|
||||||
$this->body = file_get_contents(ROOT . '/mail/' . $template . '.html');
|
$this->body = file_get_contents(ROOT . '/mail/' . $template . '.html');
|
||||||
|
|
||||||
|
$baseParameters = [
|
||||||
|
'APP_NAME' => $_ENV['APP_NAME'],
|
||||||
|
'BASE_URL' => \Container::$request->getBase(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$params = array_merge($baseParameters, $params);
|
||||||
|
|
||||||
foreach ($params as $key => $param) {
|
foreach ($params as $key => $param) {
|
||||||
$this->body = str_replace('{{' . $key . '}}', $param, $this->body);
|
$this->body = str_replace('{{' . $key . '}}', $param, $this->body);
|
||||||
}
|
}
|
||||||
@@ -58,8 +65,8 @@ class Mail
|
|||||||
$mailer->Mailer = 'mail';
|
$mailer->Mailer = 'mail';
|
||||||
}
|
}
|
||||||
|
|
||||||
$mailer->setFrom($_ENV['MAIL_FROM'], 'MapGuesser');
|
$mailer->setFrom($_ENV['MAIL_FROM'], $_ENV['APP_NAME']);
|
||||||
$mailer->addReplyTo($_ENV['MAIL_FROM'], 'MapGuesser');
|
$mailer->addReplyTo($_ENV['MAIL_FROM'], $_ENV['APP_NAME']);
|
||||||
|
|
||||||
$mailer->Sender = !empty($_ENV['MAIL_BOUNCE']) ? $_ENV['MAIL_BOUNCE'] : $_ENV['MAIL_FROM'];
|
$mailer->Sender = !empty($_ENV['MAIL_BOUNCE']) ? $_ENV['MAIL_BOUNCE'] : $_ENV['MAIL_FROM'];
|
||||||
$mailer->Subject = $this->subject;
|
$mailer->Subject = $this->subject;
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ class RouteCollection
|
|||||||
{
|
{
|
||||||
$groupNumber = count($uri);
|
$groupNumber = count($uri);
|
||||||
|
|
||||||
|
// response to HEAD request with the GET content
|
||||||
|
if ($method === 'head') {
|
||||||
|
$method = 'get';
|
||||||
|
}
|
||||||
|
|
||||||
if (!isset($this->searchTable[$method][$groupNumber])) {
|
if (!isset($this->searchTable[$method][$groupNumber])) {
|
||||||
return null;
|
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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
-19
@@ -13,11 +13,11 @@ $jsFiles = [
|
|||||||
];
|
];
|
||||||
?>
|
?>
|
||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<div class="header small">
|
<header class="small">
|
||||||
<h1>
|
<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 ?>">
|
<img class="inline" width="1em" height="1em" src="<?= $_ENV['STATIC_ROOT'] ?>/img/icon.svg?rev=<?= REVISION ?>"><!--
|
||||||
<span>MapGuesser</span>
|
--><span><?= $_ENV['APP_NAME'] ?></span>
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="header">
|
<p class="header">
|
||||||
@@ -28,26 +28,26 @@ $jsFiles = [
|
|||||||
<path fill-rule="evenodd" d="M8 3.5a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5H4a.5.5 0 0 1 0-1h3.5V4a.5.5 0 0 1 .5-.5z"/>
|
<path fill-rule="evenodd" d="M8 3.5a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5H4a.5.5 0 0 1 0-1h3.5V4a.5.5 0 0 1 .5-.5z"/>
|
||||||
<path fill-rule="evenodd" d="M7.5 8a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1H8.5V12a.5.5 0 0 1-1 0V8z"/>
|
<path fill-rule="evenodd" d="M7.5 8a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1H8.5V12a.5.5 0 0 1-1 0V8z"/>
|
||||||
<path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
<path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
||||||
</svg>
|
</svg><!--
|
||||||
<span id="added" class="bold">0</span><!--
|
--><span id="added" class="bold">0</span><!--
|
||||||
--></span><!--
|
--></span><!--
|
||||||
--><span><!--
|
--><span><!--
|
||||||
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
--><svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
--><svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M15.502 1.94a.5.5 0 0 1 0 .706a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/> <path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
<path d="M15.502 1.94a.5.5 0 0 1 0 .706a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/> <path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
||||||
</svg>
|
</svg><!--
|
||||||
<span id="edited" class="bold">0</span><!--
|
--><span id="edited" class="bold">0</span><!--
|
||||||
--></span><!--
|
--></span><!--
|
||||||
--><span><!--
|
--><span><!--
|
||||||
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
--><svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
--><svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" d="M3.5 8a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1H4a.5.5 0 0 1-.5-.5z"/>
|
<path fill-rule="evenodd" d="M3.5 8a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1H4a.5.5 0 0 1-.5-.5z"/>
|
||||||
<path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
<path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
||||||
</svg>
|
</svg><!--
|
||||||
<span id="deleted" class="bold">0</span><!--
|
--><span id="deleted" class="bold">0</span><!--
|
||||||
--></span>
|
--></span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</header>
|
||||||
<div id="metadata" class="modal">
|
<div id="metadata" class="modal">
|
||||||
<h2>Edit map data</h2>
|
<h2>Edit map data</h2>
|
||||||
<form id="metadataForm" class="marginTop">
|
<form id="metadataForm" class="marginTop">
|
||||||
@@ -59,18 +59,20 @@ $jsFiles = [
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="map"></div>
|
<div class="full">
|
||||||
<div id="control">
|
<div id="map"></div>
|
||||||
<button id="saveButton" class="fullWidth" disabled>Save</button>
|
<div id="panorama"></div>
|
||||||
</div>
|
<div id="noPano">
|
||||||
<div id="panorama"></div>
|
|
||||||
<div id="noPano">
|
|
||||||
<p class="bold">No panorama is available for this location.</p>
|
<p class="bold">No panorama is available for this location.</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="placeControl">
|
<div id="control">
|
||||||
|
<button id="saveButton" class="fullWidth" disabled>Save</button>
|
||||||
|
</div>
|
||||||
|
<div id="placeControl">
|
||||||
<button id="applyButton" class="fullWidth">Apply</button>
|
<button id="applyButton" class="fullWidth">Apply</button>
|
||||||
<button id="closeButton" class="gray fullWidth marginTop">Close</button>
|
<button id="closeButton" class="gray fullWidth marginTop">Close</button>
|
||||||
<button id="deleteButton" class="red fullWidth marginTop">Delete</button>
|
<button id="deleteButton" class="red fullWidth marginTop">Delete</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
var tileUrl = '<?= $_ENV['LEAFLET_TILESERVER_URL'] ?>';
|
var tileUrl = '<?= $_ENV['LEAFLET_TILESERVER_URL'] ?>';
|
||||||
|
|||||||
+2
-3
@@ -1,7 +1,6 @@
|
|||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>404 | Page not found</h2>
|
<h2>404 | Page not found</h2>
|
||||||
<p>The requested URL was not found on this server. <a href="/" title="MapGuesser">Back to start.</a></p>
|
<p>The requested URL was not found on this server. <a href="/" title="<?= $_ENV['APP_NAME'] ?>">Back to start.</a></p>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
+12
-10
@@ -8,11 +8,11 @@ $jsFiles = [
|
|||||||
];
|
];
|
||||||
?>
|
?>
|
||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<div class="header small">
|
<header class="small">
|
||||||
<h1>
|
<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 ?>">
|
<img class="inline" width="1em" height="1em" src="<?= $_ENV['STATIC_ROOT'] ?>/img/icon.svg?rev=<?= REVISION ?>"><!--
|
||||||
<span>MapGuesser</span>
|
--><span><?= $_ENV['APP_NAME'] ?></span>
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="header">
|
<p class="header">
|
||||||
@@ -20,13 +20,14 @@ $jsFiles = [
|
|||||||
--><span>Round <span id="currentRound" class="bold"></span></span><!--
|
--><span>Round <span id="currentRound" class="bold"></span></span><!--
|
||||||
--><span>Score <span id="currentScoreSum" class="bold"></span></span>
|
--><span>Score <span id="currentScoreSum" class="bold"></span></span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</header>
|
||||||
<div id="guessCover"></div>
|
<div class="full">
|
||||||
<div id="panorama"></div>
|
<div id="panoCover"></div>
|
||||||
<div id="showGuessButtonContainer">
|
<div id="panorama"></div>
|
||||||
|
<div id="showGuessButtonContainer">
|
||||||
<button id="showGuessButton" class="fullWidth">Show guess map</button>
|
<button id="showGuessButton" class="fullWidth">Show guess map</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="guess">
|
<div id="guess">
|
||||||
<div id="closeGuessButtonContainer" class="buttonContainer marginBottom">
|
<div id="closeGuessButtonContainer" class="buttonContainer marginBottom">
|
||||||
<button id="closeGuessButton" class="fullWidth gray">Close</button>
|
<button id="closeGuessButton" class="fullWidth gray">Close</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,6 +55,7 @@ $jsFiles = [
|
|||||||
<button id="showSummaryButton" class="fullWidth">Show summary</button>
|
<button id="showSummaryButton" class="fullWidth">Show summary</button>
|
||||||
<button id="startNewGameButton" class="fullWidth">Play this map again</button>
|
<button id="startNewGameButton" class="fullWidth">Play this map again</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
var mapId = <?= $mapId ?>;
|
var mapId = <?= $mapId ?>;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Account activation</h2>
|
<h2>Account activation</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<p class="error justify">Activation failed. Please check the link you entered or retry <a href="/signup" title="Sign up">sign up</a>!</p>
|
<p class="error justify">Activation failed. Please check the link you entered or retry <a href="/signup" title="Sign up">sign up</a>!</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Account cancellation</h2>
|
<h2>Account cancellation</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<?php if ($success) : ?>
|
<?php if ($success) : ?>
|
||||||
@@ -9,5 +8,5 @@
|
|||||||
<p class="error justify">Cancellation failed. Please check the link you entered! Maybe the account was already deleted, in this case no further action is required.</p>
|
<p class="error justify">Cancellation failed. Please check the link you entered! Maybe the account was already deleted, in this case no further action is required.</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Login up with Google</h2>
|
<h2>Login up with Google</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<p class="error justify">Authenticating with Google failed. Please <a href="/login/google" title="Login with Google">retry</a>!</p>
|
<p class="error justify">Authenticating with Google failed. Please <a href="/login/google" title="Login with Google">retry</a>!</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Sign up</h2>
|
<h2>Sign up</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<form id="googleSignupForm" action="/signup/google" method="post">
|
<form id="googleSignupForm" action="/signup/google" method="post">
|
||||||
@@ -22,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
var form = document.getElementById('googleSignupForm');
|
var form = document.getElementById('googleSignupForm');
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ $jsFiles = [
|
|||||||
?>
|
?>
|
||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Login</h2>
|
<h2>Login</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<form id="loginForm" action="/login" method="post">
|
<form id="loginForm" action="/login" method="post">
|
||||||
@@ -21,5 +20,5 @@ $jsFiles = [
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
@@ -5,7 +5,6 @@ $jsFiles = [
|
|||||||
?>
|
?>
|
||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Sign up</h2>
|
<h2>Sign up</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<form id="signupForm" action="/signup" method="post">
|
<form id="signupForm" action="/signup" method="post">
|
||||||
@@ -31,5 +30,5 @@ $jsFiles = [
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Sign up</h2>
|
<h2>Sign up</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<p class="justify">Sign up was successful. Please check your email and click on the activation link to activate your account!</p>
|
<p class="justify">Sign up was successful. Please check your email and click on the activation link to activate your account!</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
+93
-13
@@ -5,36 +5,34 @@ $cssFiles = [
|
|||||||
?>
|
?>
|
||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Playable maps</h2>
|
|
||||||
<div id="mapContainer">
|
<div id="mapContainer">
|
||||||
<?php foreach ($maps as $map): ?>
|
<?php foreach ($maps as $map): ?>
|
||||||
<div class="mapItem">
|
<div class="mapItem">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<p class="title"><?= $map['name'] ?></p>
|
<p class="title"><?= $map['name'] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="imgContainer">
|
<div class="imgContainer" data-bound-south-lat="<?= $map['bound_south_lat'] ?>" data-bound-west-lng="<?= $map['bound_west_lng'] ?>" data-bound-north-lat="<?= $map['bound_north_lat'] ?>" data-bound-east-lng="<?= $map['bound_east_lng'] ?>"></div>
|
||||||
<img src="https://maps.googleapis.com/maps/api/staticmap?size=350x175&visible=<?= $map['bound_south_lat'] . ',' . $map['bound_west_lng'] . '|' . $map['bound_north_lat'] . ',' . $map['bound_east_lng'] ?>&key=<?= $_ENV['GOOGLE_MAPS_JS_API_KEY'] ?>" alt="Map area">
|
|
||||||
</div>
|
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<p>
|
<p>
|
||||||
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" />
|
<path fill-rule="evenodd" d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" />
|
||||||
</svg>
|
</svg><!--
|
||||||
<?= $map['num_places'] ?> places
|
--><?= $map['num_places'] ?> places
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" d="M12.5 2h-9V1h9v1zm-10 1.5v9h-1v-9h1zm11 9v-9h1v9h-1zM3.5 14h9v1h-9v-1z" />
|
<path fill-rule="evenodd" d="M12.5 2h-9V1h9v1zm-10 1.5v9h-1v-9h1zm11 9v-9h1v9h-1zM3.5 14h9v1h-9v-1z" />
|
||||||
<path fill-rule="evenodd" d="M14 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM2 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4z" />
|
<path fill-rule="evenodd" d="M14 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM2 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4z" />
|
||||||
</svg>
|
</svg><!--
|
||||||
~ <?= $map['area'][0] ?> <?= $map['area'][1] ?><sup>2</sup>
|
-->~ <?= $map['area'][0] ?> <?= $map['area'][1] ?><sup>2</sup>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="small justify marginTop"><?= $map['description'] ?></p>
|
<div class="description marginTop">
|
||||||
|
<p class="small center"><?= $map['description'] ?></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($isAdmin): ?>
|
<?php if ($isAdmin): ?>
|
||||||
<div class="buttonContainer">
|
<div class="buttonContainer">
|
||||||
@@ -62,10 +60,90 @@ $cssFiles = [
|
|||||||
<?php endfor; ?>
|
<?php endfor; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
|
<script>
|
||||||
|
(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 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;
|
||||||
|
|
||||||
|
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): ?>
|
<?php if ($isAdmin): ?>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function () {
|
||||||
Maps = {
|
Maps = {
|
||||||
deleteMap: function(mapId, mapName) {
|
deleteMap: function(mapId, mapName) {
|
||||||
MapGuesser.showModalWithContent('Delete map', 'Are you sure you want to delete map \'' + mapName + '\'?', [{
|
MapGuesser.showModalWithContent('Delete map', 'Are you sure you want to delete map \'' + mapName + '\'?', [{
|
||||||
@@ -91,7 +169,9 @@ $cssFiles = [
|
|||||||
};
|
};
|
||||||
|
|
||||||
var buttons = document.getElementById('mapContainer').getElementsByClassName('deleteButton');
|
var buttons = document.getElementById('mapContainer').getElementsByClassName('deleteButton');
|
||||||
for (var button of buttons) {
|
for (var i = 0; i < buttons.length; i++) {
|
||||||
|
var button = buttons[i];
|
||||||
|
|
||||||
button.onclick = function() {
|
button.onclick = function() {
|
||||||
Maps.deleteMap(this.dataset.mapId, this.dataset.mapName);
|
Maps.deleteMap(this.dataset.mapId, this.dataset.mapName);
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-2
@@ -5,7 +5,6 @@ $jsFiles = [
|
|||||||
?>
|
?>
|
||||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||||
<div class="main">
|
|
||||||
<h2>Profile</h2>
|
<h2>Profile</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<form id="profileForm" action="/profile" method="post">
|
<form id="profileForm" action="/profile" method="post">
|
||||||
@@ -21,5 +20,5 @@ $jsFiles = [
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php require ROOT . '/views/templates/footer.php'; ?>
|
||||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<p><span class="bold"><?= $_ENV['APP_NAME'] ?></span> <?= str_replace('Release_', '', VERSION) ?></p><!--
|
||||||
|
--><p>© Pőcze Bence <?= (new DateTime(REVISION_DATE))->format('Y') ?></p>
|
||||||
|
</footer>
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
<div class="header">
|
<header>
|
||||||
<h1>
|
<h1>
|
||||||
<a href="/" title="MapGuesser">
|
<a href="/" title="<?= $_ENV['APP_NAME'] ?>">
|
||||||
<img class="inline" width="1em" height="1em" src="<?= $_ENV['STATIC_ROOT'] ?>/img/icon.svg?rev=<?= REVISION ?>">
|
<img class="inline" width="1em" height="1em" src="<?= $_ENV['STATIC_ROOT'] ?>/img/icon.svg?rev=<?= REVISION ?>"><!--
|
||||||
<span>MapGuesser</span>
|
--><span><?= $_ENV['APP_NAME'] ?></span>
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="header">
|
<p>
|
||||||
<?php if (Container::$request->user()) : ?>
|
<?php if (Container::$request->user()) : ?>
|
||||||
<span><a href="/profile" title="Profile">
|
<span><a href="/profile" title="Profile">
|
||||||
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
|
<path fill-rule="evenodd" d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
|
||||||
</svg>
|
</svg><!--
|
||||||
<?= Container::$request->user()->getDisplayName() ?><!--
|
--><?= Container::$request->user()->getDisplayName() ?><!--
|
||||||
--></a></span><!--
|
--></a></span><!--
|
||||||
--><span><a href="/logout" title="Logout">Logout</a></span>
|
--><span><a href="/logout" title="Logout">Logout</a></span>
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
@@ -20,4 +20,5 @@
|
|||||||
--><span><a href="/login" title="Login">Login</a></span>
|
--><span><a href="/login" title="Login">Login</a></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</header>
|
||||||
|
<main>
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
const STATIC_ROOT = '<?= $_ENV['STATIC_ROOT'] ?>';
|
const STATIC_ROOT = '<?= $_ENV['STATIC_ROOT'] ?>';
|
||||||
const REVISION = '<?= REVISION ?>';
|
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>
|
||||||
<script src="<?= $_ENV['STATIC_ROOT'] ?>/js/mapguesser.js?rev=<?= REVISION ?>"></script>
|
<script src="<?= $_ENV['STATIC_ROOT'] ?>/js/mapguesser.js?rev=<?= REVISION ?>"></script>
|
||||||
<?php if (isset($jsFiles)) : ?>
|
<?php if (isset($jsFiles)) : ?>
|
||||||
@@ -14,5 +17,33 @@
|
|||||||
<script src="<?= $jsFile ?>"></script>
|
<script src="<?= $jsFile ?>"></script>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>MapGuesser</title>
|
<title><?= $_ENV['APP_NAME'] ?></title>
|
||||||
<link href="<?= $_ENV['STATIC_ROOT'] ?>/css/mapguesser.css?rev=<?= REVISION ?>" rel="stylesheet">
|
<link href="<?= $_ENV['STATIC_ROOT'] ?>/css/mapguesser.css?rev=<?= REVISION ?>" rel="stylesheet">
|
||||||
<?php if (isset($cssFiles)) : ?>
|
<?php if (isset($cssFiles)) : ?>
|
||||||
<?php foreach ($cssFiles as $cssFile) : ?>
|
<?php foreach ($cssFiles as $cssFile) : ?>
|
||||||
@@ -22,6 +22,14 @@
|
|||||||
<link rel="icon" type="image/png" sizes="16x16" href="<?= $_ENV['STATIC_ROOT'] ?>/img/favicon/16x16.png?rev=<?= REVISION ?>">
|
<link rel="icon" type="image/png" sizes="16x16" href="<?= $_ENV['STATIC_ROOT'] ?>/img/favicon/16x16.png?rev=<?= REVISION ?>">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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">
|
<div id="loading">
|
||||||
<img src="<?= $_ENV['STATIC_ROOT'] ?>/img/loading.svg?rev=<?= REVISION ?>" width="64" height="64">
|
<img src="<?= $_ENV['STATIC_ROOT'] ?>/img/loading.svg?rev=<?= REVISION ?>" width="64" height="64">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ if (!empty($_ENV['DEV'])) {
|
|||||||
|
|
||||||
Container::$routeCollection = new MapGuesser\Routing\RouteCollection();
|
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) {
|
Container::$routeCollection->group('login', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||||
$routeCollection->get('login', '', [MapGuesser\Controller\LoginController::class, 'getLoginForm']);
|
$routeCollection->get('login', '', [MapGuesser\Controller\LoginController::class, 'getLoginForm']);
|
||||||
$routeCollection->post('login-action', '', [MapGuesser\Controller\LoginController::class, 'login']);
|
$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->get('profile', '', [MapGuesser\Controller\UserController::class, 'getProfile']);
|
||||||
$routeCollection->post('profile-action', '', [MapGuesser\Controller\UserController::class, 'saveProfile']);
|
$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) {
|
Container::$routeCollection->group('game', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||||
$routeCollection->get('game', '{mapId}', [MapGuesser\Controller\GameController::class, 'getGame']);
|
$routeCollection->get('game', '{mapId}', [MapGuesser\Controller\GameController::class, 'getGame']);
|
||||||
$routeCollection->get('game-json', '{mapId}/json', [MapGuesser\Controller\GameController::class, 'getGameJson']);
|
$routeCollection->get('game-json', '{mapId}/json', [MapGuesser\Controller\GameController::class, 'getGameJson']);
|
||||||
@@ -49,15 +50,19 @@ Container::$routeCollection->group('admin', function (MapGuesser\Routing\RouteCo
|
|||||||
$routeCollection->post('admin.deleteMap', 'deleteMap/{mapId}', [MapGuesser\Controller\MapAdminController::class, 'deleteMap']);
|
$routeCollection->post('admin.deleteMap', 'deleteMap/{mapId}', [MapGuesser\Controller\MapAdminController::class, 'deleteMap']);
|
||||||
});
|
});
|
||||||
|
|
||||||
Container::$sessionHandler = new MapGuesser\Session\DatabaseSessionHandler();
|
if (isset($_COOKIE['COOKIES_CONSENT'])) {
|
||||||
|
Container::$sessionHandler = new MapGuesser\Session\DatabaseSessionHandler();
|
||||||
|
|
||||||
session_set_save_handler(Container::$sessionHandler, true);
|
session_set_save_handler(Container::$sessionHandler, true);
|
||||||
session_start([
|
session_start([
|
||||||
'gc_maxlifetime' => 604800,
|
'gc_maxlifetime' => 604800,
|
||||||
'cookie_lifetime' => 604800,
|
'cookie_lifetime' => 604800,
|
||||||
'cookie_httponly' => true,
|
'cookie_httponly' => true,
|
||||||
'cookie_samesite' => 'Lax'
|
'cookie_samesite' => 'Lax'
|
||||||
]);
|
]);
|
||||||
|
} else {
|
||||||
|
$_SESSION = [];
|
||||||
|
}
|
||||||
|
|
||||||
Container::$request = new MapGuesser\Request\Request($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'], $_GET, $_POST, $_SESSION);
|
Container::$request = new MapGuesser\Request\Request($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'], $_GET, $_POST, $_SESSION);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user