Browse Source

Implemented chat sessions view.

pull/16/head
Simon Eisenmann 11 years ago
parent
commit
a30e815fb0
  1. 13
      src/i18n/messages-de.po
  2. 11
      src/i18n/messages.pot
  3. 59
      src/styles/components/_chat.scss
  4. 56
      static/js/directives/chat.js
  5. 20
      static/partials/chat.html
  6. 2
      static/partials/chatroom.html
  7. 2
      static/translation/messages-de.json

13
src/i18n/messages-de.po

@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Spreed Speak Freely\n" "Project-Id-Version: Spreed Speak Freely\n"
"Report-Msgid-Bugs-To: simon@struktur.de\n" "Report-Msgid-Bugs-To: simon@struktur.de\n"
"POT-Creation-Date: 2014-03-18 19:10+0100\n" "POT-Creation-Date: 2014-03-20 18:31+0100\n"
"PO-Revision-Date: 2014-03-18 19:10+0100\n" "PO-Revision-Date: 2014-03-20 18:31+0100\n"
"Last-Translator: Simon Eisenmann <simon@struktur.de>\n" "Last-Translator: Simon Eisenmann <simon@struktur.de>\n"
"Language-Team: de <LL@li.org>\n" "Language-Team: de <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0\n" "Plural-Forms: nplurals=1; plural=0\n"
@ -48,6 +48,12 @@ msgstr "Audio-Konferenz starten"
msgid "No other users online" msgid "No other users online"
msgstr "Niemand sonst online" msgstr "Niemand sonst online"
msgid "Chat sessions"
msgstr "Chat-Sitzungen"
msgid "Room chat"
msgstr "Raum-Chat"
msgid "Peer to peer" msgid "Peer to peer"
msgstr "Peer-to-peer" msgstr "Peer-to-peer"
@ -388,9 +394,6 @@ msgstr "Chat mit"
msgid "Message from " msgid "Message from "
msgstr "Nachricht von " msgstr "Nachricht von "
msgid "Room chat"
msgstr "Raum-Chat"
#, python-format #, python-format
msgid "You are now in room %s ..." msgid "You are now in room %s ..."
msgstr "Sie sind nun im Raum %s ..." msgstr "Sie sind nun im Raum %s ..."

11
src/i18n/messages.pot

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Spreed Speak Freely 1.0\n" "Project-Id-Version: Spreed Speak Freely 1.0\n"
"Report-Msgid-Bugs-To: simon@struktur.de\n" "Report-Msgid-Bugs-To: simon@struktur.de\n"
"POT-Creation-Date: 2014-03-18 19:10+0100\n" "POT-Creation-Date: 2014-03-20 18:31+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -48,6 +48,12 @@ msgstr ""
msgid "No other users online" msgid "No other users online"
msgstr "" msgstr ""
msgid "Chat sessions"
msgstr ""
msgid "Room chat"
msgstr ""
msgid "Peer to peer" msgid "Peer to peer"
msgstr "" msgstr ""
@ -382,9 +388,6 @@ msgstr ""
msgid "Message from " msgid "Message from "
msgstr "" msgstr ""
msgid "Room chat"
msgstr ""
#, python-format #, python-format
msgid "You are now in room %s ..." msgid "You are now in room %s ..."
msgstr "" msgstr ""

59
src/styles/components/_chat.scss

@ -32,24 +32,67 @@ overflow:hidden;
-o-perspective: 1000; -o-perspective: 1000;
perspective: 1000; perspective: 1000;
} }
.withChat #chat .chatpane { .withChat #chat .chatcontainer {
left:0px; left:0px;
} }
.withChat.withChatMaximized #chat { .withChat.withChatMaximized #chat {
left:0px; left:0px;
width:auto; width:auto;
.chatpane { .chatcontainer {
width:auto; width:auto;
} }
} }
.chatpane { .chatcontainer {
position:absolute; position:absolute;
top:0px; top:0px;
left:260px; left:260px;
bottom:0px;
right:0px; right:0px;
bottom:0px;
width:260px; 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; transition: left 200ms ease-in-out;
}
.chatlist {
position:absolute;
top:0px;
left:0px;
bottom:0px;
right:0px;
background: #e7e7e7;
.list-group {
margin-top:-1px;
margin-bottom:-1px;
max-height:100%;
overflow-x: hidden;
overflow-y: auto;
}
.list-group-item {
border-right:none;
border-left:none;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
}
.list-group-item .fa-lg {
display:inline-block;
width:18px;
text-align:center;
}
.list-group-item .badge {
background: #84b819;
border: 1px solid white;
font-size:.8em;
}
}
.chatpane {
position:absolute;
top:0px;
left:0px;
bottom:0px;
right:0px;
-webkit-transition: 0.3s; -webkit-transition: 0.3s;
-webkit-transform-style: preserve-3d; -webkit-transform-style: preserve-3d;
-moz-transition: 0.3s; -moz-transition: 0.3s;
@ -87,7 +130,7 @@ display:block;
} }
.chat .chatbody { .chat .chatbody {
position:absolute; position:absolute;
bottom:0px; bottom:-1px;
left:0px; left:0px;
right:0px; right:0px;
top: 36px; top: 36px;
@ -121,7 +164,7 @@ display:block;
text-align:center; text-align:center;
} }
.chat .chatheader .chatheadertitle { .chat .chatheader .chatheadertitle {
padding-left:26px; padding-left:28px;
display:inline; display:inline;
} }
.chat .chatheader .ctrl { .chat .chatheader .ctrl {
@ -348,7 +391,7 @@ text-overflow:ellipsis;
background: #e7e7e7; background: #e7e7e7;
position: absolute; position: absolute;
left:0px; left:0px;
bottom:0px; bottom:1px;
right:0px; right:0px;
margin:0 auto; margin:0 auto;
} }
@ -405,7 +448,7 @@ border-color:#66afe9;
100% {background-color: rgba(132,184,25,1.0);} 100% {background-color: rgba(132,184,25,1.0);}
} }
.chat.newmessage .chatheader { .chat.newmessage .chatheader, .chatlist .list-group-item.newmessage {
animation: newmessage 1s ease -0.3s infinite; animation: newmessage 1s ease -0.3s infinite;
-webkit-animation: newmessage 1s ease -0.3s infinite; -webkit-animation: newmessage 1s ease -0.3s infinite;
} }

56
static/js/directives/chat.js

@ -38,6 +38,23 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
return ctrl.rooms[id]; return ctrl.rooms[id];
} }
$scope.currentRoom = null;
$scope.currentRoomActive = false;
$scope.getVisibleRooms = function() {
var res = [];
for (var i=0; i<ctrl.visibleRooms.length; i++) {
var r = rooms[ctrl.visibleRooms[i]];
if (!r || r.id === ctrl.group) {
continue;
}
res.push(r);
}
return res;
};
$scope.getGroupRoom = function() {
return rooms[ctrl.group];
};
mediaStream.api.e.on("received.chat", function(event, id, from, data, p2p) { mediaStream.api.e.on("received.chat", function(event, id, from, data, p2p) {
//console.log("received", data, id, from); //console.log("received", data, id, from);
@ -117,11 +134,14 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
var chat = $compile(templateChatroom); var chat = $compile(templateChatroom);
return function(scope, iElement, iAttrs, controller) { return function(scope, iElement, iAttrs, controller) {
var pane = iElement.find(".chatpane");
scope.showGroupRoom = function(settings, options) { scope.showGroupRoom = function(settings, options) {
var stngs = $.extend({title: translation._("Room chat")}, settings); var stngs = $.extend({title: translation._("Room chat")}, settings);
return scope.showRoom(controller.group, stngs, options); return scope.showRoom(controller.group, stngs, options);
}; };
scope.currentRoom = null;
scope.showRoom = function(id, settings, options) { scope.showRoom = function(id, settings, options) {
var options = $.extend({}, options); var options = $.extend({}, options);
var subscope = controller.rooms[id]; var subscope = controller.rooms[id];
@ -142,6 +162,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
subscope.firstmessage = true; subscope.firstmessage = true;
subscope.p2pstate = false; subscope.p2pstate = false;
subscope.active = false; subscope.active = false;
subscope.pending = 0;
if (!subscope.isgroupchat) { if (!subscope.isgroupchat) {
buddyData.push(id); buddyData.push(id);
} }
@ -156,12 +177,16 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
scope.killRoom(id); scope.killRoom(id);
}; };
subscope.seen = function() { subscope.seen = function() {
subscope.pending = 0;
scope.$emit("chatseen", subscope.id); scope.$emit("chatseen", subscope.id);
if (subscope.newmessage) { if (subscope.newmessage) {
subscope.newmessage = false; subscope.newmessage = false;
subscope.$broadcast("seen"); subscope.$broadcast("seen");
} }
}; };
subscope.deactivate =function() {
scope.deactivateRoom();
};
subscope.toggleMax = function() { subscope.toggleMax = function() {
scope.toggleMax(); scope.toggleMax();
}; };
@ -235,6 +260,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
}); });
subscope.$on("incoming", function(event, message, from, userid) { subscope.$on("incoming", function(event, message, from, userid) {
if (from !== userid) { if (from !== userid) {
subscope.pending++;
scope.$emit("chatincoming", subscope.id); scope.$emit("chatincoming", subscope.id);
} }
if (subscope.firstmessage || !desktopNotify.windowHasFocus) { if (subscope.firstmessage || !desktopNotify.windowHasFocus) {
@ -250,7 +276,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
}); });
chat(subscope, function(clonedElement, $scope) { chat(subscope, function(clonedElement, $scope) {
iElement.append(clonedElement); pane.append(clonedElement);
$scope.element=clonedElement; $scope.element=clonedElement;
$scope.visible = true; $scope.visible = true;
if (options.autofocus) { if (options.autofocus) {
@ -303,6 +329,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
safeApply(subscope); safeApply(subscope);
return subscope; return subscope;
}; };
scope.hideRoom = function(id) { scope.hideRoom = function(id) {
var subscope = controller.rooms[id]; var subscope = controller.rooms[id];
if (!subscope) { if (!subscope) {
@ -322,13 +349,15 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
}); });
if (scope.currentRoom === subscope) { if (scope.currentRoom === subscope) {
scope.currentRoom = null; scope.currentRoom = null;
scope.currentRoomActive = false;
} }
if (!controller.visibleRooms.length) { if (!controller.visibleRooms.length) {
scope.showGroupRoom(null, {restore: true, noenable: true, activate: true}); scope.showGroupRoom(null, {restore: true, noenable: true, noactivate: true});
// If last visible room was removed, hide chat. // If last visible room was removed, hide chat.
scope.layout.chat = false; scope.layout.chat = false;
} }
}; };
scope.killRoom = function(id) { scope.killRoom = function(id) {
scope.hideRoom(id); scope.hideRoom(id);
var subscope = controller.rooms[id]; var subscope = controller.rooms[id];
@ -340,39 +369,50 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
subscope.$destroy(); subscope.$destroy();
}, 0); }, 0);
}; };
scope.toggleMax = function() { scope.toggleMax = function() {
scope.layout.chatMaximized = !scope.layout.chatMaximized; scope.layout.chatMaximized = !scope.layout.chatMaximized;
}; };
scope.activateRoom = function(id, active) { scope.activateRoom = function(id, active) {
var subscope = controller.rooms[id];
if (!subscope) {
return;
}
var visible = !!scope.layout.chat; var visible = !!scope.layout.chat;
var flip = false; var flip = false;
var subscope = controller.rooms[id];
//console.log("toggleActive", active, id, scope.currentRoom, scope.currentRoom == subscope, subscope.active); //console.log("toggleActive", active, id, scope.currentRoom, scope.currentRoom == subscope, subscope.active);
if (scope.currentRoom == subscope) { if (scope.currentRoom == subscope) {
subscope.active = active; subscope.active = active;
scope.currentRoomActive = true;
if (visible) { if (visible) {
flip = true; flip = true;
} }
} else { } else {
if (scope.currentRoom) { if (scope.currentRoom) {
scope.currentRoom.active = false; scope.currentRoom.active = false;
scope.currentRoom.hide(); //scope.currentRoom.hide();
if (visible) { if (visible) {
flip = true; flip = true;
} }
} }
if (active) { if (active) {
scope.currentRoom = subscope; scope.currentRoom = subscope;
scope.currentRoomActive = true;
} }
subscope.active = active; subscope.active = active;
} }
if (flip) { if (flip) {
iElement.toggleClass("flip"); pane.toggleClass("flip");
} }
}; };
scope.deactivateRoom = function() {
scope.currentRoomActive = false;
};
scope.$watch("layout.chat", function(chat) { scope.$watch("layout.chat", function(chat) {
iElement.removeClass("flip"); pane.removeClass("flip");
}); });
scope.$on("room", function(event, room) { scope.$on("room", function(event, room) {
@ -381,7 +421,7 @@ define(['underscore', 'text!partials/chat.html', 'text!partials/chatroom.html'],
} else { } else {
var subscope; var subscope;
if (!controller.visibleRooms.length) { if (!controller.visibleRooms.length) {
subscope = scope.showGroupRoom(null, {restore: true, noenable: true}); subscope = scope.showGroupRoom(null, {restore: true, noenable: true, noactivate: true});
} else { } else {
subscope = controller.get(controller.group); subscope = controller.get(controller.group);
} }

20
static/partials/chat.html

@ -1 +1,19 @@
<div class="chatpane"></div> <div class="chatcontainer">
<div class="chatpane" ng-show="currentRoomActive"></div>
<div class="chatlist" ng-hide="currentRoomActive">
<div class="chat visible active">
<div class="chatheader"><div class="chatstatusicon" ng-click="activateRoom(currentRoom.id, true)"><i class="fa fa-angle-right"></i> <i class="fa fa fa-comments-o"></i></div><div class="chatheadertitle"><span>{{_("Chat sessions")}}</span></div></div>
<div class="chatbody">
<div class="list-group nicescroll">
<a ng-if="roomstatus" ng-click="activateRoom('', true)" class="list-group-item">
<span class="badge" ng-show="getGroupRoom().pending">{{getGroupRoom().pending}}</span>
<i class="fa fa-users fa-lg"></i> {{_("Room chat")}}
</a>
<a ng-repeat="room in getVisibleRooms()" ng-click="activateRoom(room.id, true)" class="list-group-item" ng-class="{newmessage: room.pending}">
<span class="badge" ng-show="room.pending">{{room.pending}}</span><i class="fa fa-user fa-lg"></i> {{room.id|displayName}}
</a>
</div>
</div>
</div>
</div>
</div>

2
static/partials/chatroom.html

@ -1,5 +1,5 @@
<div ng-controller="ChatroomController" class="chat room-{{index}}" ng-class="{'newmessage': newmessage, 'visible': visible, 'chat-p2p': 'p2pstate', 'with_pictures': isgroupchat, 'active': active}"> <div ng-controller="ChatroomController" class="chat room-{{index}}" ng-class="{'newmessage': newmessage, 'visible': visible, 'chat-p2p': 'p2pstate', 'with_pictures': isgroupchat, 'active': active}">
<div class="chatheader"><div class="chatstatusicon"><i class="fa fa fa-comments-o"></i></div><div class="chatheadertitle"><span ng-show="p2pstate" class="fa fa-exchange" title="{{_('Peer to peer')}}"/><span>{{settings.title}} {{id|displayName}}</span></div> <div class="ctrl"><i ng-hide="layout.chatMaximized" ng-click="toggleMax()" class="fa fa-expand"></i><i ng-show="layout.chatMaximized" ng-click="toggleMax()" class="fa fa-compress"></i><i title="{{_('Close chat')}}" ng-click="hide()" class="fa fa-times"></i></div></div> <div class="chatheader"><div class="chatstatusicon" ng-click="deactivateRoom()"><i class="fa fa-angle-left"></i> <i class="fa fa fa-comments-o"></i></div><div class="chatheadertitle"><span ng-show="p2pstate" class="fa fa-exchange" title="{{_('Peer to peer')}}"/><span>{{settings.title}} {{id|displayName}}</span></div> <div class="ctrl"><i ng-hide="layout.chatMaximized" ng-click="toggleMax()" class="fa fa-expand"></i><i ng-show="layout.chatMaximized" ng-click="toggleMax()" class="fa fa-compress"></i><!--<i title="{{_('Close chat')}}" ng-click="hide()" class="fa fa-times"></i>--></div></div>
<div class="chatbody"> <div class="chatbody">
<div class="outputbox"> <div class="outputbox">
<div class="output nicescroll"></div> <div class="output nicescroll"></div>

2
static/translation/messages-de.json

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save