From d193ec0f11674308ccb3ea3d4ec2e759501c1d9c Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Sat, 30 Nov 2019 00:43:50 +0530 Subject: [PATCH] Javascript user search implemented --- .../controller/RegistrationController.java | 2 +- .../ros/chatto/service/UserTokenService.java | 23 ++- .../src/main/resources/application.properties | 2 +- chatto/src/main/resources/static/css/chat.css | 12 ++ chatto/src/main/resources/static/js/chat.js | 166 ++++++++++++++---- chatto/src/main/resources/static/js/login.js | 31 ++-- chatto/src/main/resources/templates/chat.html | 57 +++++- .../resources/templates/registration.html | 2 +- 8 files changed, 227 insertions(+), 68 deletions(-) diff --git a/chatto/src/main/java/org/ros/chatto/controller/RegistrationController.java b/chatto/src/main/java/org/ros/chatto/controller/RegistrationController.java index 367d580..c01761f 100644 --- a/chatto/src/main/java/org/ros/chatto/controller/RegistrationController.java +++ b/chatto/src/main/java/org/ros/chatto/controller/RegistrationController.java @@ -73,7 +73,7 @@ public class RegistrationController { return "user/home"; } - @GetMapping(value = "/img/{image_id}", produces = MediaType.IMAGE_PNG_VALUE) + @GetMapping(value = "/img/captcha/{image_id}", produces = MediaType.IMAGE_PNG_VALUE) public ResponseEntity getImage(@PathVariable("image_id") Long imageId) throws IOException { final String captchaText = captchaMap.get(imageId); diff --git a/chatto/src/main/java/org/ros/chatto/service/UserTokenService.java b/chatto/src/main/java/org/ros/chatto/service/UserTokenService.java index 2dc871e..aa346de 100644 --- a/chatto/src/main/java/org/ros/chatto/service/UserTokenService.java +++ b/chatto/src/main/java/org/ros/chatto/service/UserTokenService.java @@ -1,6 +1,5 @@ package org.ros.chatto.service; -import javax.transaction.Transactional; import org.ros.chatto.model.UserToken; import org.ros.chatto.repository.TokenRepository; @@ -8,43 +7,43 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.extern.slf4j.Slf4j; @Service +@Transactional +@Slf4j @CacheConfig(cacheNames = "userTokenCache") public class UserTokenService { @Autowired private TokenRepository tokenRepository; + @Transactional(readOnly = true) @Cacheable(value = "userTokenCache", key = "#userName", unless="#result == null") public UserToken getTokenByUserName(String userName) { - System.out.println("Inside 1"); + log.debug("Inside 1"); return tokenRepository.findByUserName(userName); } - + @Transactional(readOnly = true) @Cacheable(value = "userTokenCache", key = "#tokenString", unless="#result == null") public UserToken getTokenByTokenString(String tokenString) { - System.out.println("Inside 2"); + log.debug("Inside 2"); return tokenRepository.findByToken(tokenString); } - @Transactional public void saveToken(UserToken userToken) { -// UserToken userToken2 = tokenRepository.findByToken(userToken.getTokenContent()); -// if(userToken2!=null) { -// System.out.println("Found valid token"); -// return; -// } -// System.out.println("Saving token"); + log.info("Saving auth token"); tokenRepository.save(userToken); } - @Transactional public void deleteToken(String userName) { + log.info("Deleting token for {}", userName); tokenRepository.deleteByUserName(userName); } } diff --git a/chatto/src/main/resources/application.properties b/chatto/src/main/resources/application.properties index 959a4cf..553ef96 100644 --- a/chatto/src/main/resources/application.properties +++ b/chatto/src/main/resources/application.properties @@ -14,7 +14,7 @@ spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDial spring.jpa.hibernate.ddl-auto = none spring.jpa.open-in-view=false -spring.jpa.properties.hibernate.generate_statistics=true +#spring.jpa.properties.hibernate.generate_statistics=true logging.level.org.hibernate.stat=debug logging.level.org.springframework.web=DEBUG logging.level.web=DEBUG diff --git a/chatto/src/main/resources/static/css/chat.css b/chatto/src/main/resources/static/css/chat.css index 23841e6..4ea7881 100644 --- a/chatto/src/main/resources/static/css/chat.css +++ b/chatto/src/main/resources/static/css/chat.css @@ -69,6 +69,13 @@ html { color: white !important; } +.search-cancel { + background-color: rgba(0, 0, 0, 0.3) !important; + border: 0 !important; + /* border-color: rgba(0, 0, 0, 0.3) !important; */ + color: white !important; +} + .search:focus { box-shadow: none !important; outline: 0px !important; @@ -250,6 +257,7 @@ html { position: absolute; padding: 15px 0; background-color: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(6px); color: white; border-radius: 15px; top: 30px; @@ -278,6 +286,10 @@ html { background-color: rgba(0, 0, 0, 0.2); } +.bg-blur { + backdrop-filter: blur(6px); +} + @media(max-width: 576px) { .contacts_card { margin-bottom: 15px !important; diff --git a/chatto/src/main/resources/static/js/chat.js b/chatto/src/main/resources/static/js/chat.js index 692d8ba..33ba6a6 100644 --- a/chatto/src/main/resources/static/js/chat.js +++ b/chatto/src/main/resources/static/js/chat.js @@ -18,6 +18,7 @@ var chatTextArea = document.getElementById('chatTextArea'); var postNewMessageUrl = `http://${hostAddress}/api/chat/post/message`; //hostAddress variable is set in the thymeleaf head fragment var getAllMessagesUrl = `http://${hostAddress}/api/chat/get/messages/`; var getNewMessagesUrl = `http://${hostAddress}/api/chat/get/messages/`; +var getActiveUsersUrl = `http://${hostAddress}/api/chat/get/active-users/`; // var postNewMessageUrl = "http://localhost:8080/api/chat/post/message"; // var getAllMessagesUrl = "http://localhost:8080/api/chat/get/messages/"; // var getNewMessagesUrl = "http://localhost:8080/api/chat/get/messages/"; @@ -32,6 +33,10 @@ var source = document.getElementById("msg_container_template").innerHTML; var msgContainerTemplate = Handlebars.compile(source); var source = document.getElementById("msg_container_send_template").innerHTML; var msgContainerSendTemplate = Handlebars.compile(source); +var source = document.getElementById("user-contact-online-template").innerHTML; +var userContactOnlineTemplate = Handlebars.compile(source); +var source = document.getElementById("user-contact-offline-template").innerHTML; +var userContactOfflineTemplate = Handlebars.compile(source); var chatAreaNew = document.getElementById('chat_area_new'); @@ -39,6 +44,22 @@ var userBoxes = document.getElementsByName('user-box'); var md = window.markdownit(); +var activeUsers = {}; + +var fuseOptions = { + shouldSort: true, + threshold: 0.01, + location: 0, + distance: 100, + maxPatternLength: 32, + minMatchCharLength: 1, + keys: [ + "userName", + ] +}; + +log.setLevel('TRACE'); + alertify.set('notifier', 'position', 'top-center'); // Loop through the buttons and add the active class to the current/clicked button @@ -56,39 +77,54 @@ alertify.set('notifier', 'position', 'top-center'); // }); // } -for (let i = 0; i < userBoxes.length; i++) { - userBoxes[i].addEventListener('click', function() { - let current = document.getElementsByClassName('user-box active'); - let passphrase = passphraseInput.value; - if (current.length > 0) { - if (passphrase == '') { - // alert('Please input passphrase') - alertify.error('Please enter a passphrase'); - return; - } - current[0].className = current[0].className.replace(" active", ""); +getActiveUsers(authToken) + .then(data => { + // activeUsers = data; + sessionStorage.setItem('activeUsers', JSON.stringify(data)); + log.log(sessionStorage.getItem('activeUsers')); + }) +for (let i = 0; i < userBoxes.length; i++) { + userBoxes[i].addEventListener('click', userCallBack) +} + +function addUserCallBacks() { + for (let i = 0; i < userBoxes.length; i++) { + userBoxes[i].addEventListener('click', userCallBack) + } +} + +function userCallBack() { + let current = document.getElementsByClassName('user-box active'); + let passphrase = passphraseInput.value; + if (current.length > 0) { + if (passphrase == '') { + // alert('Please input passphrase') + alertify.error('Please enter a passphrase'); + return; } - // Add the active class to the current/clicked button - else if (current.length == 0) { - let elem = document.getElementById('passphrase-initial'); - passphrase = elem.value; - if (passphrase == '') { - // alert('Please input passphrase') - alertify.error('Please enter a passphrase'); - return; - } - document.getElementById('no-user-selected').hidden = true; - document.getElementById('chat-card').hidden = false; - elem.hidden = true; + current[0].className = current[0].className.replace(" active", ""); + + } + // Add the active class to the current/clicked button + else if (current.length == 0) { + let elem = document.getElementById('passphrase-initial'); + passphrase = elem.value; + if (passphrase == '') { + // alert('Please input passphrase') + alertify.error('Please enter a passphrase'); + return; } - // console.log(this.getElementsByClassName('to-user-span')); - let userName = this.getElementsByClassName('to-user-span')[0].innerText; - document.getElementById('user-name-span').innerText = userName; - populateMessages(userName, passphrase); - sessionStorage.setItem('selectedUser', userName); - this.className += " active"; - }) + document.getElementById('no-user-selected').hidden = true; + document.getElementById('chat-card').hidden = false; + elem.hidden = true; + } + // console.log(this.getElementsByClassName('to-user-span')); + let userName = this.getElementsByClassName('to-user-span')[0].innerText; + document.getElementById('user-name-span').innerText = userName; + populateMessages(userName, passphrase); + sessionStorage.setItem('selectedUser', userName); + this.className += " active"; } function populateMessages(userName, passphrase) { @@ -240,12 +276,11 @@ function populateMessages(userName, passphrase) { scrollChatAreaAnimated(2400); }) - + }); } - // sessionStorage.clear(); // chatTextArea.append(JSON.stringify(storedMessages)); } @@ -317,6 +352,56 @@ document.getElementById('chatMessageForm').addEventListener('submit', function(e messageSend(JSON.stringify(chatMessageDTO)); }) +document.getElementById('user-search').addEventListener('submit', function(e) { + e.preventDefault(); + let contactsBox = document.getElementById('contacts-box'); + let temp = contactsBox.innerHTML; + // log.trace(temp); + let searchTerm = document.getElementById('user-search-term').value; + log.debug("search term value = " + searchTerm); + let list = JSON.parse(sessionStorage.getItem('activeUsers')); + log.debug("active users"); + log.debug(list); + let fuse = new Fuse(list, fuseOptions); + let searchResult = fuse.search(searchTerm); + populateContactsBox(contactsBox, searchResult); + addUserCallBacks(); + log.debug(searchResult); +}) +document.getElementById('user-search-term').addEventListener('input', function(e) { + e.preventDefault(); + if (this.value.length < 2) { + log.debug("inputted") + let cancelButton = document.getElementById('user-search-cancel'); + cancelButton.hidden = false; + } +}) +document.getElementById('user-search-cancel').addEventListener('click', function(e) { + e.preventDefault(); + let list = JSON.parse(sessionStorage.getItem('activeUsers')); + let contactsBox = document.getElementById('contacts-box'); + populateContactsBox(contactsBox,list); + addUserCallBacks(); + document.getElementById('user-search-term').value = ""; + this.hidden = true; +}) + +function populateContactsBox(contactsBox, list) +{ + let userContactBoxList = ""; + list.forEach(function(activeUser) { + log.debug(activeUser); + if (activeUser.online) { + userContactBoxList += userContactOnlineTemplate(activeUser); + } else { + userContactBoxList += userContactOfflineTemplate(activeUser); + } + }) + contactsBox.innerHTML = userContactBoxList; +} + + + // console.log('Credentials = ' + JSON.parse(sessionStorage.getItem('credentials'))); @@ -379,6 +464,23 @@ async function getNewMessages(toUser, lastMessageTimeStamp) { return data; } + +async function getActiveUsers(authToken2) { + let headers = new Headers(); + // headers.append('Authorization', basicAuthToken); + headers.append('X-AUTH-TOKEN', authToken2); + let response = await fetch(getActiveUsersUrl, { + method: 'GET', + headers: headers + }); + console.log(response.clone()); + if (fetchErrorHandler(response.clone())) { + return null; + } + let data = await response.json(); + return data; +} + $(document).ready(function() { $('#action_menu_btn').click(function() { $('.action_menu').toggle(); diff --git a/chatto/src/main/resources/static/js/login.js b/chatto/src/main/resources/static/js/login.js index 7c5a2a8..0cd8c80 100644 --- a/chatto/src/main/resources/static/js/login.js +++ b/chatto/src/main/resources/static/js/login.js @@ -1,13 +1,6 @@ function storeCredentials() { let usernameInput = document.getElementById('username'); let passwordInput = document.getElementById('password'); - let credentials = { - username: usernameInput.value, - password: passwordInput.value - } - // sessionStorage.setItem('credentials', JSON.stringify(credentials)); - localStorage.setItem('username', usernameInput.value); - var jqxhr = $.ajax({ type: 'GET', url: `http://${hostAddress}/api/chat/get/token`, @@ -19,16 +12,28 @@ function storeCredentials() { jqxhr.done(function() { let authToken = jqxhr.getResponseHeader('X-AUTH-TOKEN'); localStorage.setItem('authToken', authToken); + authToken = localStorage.getItem('authToken') console.log("getting header " + authToken); + secondClick = true; + $('#loginForm').submit(); + }); //this section is executed when the server responds with error jqxhr.fail(function() { - console.error('Error retrieving auth token'); + log.error('Error retrieving auth token'); + alertify.error('Error retrieving auth token. Please log in again') }) + localStorage.setItem('username', usernameInput.value); } -let loginForm = document.getElementById('loginForm'); -loginForm.addEventListener('submit', function(e) { - // e.preventDefault(); - storeCredentials(); -}) \ No newline at end of file +let secondClick = false; +$('#loginForm').on('submit', function(e) { + if(!secondClick) { + secondClick = true; + e.preventDefault(); + storeCredentials(); + } + // else { + // secondClick = false; + // } +}) diff --git a/chatto/src/main/resources/templates/chat.html b/chatto/src/main/resources/templates/chat.html index 8a6a7c4..fe94b9e 100644 --- a/chatto/src/main/resources/templates/chat.html +++ b/chatto/src/main/resources/templates/chat.html @@ -20,6 +20,8 @@ + + @@ -54,12 +56,16 @@
-
- -
- +
+
@@ -76,7 +82,7 @@
- +
  • @@ -89,7 +95,7 @@

    Khalid is online

    - +

    @@ -106,7 +112,6 @@
    Hello how are you
    -
  • @@ -255,6 +260,42 @@
    + + + diff --git a/chatto/src/main/resources/templates/registration.html b/chatto/src/main/resources/templates/registration.html index 327f868..2663ef3 100644 --- a/chatto/src/main/resources/templates/registration.html +++ b/chatto/src/main/resources/templates/registration.html @@ -59,7 +59,7 @@