diff --git a/scripts/communication/template/communication.css b/scripts/communication/template/communication.css new file mode 100644 index 00000000000..c68e3da2471 --- /dev/null +++ b/scripts/communication/template/communication.css @@ -0,0 +1,110 @@ +html, body { + height: 100%; + font-size: 13px; +} + +/* Styles for message text box */ +.size-message { + height: 50px; + width: 99.5%; +} + +/* Styles for top right icons */ +.right_icons { + margin-left: 92%; +} + +ul, li, +.anchor { + cursor: pointer; + color: black; +} + +.messages { + overflow-y: auto; + height: 100%; + margin-left: 2px; +} + +.send_message { + margin-top: 5px; + margin-left: 2px; +} + +.user_name { + font-style: italic; +} + +.user_message { + background-color: #DFE5F9; + width: 99%; +} + +.date_time { + font-style: italic; + font-size: 12px; +} + +.date_time span { + float: right; +} + +.tab-content { + height: 65%; +} + +.tab-pane { + height: 100%; +} + +.nav li a { + padding: 7px 7px; +} + +ul > li i { + padding-left: 4px; + font-size: 12px; +} + +/****styles for overflow tabs****/ +.wrapper { + position: relative; + margin: 0 auto; + overflow: hidden; +height: 45px; +} + +.list { + position: absolute; + left: 0px; + top: 0px; +min-width: 3000px; + margin-top: 0px; +} + +.list li { +display: table-cell; + position: relative; + text-align: center; + color: #efefef; + vertical-align: middle; +} + +.scroller { + text-align: center; + cursor: pointer; + display: none; + padding: 5px; + padding-top: 9px; + vertical-align: middle; + background-color: #fff; +} + +.scroller-right { + float: right; +} + +.scroller-left { + float: left; +} + diff --git a/scripts/communication/template/communication.html b/scripts/communication/template/communication.html index add0bb74298..6088151280e 100644 --- a/scripts/communication/template/communication.html +++ b/scripts/communication/template/communication.html @@ -3,117 +3,7 @@ Chat - +
@@ -156,507 +46,6 @@ - + diff --git a/scripts/communication/template/communication.js b/scripts/communication/template/communication.js new file mode 100644 index 00000000000..c393ecab329 --- /dev/null +++ b/scripts/communication/template/communication.js @@ -0,0 +1,499 @@ +// the namespace events connect to +var namespace = '/chat', + socket = io.connect(window.location.protocol + '//' + document.domain + ':' + location.port + namespace); +// socketio events +var events_module = { + // event handler for sent data from server + event_response: function (socket) { + socket.on('event response', function (msg) { + var orig_message = msg.data.split(':'), + message = "", + uid = utils.get_userid(), + $el_all_messages = $('#all_messages'), + $el_tab_li = $("a[data-target='#all_chat_tab']"); + // builds the message to be displayed + message = utils.build_message(orig_message, uid); + // append only for non empty messages + if (orig_message[0].length > 0) { + utils.append_message($el_all_messages, message); + // adding message to build full chat history + if (!localStorage[uid]) { + localStorage[uid] = message + '
'; + } + else { + localStorage[uid] = localStorage[uid] + message + '
'; + } + } + // updates the user session storage with all the messages + sessionStorage[uid] = $el_all_messages.html(); + // show the last item by scrolling to the end + utils.scroll_to_last($el_all_messages); + if (uid !== orig_message[1].split('-')[1]) { + utils.show_notification($el_tab_li); + } + }); + }, + // event handler for room messages + event_response_room: function (socket) { + socket.on('event response room', function (msg) { + var $el_all_messages = $('#all_messages'), + message = '', + uid = utils.get_userid(), + tab_counter = 0, + $el_tab_li = null; + // response when user joins + if (msg.userjoin) { + message = msg.userjoin.split("-")[0] + " has joined " + msg.data + ":" + msg.userjoin; + utils.append_message($el_all_messages, utils.build_message(message.split(":"), uid)); + utils.scroll_to_last($el_all_messages); + if (uid !== msg.userjoin.split('-')[1]) { + $el_tab_li = $("a[data-target='#all_chat_tab']"); + utils.show_notification($el_tab_li); + } + } // response when user leaves + else if (msg.userleave) { + message = msg.userleave.split("-")[0] + " has left " + msg.data + ":" + msg.userleave; + utils.append_message($el_all_messages, utils.build_message(message.split(":"), uid)); + utils.scroll_to_last($el_all_messages); + if (uid !== msg.userleave.split('-')[1]) { + $el_tab_li = $("a[data-target='#all_chat_tab']"); + utils.show_notification($el_tab_li); + } + } + else { // normal message sharing when connected + for (var counter = 0; counter < click_events.connected_room.length; counter++) { + if (msg.chatroom === click_events.connected_room[counter]) { + tab_counter = counter; + break; + } + } + $el_room_msg = $("#all_messages_" + tab_counter); + utils.append_message($el_room_msg, utils.build_message(msg.data.split(':'), uid)); + utils.scroll_to_last($el_room_msg); + if (uid !== msg.data.split(':')[1].split('-')[1]) { + $el_tab_li = $("a[data-target='#tabroom_" + tab_counter + "'" + " ]"); + utils.show_notification($el_tab_li); + } + } + }); + }, + // event handler for new connections + event_connect: function (socket) { + socket.on('connect', function () { + var send_data = {}; + send_data.data = 'connected' + ':' + utils.get_username(); + socket.emit('event connect', send_data); + }); + } +} +// all the click events of buttons +var click_events = { + // on form load, user is connected, so the value is true + is_connected: true, + active_tab: "#all_chat_tab", + connected_room: [], + tab_id_number: 0, + broadcast_data: function (socket) { + $('#send_data').keydown(function (event) { + if (click_events.is_connected) { + var send_data = {}, + tab_counter = 0, + event_name = ""; + if (event.keyCode == 13 || event.which == 13) { + // if the tab is all chats + if (click_events.active_tab === '#all_chat_tab') { + send_data.data = escape($('#send_data').val()) + ':' + utils.get_userdata(); + event_name = 'event broadcast'; + } + else { // if the tab belongs to room + tab_counter = $('.nav-tabs>li.active').children().attr("data-target").split('_')[1]; + send_data.data = escape($('#send_data').val()) + ':' + utils.get_userdata(); + send_data.room = click_events.connected_room[tab_counter]; + event_name = 'event room'; + } + socket.emit(event_name, send_data); + $('#send_data').val(''); + return false; + } + } + }); + }, + // sets the current active tab + active_element: function () { + $('.nav-tabs>li').click(function (e) { + if( e.target.attributes['data-target'] ) { + click_events.active_tab = e.target.attributes['data-target'].nodeValue; + $(this).children().css('background-color', ''); + // hides the message textarea for create room tab + utils.show_hide_textarea( $(this).children() ); + var tab_content_id = $('.nav li.active').children().attr('data-target'); + // scroll to last in the tab content + if( tab_content_id ) { + utils.scroll_to_last( $(tab_content_id) ); + } + } + }); + }, + // event for connected and disconneted states + connect_disconnect: function (socket) { + $('#online_status').click(function () { + var $el_online_status = $('#online_status'), + $el_input_text = $('#send_data'), + send_data = {} + connected_message = 'Type your message...', + uid = utils.get_userid(); + if (click_events.is_connected) { + click_events.make_disconnect(uid, $el_input_text, $el_online_status); + } + else { + socket.connect(); + click_events.is_connected = true; + sessionStorage['connected'] = true; + utils.update_online_status($el_online_status, click_events.is_connected); + $el_input_text.prop('disabled', false); + $el_input_text.val(''); + $el_input_text.prop('placeholder', connected_message); + } + }); + }, + // clear all the messages + clear_messages: function () { + $('#clear_messages').click(function ( e ) { + // clears all the messages + utils.clear_message_area(); + return false; + }); + }, + // shows full chat history + show_chat_history: function () { + $('#chat_history').click(function (events) { + utils.fill_messages(localStorage[utils.get_userid()]); + }); + }, + // delete full history + delete_history: function () { + $('#delete_history').click(function () { + var uid = utils.get_userid(); + localStorage.removeItem(uid); + sessionStorage.removeItem(uid); + utils.clear_message_area(); + }); + }, + // makes disconnect + make_disconnect: function (uid, $el_input_text, $el_online_status) { + var send_data = {} + disconnected_message = 'You are now disconnected. To send/receive messages, please connect'; + click_events.is_connected = false; + send_data.data = "disconnected" + ":" + utils.get_username(); + socket.emit('event disconnect', send_data); + sessionStorage.removeItem(uid); + sessionStorage['connected'] = false; + utils.update_online_status($el_online_status, click_events.is_connected); + $el_input_text.val(''); + $el_input_text.prop('placeholder', disconnected_message); + $el_input_text.prop('disabled', true); + }, + // for creating/joining chat room + create_chat_room: function (socket) { + var $el_txtbox_chat_room = $('#txtbox_chat_room'), + $el_chat_room_tab = $('#chat_room_tab'), + tab_room_header_template = "", + tab_room_body_template = "", + tab_id = "", + tab_name = "", + self = this; + $el_txtbox_chat_room.keydown(function (e) { + var chat_room_name = $el_txtbox_chat_room.val(); + if (e.which === 13 || e.keyCode === 13) { + if( chat_room_name.length > 0 ) { + socket.emit('join', {room: chat_room_name, userjoin: utils.get_userdata()}); + self.connected_room.push( chat_room_name ); + // removes the active class from the chat creating tab + $el_chat_room_tab.removeClass('fade active in').addClass('fade'); + $('ul>li.active').removeClass('active'); + // sets new tab id + tab_id = "tabroom_" + self.tab_id_number; + tab_name = self.connected_room[self.connected_room.length - 1]; + // create chat room tab header for new room + tab_room_header_template = "
  • "; + $('#chat_tabs').append( tab_room_header_template ); + + // create chat room tab body for new room + tab_room_body_template = "
    "; + $('.tab-content').append(tab_room_body_template); + self.leave_close_room(); + self.active_element(); + $el_txtbox_chat_room.val(""); + self.tab_id_number++; + // displays the textarea + $('#send_data').css('display', 'block'); + // adjusts the left/right scrollers + // when a tab is created + utils.adjust_scrollers(); + return false; + } + } + }); + }, + // for chat rooms/ group chat + leave_close_room: function () { + var tab_counter = ""; + $('.close-room').click(function (e) { + e.stopPropagation(); + tab_counter = $(this).parent().attr('data-target').split("_")[1]; + // leaves room + socket.emit('leave', {room: click_events.connected_room[tab_counter], userleave: utils.get_userdata()}); + // removes tab and its content + $('.tab-content ' + $(this).parent().attr('data-target')).remove(); + $(this).parent().parent().remove(); + // selects the last tab and makes it active + $('#chat_tabs a:last').tab('show'); + // hides or shows textarea + utils.show_hide_textarea( $('#chat_tabs a:last') ); + // adjusts the left/right scrollers + // when a tab is deleted + utils.adjust_scrollers(); + return false; + }); + }, + // registers overflow tabs left/right click events + overflow_left_right_scroll: function() { + $('.scroller-right').click(function() { + $('.scroller-left').fadeIn('slow'); + $('.scroller-right').fadeOut('slow'); + // performs animation when the scroller is clicked + // and shifts the tab list to the right end + $('.list').animate({left: "+=" + utils.get_width_hidden_list() + "px"}, 'slow', function() { }); + }); + $('.scroller-left').click(function() { + $('.scroller-right').fadeIn('slow'); + $('.scroller-left').fadeOut('slow'); + // performs animation when the scroller is clicked + // and shifts the tab list to the left end + $('.list').animate({left: "-=" + utils.get_list_left_position() + "px"}, 'slow', function() { }); + }); + }, +} +// utility methods +var utils = { + // get the current username of logged in user + // from the querystring of the URL + get_userdata: function () { + var $el_modal_body = $('.modal-body'), + user_data = $el_modal_body.context.URL.split('?')[1], + data = user_data.split('&'), + userid_data = data[1], + username_data = data[0]; + if (data) { + return unescape(username_data.split('=')[1] + "-" + userid_data.split('=')[1]); + } + else { + return ""; + } + }, + // fill in all messages + fill_messages: function (collection) { + var uid = utils.get_userid(), + message_html = $.parseHTML(collection), + $el_all_messages = $('#all_messages'); + // clears the previous items + this.clear_message_area(); + if (collection) { + $el_all_messages.append($('').html(message_html)); + } + // show the last item by scrolling to the end + utils.scroll_to_last($el_all_messages); + }, + // gets the user id + get_userid: function () { + return utils.get_userdata().split('-')[1]; + }, + // gets the user name + get_username: function () { + return utils.get_userdata().split('-')[0]; + }, + // scrolls to the last of element + scroll_to_last: function ($el) { + if ($el[0]) { + $el.scrollTop($el[0].scrollHeight); + } + }, + // append message + append_message: function ($el, message) { + $el.append(message); + $el.append('
    '); + }, + // builds message + build_message: function (original_message, uid) { + var from_uid = original_message[1].split('-')[1], + message_user = "", + message_text = ""; + // for user's own messages + if (from_uid === uid) { + message_user = this.build_message_username_template('me'); + } + // for other user's messages + else { + message_user = this.build_message_username_template(unescape(original_message[1].split('-')[0])); + } + message_text = this.build_message_template(original_message); + return message_user + message_text; + }, + // builds message template + build_message_template: function (original_message) { + return "
    " + unescape(original_message[0]) + + "
    " + this.get_time() + "" + + "
    "; + }, + // builds template for username for message display + build_message_username_template: function (username) { + return "" + username + "
    "; + }, + // adds an information about the online status + update_online_status: function ($el, connected) { + if (connected) { + $el.prop("title", "You are online! Press to be offline.").css("color", "#00FF00"); + } + else { + $el.prop("title", "You are offline! Press to be online.").css( "color", "#FF0000"); + } + }, + // gets the current time + get_time: function () { + var currentdate = new Date(), + datetime = "", + hours = 0, + minutes = 0; + hours = ( currentdate.getHours() < 10 ) ? ( "0" + currentdate.getHours() ) : currentdate.getHours(); + minutes = ( currentdate.getMinutes() < 10 ) ? ( "0" + currentdate.getMinutes() ) : currentdate.getMinutes(); + datetime = hours + ":" + minutes; + return datetime; + }, + // gets the current date + get_date: function () { + var currentdate = new Date(), + day, + month; + month = ( (currentdate.getMonth() + 1 ) < 10) ? ( "0" + (currentdate.getMonth() + 1) ) : ( currentdate.getMonth() + 1 ); + day = ( currentdate.getDate() < 10 ) ? ( "0" + currentdate.getDate() ) : currentdate.getDate(); + return month + "/" + day + "/" + currentdate.getFullYear(); + }, + // clears the message list + clear_message_area: function () { + $('#all_messages').html(""); + }, + // shows notification when a message is + // pushed to the inactive tab + show_notification: function ($el) { + if (!$el.parent().hasClass('active')) { + $el.css('background-color', '#FCD116'); + for (var i = 2; i >= 1; i--) { + $el.fadeOut(200).fadeIn(200); + } + } + }, + // adjusts the scrollers when a + // tab is added or deleted + adjust_scrollers: function() { + if ( $('.wrapper').width() < this.get_list_width() ) { + $('.scroller-right').show(); + } + else { + $('.scroller-right').hide(); + } + + if (this.get_list_left_position() < 0) { + $('.scroller-left').show(); + } + else { + $('.item').animate( {left: "-=" + this.get_list_left_position() + "px"}, 'slow' ); + $('.scroller-left').hide(); + } + }, + // gets the widht of all li elements + get_list_width: function() { + var total_width = 0; + $('.list li').each(function() { + var li_width = $(this).width(); + total_width += li_width; + }); + return total_width; + }, + // gets the hidden width of the tab + get_width_hidden_list: function() { + var scroll_icon_width = 50; + return ( $('.wrapper').width() - this.get_list_width() - this.get_list_left_position() - scroll_icon_width ); + }, + get_list_left_position: function() { + return $('.list').position().left; + }, + // checks the session storage on page load + checks_session_storage: function() { + if (sessionStorage['connected']) { + if (sessionStorage['connected'] === 'true' || sessionStorage['connected'] === true) { + utils.update_online_status($('#online_status'), true); + click_events.is_connected = true; + } + else { + click_events.make_disconnect(uid, $('#send_data'), $('#online_status')); + utils.clear_message_area(); + } + } + else { + utils.update_online_status($('#online_status'), true); + click_events.is_connected = true; + } + }, + // show/hide textarea message box + show_hide_textarea: function( $selector ) { + if ( $selector.attr("data-target") === "#chat_room_tab" ) { + $('#send_data').css('display', 'none'); + } + else { + $('#send_data').css('display', 'block'); + } + }, +} + +// registers the events when this document is ready +$(document).ready(function () { + // fill the messages if user is already connected + // and comes back to the chat window + var uid = utils.get_userid(); + + // registers response event + events_module.event_response(socket); + // registers room response event + events_module.event_response_room(socket); + // registers connect event + events_module.event_connect(socket); + + // registers create room event + click_events.create_chat_room(socket); + // broadcast the data + click_events.broadcast_data(socket); + // disconnet the user from the chat server + click_events.connect_disconnect(socket); + // show chat history + click_events.show_chat_history(); + // clears all the messages + click_events.clear_messages(); + // deletes full chat history + click_events.delete_history(); + click_events.active_element(); + click_events.leave_close_room(); + // register tab overflow scroll events + click_events.overflow_left_right_scroll(); + + // build tabs + $('#chat_tabs').tab(); + $('#send_data').val(""); + utils.fill_messages(sessionStorage[uid]); + // updates online status text + // by checking if user was connected or not + utils.checks_session_storage(); + utils.scroll_to_last($('#all_messages')); +}); diff --git a/scripts/communication_server.py b/scripts/communication_server.py index 710eb52d40c..8d88be74cef 100755 --- a/scripts/communication_server.py +++ b/scripts/communication_server.py @@ -65,12 +65,16 @@ socketio = SocketIO(app) def findUserByCookie(request): cookie_value = request.cookies.get('galaxysession') if not cookie_value: - return + return None session_key = security_helper.decode_guid(cookie_value) user_session = sa_session.query(model.GalaxySession) \ - .filter_by(session_key=session_key, is_valid=True).first() - return user_session.user + .filter_by(session_key=session_key).first() + + if user_session: + return user_session.user + + return None # Taken from flask.pocoo.org/snippets/56/ def crossdomain(origin=None, methods=None, headers=None,