diff --git a/web/mustard/.htaccess b/web/mustard/.htaccess index 56610dd..226358b 100644 --- a/web/mustard/.htaccess +++ b/web/mustard/.htaccess @@ -1,3 +1,2 @@ RewriteEngine Off RewriteEngine On -php_flag mail.add_x_header Off diff --git a/web/mustard/include/menu.php b/web/mustard/include/menu.php index cbcda67..07c8b52 100644 --- a/web/mustard/include/menu.php +++ b/web/mustard/include/menu.php @@ -7,7 +7,7 @@ if ($account['Level']!='guest') { 'instances'=>array('liadd'=>null, 'href'=>'instances.php', 'title'=>'Istanze', 'selected'=>false, 'submenu'=>null), 'blacklist'=>array('liadd'=>null, 'href'=>'#', 'title'=>'Blacklist', 'selected'=>false, 'submenu'=>null), 'accounts'=>array('liadd'=>null, 'href'=>'#', 'title'=>'Accounts', 'selected'=>false, 'submenu'=>null), - 'notifs'=>array('liadd'=>null, 'href'=>'#', 'title'=>'Notifiche', 'selected'=>false, 'submenu'=>null), + 'notifs'=>array('liadd'=>null, 'href'=>'notifs.php', 'title'=>'Notifiche', 'selected'=>false, 'submenu'=>null), 'account'=>array('liadd'=>null, 'href'=>'account.php?id='.$account['ID'], 'title'=>'Il tuo account', 'selected'=>false, 'submenu'=>null), 'logout'=>array('liadd'=>null, 'href'=>'logout.php', 'title'=>'Logout', 'selected'=>false, 'submenu'=>null) ) diff --git a/web/mustard/include/notifs.php b/web/mustard/include/notifs.php index 9f0229e..198bb7d 100644 --- a/web/mustard/include/notifs.php +++ b/web/mustard/include/notifs.php @@ -2,12 +2,14 @@ function notifs(&$link) { $chunksize=20; // questo deve essere settato paro-paro in notifsh.php $i=0; - $notifs='
'.N; - $notifs.='
'.N; + $notifs = array(); + $notif_divs='
'.N; + $notif_divs.='
'.N; $unreadnotifs=false; $res=mysqli_query($link,'SELECT * FROM Notifications ORDER BY Microtime DESC') or muoribene(mysqli_error($link),true); while ($row=mysqli_fetch_assoc($res)) { + array_push($notifs, $row); if ($row['Seen']==0) { $unreadnotifs=true; $notifclass='notifunseen'; @@ -17,12 +19,12 @@ function notifs(&$link) { $i++; if ($i<=$chunksize) { if ($i==1) $lastmicrotime=$row['Microtime']; - $notifs.='
'.strftime('%d/%m/%y %T',$row['Microtime']).': '.$row['Notification'].'
'.N; + $notif_divs.='
'.strftime('%d/%m/%y %T',$row['Microtime']).': '.$row['Notification'].'
'.N; } } - $notifs.='
'.N; - $notifs.=''.N; - $notifs.='
'.N; + $notif_divs.='
'.N; + $notif_divs.='
Vedi tutte le notifiche
'.N; + $notif_divs.='
'.N; if ($unreadnotifs) { $imgoff='imgs/bell_act_off.svg'; $imgon='imgs/bell_act_on.svg'; @@ -31,7 +33,8 @@ function notifs(&$link) { $imgon='imgs/bell_on.svg'; } return(array( - 'div'=>$notifs, + 'notifs'=>$notifs, + 'div'=>$notif_divs, 'imgoff'=>$imgoff, 'imgon'=>$imgon, 'lastmicrotime'=>$lastmicrotime, diff --git a/web/mustard/js/notifs.js.php b/web/mustard/js/notifs.js.php index 9645e2c..10ff291 100644 --- a/web/mustard/js/notifs.js.php +++ b/web/mustard/js/notifs.js.php @@ -19,19 +19,112 @@ function markread(notif) { xhr.responseType='json'; xhr.send(); xhr.onload=function() { - notif.className='notifseen'; let jarr=xhr.response; if (jarr['hmunseen']==0) { notifimgon='imgs/bell_on.svg'; notifimgoff='imgs/bell_off.svg'; bell.src=notifimgon; } + + if (notif.classList.contains("notifunseen")){ + // Notifica nella navbar + notif.className='notifseen'; + } else if (notif.classList.contains("unseen")) { + // Notifica nella pagina di gestione notifiche + notif.classList.remove("unseen"); + notif.classList.add("seen"); + } }; xhr.onerror=function() { alert('La richiesta è fallita.'); }; } -lmt=; + +function markdeleted(notif) { + let xhr = new XMLHttpRequest(); + xhr.open('GET', 'notifsh.php?act=delete&id=' + notif.id.replace(/^notif-([0-9]+)$/, '$1')); + xhr.responseType = 'json'; + xhr.send(); + xhr.onload = function () { + if (xhr.response['deleted']) { + notif.classList.add("deleted"); + } else { + alert("Il server non ha potuto cancellare la notifica '" + notif.text + "'"); + } + }; + xhr.onerror = function () { + alert('La richiesta è fallita.'); + }; +} + +function getAliveNotifs(){ + let notifs = Array.from(document.querySelectorAll("div.notif")); + return notifs.filter(n => { + let classes = Array.from(n.classList); + return !(classes.includes("deleted") || classes.includes("filtered")); + }) +} + +function getAliveCheckboxes() { + let notifs = getAliveNotifs(); + return notifs.map(n => n.querySelector("input.seen-checkbox")) +} + +function readSelected() { + let selected = getSelectedNotifs() + let request = { + "act": "massread", + "ids": selected.map(div => div.id.replace(/^notif-([0-9]+)$/, '$1')) + } + let xhr = new XMLHttpRequest(); + xhr.open('POST', 'notifs.php'); + xhr.setRequestHeader('Content-type','application/json'); + xhr.responseType = 'json'; + xhr.send(JSON.stringify(request)); + xhr.onload = function () { + if (xhr.response['done']) { + selected.forEach(notif => { + notif.classList.remove("unseen"); + notif.classList.add("seen"); + }) + } else { + alert("Il server non ha potuto completare la richiesta:\n" + xhr.response["error"]); + } + }; + xhr.onerror = function () { + alert('La richiesta è fallita.'); + }; +} + +function deleteSelected() { + let selected = getSelectedNotifs() + let request = { + "act": "massdelete", + "ids": selected.map(div => div.id.replace(/^notif-([0-9]+)$/, '$1')) + } + let xhr = new XMLHttpRequest(); + xhr.open('POST', 'notifs.php'); + xhr.setRequestHeader('Content-type','application/json'); + xhr.responseType = 'json'; + xhr.send(JSON.stringify(request)); + xhr.onload = function () { + if (xhr.response['done']) { + selected.forEach(notif => notif.classList.add("deleted")); + } else { + alert("Il server non ha potuto completare la richiesta:\n" + xhr.response["error"]); + } + }; + xhr.onerror = function () { + alert('La richiesta è fallita.'); + }; +} + +function getSelectedNotifs() { + let notifs = getAliveNotifs(); + return notifs.filter(notif => notif.querySelector("input.seen-checkbox").checked) +} + +lmt =; chunk=0; end=false; loading=false; diff --git a/web/mustard/notifs.php b/web/mustard/notifs.php new file mode 100644 index 0000000..08787c4 --- /dev/null +++ b/web/mustard/notifs.php @@ -0,0 +1,368 @@ + true, + "error" => "" + ); + $body = json_decode(file_get_contents('php://input'), true); + if (array_key_exists('act', $body) && + array_key_exists('ids', $body) && + are_valid_ids($body["ids"])) { + switch ($body['act']) { + case "massread": + mysqli_query($link, 'UPDATE Notifications SET Seen=1 WHERE ID in (' . implode(", ", $body["ids"]) . ')') + or muoribene(mysqli_error($link), true); + break; + case "massdelete": + mysqli_query($link, 'UPDATE Notifications SET Deleted=1 WHERE ID in (' . implode(", ", $body["ids"]) . ')') + or muoribene(mysqli_error($link), true); + break; + default: + http_response_code(400); + $response["done"] = false; + $response["error"] = "Unknown act."; + } + } else { + http_response_code(400); + $response["done"] = false; + $response["error"] = "Bad request."; + } + echo(json_encode($response)); + mysqli_close($link); + exit(0); +} + + +$dbg .= $dlang . '
' . N; +$dbg .= '
' . print_r($_GET, 1) . '
'; + +$dbg .= '
' . print_r($inst, 1) . '
' . N; + +if ($account['Level'] != 'guest') { + require('include/notifs.php'); + $notifs = notifs($link); +} else { + muoribene("Non hai i permessi per vedere questa pagina", true); +} + +$filtordon = false; +if ($filtordon) { + $filtordimgoff = 'imgs/cerca_act_off.svg'; + $filtordimgon = 'imgs/cerca_act_on.svg'; +} else { + $filtordimgoff = 'imgs/cerca_off.svg'; + $filtordimgon = 'imgs/cerca_on.svg'; +} +?> + + + + Mustard - Notifs + + + + + + + + + + + + + + + + + + + + + +
+
+ "sev-normal", + 2 => "sev-warning", + 3 => "sev-error" + ); + $seen_class = array( + 0 => "unseen", + 1 => "seen" + ); + $deleted = array( + 0 => "", + 1 => "deleted" + ); + foreach ($notifs['notifs'] as $n) { + echo("
" . + "" . + "" . + "" . + "

" . strftime('%d/%m/%y %T', $n['Microtime']) . ": " . $n["Notification"] . "

" . + "
\n"); + } + } ?> +
+ + + + +
+ +
+ +
+ +
+ + + + + diff --git a/web/mustard/notifsh.php b/web/mustard/notifsh.php index cd0ffdf..c037529 100644 --- a/web/mustard/notifsh.php +++ b/web/mustard/notifsh.php @@ -10,22 +10,27 @@ require('include/getadmacc.php'); if ($account['Level']=='guest') muoribene('Sorry, you are not authorized.',true); -if (array_key_exists('act',$_GET) && $_GET['act']=='markread' && array_key_exists('id',$_GET) && preg_match('/^[0-9]+$/',$_GET['id'])===1) { - $_GET['id']+=0; - mysqli_query($link,'UPDATE Notifications SET Seen=1 WHERE ID='.$_GET['id']) - or muoribene(mysqli_error($link),true); - $res=mysqli_query($link,'SELECT ID FROM Notifications WHERE Seen=0') - or muoribene(mysqli_error($link),true); - echo('{"hmunseen":'.mysqli_num_rows($res).'}'.N); -} elseif (array_key_exists('act',$_GET) && $_GET['act']=='loadchunk' && array_key_exists('chunk',$_GET) && preg_match('/^[0-9]+$/',$_GET['chunk'])===1) { - $_GET['chunk']+=0; - $chunksize=20; // questo dev'essere uguale in include/notifs.php - $res=mysqli_query($link,'SELECT * FROM Notifications WHERE Deleted=0 ORDER BY Microtime DESC LIMIT '.($_GET['chunk']*$chunksize).','.$chunksize) - or muoribene(mysqli_error($link),true); - $buf=array(); - while ($row=mysqli_fetch_assoc($res)) { - ($row['Seen']==0) ? $notifclass='notifunseen' : $notifclass='notifseen'; - $buf[]='
'.strftime('%d/%m/%y %T',$row['Microtime']).': '.$row['Notification'].'
'; +if (array_key_exists('act', $_GET) && $_GET['act'] == 'markread' && array_key_exists('id', $_GET) && preg_match('/^[0-9]+$/', $_GET['id']) === 1) { + $_GET['id'] += 0; + mysqli_query($link, 'UPDATE Notifications SET Seen=1 WHERE ID=' . $_GET['id']) + or muoribene(mysqli_error($link), true); + $res = mysqli_query($link, 'SELECT ID FROM Notifications WHERE Seen=0') + or muoribene(mysqli_error($link), true); + echo('{"hmunseen":' . mysqli_num_rows($res) . '}' . N); +} elseif (array_key_exists('act', $_GET) && $_GET['act'] == 'delete' && array_key_exists('id', $_GET) && preg_match('/^[0-9]+$/', $_GET['id']) === 1) { + $_GET['id'] += 0; + mysqli_query($link, 'UPDATE Notifications SET Deleted=1 WHERE ID=' . $_GET['id']) + or muoribene(mysqli_error($link), true); + echo('{"deleted":' . true . '}' . N); +} elseif (array_key_exists('act', $_GET) && $_GET['act'] == 'loadchunk' && array_key_exists('chunk', $_GET) && preg_match('/^[0-9]+$/', $_GET['chunk']) === 1) { + $_GET['chunk'] += 0; + $chunksize = 20; // questo dev'essere uguale in include/notifs.php + $res = mysqli_query($link, 'SELECT * FROM Notifications WHERE Deleted=0 ORDER BY Microtime DESC LIMIT ' . ($_GET['chunk'] * $chunksize) . ',' . $chunksize) + or muoribene(mysqli_error($link), true); + $buf = array(); + while ($row = mysqli_fetch_assoc($res)) { + ($row['Seen'] == 0) ? $notifclass = 'notifunseen' : $notifclass = 'notifseen'; + $buf[] = '
' . strftime('%d/%m/%y %T', $row['Microtime']) . ': ' . $row['Notification'] . '
'; } echo(json_encode($buf)); } elseif (array_key_exists('act',$_GET) && $_GET['act']=='loadnew' && array_key_exists('lmt',$_GET) && preg_match('/^[0-9]+(\.[0-9]+)?$/',$_GET['lmt'])===1) { diff --git a/web/mustard/php.ini b/web/mustard/php.ini new file mode 100644 index 0000000..2c8e24b --- /dev/null +++ b/web/mustard/php.ini @@ -0,0 +1 @@ +mail.add_x_header="0" diff --git a/web/mustard/theme.css b/web/mustard/theme.css index cbd8e95..59cbd2a 100644 --- a/web/mustard/theme.css +++ b/web/mustard/theme.css @@ -578,6 +578,7 @@ input { } .edtab .desc { margin-bottom: 6px; + } .edtab .butdiv { width: 22px; @@ -840,6 +841,115 @@ input { } +#notifs-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; + margin-top: 32px; +} + +#notifs-list-controls { + display: inline-block; + position: absolute; + left: 50%; + transform: translateX(-50%); + margin-top: 5px; +} + +#global-selector { + width: auto; + margin: 2px 1px 2px 2px; +} + +.control-btn { + margin-top: 2px; + margin-bottom: 2px; +} + +#read-btn { + margin-left: 1px; + margin-right: 2px; + float: right; + visibility: hidden; +} + +#delete-btn { + margin-left: 1px; + margin-right: 1px; + float: right; + visibility: hidden; +} + +#reverse-btn { + margin-left: 1px; + margin-right: 1px; +} + +#notifs-list { + grid-column: 2; +} + +div.notif { + padding: 5px; + margin: 10px; + word-break: break-word; + background-color: #87DE87; + border-radius: 5px; +} + +div.notif p { + font-size: 10pt; + text-align: center; + margin: 10px; + padding: 3px; +} + +div.notif input { + width: auto; +} + +div.notif button { + float: right; +} + +div.deleted { + display: none; +} + +div.sev-warning { + background-color: #FFEEAA; +} + +div.sev-error { + background-color: #DE8787; +} + +div.seen { + background-color: lightgrey; +} + +div.filtered { + display: none; +} + +#plancia .notifs-criterion { + display: flex; +} + +#plancia .notifs-criterion label { + margin: 2px; +} + +#plancia #clear-filters-btn { + margin: 2px auto; + width: 100%; +} + +#plancia #apply-filters-btn { + margin: 2px auto; + width: 100%; +} + @media only screen and (max-width:720px) { .bigtab td { width: 244px;