[skip-ci] Merge pull request #140 from allerta-vvf/improvements

Code style improvements
This commit is contained in:
Matteo Gheza 2021-04-05 23:35:00 +02:00 committed by GitHub
commit c3461c5eaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 732 additions and 728 deletions

View File

@ -1,4 +1,4 @@
FROM trafex/alpine-nginx-php7:latest AS webserver
FROM trafex/alpine-nginx-php7:1.10.0 AS webserver
LABEL maintainer="matteo@matteogheza.it"
LABEL version="1.0"
@ -16,4 +16,4 @@ RUN composer install --no-dev --optimize-autoloader --no-interaction --no-progre
#RUN echo "@reboot cd /var/www/html/install && php install.php config" > /etc/crontabs/root
USER nobody
EXPOSE 8080
EXPOSE 8080

View File

@ -75,7 +75,7 @@ foreach ($remotes as $key => $value) {
$config[$key]["before"] = [];
} else {
$env = isset($config[$key]["sentry_env"]) ? $config[$key]["sentry_env"] : "prod";
$config[$key]["before"][] = "local: cd server/resources && npm i && npm run prod -- --env sentry_environment=".$env;
$config[$key]["before"][] = "local: cd server/resources && npm i && npm run prod -- --env sentryEnvironment=".$env;
}
if(isset($value["after"]) && $value["after"] === false){
$config[$key]["after"] = [];

View File

@ -217,7 +217,7 @@ $routeInfo = $dispatcher->dispatch($httpMethod, $uri);
function responseApi($content, $status_code=200)
{
global $responseFormat, $responseFormatType;
global $responseFormat;
if($status_code !== 200) {
http_response_code($status_code);
}

View File

@ -51,7 +51,7 @@ class InlinekeyboardCommand extends UserCommand
{
$chat_id = $this->getMessage()->getChat()->getId();
$switch_element = mt_rand(0, 9) < 5 ? 'true' : 'false';
$switch_element = random_int(0, 9) < 5 ? 'true' : 'false';
$inline_keyboard = new InlineKeyboard(
[

View File

@ -92,7 +92,7 @@ class KeyboardCommand extends UserCommand
);
//Return a random keyboard.
//$keyboard = $keyboards[mt_rand(0, count($keyboards) - 1)]
//$keyboard = $keyboards[random_int(0, count($keyboards) - 1)]
$keyboard = $keyboards[4]
->setResizeKeyboard(true)
->setOneTimeKeyboard(true)

View File

@ -57,13 +57,6 @@ class StartCommand extends SystemCommand
$chat_id = $message->getChat()->getId();
$keyboard = new Keyboard(
['7', '8', '9'],
['4', '5', '6'],
['1', '2', '3'],
[' ', '0', ' ']
);
$text = 'Hi there!' . PHP_EOL . 'Type /help to see all commands!';
$data = [

View File

@ -193,7 +193,7 @@ class tools
header("data: ".$response_data);
header("Content-type: application/json");
if(!is_null($debugbar)) $debugbar->sendDataInHeaders(true);
if(isset($_GET["old_data"]) && $_GET["old_data"] !== $response_data){
if(isset($_GET["oldData"]) && $_GET["oldData"] !== $response_data){
print($json_response);
} else {
print("{}");
@ -246,10 +246,10 @@ class database
}
if($this->load_from_file) {
if(file_exists($this->options_cache_file)/* && time()-@filemtime($this->options_cache_file) < 604800*/) {
$this->options = unserialize(file_get_contents($this->options_cache_file), ['allowed_classes' => false]);
$this->options = json_decode(file_get_contents($this->options_cache_file), true);
} else {
$this->options = $this->exec("SELECT * FROM `%PREFIX%_options` WHERE `enabled` = 1", true);
file_put_contents($this->options_cache_file, serialize($this->options));
file_put_contents($this->options_cache_file, json_encode($this->options));
}
} else {
$this->options = $this->exec("SELECT * FROM `%PREFIX%_options` WHERE `enabled` = 1", true);
@ -469,7 +469,7 @@ class user
return array("autenticated" => $this->authenticated(), "id" => $this->auth->getUserId(), "name" => $this->name(), "full_viewer" => $this->requireRole(Role::FULL_VIEWER), "tester" => $this->requireRole(Role::TESTER), "developer" => $this->requireRole(Role::DEVELOPER));
}
public function login($name, $password, $remember_me, $twofa=null)
public function login($name, $password, $remember_me)
{
$this->tools->profiler_start("Login");
if(!empty($name)) {
@ -571,6 +571,8 @@ class user
public function add_user($email, $name, $username, $password, $phone_number, $birthday, $chief, $driver, $hidden, $disabled, $inserted_by)
{
//TODO: save birthday in db
bdump($birthday);
$this->tools->profiler_start("Add user");
$userId = $this->auth->admin()->createUserWithUniqueUsername($email, $password, $username);
if($userId) {
@ -753,7 +755,7 @@ class translations
} else {
$client_languages = explode(",", $client_languages);
$tmp_languages = [];
foreach($client_languages as $key=>$language){
foreach($client_languages as $language){
if(strpos($language, ';') == false) {
$tmp_languages[$language] = 1;
} else {
@ -875,6 +877,7 @@ function init_class($enableDebugger=true, $headers=true)
global $webpack_manifest_path;
$error = error_get_last();
if ($error) {
bdump($webpack_manifest_path);
require("error_page.php");
show_error_page(500);
}

View File

@ -12,7 +12,7 @@ function customErrorHandler(int $errNo, string $errMsg, string $file, int $line)
"file" => $file,
"line" => $line
];
$output_status = "error";
var_dump($output);
}
error_reporting(-1);
set_error_handler('customErrorHandler');

View File

@ -32,7 +32,7 @@ function client_languages()
} else {
$client_languages = explode(",", $client_languages);
$tmp_languages = [];
foreach($client_languages as $key=>$language){
foreach($client_languages as $language){
if(strpos($language, ';') == false) {
$tmp_languages[$language] = 1;
} else {
@ -659,7 +659,7 @@ function run_cli()
->setDescription(t("Destination path", false))
->setArgumentName('path')
->setValidation(
'is_writable', function ($operand, $value) {
'is_writable', function ($value) {
if(file_exists($value)) {
printf(t("%s is not writable. Directory permissions: %s"), $value, @fileperms($value));
exit(4);

View File

@ -1,8 +1,8 @@
{
"sentry_enabled": false,
"sentry_dsn": "",
"sentry_environment": "prod",
"sentry_auth_token": "",
"sentry_organization": "",
"sentry_project": ""
"sentryEnabled": false,
"sentryDsn": "",
"sentryEnvironment": "prod",
"sentryAuthToken": "",
"sentryOrganization": "",
"sentryProject": ""
}

View File

@ -1,19 +1,20 @@
var GAME_LOADING_ERROR_MSG = 'Game loading failed, please retry later.';
const GAME_LOADING_ERROR_MSG = "Game loading failed, please retry later.";
async function play(game){
async function play (game) {
console.log("Opening game " + game + "...");
try {
await import(`./games/${game}/game.js`)
.then(({default: Game}) => {
var game = new Game();
$("body").append('<div class="modal" id="modal_game" tabindex="-1" role="dialog" data-backdrop="static" style="display: none; min-width: 100%; margin: 0px;"><div class="modal-dialog" role="document" style="min-width: 100%; margin: 0;"><div class="modal-content" style="min-height: 100vh;" id="modal_game_content"></div></div></div>');
$("#modal_game_content").append(`<div class="modal-header"><h5 class="modal-title" style="color: black">${game.title}</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div class="modal-body" id="modal_game_body"></div>`);
$("#modal_game_body").append(`<div id="game_content" style="text-align: center"></div><p style="text-align: right; color: black;">Game by <a style="color: blue" target="_blank" href="${game.author_url}">${game.author}</a></p>`);
$('#modal_game').modal('show');
game.initialize($("#game_content"));
});
$('#modal_game').on('hidden.bs.modal', function (e) {
.then(({ default: Game }) => {
const game = new Game();
$("body").append("<div class=\"modal\" id=\"modal_game\" tabindex=\"-1\" role=\"dialog\" data-backdrop=\"static\" style=\"display: none; min-width: 100%; margin: 0px;\"><div class=\"modal-dialog\" role=\"document\" style=\"min-width: 100%; margin: 0;\"><div class=\"modal-content\" style=\"min-height: 100vh;\" id=\"modal_game_content\"></div></div></div>");
$("#modal_game_content").append(`<div class="modal-header"><h5 class="modal-title" style="color: black">${game.title}</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div class="modal-body" id="modal_game_body"></div>`);
$("#modal_game_body").append(`<div id="game_content" style="text-align: center"></div><p style="text-align: right; color: black;">Game by <a style="color: blue" target="_blank" href="${game.authorUrl}">${game.author}</a></p>`);
$("#modal_game").modal("show");
game.initialize($("#game_content"));
});
$("#modal_game").on("hidden.bs.modal", function (e) {
$("#modal_game").remove();
})
});
} catch (error) {
console.error(error);
toastr.error(GAME_LOADING_ERROR_MSG);
@ -21,4 +22,4 @@ async function play(game){
}
window.play = play;
window.GAME_LOADING_ERROR_MSG = GAME_LOADING_ERROR_MSG;
window.GAME_LOADING_ERROR_MSG = GAME_LOADING_ERROR_MSG;

View File

@ -2,7 +2,7 @@ export default class {
constructor(){
this.title = "Empty game";
this.author = "Prova";
this.author_url = "https://example.com/";
this.authorUrl = "https://example.com/";
}
initialize(container){

View File

@ -1,18 +1,18 @@
import {default as createUnityInstance} from './ld46.loader.js';
import {default as createUnityInstance} from "./ld46.loader.js";
import build_size_data from './ld46.data.gz';
import build_size_framework from './ld46.framework.js.gz';
import build_size_wasm from './ld46.wasm.gz';
import buildSizeData from "./ld46.data.gz";
import buildSizeFramework from "./ld46.framework.js.gz";
import buildSizeWasm from "./ld46.wasm.gz";
console.log("data "+build_size_data);
console.log("framework "+build_size_framework);
console.log("wasm "+build_size_wasm);
console.log("data "+buildSizeData);
console.log("framework "+buildSizeFramework);
console.log("wasm "+buildSizeWasm);
export default class {
constructor(){
this.title = "What the firetruck";
this.author = "dvdfu";
this.author_url = "https://github.com/dvdfu";
this.authorUrl = "https://github.com/dvdfu";
}
initialize(container){

View File

@ -1,237 +1,237 @@
body:not(table) {
max-width: 100%;
overflow-x: hidden;
max-width: 100%;
overflow-x: hidden;
}
@keyframes gradual_blur {
0% {-webkit-filter: blur(0px);}
50% {-webkit-filter: blur(2px);}
100% {-webkit-filter: blur(5px);}
0% { -webkit-filter: blur(0); }
50% { -webkit-filter: blur(2px); }
100% { -webkit-filter: blur(5px); }
}
.loading_blur {
animation: gradual_blur 1s;
animation-fill-mode: forwards;
cursor: wait;
animation: gradual_blur 1s;
animation-fill-mode: forwards;
cursor: wait;
}
.loading_no_blur {
animation: gradual_blur 1s;
animation-direction: reverse;
animation-fill-mode: forwards;
animation: gradual_blur 1s;
animation-direction: reverse;
animation-fill-mode: forwards;
}
.loading_overlay {
position: absolute;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
center {
text-align: center;
text-align: center;
}
#modulogin {
margin-top: 60px;
padding: 30px 0 30px 0;
width: 90%;
height: auto;
background: #fafafa;
border-radius: 15px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
margin-top: 60px;
padding: 30px 0 30px 0;
width: 90%;
height: auto;
background: #fafafa;
border-radius: 15px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
input::placeholder {
color: lightgray;
color: lightgray;
}
.modal-text {
margin-top: 15px;
line-height: 25px;
font-size: 1.0em;
font-family: calibri;
margin-top: 15px;
line-height: 25px;
/*
font-size: 1em;
font-family: calibri;
*/
}
/* Add a black background color to the top navigation */
.topnav {
background-color: red;
overflow: hidden;
background-color: red;
overflow: hidden;
}
/* Style the links inside the navigation bar */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
/* Change the color of links on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
background-color: #ddd;
color: black;
}
/* Add an active class to highlight the current page */
.active {
background-color: #4CAF50;
color: white;
background-color: #4caf50;
color: white;
}
/* Hide the link that should open and close the topnav on small screens */
.topnav .icon {
display: none;
display: none;
}
/* When the screen is less than 600 pixels wide, hide all links, except for the first one ("Home"). Show the link that contains should open and close the topnav (.icon) */
@media screen and (max-width: 600px) {
.topnav a:not(:first-child) {
display: none;
}
.topnav a:not(:first-child) {
display: none;
}
.topnav a.icon {
float: right;
display: block;
}
.topnav a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
@media screen and (max-width: 600px) {
.topnav.responsive {
position: relative;
}
.topnav.responsive {
position: relative;
}
.topnav.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
}
#bottom {
background-color: grey;
color: white;
background-color: grey;
color: white;
}
div.img {
border: 2px solid white;
float: left;
margin: 10px;
width: 100px;
height: 100px;
border: 2px solid white;
float: left;
margin: 10px;
width: 100px;
height: 100px;
}
#add {
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: bold 12px Arial, Helvetica, sans-serif;
color: #fff;
padding: 10px 20px;
border: solid 1px #0076a3;
background: #0095cd;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: bold 12px Arial, Helvetica, sans-serif;
color: #fff;
padding: 10px 20px;
border: solid 1px #0076a3;
background: #0095cd;
}
.form_input {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
box-sizing: border-box;
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
box-sizing: border-box;
}
button {
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
background-color: #4caf50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
}
button:hover {
opacity: 0.8;
opacity: 0.8;
}
.container {
padding: 16px;
padding: 16px;
}
span.psw {
float: right;
padding-top: 16px;
float: right;
padding-top: 16px;
}
/* Change styles for span and cancel button on extra small screens */
@media screen and (max-width: 300px) {
span.psw {
display: block;
float: none;
}
span.psw {
display: block;
float: none;
}
.cancelbtn {
width: 100%;
}
.cancelbtn {
width: 100%;
}
}
textarea {
width: 100%;
height: 150px;
padding: 12px 20px;
box-sizing: border-box;
border: 2px solid #ccc;
border-radius: 4px;
background-color: #f8f8f8;
resize: none;
width: 100%;
height: 150px;
padding: 12px 20px;
box-sizing: border-box;
border: 2px solid #ccc;
border-radius: 4px;
background-color: #f8f8f8;
resize: none;
}
#href {
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: bold 12px Arial, Helvetica, sans-serif;
color: #fff;
padding: 10px 20px;
border: solid 1px #0076a3;
background: #0095cd;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: bold 12px Arial, Helvetica, sans-serif;
color: #fff;
padding: 10px 20px;
border: solid 1px #0076a3;
background: #0095cd;
}
table {
margin: auto;
max-width: 95%;
text-align:center;
overflow-x:auto;
margin: auto;
max-width: 95%;
text-align: center;
overflow-x: auto;
}
#table_wrapper{
margin-left:auto;
margin-right:auto;
width: 95%;
#table_wrapper {
margin-left: auto;
margin-right: auto;
width: 95%;
}
th, td {
text-align: center;
vertical-align: middle !important;
th,
td {
text-align: center;
vertical-align: middle !important;
}
.fa{
vertical-align: middle;
font-size: 20px;
}
.fa {
vertical-align: middle;
font-size: 20px;
}

View File

@ -1,49 +1,50 @@
jQuery = $;
window.$ = window.jQuery = $;
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import './main.css';
import './font-awesome.scss';
import 'bootstrap-datepicker';
import '../node_modules/bootstrap-toggle/css/bootstrap-toggle.css';
import '../node_modules/bootstrap-toggle/js/bootstrap-toggle.js';
import '../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.css';
import 'time-input-polyfill/auto';
import 'jquery-pjax';
import toastr from 'toastr'
import 'toastr/build/toastr.css';
import "bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
import "./main.css";
import "./font-awesome.scss";
import "bootstrap-datepicker";
import "../node_modules/bootstrap-toggle/css/bootstrap-toggle.css";
import "../node_modules/bootstrap-toggle/js/bootstrap-toggle.js";
import "../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.css";
import "time-input-polyfill/auto";
import "jquery-pjax";
import toastr from "toastr";
import "toastr/build/toastr.css";
window.toastr = toastr;
toastr.options = {
"closeButton": false,
"debug": false,
"newestOnTop": false,
"progressBar": true,
"positionClass": "toast-bottom-right",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
}
closeButton: false,
debug: false,
newestOnTop: false,
progressBar: true,
positionClass: "toast-bottom-right",
preventDuplicates: false,
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
$.fn.loading = function(action="start", options) {
var opts = $.extend( {}, $.fn.loading.defaults, options );
$.fn.loading = function (action = "start", options) {
const opts = $.extend({}, $.fn.loading.defaults, options);
if(action == "show") {
this.addClass("loading_blur");
$( "body" ).append( "<div id='loading_div' class='loading_overlay'><p class=''><b>"+opts.message+"</b></p></div>" );
} else if(action == "hide") {
this.removeClass("loading_blur");
this.addClass("loading_no_blur");
setTimeout(() => {
this.removeClass("loading_no_blur");
}, 1000);
$( "#loading_div" ).remove();
if (action === "show") {
this.addClass("loading_blur");
$("body").append("<div id='loading_div' class='loading_overlay'><p class=''><b>" + opts.message + "</b></p></div>");
} else if (action === "hide") {
this.removeClass("loading_blur");
this.addClass("loading_no_blur");
setTimeout(() => {
this.removeClass("loading_no_blur");
}, 1000);
$("#loading_div").remove();
}
};
@ -51,74 +52,74 @@ $.fn.loading.defaults = {
message: "Loading..."
};
console.log("Commit: "+process.env.GIT_VERSION);
console.log("Date: "+process.env.GIT_AUTHOR_DATE);
console.log("Bundle mode: "+process.env.BUNDLE_MODE);
console.log("Bundle date: "+new Date(process.env.BUNDLE_DATE).toISOString());
console.log("Commit: " + process.env.GIT_VERSION);
console.log("Date: " + process.env.GIT_AUTHOR_DATE);
console.log("Bundle mode: " + process.env.BUNDLE_MODE);
console.log("Bundle date: " + new Date(process.env.BUNDLE_DATE).toISOString());
$(document).pjax('a:not(.pjax_disable)', '#content', {timeout: 100000});
$(document).on('pjax:start', function() {
if(document.getElementById("topNavBar") !== undefined){
$(document).pjax("a:not(.pjax_disable)", "#content", { timeout: 100000 });
$(document).on("pjax:start", function () {
if (document.getElementById("topNavBar") !== undefined) {
document.getElementById("topNavBar").className = "topnav";
}
old_data = "null";
oldData = "null";
fillTable = undefined;
table_engine = "datatables";
if(window.loadTable_interval !== undefined){
clearInterval(window.loadTable_interval);
window.loadTable_interval = undefined;
tableEngine = "datatables";
if (window.loadTableInterval !== undefined) {
clearInterval(window.loadTableInterval);
window.loadTableInterval = undefined;
}
})
});
// Cookie functions from w3schools
function setCookie(cname, cvalue, exdays) {
var d = new Date();
function setCookie (cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
const expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
function getCookie (cname) {
const name = cname + "=";
const decodedCookie = decodeURIComponent(document.cookie);
const ca = decodedCookie.split(";");
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === " ") {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
$( document ).ajaxError(function(event, xhr, settings, error) {
console.error("Error requesting content: "+error+" - status code "+xhr.status);
console.log(event);
console.log(xhr);
console.log(settings);
$(document).ajaxError(function (event, xhr, settings, error) {
console.error("Error requesting content: " + error + " - status code " + xhr.status);
console.log(event);
console.log(xhr);
console.log(settings);
});
if (getCookie("authenticated")) {
var installServiceWorker = false;
if(window.skipServiceWorkerInstallation !== undefined){ //if you want to disable SW for example via GreasyFork userscript
if (window.skipServiceWorkerInstallation !== undefined) { // if you want to disable SW for example via GreasyFork userscript
installServiceWorker = false;
}
if(getCookie("disableServiceWorkerInstallation")){
if (getCookie("disableServiceWorkerInstallation")) {
console.log("Skipping ServiceWorker installation because cookie 'disableServiceWorkerInstallation' exists");
installServiceWorker = false;
}
if ('serviceWorker' in navigator) {
if ('connection' in navigator && navigator.connection.saveData && !getCookie("forceServiceWorkerInstallation")) {
if ("serviceWorker" in navigator) {
if ("connection" in navigator && navigator.connection.saveData && !getCookie("forceServiceWorkerInstallation")) {
console.log("Skipping ServiceWorker installation because saveData is enabled");
installServiceWorker = false;
}
if ('storage' in navigator && 'estimate' in navigator.storage && !getCookie("forceServiceWorkerInstallation")){
navigator.storage.estimate().then(quota => {
if ("storage" in navigator && "estimate" in navigator.storage && !getCookie("forceServiceWorkerInstallation")) {
navigator.storage.estimate().then((quota) => {
const requiredMemory = 3 * 1e+6;
if (quota < requiredMemory) {
console.log("Skipping ServiceWorker installation because memory is low. memory="+quota);
console.log("Skipping ServiceWorker installation because memory is low. memory=" + quota);
installServiceWorker = false;
}
});
@ -127,112 +128,116 @@ if (getCookie("authenticated")) {
installServiceWorker = false;
}
}
if(installServiceWorker){
window.addEventListener('load', () => {
navigator.serviceWorker.register('sw.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
if (installServiceWorker) {
window.addEventListener("load", () => {
navigator.serviceWorker.register("sw.js").then((registration) => {
console.log("SW registered: ", registration);
}).catch((registrationError) => {
console.log("SW registration failed: ", registrationError);
});
});
}
$( document ).ready(function() {
if($("#frontend_version") !== undefined){
$("#frontend_version").append(process.env.GIT_VERSION+" aggiornamento "+new Date(process.env.BUNDLE_DATE).toLocaleString());
$(document).ready(function () {
if ($("#frontend_version") !== undefined) {
$("#frontend_version").append(process.env.GIT_VERSION + " aggiornamento " + new Date(process.env.BUNDLE_DATE).toLocaleString());
}
});
var offline = false;
var loadTable_interval = undefined;
var old_data = "null";
var table_engine = "datatables";
const offline = false;
const loadTableInterval = undefined;
var oldData = "null";
var tableEngine = "datatables";
var fillTable = undefined;
async function loadTable({table_page, set_interval=true, interval=10000, onlineReload=false, use_custom_table_engine=false, callback=false}){
if (typeof fillTable === "undefined"){
if(use_custom_table_engine !== false){
table_engine = use_custom_table_engine;
} else if ('connection' in navigator && navigator.connection.saveData) {
table_engine = "default";
async function loadTable ({ tablePage, setTableRefreshInterval = true, interval = 10000, onlineReload = false, useCustomTableEngine = false, callback = false }) {
if (typeof fillTable === "undefined") {
if (useCustomTableEngine !== false) {
tableEngine = useCustomTableEngine;
} else if ("connection" in navigator && navigator.connection.saveData) {
tableEngine = "default";
}
fillTable = await import(`./table_engine_${table_engine}.js`)
.then(({default: _}) => {
return _;
});
fillTable = await import(`./table_engine_${tableEngine}.js`)
.then(({ default: _ }) => {
return _;
});
}
if ('getBattery' in navigator) {
if ("getBattery" in navigator) {
navigator.getBattery().then((level, charging) => {
if (!charging && level < 0.2) {
return;
}
})
});
}
if ('deviceMemory' in navigator && navigator.deviceMemory < 0.2) {
if ("deviceMemory" in navigator && navigator.deviceMemory < 0.2) {
return;
}
let replaceLatLngWithMap = table_page == "services" || table_page == "trainings";
$.getJSON({ url: "resources/ajax/ajax_"+table_page+".php", data: { "old_data": old_data }, success: function( data, status, xhr ) {
old_data = xhr.getResponseHeader('data'); //TODO: refactoring and adding comments
console.log(data);
if(data.length > 0){
fillTable({data, replaceLatLngWithMap, callback});
var headers = new Headers();
headers.append('date', Date.now());
caches.open('tables-1').then((cache) => {
cache.put('/table_'+table_page+'.json', new Response(xhr.responseText, {headers: headers}))
});
}
if(window.offline){ // if xhr request successful, client is online
console.log(onlineReload);
if(onlineReload){
location.reload(); //for offline page
} else {
$("#offline_alert").hide(400);
window.offline = false;
const replaceLatLngWithMap = tablePage === "services" || tablePage === "trainings";
$.getJSON({
url: "resources/ajax/ajax_" + tablePage + ".php",
data: { oldData: oldData },
success: function (data, status, xhr) {
oldData = xhr.getResponseHeader("data"); // TODO: refactoring and adding comments
console.log(data);
if (data.length > 0) {
fillTable({ data, replaceLatLngWithMap, callback });
const headers = new Headers();
headers.append("date", Date.now());
caches.open("tables-1").then((cache) => {
cache.put("/table_" + tablePage + ".json", new Response(xhr.responseText, { headers: headers }));
});
}
if (window.offline) { // if xhr request successful, client is online
console.log(onlineReload);
if (onlineReload) {
location.reload(); // for offline page
} else {
$("#offline_alert").hide(400);
window.offline = false;
}
}
}
}}).fail(function(data, status) {
if(status == "parsererror"){
if($("#table_body").children().length == 0) { //this is a server-side authentication error on some cheap hosting providers
loadTable(table_page, set_interval, interval); //retry
}).fail(function (data, status) {
if (status === "parsererror") {
if ($("#table_body").children().length === 0) { // this is a server-side authentication error on some cheap hosting providers
loadTable(tablePage, setTableRefreshInterval, interval); // retry
} // else nothing
} else {
caches.open('tables-1').then(cache => {
cache.match("/table_"+table_page+".json").then(response => {
response.json().then(data => {
fillTable({data, replaceLatLngWithMap, callback});
caches.open("tables-1").then((cache) => {
cache.match("/table_" + tablePage + ".json").then((response) => {
response.json().then((data) => {
fillTable({ data, replaceLatLngWithMap, callback });
console.log("Table loaded from cache");
$("#offline_update").text(new Date(parseInt(response.headers.get("date"))).toLocaleString());
$("#offline_update").text(new Date(parseInt(response.headers.get("date"), 10)).toLocaleString());
});
});
});
if(!window.offline){ // if xhr request fails, client is offline
if (!window.offline) { // if xhr request fails, client is offline
$("#offline_alert").show(400);
window.offline = true;
}
}
});
if(set_interval){
if ('connection' in navigator && navigator.connection.saveData) {
if (setTableRefreshInterval) {
if ("connection" in navigator && navigator.connection.saveData) {
interval += 5000;
}
console.log("table_load interval "+interval);
window.loadTable_interval = setInterval(function() {
window.loadTable({table_page, set_interval: false, interval, onlineReload, use_custom_table_engine, callback: false});
console.log("table_load interval " + interval);
window.loadTableInterval = setInterval(function () {
window.loadTable({ tablePage, setTableRefreshInterval: false, interval, onlineReload, useCustomTableEngine, callback: false });
}, interval);
}
}
function chat() {
function chat () {
setCookie("chat", "true", 1);
location.reload();
}
window.addEventListener('securitypolicyviolation',console.error.bind(console));
window.addEventListener("securitypolicyviolation", console.error.bind(console));
function menu() {
var topNavBar = document.getElementById("topNavBar");
function menu () {
const topNavBar = document.getElementById("topNavBar");
if (topNavBar.className === "topnav") {
topNavBar.className += " responsive";
} else {
@ -240,9 +245,9 @@ function menu() {
}
}
window.loadTable_interval = loadTable_interval;
window.loadTableInterval = loadTableInterval;
window.loadTable = loadTable;
window.setCookie = setCookie;
window.getCookie = getCookie;
window.chat = chat;
window.menu = menu;
window.menu = menu;

View File

@ -1,32 +1,33 @@
div#map {
width: 100%;
height: 500px;
width: 100%;
height: 500px;
}
.map {
width: 100%;
height: 500px;
width: 100%;
height: 500px;
}
div#search {
background-color: rgba(255, 255, 255, 0.4);
bottom: 40px;
left: 40px;
width: auto;
height: auto;
padding: 10px;
background-color: rgba(255, 255, 255, 0.4);
bottom: 40px;
left: 40px;
width: auto;
height: auto;
padding: 10px;
}
div#results {
font-style: sans-serif;
color: black;
font-size: 75%;
font-style: sans-serif;
color: black;
font-size: 75%;
}
.fa.fa-map-marker-alt,.fa.fa-spinner.fa-spin {
line-height: inherit;
.fa.fa-map-marker-alt,
.fa.fa-spinner.fa-spin {
line-height: inherit;
}
.leaflet-pane.leaflet-shadow-pane {
display: none;
}
display: none;
}

View File

@ -1,210 +1,210 @@
import L from 'leaflet';
import 'leaflet.locatecontrol';
import '../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css'
import '../node_modules/leaflet/dist/leaflet.css';
import './maps.css';
import L from "leaflet";
import "leaflet.locatecontrol";
import "../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css";
import "../node_modules/leaflet/dist/leaflet.css";
import "./maps.css";
const iconRetinaUrl = 'resources/dist/marker-icon-2x.png';
const iconUrl = 'resources/dist/marker-icon.png';
const shadowUrl = 'resources/dist/marker-shadow.png';
const iconRetinaUrl = "resources/dist/marker-icon-2x.png";
const iconUrl = "resources/dist/marker-icon.png";
const shadowUrl = "resources/dist/marker-shadow.png";
const iconDefault = new L.Icon({
iconRetinaUrl,
iconUrl,
shadowUrl,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
tooltipAnchor: [16, -28],
shadowSize: [41, 41]
iconRetinaUrl,
iconUrl,
shadowUrl,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
tooltipAnchor: [16, -28],
shadowSize: [41, 41]
});
var marker;
var feature;
var map;
let marker;
let feature;
let map;
function set_marker(LatLng){
if(marker){
console.log("Marker exists");
//console.log(marker);
marker.remove();
}
function setMarker (LatLng) {
if (marker) {
console.log("Marker exists");
// console.log(marker);
marker.remove();
}
console.log(LatLng);
if($("input[name='place']").val() !== undefined){
if ($("input[name='place']").val() !== undefined) {
$("input[name='place']").val(LatLng.lat + ";" + LatLng.lng);
}
marker = L.marker(LatLng, {icon: iconDefault}).addTo(map);
marker = L.marker(LatLng, { icon: iconDefault }).addTo(map);
}
function load_map(lat=undefined, lng=undefined, selector_id=undefined, select=true) {
if(lat == undefined && lng == undefined){
lat = 45.5285; //TODO: replace hard-coded into cookie reading
lng = 10.2956;
}
if(selector_id == undefined){
selector_id = "map";
}
let zoom = select ? 10 : 17;
let latLng = new L.LatLng(lat, lng);
map = new L.Map(selector_id, {zoomControl: true});
function loadMap (lat = undefined, lng = undefined, selectorId = undefined, select = true) {
if (lat === undefined && lng === undefined) {
lat = 45.5285; // TODO: replace hard-coded into cookie reading
lng = 10.2956;
}
if (selectorId === undefined) {
selectorId = "map";
}
const zoom = select ? 10 : 17;
const latLng = new L.LatLng(lat, lng);
map = new L.Map(selectorId, { zoomControl: true });
let osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttribution = 'Map data &copy; 2012 <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
osm = new L.TileLayer(osmUrl, {maxZoom: 20, attribution: osmAttribution});
const osmUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const osmAttribution = "Map data &copy; 2012 <a href=\"http://openstreetmap.org\">OpenStreetMap</a> contributors";
const osm = new L.TileLayer(osmUrl, { maxZoom: 20, attribution: osmAttribution });
map.setView(latLng, zoom).addLayer(osm);
map.setView(latLng, zoom).addLayer(osm);
if(select){
map.on('click', function(e) {
set_marker(e.latlng);
});
if (select) {
map.on("click", function (e) {
setMarker(e.latlng);
});
L.Control.CustomLocate = L.Control.Locate.extend({
_drawMarker: function() {
set_marker(this._event.latlng);
},
_onDrag: function(){},
_onZoom: function(){},
_onZoomEnd: function(){},
});
L.Control.CustomLocate = L.Control.Locate.extend({
_drawMarker: function () {
setMarker(this._event.latlng);
},
_onDrag: function () {},
_onZoom: function () {},
_onZoomEnd: function () {}
});
let lc = new L.Control.CustomLocate({
icon: "fa fa-map-marker",
cacheLocation: false, //disabled for privacy reasons
}).addTo(map);
const lc = new L.Control.CustomLocate({
icon: "fa fa-map-marker",
cacheLocation: false // disabled for privacy reasons
}).addTo(map);
if($("#addr").val() !== undefined){
document.getElementById("addr").addEventListener("keydown", function(event) {
if (event.key === "Enter") {
event.preventDefault();
document.querySelector("#search > button").click();
}
});
}
if ($("#addr").val() !== undefined) {
document.getElementById("addr").addEventListener("keydown", function (event) {
if (event.key === "Enter") {
event.preventDefault();
document.querySelector("#search > button").click();
}
});
}
if(getCookie("experimental_read_clipboard")){
window.addEventListener("focus", function(event) {
if($("#addr").val() == ""){
console.log("Loading location from clipboard");
navigator.clipboard.readText().then(text => {
$("#addr").val(text);
if(!addr_search()){
$("#addr").val("");
}
}).catch(err => {
console.error('Failed to read clipboard contents: ', err);
});
}
});
}
} else {
set_marker(latLng);
}
map.invalidateSize();
if (getCookie("experimental_read_clipboard")) {
window.addEventListener("focus", function (event) {
if ($("#addr").val() === "") {
console.log("Loading location from clipboard");
navigator.clipboard.readText().then((text) => {
$("#addr").val(text);
if (!addrSearch()) {
$("#addr").val("");
}
}).catch((err) => {
console.error("Failed to read clipboard contents: ", err);
});
}
});
}
} else {
setMarker(latLng);
}
map.invalidateSize();
}
// from unknown source in the Internet
function chooseAddr(addr_lat, addr_lng, zoom=undefined, lat1=undefined, lng1=undefined, lat2=undefined, lng2=undefined, osm_type=undefined) {
addr_lat = addr_lat.replace(",", ".");
addr_lng = addr_lng.replace(",", ".");
if(lat1 !== undefined && lng1 !== undefined && lat2 !== undefined && lng2 !== undefined && osm_type !== undefined){
let loc1 = new L.LatLng(lat1, lng1);
let loc2 = new L.LatLng(lat2, lng2);
let bounds = new L.LatLngBounds(loc1, loc2);
console.log(lat1, lng1, lat2, lng2, osm_type);
set_marker(new L.LatLng(addr_lat, addr_lng));
if (feature) {
map.removeLayer(feature);
}
if (osm_type == "node") {
map.fitBounds(bounds);
map.setZoom(18);
} else {
let loc3 = new L.LatLng(lat1, lng2);
let loc4 = new L.LatLng(lat2, lng1);
feature = L.polyline( [loc1, loc4, loc2, loc3, loc1], {color: 'red'}).addTo(map);
map.fitBounds(bounds);
}
} else if (addr_lat !== undefined && addr_lng !== undefined){
let loc = new L.LatLng(addr_lat, addr_lng);
console.log(loc);
set_marker(loc);
if(zoom !== undefined){
map.setView(loc, zoom);
} else {
map.setView(loc);
}
}
function chooseAddr (addrLat, addrLng, zoom = undefined, lat1 = undefined, lng1 = undefined, lat2 = undefined, lng2 = undefined, osmType = undefined) {
addrLat = addrLat.replace(",", ".");
addrLng = addrLng.replace(",", ".");
if (lat1 !== undefined && lng1 !== undefined && lat2 !== undefined && lng2 !== undefined && osmType !== undefined) {
const loc1 = new L.LatLng(lat1, lng1);
const loc2 = new L.LatLng(lat2, lng2);
const bounds = new L.LatLngBounds(loc1, loc2);
console.log(lat1, lng1, lat2, lng2, osmType);
setMarker(new L.LatLng(addrLat, addrLng));
if (feature) {
map.removeLayer(feature);
}
if (osmType === "node") {
map.fitBounds(bounds);
map.setZoom(18);
} else {
const loc3 = new L.LatLng(lat1, lng2);
const loc4 = new L.LatLng(lat2, lng1);
feature = L.polyline([loc1, loc4, loc2, loc3, loc1], { color: "red" }).addTo(map);
map.fitBounds(bounds);
}
} else if (addrLat !== undefined && addrLng !== undefined) {
const loc = new L.LatLng(addrLat, addrLng);
console.log(loc);
setMarker(loc);
if (zoom !== undefined) {
map.setView(loc, zoom);
} else {
map.setView(loc);
}
}
}
// started from https://derickrethans.nl/leaflet-and-nominatim.html
function addr_search(string_results_found=undefined, string_results_not_found=undefined) {
function searchError(error, checkClipboard){
if(!checkClipboard){
$('<p>', { html: string_results_not_found }).appendTo('#results');
console.error(error);
}
return false;
}
let inp = document.getElementById("addr").value;
//if translation strings are not defined, skip the nominatim step and don't log errors (no console.error)
let checkClipboard = string_results_found==undefined && string_results_not_found==undefined;
$('#results').empty();
function addrSearch (stringResultsFound= undefined, stringResultsNotFound = undefined) {
function searchError (error, checkClipboard) {
if (!checkClipboard) {
$("<p>", { html: stringResultsNotFound }).appendTo("#results");
console.error(error);
}
return false;
}
let inp = document.getElementById("addr").value;
// if translation strings are not defined, skip the nominatim step and don't log errors (no console.error)
const checkClipboard = stringResultsFound=== undefined && stringResultsNotFound === undefined;
$("#results").empty();
if(inp.match("\@(-?[\d\.]*)")){ //Google Maps
try {
inp = inp.split("@")[1].split(",");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if(inp.includes("#map=")) { //OpenStreetMap website
try {
inp = inp.split("#map=")[1].split("/");
chooseAddr(inp[1], inp[2], inp[0]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if(inp.match(/[0-9]+,\s[0-9]+/)) { //Bing
try {
inp = inp.split(", ");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if(inp.match(/[0-9]+;[0-9]+/)) { //DB dump
try {
inp = inp.split(";");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if(!checkClipboard) {
$.getJSON('https://nominatim.openstreetmap.org/search?format=json&limit=5&q=' + inp, function(data) {
let items = [];
if (inp.match("\@(-?[\d\.]*)")) { // Google Maps
try {
inp = inp.split("@")[1].split(",");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (inp.includes("#map=")) { // OpenStreetMap website
try {
inp = inp.split("#map=")[1].split("/");
chooseAddr(inp[1], inp[2], inp[0]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (inp.match(/[0-9]+,\s[0-9]+/)) { // Bing
try {
inp = inp.split(", ");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (inp.match(/[0-9]+;[0-9]+/)) { // DB dump
try {
inp = inp.split(";");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (!checkClipboard) {
$.getJSON("https://nominatim.openstreetmap.org/search?format=json&limit=5&q=" + inp, function (data) {
const items = [];
$.each(data, function(key, val) {
items.push("<li><a href='' onclick='chooseAddr(\"" + val.lat + "\", \"" + val.lon + "\", undefined, " + val.boundingbox[0] + ", " + val.boundingbox[2] + ", " + val.boundingbox[1] + ", " + val.boundingbox[3] + ", \"" + val.osm_type + "\"); return false;'>" + val.display_name + '</a></li>');
});
$.each(data, function (key, val) {
items.push("<li><a href='' onclick='chooseAddr(\"" + val.lat + "\", \"" + val.lon + "\", undefined, " + val.boundingbox[0] + ", " + val.boundingbox[2] + ", " + val.boundingbox[1] + ", " + val.boundingbox[3] + ", \"" + val.osm_type + "\"); return false;'>" + val.display_name + "</a></li>");
});
if (items.length != 0) {
$('<p>', { html: string_results_found+":" }).appendTo('#results');
$('<ul/>', {
'class': 'results-list',
html: items.join('')
}).appendTo('#results');
} else {
$('<p>', { html: string_results_not_found }).appendTo('#results');
}
});
} else {
return false;
}
if (items.length !== 0) {
$("<p>", { html: stringResultsFound+ ":" }).appendTo("#results");
$("<ul/>", {
class: "results-list",
html: items.join("")
}).appendTo("#results");
} else {
$("<p>", { html: stringResultsNotFound }).appendTo("#results");
}
});
} else {
return false;
}
}
window.load_map = load_map;
window.addr_search = addr_search;
window.chooseAddr = chooseAddr;
window.loadMap = loadMap;
window.addrSearch = addrSearch;
window.chooseAddr = chooseAddr;

View File

@ -1 +1 @@
import {Howl, Howler} from 'howler';
import { Howl, Howler } from "howler";

View File

@ -1,16 +1,16 @@
import * as Sentry from "@sentry/browser";
import { Integrations } from "@sentry/tracing";
if(process.env.config && process.env.config.sentry_enabled){
if('connection' in navigator && navigator.connection.saveData){
if (process.env.config && process.env.config.sentryEnabled) {
if ("connection" in navigator && navigator.connection.saveData) {
console.log("Skipping Sentry init because data save is enabled");
} else {
Sentry.init({
dsn: process.env.config.sentry_dsn,
dsn: process.env.config.sentryDsn,
integrations: [new Integrations.BrowserTracing()],
tracesSampleRate: 0.6,
release: "allerta-vvf-frontend@"+process.env.GIT_VERSION,
environment: process.env.config.sentry_environment
release: "allerta-vvf-frontend@" + process.env.GIT_VERSION,
environment: process.env.config.sentryEnvironment
});
}
}
}

View File

@ -1,18 +1,19 @@
const cacheVersion = process.env.BUNDLE_DATE;
const cacheName = "static-"+cacheVersion;
const expectedCaches = [cacheName, 'tables-1'];
const cacheName = "static-" + cacheVersion;
const expectedCaches = [cacheName, "tables-1"];
const urls = ['offline.php', 'manifest.webmanifest', 'resources/images/favicon.ico', 'resources/dist/marker-icon.png', 'resources/dist/layers.png', 'resources/dist/layers-2x.png', 'resources/images/android-chrome-192x192.png', 'resources/images/android-chrome-384x384.png', 'resources/images/black_helmet.png', 'resources/images/red_helmet.png', 'resources/images/wheel.png', 'resources/images/logo.png', 'resources/images/owner.png', 'resources/dist/fonts/fontawesome-webfont.woff2'];
const urls = ["offline.php", "manifest.webmanifest", "resources/images/favicon.ico", "resources/dist/marker-icon.png", "resources/dist/layers.png", "resources/dist/layers-2x.png", "resources/images/android-chrome-192x192.png", "resources/images/android-chrome-384x384.png", "resources/images/black_helmet.png", "resources/images/red_helmet.png", "resources/images/wheel.png", "resources/images/logo.png", "resources/images/owner.png", "resources/dist/fonts/fontawesome-webfont.woff2"];
function fetchHandler(event, content_type, not_found_message){
function fetchHandler (event, contentType, notFoundMessage) {
// TODO: refactoring
console.log(event);
// FROM https://googlechrome.github.io/samples/service-worker/custom-offline-page/
// We only want to call event.respondWith() if this is a navigation request
// for an HTML page.
if (event.request.mode === 'navigate') {
if (event.request.mode === "navigate") {
event.respondWith((async () => {
console.log("respond with");
try {
// First, try to use the navigation preload response if it's supported.
const preloadResponse = await event.preloadResponse;
@ -28,10 +29,10 @@ function fetchHandler(event, content_type, not_found_message){
// due to a network error.
// If fetch() returns a valid HTTP response with a response code in
// the 4xx or 5xx range, the catch() will NOT be called.
console.log('Fetch failed; returning offline page instead.', error);
console.log("Fetch failed; returning offline page instead.", error);
const cache = await caches.open(cacheName);
if(event.request.headers.get('Accept').includes('text/html')){
if (event.request.headers.get("Accept").includes("text/html")) {
cacheFileName = "offline.php";
} else {
cacheFileName = event.request.url;
@ -49,57 +50,57 @@ function fetchHandler(event, content_type, not_found_message){
// were no service worker involvement.
}
self.addEventListener('fetch', function (event) {
var request = event.request;
self.addEventListener("fetch", function (event) {
const request = event.request;
// https://stackoverflow.com/a/49719964
if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') return;
if (event.request.cache === "only-if-cached" && event.request.mode !== "same-origin") return;
if (request.headers.get('Accept').includes('text/html')) {
if (request.headers.get("Accept").includes("text/html")) {
fetchHandler(event, null, "offline.php");
} else if (request.destination == "script") {
fetchHandler(event, "application/javascript", "console.error('Script "+event.request.url+" not found');");
} else if (request.destination == "image") {
} else if (request.destination === "script") {
fetchHandler(event, "application/javascript", "console.error('Script " + event.request.url + " not found');");
} else if (request.destination === "image") {
fetchHandler(event, null, "resources/images/logo.png");
} else if (request.destination == "font") {
} else if (request.destination === "font") {
fetchHandler(event, null, null);
} else if (request.destination == "manifest" || request.url.includes("manifest")) {
} else if (request.destination === "manifest" || request.url.includes("manifest")) {
fetchHandler(event, null, "manifest.webmanifest");
} else {
event.respondWith(fetch(request));
}
});
self.addEventListener('install', event => {
self.addEventListener("install", (event) => {
self.skipWaiting();
event.waitUntil(
caches.open(cacheName).then(cache => {
caches.open(cacheName).then((cache) => {
cache.addAll(urls);
fetch('resources/dist/manifest.json')
.then(response => response.json())
.then(manifest => {
let scripts_required = ["main.js", "maps.js"];
scripts_required.map(script_name => {
fetch("resources/dist/manifest.json")
.then((response) => response.json())
.then((manifest) => {
const scriptsRequired = ["main.js", "maps.js"];
scriptsRequired.map((scriptName) => {
console.log(manifest);
console.log(script_name);
cache.add("resources/dist/"+manifest[script_name]);
console.log(scriptName);
cache.add("resources/dist/" + manifest[scriptName]);
});
});
})
);
})
});
self.addEventListener('activate', event => {
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then(keys => Promise.all(
keys.map(key => {
caches.keys().then((keys) => Promise.all(
keys.map((key) => {
if (!expectedCaches.includes(key)) {
console.log("Deleting cache "+key);
console.log("Deleting cache " + key);
return caches.delete(key);
}
})
)).then(() => {
console.log('Service worker now ready to handle fetches!');
console.log("Service worker now ready to handle fetches!");
})
);
});
});

View File

@ -1,39 +1,39 @@
import jsZip from 'jszip';
window.JSZip = jsZip;
import jsZip from "jszip";
import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
import "datatables.net-bs4/js/dataTables.bootstrap4.min.js";
import "datatables.net-bs4/css/dataTables.bootstrap4.min.css";
import "datatables.net-responsive-bs4/js/responsive.bootstrap4.min.js";
import "datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css";
import "datatables.net-buttons";
import "datatables.net-buttons-bs4/js/buttons.bootstrap4.js";
import "datatables.net-buttons-bs4/css/buttons.bootstrap4.css";
import "datatables.net-buttons/js/buttons.html5.js";
import "datatables.net-buttons/js/buttons.print.js";
window.JSZip = jsZip;
pdfMake.vfs = pdfFonts.pdfMake.vfs;
import 'datatables.net-bs4/js/dataTables.bootstrap4.min.js';
import 'datatables.net-bs4/css/dataTables.bootstrap4.min.css';
import 'datatables.net-responsive-bs4/js/responsive.bootstrap4.min.js';
import 'datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css';
import 'datatables.net-buttons';
import 'datatables.net-buttons-bs4/js/buttons.bootstrap4.js';
import 'datatables.net-buttons-bs4/css/buttons.bootstrap4.css';
import 'datatables.net-buttons/js/buttons.html5.js';
import 'datatables.net-buttons/js/buttons.print.js';
export default async function fillTable({data, replaceLatLngWithMap=false, callback=false}){
export default async function fillTable ({ data, replaceLatLngWithMap = false, callback = false }) {
$("#table_body").empty();
$.each(data, function(row_num, item) {
let row = document.createElement("tr");
row.id = "row-"+row_num;
$.each(item, function(cell_num, i) {
if(i !== null){
if(replaceLatLngWithMap && i.match(/[+-]?\d+([.]\d+)?[;][+-]?\d+([.]\d+)?/gm)){ /* credits to @visoom https://github.com/visoom */
let lat = i.split(";")[0];
let lng = i.split(";")[1];
let mapDiv = document.createElement("div");
$.each(data, function (rowNum, item) {
const row = document.createElement("tr");
row.id = "row-" + rowNum;
$.each(item, function (cellNum, i) {
if (i !== null) {
if (replaceLatLngWithMap && i.match(/[+-]?\d+([.]\d+)?[;][+-]?\d+([.]\d+)?/gm)) { /* credits to @visoom https://github.com/visoom */
const lat = i.split(";")[0];
const lng = i.split(";")[1];
const mapDiv = document.createElement("div");
mapDiv.className = "map";
mapDiv.id = "map-"+row_num;
let mapScript = document.createElement("script");
mapScript.appendChild(document.createTextNode("load_map("+lat+", "+lng+", \"map-"+row_num+"\", false)"));
mapDiv.id = "map-" + rowNum;
const mapScript = document.createElement("script");
mapScript.appendChild(document.createTextNode("loadMap(" + lat + ", " + lng + ", \"map-" + rowNum + "\", false)"));
mapDiv.appendChild(mapScript);
let cell = document.createElement("td");
const cell = document.createElement("td");
cell.appendChild(mapDiv);
row.appendChild(cell);
} else {
let cell = document.createElement("td");
const cell = document.createElement("td");
cell.innerHTML = i;
row.appendChild(cell);
}
@ -44,31 +44,31 @@ export default async function fillTable({data, replaceLatLngWithMap=false, callb
let loadedLanguage = {};
try {
let language = navigator.language || navigator.userLanguage;
language = language.toLowerCase().replace("_","-");
language = language.toLowerCase().replace("_", "-");
language = "it_it";
loadedLanguage = await import(`datatables.net-plugins/i18n/${language}.json`)
.then(({default: _}) => {
return _;
});
.then(({ default: _ }) => {
return _;
});
} catch (error) {
console.error("Error loading DataTables translation:");
console.log(error);
loadedLanguage = {};
}
if(! $.fn.DataTable.isDataTable( '#table' )){
var table_dt = $('#table').DataTable({
if (!$.fn.DataTable.isDataTable("#table")) {
var tableDt = $("#table").DataTable({
responsive: true,
language: loadedLanguage,
buttons: [ 'excel', 'pdf', 'csv' ]
buttons: ["excel", "pdf", "csv"]
});
table_dt.buttons().container()
.appendTo( '#table_wrapper :nth-child(1):eq(0)' );
tableDt.buttons().container()
.appendTo("#table_wrapper :nth-child(1):eq(0)");
if(callback !== false){
callback(table_dt);
if (callback !== false) {
callback(tableDt);
}
} else {
table_dt.rows().invalidate();
tableDt.rows().invalidate();
}
window.table_dt = table_dt;
}
window.tableDt = tableDt;
}

View File

@ -1,24 +1,24 @@
export default async function fillTable({data, replaceLatLngWithMap=false, callback=false}){
export default async function fillTable ({ data, replaceLatLngWithMap = false, callback = false }) {
$("#table_body").empty();
$.each(data, function(row_num, item) {
let row = document.createElement("tr");
row.id = "row-"+row_num;
$.each(item, function(cell_num, i) {
if(i !== null){
if(replaceLatLngWithMap && i.match(/[+-]?\d+([.]\d+)?[;][+-]?\d+([.]\d+)?/gm)){ /* credits to @visoom https://github.com/visoom */
let lat = i.split(";")[0];
let lng = i.split(";")[1];
let mapDiv = document.createElement("div");
$.each(data, function (rowNum, item) {
const row = document.createElement("tr");
row.id = "row-" + rowNum;
$.each(item, function (cellNum, i) {
if (i !== null) {
if (replaceLatLngWithMap && i.match(/[+-]?\d+([.]\d+)?[;][+-]?\d+([.]\d+)?/gm)) { /* credits to @visoom https://github.com/visoom */
const lat = i.split(";")[0];
const lng = i.split(";")[1];
const mapDiv = document.createElement("div");
mapDiv.className = "map";
mapDiv.id = "map-"+row_num;
let mapScript = document.createElement("script");
mapScript.appendChild(document.createTextNode("load_map("+lat+", "+lng+", \"map-"+row_num+"\", false)"));
mapDiv.id = "map-" + rowNum;
const mapScript = document.createElement("script");
mapScript.appendChild(document.createTextNode("loadMap(" + lat + ", " + lng + ", \"map-" + rowNum + "\", false)"));
mapDiv.appendChild(mapScript);
let cell = document.createElement("td");
const cell = document.createElement("td");
cell.appendChild(mapDiv);
row.appendChild(cell);
} else {
let cell = document.createElement("td");
const cell = document.createElement("td");
cell.innerHTML = i;
row.appendChild(cell);
}
@ -26,7 +26,7 @@ export default async function fillTable({data, replaceLatLngWithMap=false, callb
});
document.getElementById("table_body").appendChild(row);
});
if(callback !== false){
if (callback !== false) {
callback();
}
}
}

View File

@ -1,56 +1,56 @@
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const WebpackAssetsManifest = require('webpack-assets-manifest');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
var webpack = require('webpack');
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
const WebpackAssetsManifest = require("webpack-assets-manifest");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
var webpack = require("webpack");
module.exports = {
entry: {
main: path.resolve(__dirname, './src/main.js'),
maps: path.resolve(__dirname, './src/maps.js'),
players: path.resolve(__dirname, './src/players.js'),
sw: path.resolve(__dirname, './src/sw.js'),
games: path.resolve(__dirname, './src/games.js'),
main: path.resolve(__dirname, "./src/main.js"),
maps: path.resolve(__dirname, "./src/maps.js"),
players: path.resolve(__dirname, "./src/players.js"),
sw: path.resolve(__dirname, "./src/sw.js"),
games: path.resolve(__dirname, "./src/games.js"),
},
output: {
filename: (pathData) => {
return pathData.chunk.name === 'sw' ? '../../sw.js': '[name].[contenthash].js';
return pathData.chunk.name === "sw" ? "../../sw.js": "[name].[contenthash].js";
},
path: path.resolve(__dirname, 'dist'),
publicPath: 'resources/dist/',
chunkFilename: '[name].bundle.js?h=[chunkhash]'
path: path.resolve(__dirname, "dist"),
publicPath: "resources/dist/",
chunkFilename: "[name].bundle.js?h=[chunkhash]"
},
resolve: {
alias: {
// Force all modules to use the same jquery version.
'jquery': path.join(__dirname, 'node_modules/jquery/src/jquery')
"jquery": path.join(__dirname, "node_modules/jquery/src/jquery")
}
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
use: ["style-loader", "css-loader"],
},
{
test: /\.s(a|c)ss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: require.resolve('jquery'),
loader: 'expose-loader',
test: require.resolve("jquery"),
loader: "expose-loader",
options: {
exposes: ['$', 'jQuery'],
exposes: ["$", "jQuery"],
},
},
{
test: /\.(gif|png|jpg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
loader: "file-loader",
options: {
name: '[name].[ext]',
outputPath: './'
name: "[name].[ext]",
outputPath: "./"
}
}
]
@ -58,11 +58,11 @@ module.exports = {
{
test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
use: [{
loader: 'file-loader',
loader: "file-loader",
options: {
name: '[name].[ext]',
outputPath: 'fonts/',
publicPath: 'resources/dist/fonts'
name: "[name].[ext]",
outputPath: "fonts/",
publicPath: "resources/dist/fonts"
}
}]
},
@ -70,14 +70,14 @@ module.exports = {
test: /\.(gz|wasm|js_resource|data)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
loader: "file-loader",
options: {
name: '[name].[ext]',
outputPath: './'
name: "[name].[ext]",
outputPath: "./"
}
}
],
type: 'asset/resource'
type: "asset/resource"
}
],
},
@ -86,7 +86,7 @@ module.exports = {
new CleanWebpackPlugin(),
new CopyPlugin({
patterns: [
{ from: 'node_modules/leaflet/dist/images', to: '.', noErrorOnMissing: true }
{ from: "node_modules/leaflet/dist/images", to: ".", noErrorOnMissing: true }
],
}),
new WebpackAssetsManifest()

View File

@ -1,13 +1,13 @@
const { merge } = require('webpack-merge');
const prod = require('./webpack.prod.js');
const { merge } = require("webpack-merge");
const prod = require("./webpack.prod.js");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = smp.wrap(merge(prod, {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
analyzerMode: "static",
openAnalyzer: true,
generateStatsFile: true
})

View File

@ -1,19 +1,19 @@
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
var webpack = require('webpack');
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
var webpack = require("webpack");
module.exports = merge(common, {
mode: 'development',
mode: "development",
devtool: false,
devServer: {
contentBase: './dist',
contentBase: "./dist",
},
plugins: [
new webpack.EnvironmentPlugin({
GIT_VERSION: null,
GIT_AUTHOR_DATE: null,
BUNDLE_DATE: Date.now(),
BUNDLE_MODE: 'development'
BUNDLE_MODE: "development"
})
]
});

View File

@ -1,18 +1,18 @@
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const TerserPlugin = require("terser-webpack-plugin");
const SentryWebpackPlugin = require("@sentry/webpack-plugin");
const AfterBuildPlugin = require('@fiverr/afterbuild-webpack-plugin');
const child_process = require('child_process');
const InjectPlugin = require('webpack-inject-plugin').default;
const colors = require('colors/safe');
const fs = require('fs');
const glob = require('glob');
const AfterBuildPlugin = require("@fiverr/afterbuild-webpack-plugin");
const childProcess = require("child_process");
const InjectPlugin = require("webpack-inject-plugin").default;
const colors = require("colors/safe");
const fs = require("fs");
const glob = require("glob");
function git(command) {
return child_process.execSync(`git ${command}`, { encoding: 'utf8' }).trim();
return childProcess.execSync(`git ${command}`, { encoding: "utf8" }).trim();
}
var webpack = require('webpack');
var webpack = require("webpack");
if (!fs.existsSync("config.json")) {
fs.copyFileSync("config_sample.json", "config.json");
@ -27,7 +27,7 @@ const removeSourceMapUrlAfterBuild = () => {
//console.log(files);
files.forEach((key) => {
countMatchAssets += 1;
let asset = fs.readFileSync(key, 'utf8');
let asset = fs.readFileSync(key, "utf8");
let source = asset.split("//# sourceMappingURL=")[0].replace(/\n$/, "");
fs.writeFileSync(key, source);
});
@ -42,16 +42,16 @@ const removeSourceMapUrlAfterBuild = () => {
fs.unlinkSync(key);
});
});
}
};
var config_file = require('./config.json');
const sentry_enabled = config_file.sentry_enabled &&
config_file.sentry_auth_token &&
config_file.sentry_organization &&
config_file.sentry_project;
var configFile = require("./config.json");
const sentryEnabled = configFile.sentryEnabled &&
configFile.sentryAuthToken &&
configFile.sentryOrganization &&
configFile.sentryProject;
var prod_config = {
mode: 'production',
var prodConfig = {
mode: "production",
devtool: false,
module: {
rules: [
@ -59,10 +59,10 @@ var prod_config = {
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
loader: "babel-loader",
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
presets: ["@babel/preset-env"],
plugins: ["@babel/plugin-transform-runtime"]
}
}
}
@ -75,56 +75,56 @@ var prod_config = {
minimizer: [new TerserPlugin({
parallel: true,
extractComments: true,
sourceMap: sentry_enabled ? true : false
sourceMap: sentryEnabled ? true : false
})]
}
};
module.exports = (env) => {
//run webpack build with '--env sentry_environment=custom-sentry-env' to replace Sentry environment
if(env.sentry_environment){
console.log(colors.green("INFO using custom sentry_environment "+env.sentry_environment));
config_file.sentry_environment = env.sentry_environment;
//run webpack build with "--env sentryEnvironment=custom-sentry-env" to replace Sentry environment
if(env.sentryEnvironment){
console.log(colors.green("INFO using custom sentryEnvironment "+env.sentryEnvironment));
configFile.sentryEnvironment = env.sentryEnvironment;
}
if(!config_file.sentry_environment){
config_file.sentry_environment = "prod";
if(!configFile.sentryEnvironment){
configFile.sentryEnvironment = "prod";
}
if(sentry_enabled){
prod_config.plugins.push(
if(sentryEnabled){
prodConfig.plugins.push(
new webpack.SourceMapDevToolPlugin({
filename: '[file].map'
filename: "[file].map"
}),
new SentryWebpackPlugin({
authToken: config_file.sentry_auth_token,
org: config_file.sentry_organization,
project: config_file.sentry_project,
urlPrefix: '~/dist',
include: './dist',
authToken: configFile.sentryAuthToken,
org: configFile.sentryOrganization,
project: configFile.sentryProject,
urlPrefix: "~/dist",
include: "./dist",
setCommits: {
auto: true
},
release: "allerta-vvf-frontend@"+git('describe --always')
release: "allerta-vvf-frontend@"+git("describe --always")
}),
new AfterBuildPlugin(removeSourceMapUrlAfterBuild),
new InjectPlugin(function() {
return "import './src/sentry.js';";
},{ entryName: 'main' })
},{ entryName: "main" })
);
console.log(colors.green("INFO Sentry Webpack plugins enabled"));
}
prod_config.plugins.push(
prodConfig.plugins.push(
new webpack.EnvironmentPlugin({
GIT_VERSION: git('describe --always'),
GIT_AUTHOR_DATE: git('log -1 --format=%aI'),
GIT_VERSION: git("describe --always"),
GIT_AUTHOR_DATE: git("log -1 --format=%aI"),
BUNDLE_DATE: Date.now(),
BUNDLE_MODE: 'production',
config: config_file
BUNDLE_MODE: "production",
config: configFile
})
);
return merge(common, prod_config);
}
return merge(common, prodConfig);
};

View File

@ -82,12 +82,12 @@
<div id="map"></div>
<div id="search">
<input type="text" name="addr" value="" id="addr" size="10" />
<button type="button" onclick="addr_search('{{ 'Search results'|t }}', '{{ 'No results found'|t }}');"
<button type="button" onclick="addrSearch('{{ 'Search results'|t }}', '{{ 'No results found'|t }}');"
class="btn btn-primary">{{ 'Search'|t }}</button>
<div id="results"></div>
</div>
<input type="hidden" name="place" value="" />
<script src="{{ urlsoftware }}/resources/dist/{{ resource('maps.js') }}" onload="load_map();"></script>
<script src="{{ urlsoftware }}/resources/dist/{{ resource('maps.js') }}" onload="loadMap();"></script>
{% else %}
<label><b>{{ 'Service place'|t }}</b></label>
<input type="text" name="place" required value="{{ values.place }}">

View File

@ -67,12 +67,12 @@
<div id="map"></div>
<div id="search">
<input type="text" name="addr" value="" id="addr" size="10" />
<button type="button" onclick="addr_search('{{ 'Search results'|t }}', '{{ 'No results found'|t }}');"
<button type="button" onclick="addrSearch('{{ 'Search results'|t }}', '{{ 'No results found'|t }}');"
class="btn btn-primary">{{ 'Search'|t }}</button>
<div id="results"></div>
</div>
<input type="hidden" name="place" value="" />
<script src="{{ urlsoftware }}/resources/dist/{{ resource('maps.js') }}" onload="load_map();"></script>
<script src="{{ urlsoftware }}/resources/dist/{{ resource('maps.js') }}" onload="loadMap();"></script>
{% else %}
<label><b>{{ 'Training place'|t }}</b></label>
<input type="text" name="place" required value="{{ values.place }}">

View File

@ -67,8 +67,8 @@
},
success: function (data) {
toastr.success(`{{ 'Thanks, %s, you have given %s in case of alert.'|t|format(user.name, '${generate_alert_string(id)}') }}`);
clearInterval(window.loadTable_interval); //stop reloading
loadTable({table_page: "list", use_custom_table_engine: "default"});
clearInterval(window.loadTableInterval); //stop reloading
loadTable({tablePage: "list", useCustomTableEngine: "default"});
}
});
}
@ -84,8 +84,8 @@
},
success: function (data) {
toastr.success(`{{ 'Thanks, %s, you have removed %s in case of alert.'|t|format(user.name, '${generate_alert_string(id)}') }}`);
clearInterval(window.loadTable_interval); //stop reloading
loadTable({table_page: "list", use_custom_table_engine: "default"});
clearInterval(window.loadTableInterval); //stop reloading
loadTable({tablePage: "list", useCustomTableEngine: "default"});
}
});
}
@ -114,7 +114,7 @@
</tbody>
</table>
<script>
loadTable({table_page: "list", use_custom_table_engine: "default"});
loadTable({tablePage: "list", useCustomTableEngine: "default"});
</script>
</div>

View File

@ -19,8 +19,8 @@
</tbody>
</table>
<script>
loadTable({table_page: "log", set_interval: false, callback: function(table_dt) {
table_dt
loadTable({tablePage: "log", setInterval: false, callback: function(tableDt) {
tableDt
.column( '3:visible' )
.order( 'desc' )
.draw();

View File

@ -36,7 +36,7 @@
</tbody>
</table>
<script>
loadTable({table_page: "services", interval: 120000});
loadTable({tablePage: "services", interval: 120000});
</script>
</div>
<br>

View File

@ -34,7 +34,7 @@
</tbody>
</table>
<script>
loadTable({table_page: "trainings", interval: 120000});
loadTable({tablePage: "trainings", interval: 120000});
</script>
</div>
<br>