diff --git a/assets/images/wait.gif b/assets/images/wait.gif new file mode 100644 index 0000000..3d2c493 Binary files /dev/null and b/assets/images/wait.gif differ diff --git a/assets/js/chat/Base.js b/assets/js/chat/Base.js index 9ec3cd8..4be802b 100644 --- a/assets/js/chat/Base.js +++ b/assets/js/chat/Base.js @@ -125,11 +125,8 @@ $(document).ready(function() { }, success: function(response){ if(response.status == "ok"){ - console.log("ok1"); if(!response.available){ - console.log("ok2") if(!response.self){ - console.log("ok3") $('#finduser').css('border', '2px solid green'); $('#adduserbutton').prop('disabled', false); } @@ -219,4 +216,116 @@ function delete_friend(friend){ }); } +// This socket is to notify a user, if another user is waiting. +const socketProtocol_4 = (window.location.protocol === "https:") ? "wss" : "ws"; +const socket_4 = new WebSocket(socketProtocol_4 + "://" + window.location.host + '/ws/notify/'); + +socket_4.onopen = function (e) { + socket_4.send(JSON.stringify({ + 'available': 'ping' + })); +}; + +IgnoreList = new Array(); // List of users to ignore +Notified = new Array(); // List of users who are already notified +LoaderNotifying = new Array(); // List of users who are already showing loader + +socket_4.addEventListener('message', function (e) { + const data = JSON.parse(e.data); + if (data.status == 'notify') { //if status is notify, it means, someone is waiting + users = JSON.parse(data.from); + + //if current page is chat page, then remove the current user from the list + if(window.location.href.indexOf("chat") > -1){ + users = users.filter(function(value, index, arr){ + return value != getUserName(); + }); + } + + // if there is a loader, but user is no longer online, then remove the loader + for (var i = 0; i < LoaderNotifying.length; i++) { + user = LoaderNotifying[i]; + if(!users.includes(user)){ + $('#live_notification_'+user).empty(); + LoaderNotifying.splice(i, 1); + } + } + + // Show loader and toast notification + for(var i=0; i < users.length; i++){ + CurrentUser = users[i] + if(IgnoreList.includes(CurrentUser)){ // If user is in ignore list, then do not show toast notification + if(!LoaderNotifying.includes(CurrentUser)){ + // show loader + $('#live_notification_'+CurrentUser).append("Waiting!"); + LoaderNotifying.push(CurrentUser); + } + continue; + } + + // if user is not yet notified, then show loader + if(!Notified.includes(CurrentUser)){ + $('#live_notification_'+CurrentUser).append("Waiting!"); + LoaderNotifying.push(CurrentUser); + } + + // Notify a user (toast notification) + Notified.push(CurrentUser); + //play sound + var audio = new Audio('/static/media/notification.mp3'); + audio.play(); + Swal.fire({ + title: "A Secure Chat Room", + text: CurrentUser + " is waiting for you in the waiting room!", + icon: "warning", + position: "top-end", + confirmButtonText: 'Join Now', + denyButtonText: 'Ignore!', + toast: true, + showDenyButton: true, + confirmButtonColor: "#003d89", + timer: 3000, + }).then((result) => { + if (result.isConfirmed) { + window.location.href = "/waiting-room?user=" + CurrentUser; + //remove the user from the list + users.splice(users.indexOf(CurrentUser), 1); + + } + else if (result.isDenied) { + IgnoreList.push(CurrentUser); //add user to ignore list + //show toast message that user is ignored + Swal.fire({ + title: "User Ignored", + text: "You will not be notified again for this user for a while!", + icon: "info", + position: "top-end", + toast: true, + showConfirmButton: false, + timer: 4000, + }); + + } + } + ); + + }; + } + else{ + //No users are waiting + //if any loader active and no user is waiting, then remove the loader + for (var i = 0; i < LoaderNotifying.length; i++) { + user = LoaderNotifying[i]; + $('#live_notification_'+user).empty(); + LoaderNotifying.splice(i, 1); + } + } +}); + +setInterval(function () { + socket_4.send(JSON.stringify({ + 'available': 'ping', + })); +}, 3000); + parent.document.title = "PrivatePing - A Secure Chat Room"; \ No newline at end of file diff --git a/assets/media/notification.mp3 b/assets/media/notification.mp3 new file mode 100644 index 0000000..9161305 Binary files /dev/null and b/assets/media/notification.mp3 differ diff --git a/chat/consumers.py b/chat/consumers.py index 7823e07..3e93796 100644 --- a/chat/consumers.py +++ b/chat/consumers.py @@ -156,5 +156,62 @@ def In_chat_message(self, event): 'user': user })) + def disconnect(self, code): + self.close() + + +class ChatConsumerNotify(WebsocketConsumer): + """ + Description: This consumer is used to notify the user, if anyone is in waiting room, waiting for the user to come online. + A user will receive a message with status 'notify' along with the username ('from') of friend who sent the message. + """ + http_user_and_session = True + def connect(self): + user = self.scope["user"] + self.room_name = "box4_"+str(user) + async_to_sync(self.channel_layer.group_add)( + self.room_name, + self.channel_name + ) + self.accept() + + def receive(self, text_data=None, bytes_data=None): + text_data_json = json.loads(text_data) + + if text_data_json['available']=="ping": + user = self.scope["user"] + if UserProfile.objects.filter(online=1).filter(online_for=UserProfile.objects.get(username=user)).exclude(username=user).exists(): + all = UserProfile.objects.filter(online=1).filter(online_for=UserProfile.objects.get(username=user)).exclude(username=user) + avl_users = [] + for i in all: + avl_users.append(i.username) + if len(avl_users)>0: + avl_users = json.dumps(avl_users) + async_to_sync(self.channel_layer.group_send)( + "box4_"+str(user), + { + 'type': 'NotifyUser', + 'status': 'notify', + 'from': avl_users + } + ) + else: + self.send(text_data=json.dumps({ + 'status': 'no', + 'from': 'NULL' + })) + else: + self.send(text_data=json.dumps({ + 'status': 'no', + 'from': 'NULL' + })) + def NotifyUser(self, event): + status = event['status'] + from_user = event['from'] + self.send(text_data=json.dumps({ + 'status': status, + 'from': from_user + })) + def disconnect(self, code): self.close() \ No newline at end of file diff --git a/chat/routing.py b/chat/routing.py index b9f65f8..88c10bf 100644 --- a/chat/routing.py +++ b/chat/routing.py @@ -1,8 +1,17 @@ from django.urls import re_path as url -from chat.consumers import ChatConsumer, ChatConsumerStatus, ChatConsumerCurrentStatus +from chat.consumers import * websocket_urlpatterns = [ + + # Checks the status ( typing/not typing) of the user url('ws/chat/currentstatus/', ChatConsumerCurrentStatus.as_asgi()), + + # Check the status (online/offline) of the user url('ws/chat/status/', ChatConsumerStatus.as_asgi()), + + # Handle the communication between the users url('ws/chat/', ChatConsumer.as_asgi()), + + # Notifies a user, if any user is waiting for a chat + url('ws/notify/', ChatConsumerNotify.as_asgi()), ] \ No newline at end of file diff --git a/chat/templates/chat/Base.html b/chat/templates/chat/Base.html index cbbd7a8..238bc22 100644 --- a/chat/templates/chat/Base.html +++ b/chat/templates/chat/Base.html @@ -148,6 +148,7 @@

{{friend.friend.name}}

+