diff --git a/src/styles/components/_chat.scss b/src/styles/components/_chat.scss index b02f1288..18939367 100644 --- a/src/styles/components/_chat.scss +++ b/src/styles/components/_chat.scss @@ -27,6 +27,10 @@ top:0px; pointer-events: none; z-index:45; overflow:hidden; +-webkit-perspective: 1000; +-moz-perspective: 1000; +-o-perspective: 1000; +perspective: 1000; } .withChat #chat .chatpane { left:0px; @@ -39,43 +43,71 @@ width:auto; } } .chatpane { -height:100%; position:absolute; top:0px; left:260px; bottom:0px; right:0px; width:260px; --webkit-transition: left 200ms ease-in-out; --moz-transition: left 200ms ease-in-out; --ms-transition: left 200ms ease-in-out; --o-transition: left 200ms ease-in-out; transition: left 200ms ease-in-out; +-webkit-transition: 0.2s; +-webkit-transform-style: preserve-3d; +-moz-transition: 0.2s; +-moz-transform-style: preserve-3d; +-o-transition: 0.2s; +-o-transform-style: preserve-3d; +transition: 0.2s; +transform-style: preserve-3d; +-webkit-backface-visibility: hidden; +-moz-backface-visibility: hidden; +-o-backface-visibility: hidden; +backface-visibility: hidden; +} +.withChat .chatpane.flip { +-webkit-transform: rotateY(360deg); +-moz-transform: rotateY(360deg); +-o-transform: rotateY(360deg); +transform: rotateY(360deg); } .chat { -position:absolute; pointer-events: auto; +position:absolute; top:0px; bottom:0px; right:0px; left:0px; background: #e7e7e7; +border-top: 1px solid $bordercolor; border-right:1px solid $bordercolor; overflow:hidden; display:none; } .chat.visible { +} +.chat.visible.active { display:block; } +.chat .chatbody { +position:absolute; +bottom:0px; +left:0px; +right:0px; +top: 30px; +} +.chat.active .chatbody { +} .chat .chatheader { +position:relative; background: $componentbg; padding:8px 4px 0px 8px; -border-top: 1px solid $bordercolor; border-bottom: 1px solid $bordercolor; +border-left: 1px solid $bordercolor; font-size:0.8em; font-weight:bold; height:30px; } +.chat.active .chatheader { +} .chat .chatheader .ctrl { position:absolute; top:4px; @@ -98,10 +130,8 @@ cursor: pointer; position:absolute; left:0px; right:0px; -top:34px; +top:0px; bottom:74px; -//max-width:600px; -margin:0 auto; } .chat .output { overflow-x: hidden; @@ -296,29 +326,32 @@ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } + +.chat .chatbodybottom { + background: #e7e7e7; + position: absolute; + left:0px; + bottom:0px; + right:0px; + height:90px; + margin:0 auto; +} + .chat .typinghint { -position:absolute; -left:6px; -right:6px; -bottom:60px; +padding:6px; +white-space: no-wrap; +overflow: hidden; font-size:.8em; color: #aaa; -max-width:500px; -margin:0 auto; +height:22px; } .chat .inputbox { -position:absolute; -left:0px; -bottom:0px; -right:0px; -height:60px; -//max-width:500px; -margin:0 auto; +position:relative; } .chat .inputbox .btn { position:absolute; right:6px; -top:4px; +top:0px; padding: 0.5em 1em; } .chat .inputbox > div { diff --git a/static/js/controllers/chatroomcontroller.js b/static/js/controllers/chatroomcontroller.js index 366e8b16..d7ddd6ec 100644 --- a/static/js/controllers/chatroomcontroller.js +++ b/static/js/controllers/chatroomcontroller.js @@ -25,6 +25,7 @@ define(['underscore', 'moment', 'text!partials/fileinfo.html'], function(_, mome $scope.outputElement = $(".output", $element); $scope.inputElement = $(".input", $element); + $scope.bodyElement = $(".chatbody", $element); var lastSender = null; var lastDate = null; var lastMessageContainer = null; @@ -36,7 +37,7 @@ define(['underscore', 'moment', 'text!partials/fileinfo.html'], function(_, mome var scrollAfterInput = false; // Mark seen on several events. - $element.on("mouseover mouseenter touchstart", _.debounce(function(event) { + $scope.bodyElement.on("mouseover mouseenter touchstart", _.debounce(function(event) { $scope.$parent.seen(); $scope.$apply(); }, 100)); diff --git a/static/js/directives/chat.js b/static/js/directives/chat.js index 11106b06..bb6cc7dd 100644 --- a/static/js/directives/chat.js +++ b/static/js/directives/chat.js @@ -31,6 +31,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], $scope.layout.chatMaximized = false; var rooms = {}; + var visibleRooms = []; mediaStream.api.e.on("received.chat", function(event, id, from, data, p2p) { @@ -91,14 +92,19 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], $scope.$parent.$on("startchat", function(event, id, options) { //console.log("startchat requested", event, id); - $scope.showRoom(id, {title: translation._("Chat with")}, options); + if (id === group_chat_id) { + $scope.showGroupRoom(null, options); + } else { + $scope.showRoom(id, {title: translation._("Chat with")}, options); + } }); // Shared data; return { rooms: rooms, - visibleRooms: [], + visibleRooms: visibleRooms, + group: group_chat_id, get: function(id) { return rooms[id]; } @@ -111,6 +117,10 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], var chat = $compile(templateChatroom); return function(scope, iElement, iAttrs, controller) { + scope.showGroupRoom = function(settings, options) { + var stngs = $.extend({title: translation._("Room chat")}, settings); + return scope.showRoom(controller.group, stngs, options); + }; scope.currentRoom = null; scope.showRoom = function(id, settings, options) { var options = $.extend({}, options); @@ -122,7 +132,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], subscope = controller.rooms[id] = scope.$new(); translation.inject(subscope); subscope.id = id; - subscope.isgroupchat = id === group_chat_id ? true : false; + subscope.isgroupchat = id === controller.group ? true : false; subscope.index = index; subscope.settings = settings; subscope.visible = false; @@ -131,6 +141,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], subscope.peerIsTyping = "no"; subscope.firstmessage = true; subscope.p2pstate = false; + subscope.active = false; if (!subscope.isgroupchat) { buddyData.push(id); } @@ -151,7 +162,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], subscope.$broadcast("seen"); } }; - subscope.toggle = function() { + subscope.toggleMax = function() { scope.toggleMax(); }; subscope.sendChat = function(to, message, status, mid, noloop) { @@ -273,9 +284,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], if (options.autofocus && subscope.visible) { subscope.$broadcast("focus"); } - } - if (scope.currentRoom !== subscope && scope.currentRoom) { - scope.currentRoom.hide(); + } if (options.restore && !options.noenable) { @@ -284,7 +293,10 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], } } - scope.currentRoom = subscope; + if (!options.noactivate) { + scope.activateRoom(subscope.id, true); + } + safeApply(subscope); return subscope; }; @@ -309,10 +321,9 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], scope.currentRoom = null; } if (!controller.visibleRooms.length) { - scope.showRoom(group_chat_id, {title: translation._("Room chat")}, {restore: true, noenable: true}); - if (id === group_chat_id) { - scope.layout.chat = false; - } + scope.showGroupRoom(null, {restore: true, noenable: true, activate: true}); + // If last visible room was removed, hide chat. + scope.layout.chat = false; } }; scope.killRoom = function(id) { @@ -329,17 +340,38 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'], scope.toggleMax = function() { scope.layout.chatMaximized = !scope.layout.chatMaximized; }; + scope.activateRoom = function(id, active) { + var subscope = controller.rooms[id]; + //console.log("toggleActive", active, id, scope.currentRoom, scope.currentRoom == subscope, subscope.active); + if (scope.currentRoom == subscope) { + subscope.active = active; + } else { + if (scope.currentRoom) { + scope.currentRoom.active = false; + scope.currentRoom.hide(); + } + if (active) { + scope.currentRoom = subscope; + iElement.toggleClass("flip"); + } + subscope.active = active; + } + }; scope.$on("room", function(event, room) { if (room == null) { - scope.hideRoom(group_chat_id); + scope.hideRoom(controller.group); } else { + var subscope; if (!controller.visibleRooms.length) { - scope.showRoom(group_chat_id, {title: translation._("Room chat")}, {restore: true, noenable: true}); + subscope = scope.showGroupRoom(null, {restore: true, noenable: true}); + } else { + subscope = controller.get(controller.group); + } + if (room) { + var msg = translation._("You are now in room %s ...", room); + subscope.$broadcast("display", null, $(""+msg+"")); } - var subscope = controller.get(group_chat_id); - var msg = translation._("You are now in room %s ...", room); - subscope.$broadcast("display", null, $(""+msg+"")); } }); diff --git a/static/partials/chatroom.html b/static/partials/chatroom.html index b30b71c3..9fa9f90c 100644 --- a/static/partials/chatroom.html +++ b/static/partials/chatroom.html @@ -1,16 +1,20 @@ -