diff --git a/assets/js/custom.js b/assets/js/custom.js index eb2b6f9..b25910a 100644 --- a/assets/js/custom.js +++ b/assets/js/custom.js @@ -45,8 +45,9 @@ function verifReceived() /** * Cette fonction permet de scroller au dernier message + * @param force: bool : should we force the scroll */ -function scrollDownDiscussion() +function scrollDownDiscussion(force) { var discussion_height = jQuery('.discussion-container').innerHeight(); var discussion_scroll_height = jQuery('.discussion-container')[0].scrollHeight; @@ -54,7 +55,7 @@ function scrollDownDiscussion() var scroll_before_end = discussion_scroll_height - (discussion_scroll_top + discussion_height); //On scroll uniquement si on a pas remonté plus haut que la moitié de la fenetre de discussion - if (scroll_before_end <= discussion_height / 2) + if (force || scroll_before_end <= discussion_height / 2) { jQuery('.discussion-container').animate({scrollTop: 1000000}); } @@ -115,8 +116,8 @@ jQuery(document).ready(function() var form = jQuery(this); var message = form.find('textarea').val(); var formData = new FormData(form[0]); - jQuery('.discussion-container').find('#send-message-spiner').remove(); - jQuery('.discussion-container').append('
'); + jQuery('.discussion-container').find('#send-message-spinner').remove(); + jQuery('.discussion-container').append('
'); scrollDownDiscussion(); jQuery.ajax({ url: form.attr('action'), @@ -130,7 +131,7 @@ jQuery(document).ready(function() if (!data.success) { showMessage(data.message.replace(//g, ">"), 0); - jQuery('.discussion-container').find('#send-message-spiner').remove(); + jQuery('.discussion-container').find('#send-message-spinner').remove(); } } }).done(function() diff --git a/controllers/internals/Received.php b/controllers/internals/Received.php index 285a8ca..c7c2b79 100644 --- a/controllers/internals/Received.php +++ b/controllers/internals/Received.php @@ -161,6 +161,19 @@ namespace controllers\internals; return $this->get_model()->gets_by_origin_and_user($id_user, $origin); } + /** + * Return receiveds for an origin and a user since a date. + * + * @param int $id_user : User id + * @param string $since : Date we want messages since format Y-m-d H:i:s + * @param string $origin : Number who sent the message + * @return array + */ + public function gets_since_date_by_origin_and_user(int $id_user, string $since, string $origin) + { + return $this->get_model()->gets_since_date_by_origin_and_user($id_user, $since, $origin); + } + /** * Get number of sended SMS for every date since a date for a specific user. * diff --git a/controllers/internals/Scheduled.php b/controllers/internals/Scheduled.php index b45c6ce..da65da2 100644 --- a/controllers/internals/Scheduled.php +++ b/controllers/internals/Scheduled.php @@ -254,6 +254,20 @@ namespace controllers\internals; { return $this->get_model()->gets_before_date_for_number_and_user($id_user, $date, $number); } + + /** + * Get messages scheduled after a date for a number and a user. + * + * @param int $id_user : User id + * @param $date : Date after which we want messages + * @param string $number : Number for which we want messages + * + * @return array + */ + public function gets_after_date_for_number_and_user(int $id_user, $date, string $number) + { + return $this->get_model()->gets_after_date_for_number_and_user($id_user, $date, $number); + } /** * Get all messages to send and the number to use to send theme. diff --git a/controllers/internals/Sended.php b/controllers/internals/Sended.php index 3847185..8b8d2d6 100644 --- a/controllers/internals/Sended.php +++ b/controllers/internals/Sended.php @@ -132,6 +132,19 @@ namespace controllers\internals; { return $this->get_model()->gets_by_destination_and_user($id_user, $origin); } + + /** + * Return sendeds for a destination and a user since a date. + * + * @param int $id_user : User id + * @param string $since : Date we want messages since format Y-m-d H:i:s + * @param string $origin : Number who sent the message + * @return array + */ + public function gets_since_date_by_destination_and_user(int $id_user, string $since, string $origin) + { + return $this->get_model()->gets_since_date_by_destination_and_user($id_user, $since, $origin); + } /** * Return sended for an uid and an adapter. diff --git a/controllers/publics/Discussion.php b/controllers/publics/Discussion.php index 6f26b80..13d2031 100644 --- a/controllers/publics/Discussion.php +++ b/controllers/publics/Discussion.php @@ -98,17 +98,34 @@ namespace controllers\publics; * * @param string $number : Le numéro cible * @param string $transaction_id : Le numéro unique de la transaction ajax (sert à vérifier si la requete doit être prise en compte) + * @param ?int $since : La date à partir de laquelle on veut les messages, sous forme de timestamp */ - public function get_messages($number, $transaction_id) + public function get_messages($number, $transaction_id, ?int $since = null) { $now = new \DateTime(); $now = $now->format('Y-m-d H:i:s'); $id_user = $_SESSION['user']['id']; - $sendeds = $this->internal_sended->gets_by_destination_and_user($id_user, $number); - $receiveds = $this->internal_received->gets_by_origin_and_user($id_user, $number); - $scheduleds = $this->internal_scheduled->gets_before_date_for_number_and_user($id_user, $now, $number); + if ($since && !($since = date('Y-m-d H:i:s', $since))) + { + echo json_encode(['transaction_id' => $transaction_id, 'messages' => [], 'error' => true, 'error_message' => 'Not a valid date.']); + + return false; + } + + if ($since) + { + $sendeds = $this->internal_sended->gets_since_date_by_destination_and_user($id_user, $since, $number); + $receiveds = $this->internal_received->gets_since_date_by_origin_and_user($id_user, $since, $number); + $scheduleds = $this->internal_scheduled->gets_after_date_for_number_and_user($id_user, $since, $number); + } + else + { + $sendeds = $this->internal_sended->gets_by_destination_and_user($id_user, $number); + $receiveds = $this->internal_received->gets_by_origin_and_user($id_user, $number); + $scheduleds = $this->internal_scheduled->gets_before_date_for_number_and_user($id_user, $now, $number); + } $messages = []; @@ -125,6 +142,7 @@ namespace controllers\publics; } $message = [ + 'uid' => 'sended-' . $sended['id'], 'date' => htmlspecialchars($sended['at']), 'text' => htmlspecialchars($sended['text']), 'type' => 'sended', @@ -154,10 +172,10 @@ namespace controllers\publics; } $messages[] = [ + 'uid' => 'received-' . $received['id'], 'date' => htmlspecialchars($received['at']), 'text' => htmlspecialchars($received['text']), 'type' => 'received', - 'md5' => md5($received['at'] . $received['text']), 'medias' => $medias, ]; } @@ -165,7 +183,7 @@ namespace controllers\publics; foreach ($scheduleds as $scheduled) { $medias = []; - if ($sended['mms']) + if ($scheduled['mms']) { $medias = $this->internal_media->gets_for_scheduled($scheduled['id']); foreach ($medias as &$media) @@ -175,6 +193,7 @@ namespace controllers\publics; } $messages[] = [ + 'uid' => 'scheduled-' . $scheduled['id'], 'date' => htmlspecialchars($scheduled['at']), 'text' => htmlspecialchars($scheduled['text']), 'type' => 'inprogress', @@ -188,10 +207,24 @@ namespace controllers\publics; return strtotime($a['date']) - strtotime($b['date']); }); - //On récupère uniquement les 25 derniers messages sur l'ensemble - $messages = \array_slice($messages, -25); + //Sans limite de temps, on récupère uniquement les 25 derniers messages sur l'ensemble pour limiter la charge + if (!$since) + { + $messages = \array_slice($messages, -25); + } - echo json_encode(['transaction_id' => $transaction_id, 'messages' => $messages]); + $response = [ + 'transaction_id' => $transaction_id, + 'messages' => $messages, + ]; + + if ($messages) + { + $new_limit_date = (new \DateTime($messages[count($messages) - 1]['date']))->getTimestamp(); //Use latest message as the new limit date to search + $response['new_limit_date'] = $new_limit_date; + } + + echo json_encode($response); return true; } diff --git a/models/Received.php b/models/Received.php index 23a8c05..28fabef 100644 --- a/models/Received.php +++ b/models/Received.php @@ -178,6 +178,34 @@ namespace models; return $this->_run_query($query, $params); } + + /** + * Return sendeds for an origin and a user since a date. + * + * @param int $id_user : User id + * @param string $since : Date we want messages since + * @param string $origin : Number who sent the message + * + * @return array + */ + public function gets_since_date_by_origin_and_user(int $id_user, string $since, string $origin) + { + $query = ' + SELECT * + FROM received + WHERE id_user = :id_user + AND origin = :origin + AND at > :since + '; + + $params = [ + 'id_user' => $id_user, + 'origin' => $origin, + 'since' => $since, + ]; + + return $this->_run_query($query, $params); + } /** * Get number of sended SMS for every date since a date for a specific user. diff --git a/models/Scheduled.php b/models/Scheduled.php index 7d7bc90..f1b2cdd 100644 --- a/models/Scheduled.php +++ b/models/Scheduled.php @@ -233,6 +233,63 @@ namespace models; return $this->_run_query($query, $params); } + + + /** + * Get messages scheduled after a date for a number and a user. + * + * @param int $id_user : User id + * @param $date : Date after which we want messages + * @param string $number : Number for which we want messages + * + * @return array + */ + public function gets_after_date_for_number_and_user(int $id_user, $date, string $number) + { + $query = ' + SELECT * + FROM scheduled + WHERE at > :date + AND id_user = :id_user + AND ( + id IN ( + SELECT id_scheduled + FROM scheduled_number + WHERE number = :number + ) + OR id IN ( + SELECT id_scheduled + FROM scheduled_contact + WHERE id_contact IN ( + SELECT id + FROM contact + WHERE number = :number + ) + ) + OR id IN ( + SELECT id_scheduled + FROM scheduled_group + WHERE id_group IN ( + SELECT id_group + FROM `group_contact` + WHERE id_contact IN ( + SELECT id + FROM contact + WHERE number = :number + ) + ) + ) + ) + '; + + $params = [ + 'id_user' => $id_user, + 'date' => $date, + 'number' => $number, + ]; + + return $this->_run_query($query, $params); + } /** * Get scheduleds before a date. diff --git a/models/Sended.php b/models/Sended.php index f0235ba..fa91346 100644 --- a/models/Sended.php +++ b/models/Sended.php @@ -112,6 +112,35 @@ namespace models; return $this->_run_query($query, $params); } + + + /** + * Return sendeds for an destination and a user since a date. + * + * @param int $id_user : User id + * @param string $since : Date we want messages since + * @param string $destination : Number who sent the message + * + * @return array + */ + public function gets_since_date_by_destination_and_user(int $id_user, string $since, string $destination) + { + $query = ' + SELECT * + FROM sended + WHERE id_user = :id_user + AND destination = :destination + AND at > :since + '; + + $params = [ + 'id_user' => $id_user, + 'destination' => $destination, + 'since' => $since, + ]; + + return $this->_run_query($query, $params); + } /** * Return sended for an uid and an adapter. diff --git a/routes.php b/routes.php index 0384728..db8f771 100644 --- a/routes.php +++ b/routes.php @@ -54,7 +54,10 @@ 'list_json' => '/discussion/json/', 'show' => '/discussion/show/{number}/', 'send' => '/discussion/send/{csrf}/', - 'get_messages' => '/discussion/getmessage/{number}/{transaction_id}/', + 'get_messages' => [ + '/discussion/getmessage/{number}/{transaction_id}/', + '/discussion/getmessage/{number}/{transaction_id}/{since}/', + ], ], 'Event' => [ diff --git a/templates/discussion/show.php b/templates/discussion/show.php index eed789e..be4b21f 100644 --- a/templates/discussion/show.php +++ b/templates/discussion/show.php @@ -32,7 +32,7 @@
-
+
@@ -57,22 +57,35 @@ jQuery(document).ready(function () { var alreadyReceivedMessages = []; + var limit_date = false; /** * Cette fonction vérifie régulièrement les sms pour mettre à jour l'affichage */ function getmessages () { - ajaxTransactionId = Date.now(); - jQuery.getJSON(HTTP_PWD + "/discussion/getmessage//" + ajaxTransactionId , function( data ) { + ajaxTransactionId = Date.now(); + if (limit_date == false) + { + var first_load = true; + url = HTTP_PWD + "/discussion/getmessage//" + ajaxTransactionId; + limit_date = Date.now(); //After first load, we will only search for new messages + } + else + { + var first_load = false; + url = HTTP_PWD + "/discussion/getmessage//" + ajaxTransactionId + "/" + limit_date + "/"; + } + + jQuery.getJSON(url, function( data ) { if (data.transaction_id != ajaxTransactionId) { return false; - } - - jQuery('.discussion-container').html(''); + } + jQuery('.discussion-container #load-message-spinner').remove(); + jQuery('.discussion-container #send-message-spinner').remove(); $.each(data.messages, function(key, message) { @@ -87,6 +100,10 @@ { return '
'; } + else if (['webm', 'ogg', 'ogv', 'mp4'].includes(extension)) + { + return ''; + } else { return ''; @@ -106,10 +123,10 @@ '
' + '
'; - if (alreadyReceivedMessages.indexOf(message.md5) == -1) + if (alreadyReceivedMessages.indexOf(message.uid) == -1 && !first_load) //If new message received and not first time loading { playReceptionSound(); - alreadyReceivedMessages.push(message.md5); + alreadyReceivedMessages.push(message.uid); } break; @@ -140,8 +157,17 @@ } jQuery('.discussion-container').append(texte); - }); - scrollDownDiscussion(); + }); + + //Update limit_date if set + if (data.new_limit_date !== undefined) + { + limit_date = data.new_limit_date; + } + + if (data.messages.length) { + scrollDownDiscussion(first_load); + } }); } @@ -155,9 +181,6 @@ var messageInputContainer = jQuery('.message-input-container').outerHeight(); var footerHeight = jQuery('footer').outerHeight(); - console.log(windowHeight); - console.log(containerPosition.top); - var containerHeight = Math.floor(windowHeight - (containerPosition.top + messageInputContainer) - 20); //-20 px for aesthetic jQuery('.discussion-container').outerHeight(containerHeight);