Browse Source

mustard: Aggiunti controlli per gestione in massa delle notifiche.

* web/mustard/js/notifs.js.php: Aggiunte funzioni per cancellare e
  marcare come lette che operano su liste di notifiche.
* web/mustard/notifs.php: Quando riceve una POST con un body JSON
  esegue un'azione su liste di notifiche.
* web/mustard/notifsh.php: Le notifiche non vengono più cancellate dal
  DB ma vengono marcate "deleted".
* web/mustard/theme.css: Aggiunta classe "deleted".
paul 4 years ago
parent
commit
df9782ab1e
4 changed files with 109 additions and 19 deletions
  1. 54 9
      web/mustard/js/notifs.js.php
  2. 50 9
      web/mustard/notifs.php
  3. 1 1
      web/mustard/notifsh.php
  4. 4 0
      web/mustard/theme.css

+ 54 - 9
web/mustard/js/notifs.js.php

@@ -47,7 +47,7 @@ function markdeleted(notif) {
     xhr.send();
     xhr.onload = function () {
         if (xhr.response['deleted']) {
-            notif.remove();
+            notif.classList.add("deleted");
         } else {
             alert("Il server non ha potuto cancellare la notifica '" + notif.text + "'");
         }
@@ -57,16 +57,61 @@ function markdeleted(notif) {
     };
 }
 
-function applyAllSelected(fun) {
-    let notifs = document.querySelectorAll("div#notifs-list > div");
-    notifs.forEach(function (notif) {
-        let checkbox = notif.querySelector("input.seen-checkbox");
-        if (checkbox.checked) {
-            fun(notif);
-        }});
+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 = Array.from(document.querySelectorAll("div.notif"));
+    return notifs.filter(notif => notif.querySelector("input.seen-checkbox").checked)
 }
 
-lmt=<?php echo($notifs['lastmicrotime']); ?>;
+lmt =<?php echo($notifs['lastmicrotime']); ?>;
 chunk=0;
 end=false;
 loading=false;

+ 50 - 9
web/mustard/notifs.php

@@ -20,6 +20,51 @@ function hspech($str)
     return (htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
 }
 
+function are_valid_ids($ids)
+{
+    if (count($ids) <= 0) return false;
+    foreach ($ids as $id) {
+        if (!(preg_match('/^[0-9]+$/', $id) === 1)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER["CONTENT_TYPE"] === "application/json") {
+    $response = array(
+        "done" => 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 . '<br>' . N;
 $dbg .= '<pre>' . print_r($_GET, 1) . '</pre>';
 
@@ -115,20 +160,17 @@ if ($filtordon) {
 <div id="notifs-grid">
     <div id="notifs-list-controls">
         <input id="global-selector" type="checkbox" onclick="toggleState(this)">
-        <button class="control-btn" onclick="applyAllSelected(markread)"><i class="fa fa-envelope-open-o"
-                                                                            aria-hidden="true"></i>
+        <button class="control-btn" onclick="readSelected()">
+            <i class="fa fa-envelope-open-o" aria-hidden="true"></i>
         </button>
-        <button class="control-btn" onclick="applyAllSelected(markdeleted)"><i class="fa fa-trash-o"
-                                                                               aria-hidden="true"></i>
+        <button class="control-btn" onclick="deleteSelected()">
+            <i class="fa fa-trash-o" aria-hidden="true"></i>
         </button>
     </div>
     <h1 class="control-btn">CIAONEE</h1>
     <div id="notifs-list">
         <?php
         if ($account['Level'] != 'guest') {
-            // Questi valori sono un po' a (n|c)aso,
-            // dovrebbero avere senso ma non ho
-            // indagato troppo
             $sev_classes = array(
                 1 => "sev-normal",
                 2 => "sev-warning",
@@ -139,8 +181,7 @@ if ($filtordon) {
                 1 => "seen"
             );
             foreach ($notifs['notifs'] as $n) {
-                echo("<div id=\"notif-" . $n["ID"] .
-                    "\" class=\"" . "notif " . $sev_classes[$n["Severity"]] . " " . $seen_class[$n["Seen"]] . "\">" .
+                echo("<div id=\"notif-" . $n["ID"] . "\" class=\"" . "notif " . $sev_classes[$n["Severity"]] . " " . $seen_class[$n["Seen"]] . "\">" .
                     "<input type=\"checkbox\" class=\"seen-checkbox\" onclick='notifSelect(this)'>" .
                     "<button type='button' onclick='markread(this.parentElement)'><i class=\"fa fa-envelope-open-o\" aria-hidden=\"true\"></i></button>" .
                     "<button type='button' onclick='markdeleted(this.parentElement)'><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i></button>" .

+ 1 - 1
web/mustard/notifsh.php

@@ -19,7 +19,7 @@ if (array_key_exists('act', $_GET) && $_GET['act'] == 'markread' && array_key_ex
 	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, 'DELETE FROM Notifications WHERE ID=' . $_GET['id'])
+	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) {

+ 4 - 0
web/mustard/theme.css

@@ -872,6 +872,10 @@ div.notif button {
 	float: right;
 }
 
+div.deleted {
+	display: none;
+}
+
 div.sev-warning {
 	background-color: #FFEEAA;
 }