Browse Source

online chat aapplied

Maxim Sokhatsky 11 years ago
parent
commit
220f875507

+ 20 - 1
apps/web/priv/static/app/Kakaranet-Scene.svg

@@ -3,7 +3,11 @@
     <!-- Generator: Sketch 3.0.3 (7892) - http://www.bohemiancoding.com/sketch -->
     <!-- Generator: Sketch 3.0.3 (7892) - http://www.bohemiancoding.com/sketch -->
     <title>Kakaranet-Scene</title>
     <title>Kakaranet-Scene</title>
     <desc>Created with Sketch.</desc>
     <desc>Created with Sketch.</desc>
-    <defs></defs>
+    <defs>
+    <clipPath id="myClip1"><rect id="Clip-Path-Left" x="0" y="0" width="216" height="400"/></clipPath>
+    <clipPath id="myClip2"><rect id="Clip-Path-Right" x="0" y="0" width="216" height="400"/></clipPath>
+    <clipPath id="myClip3"><rect id="Clip-Path-Left-Chat" x="0" y="0" width="216" height="400"/></clipPath>
+    </defs>
     <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
     <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
         <g id="Kakaranet-12-maxim" sketch:type="MSLayerGroup">
         <g id="Kakaranet-12-maxim" sketch:type="MSLayerGroup">
             <rect id="Sky" fill="#EDF9FF" sketch:type="MSShapeGroup" x="0" y="0" width="1070.148" height="453"></rect>
             <rect id="Sky" fill="#EDF9FF" sketch:type="MSShapeGroup" x="0" y="0" width="1070.148" height="453"></rect>
@@ -455,5 +459,20 @@
         <path d="M680.82681,16 L661.143994,16 C658.854843,16 657,17.8548426 657,20.1430683 L657,50.1835548 C657,52.4717805 658.854843,54.3266231 661.143994,54.3266231 L680.82681,54.3266231 C683.115036,54.3266231 684.969878,52.4717805 684.969878,50.1835548 L684.969878,20.1430683 C684.968952,17.8548426 683.115036,16 680.82681,16 L680.82681,16 L680.82681,16 Z M670.985865,41.0399123 C667.737344,41.0399123 665.108338,38.4072025 665.108338,35.1623855 C665.108338,31.9147904 667.737344,29.2848588 670.985865,29.2848588 C674.230682,29.2848588 676.863392,31.9147904 676.863392,35.1623855 C676.863392,38.4090546 674.230682,41.0399123 670.985865,41.0399123 L670.985865,41.0399123 L670.985865,41.0399123 Z" id="Okey-Tash-Logo-2" fill="#517ECE" sketch:type="MSShapeGroup"></path>
         <path d="M680.82681,16 L661.143994,16 C658.854843,16 657,17.8548426 657,20.1430683 L657,50.1835548 C657,52.4717805 658.854843,54.3266231 661.143994,54.3266231 L680.82681,54.3266231 C683.115036,54.3266231 684.969878,52.4717805 684.969878,50.1835548 L684.969878,20.1430683 C684.968952,17.8548426 683.115036,16 680.82681,16 L680.82681,16 L680.82681,16 Z M670.985865,41.0399123 C667.737344,41.0399123 665.108338,38.4072025 665.108338,35.1623855 C665.108338,31.9147904 667.737344,29.2848588 670.985865,29.2848588 C674.230682,29.2848588 676.863392,31.9147904 676.863392,35.1623855 C676.863392,38.4090546 674.230682,41.0399123 670.985865,41.0399123 L670.985865,41.0399123 L670.985865,41.0399123 Z" id="Okey-Tash-Logo-2" fill="#517ECE" sketch:type="MSShapeGroup"></path>
         <path d="M717.82681,16 L698.143994,16 C695.854843,16 694,17.8548426 694,20.1430683 L694,50.1835548 C694,52.4717805 695.854843,54.3266231 698.143994,54.3266231 L717.82681,54.3266231 C720.115036,54.3266231 721.969878,52.4717805 721.969878,50.1835548 L721.969878,20.1430683 C721.968952,17.8548426 720.115036,16 717.82681,16 L717.82681,16 L717.82681,16 Z M707.985865,41.0399123 C704.737344,41.0399123 702.108338,38.4072025 702.108338,35.1623855 C702.108338,31.9147904 704.737344,29.2848588 707.985865,29.2848588 C711.230682,29.2848588 713.863392,31.9147904 713.863392,35.1623855 C713.863392,38.4090546 711.230682,41.0399123 707.985865,41.0399123 L707.985865,41.0399123 L707.985865,41.0399123 Z" id="Okey-Tash-Logo-3" fill="#F6A623" sketch:type="MSShapeGroup"></path>
         <path d="M717.82681,16 L698.143994,16 C695.854843,16 694,17.8548426 694,20.1430683 L694,50.1835548 C694,52.4717805 695.854843,54.3266231 698.143994,54.3266231 L717.82681,54.3266231 C720.115036,54.3266231 721.969878,52.4717805 721.969878,50.1835548 L721.969878,20.1430683 C721.968952,17.8548426 720.115036,16 717.82681,16 L717.82681,16 L717.82681,16 Z M707.985865,41.0399123 C704.737344,41.0399123 702.108338,38.4072025 702.108338,35.1623855 C702.108338,31.9147904 704.737344,29.2848588 707.985865,29.2848588 C711.230682,29.2848588 713.863392,31.9147904 713.863392,35.1623855 C713.863392,38.4090546 711.230682,41.0399123 707.985865,41.0399123 L707.985865,41.0399123 L707.985865,41.0399123 Z" id="Okey-Tash-Logo-3" fill="#F6A623" sketch:type="MSShapeGroup"></path>
         <path d="M754.82681,16 L735.143994,16 C732.854843,16 731,17.8548426 731,20.1430683 L731,50.1835548 C731,52.4717805 732.854843,54.3266231 735.143994,54.3266231 L754.82681,54.3266231 C757.115036,54.3266231 758.969878,52.4717805 758.969878,50.1835548 L758.969878,20.1430683 C758.968952,17.8548426 757.115036,16 754.82681,16 L754.82681,16 L754.82681,16 Z M744.985865,41.0399123 C741.737344,41.0399123 739.108338,38.4072025 739.108338,35.1623855 C739.108338,31.9147904 741.737344,29.2848588 744.985865,29.2848588 C748.230682,29.2848588 750.863392,31.9147904 750.863392,35.1623855 C750.863392,38.4090546 748.230682,41.0399123 744.985865,41.0399123 L744.985865,41.0399123 L744.985865,41.0399123 Z" id="Okey-Tash-Logo-4" fill="#517ECE" sketch:type="MSShapeGroup"></path>
         <path d="M754.82681,16 L735.143994,16 C732.854843,16 731,17.8548426 731,20.1430683 L731,50.1835548 C731,52.4717805 732.854843,54.3266231 735.143994,54.3266231 L754.82681,54.3266231 C757.115036,54.3266231 758.969878,52.4717805 758.969878,50.1835548 L758.969878,20.1430683 C758.968952,17.8548426 757.115036,16 754.82681,16 L754.82681,16 L754.82681,16 Z M744.985865,41.0399123 C741.737344,41.0399123 739.108338,38.4072025 739.108338,35.1623855 C739.108338,31.9147904 741.737344,29.2848588 744.985865,29.2848588 C748.230682,29.2848588 750.863392,31.9147904 750.863392,35.1623855 C750.863392,38.4090546 748.230682,41.0399123 744.985865,41.0399123 L744.985865,41.0399123 L744.985865,41.0399123 Z" id="Okey-Tash-Logo-4" fill="#517ECE" sketch:type="MSShapeGroup"></path>
+
+
     </g>
     </g>
+
+    <foreignObject x="864" y="504" width="198" height="120" onmouseover="barHover(evt);" onmouseout="barHoverOut(evt);">
+        <div xmlns:data="Chat" id="edit"
+          style="padding:4px;background-color:#FFF687;color:#3B5998;font-family:'Exo 2';font-size:16px;"
+        contentEditable="true">Write here some text.</div>
+    </foreignObject>
+
+    <foreignObject x="10" y="504" width="198" height="120" onmouseover="onlineHover(evt);" onmouseout="onlineHoverOut(evt);">
+        <div xmlns:data="Chat+xxx" id="onlineChatEdit"
+          style="padding:4px;background-color:#FFF687;color:#3B5998;font-family:'Exo 2';font-size:16px;"
+        contentEditable="true">Write here some text.</div>
+    </foreignObject>
+
 </svg>
 </svg>

+ 1 - 1
apps/web/priv/static/app/css/main.css

@@ -1,7 +1,7 @@
 
 
 :focus {-moz-outline-style:none;}
 :focus {-moz-outline-style:none;}
 html, body {margin: 0; padding:0;}
 html, body {margin: 0; padding:0;}
-html { overflow: auto; height: 100%; }
+html { overflow: hidden; height: 100%; }
 
 
 body {
 body {
     height: 100%;
     height: 100%;

+ 4 - 2
apps/web/priv/static/app/index.htm

@@ -10,7 +10,8 @@
 <body>
 <body>
 
 
     <svg id="Refined" preserveAspectRatio="xMidYMin meet" class="svg" viewBox="0 0 1071 661"
     <svg id="Refined" preserveAspectRatio="xMidYMin meet" class="svg" viewBox="0 0 1071 661"
-         xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">    </svg>
+         xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
+        style="style="position:fixed; top:0; left:0; height:100%; width:100%;">    </svg>
 
 
     <script src="js/bert.js"></script>
     <script src="js/bert.js"></script>
     <script src="js/selector.js"></script>
     <script src="js/selector.js"></script>
@@ -18,6 +19,8 @@
     <script src="js/dragndrop.js"></script>
     <script src="js/dragndrop.js"></script>
     <script src="js/timer.js"></script>
     <script src="js/timer.js"></script>
     <script src="js/player.js"></script>
     <script src="js/player.js"></script>
+    <script src="js/chat.js"></script>
+    <script src="js/roster.js"></script>
 
 
     <script src="js/okey/okey_protocol.js"></script>
     <script src="js/okey/okey_protocol.js"></script>
     <script src="js/okey/hand.js"></script>
     <script src="js/okey/hand.js"></script>
@@ -25,7 +28,6 @@
     <script src="js/okey/deck.js"></script>
     <script src="js/okey/deck.js"></script>
     <script src="js/okey/okey.js"></script>
     <script src="js/okey/okey.js"></script>
 
 
-    <script src="js/chat.js"></script>
     <script src="js/bootloader.js"></script>
     <script src="js/bootloader.js"></script>
 
 
 <div class="controls" id="history" height=0 width=0>
 <div class="controls" id="history" height=0 width=0>

+ 61 - 21
apps/web/priv/static/app/js/bootloader.js

@@ -33,6 +33,50 @@ function template_engine(html, data) {
 
 
 function discarder(name) { return template_engine(localStorage.getItem("svg/Discarder.svg?q=" + $.timestamp), { name: name }); }
 function discarder(name) { return template_engine(localStorage.getItem("svg/Discarder.svg?q=" + $.timestamp), { name: name }); }
 
 
+function initChat() {
+    var inGameChat = '<g id="Chat"         y="0" clip-path="url(#myClip2)" transform="translate(857.000000, 107.000000)" xmlns="http://www.w3.org/2000/svg" />';
+    var onlineList = '<g id="Online-List"  y="0" clip-path="url(#myClip1)" transform="translate(1.000000, 107.000000)" xmlns="http://www.w3.org/2000/svg" />';
+    var onlineChat = '<g id="Online-Chat"  y="0" clip-path="url(#myClip3)" transform="translate(1.000000, 107.000000)" xmlns="http://www.w3.org/2000/svg" />';
+    document.getElementById("Page-1").appendChild(svg(inGameChat));
+    document.getElementById("Page-1").appendChild(svg(onlineList));
+    document.getElementById("Page-1").appendChild(svg(onlineChat));
+
+    document.getElementById('Page-1').addEventListener("mousewheel", mouseWheelHandler, false);
+
+    var clipPath1 = svg('<clipPath id="myClip1"><rect xmlns="http://www.w3.org/2000/svg" id="Clip-Path-Left" x="0" y="0" width="216" height="400"/></clipPath>');
+    var clipPath2 = svg('<clipPath id="myClip2"><rect xmlns="http://www.w3.org/2000/svg" id="Clip-Path-Right" x="0" y="0" width="216" height="400"/></clipPath>');
+    var clipPath3 = svg('<clipPath id="myClip3"><rect xmlns="http://www.w3.org/2000/svg" id="Clip-Path-Left-Chat" x="0" y="0" width="216" height="400"/></clipPath>');
+
+    document.getElementsByTagName('defs').item(0).appendChild(clipPath1);
+    document.getElementsByTagName('defs').item(0).appendChild(clipPath2);
+    document.getElementsByTagName('defs').item(0).appendChild(clipPath3);
+
+     document.getElementById("Online-List").setAttribute("clip-path","url(#myClip1)");
+     document.getElementById("Chat").setAttribute("clip-path","url(#myClip2)");
+     document.getElementById("Online-Chat").setAttribute("clip-path","url(#myClip1)");
+
+    document.getElementById("Clip-Path-Left").setAttribute("transform", "translate(0,0)");
+    document.getElementById("Clip-Path-Right").setAttribute("transform", "translate(0,0)");
+    document.getElementById("Clip-Path-Left-Chat").setAttribute("transform", "translate(0,0)");
+}
+
+function initEditors() {
+    var left = 
+'<foreignObject xmlns="http://www.w3.org/2000/svg" x="864" y="504" width="198" height="120" mouseover="barHover(evt);" mouseout="barHoverOut(evt);">' +
+        '<div xmlns="http://www.w3.org/1999/xhtml" xmlns:data="Chat" id="edit" ' +
+          ' style="padding:4px;background-color:#FFF687;color:#3B5998;font-family:"Exo 2";font-size:16px;" ' +
+        ' contentEditable="true" xmlns="http://www.w3.org/1999/xhtml">Write here some text.</div>' +
+    '</foreignObject>';
+
+    var right = '<foreignObject xmlns="http://www.w3.org/2000/svg" x="10" y="504" width="198" height="120"  onmouseover="onlineHover(evt);" onmouseout="onlineHoverOut(evt);>' +
+        '<div xmlns="http://www.w3.org/1999/xhtml" xmlns:data="Chat+xxx" id="onlineChatEdit" ' +
+          ' style="padding:4px;background-color:#FFF687;color:#3B5998;font-family:"Exo 2";font-size:16px;" ' +
+        ' contentEditable="true" xmlns="http://www.w3.org/1999/xhtml">Write here some text.</div>' +
+    '</foreignObject>';
+    document.getElementById("Page-1").appendChild(svg(left));
+    document.getElementById("Page-1").appendChild(svg(right));
+}
+
 function initDiscards() {
 function initDiscards() {
     [ {name:"Gabrielo-Discard", hand:"Player-Left-Hand"},
     [ {name:"Gabrielo-Discard", hand:"Player-Left-Hand"},
       {name:"Alina-Discard",    hand:"Player-Right-Hand"},
       {name:"Alina-Discard",    hand:"Player-Right-Hand"},
@@ -45,24 +89,9 @@ function initDiscards() {
 
 
 function PatchSVG()
 function PatchSVG()
 {
 {
-//    document.getElementById('Page-1').addEventListener("mousewheel", mouseWheelHandler, false);
 
 
         // Setup Clipping ViewPorts
         // Setup Clipping ViewPorts
 
 
-    var clipPath1 = svg('<clipPath id="myClip1"><rect xmlns="http://www.w3.org/2000/svg" id="Clip-Path-Left" x="0" y="0" width="216" height="400"/></clipPath>');
-    var clipPath2 = svg('<clipPath id="myClip2"><rect xmlns="http://www.w3.org/2000/svg" id="Clip-Path-Right" x="0" y="0" width="216" height="400"/></clipPath>');
-    var clipPath3 = svg('<clipPath id="myClip3"><rect xmlns="http://www.w3.org/2000/svg" id="Clip-Path-Left-Chat" x="0" y="0" width="216" height="400"/></clipPath>');
-    document.getElementsByTagName('defs').item(0).appendChild(clipPath1);
-    document.getElementsByTagName('defs').item(0).appendChild(clipPath2);
-    document.getElementsByTagName('defs').item(0).appendChild(clipPath3);
-
-//     document.getElementById("Online-List").setAttribute("clip-path","url(#myClip1)");
-//     document.getElementById("Chat").setAttribute("clip-path","url(#myClip2)");
-//     document.getElementById("Online-Chat").setAttribute("clip-path","url(#myClip1)");
-
-    document.getElementById("Clip-Path-Left").setAttribute("transform", "translate(0,0)");
-    document.getElementById("Clip-Path-Right").setAttribute("transform", "translate(0,0)");
-    document.getElementById("Clip-Path-Left-Chat").setAttribute("transform", "translate(0,0)");
 
 
 //  document.getElementById('Player-Statistics').style.display = 'none';
 //  document.getElementById('Player-Statistics').style.display = 'none';
     document.getElementById("Right-Bar").setAttribute("fill","lightblue");
     document.getElementById("Right-Bar").setAttribute("fill","lightblue");
@@ -80,7 +109,6 @@ function PatchSVG()
 
 
     // HTML editors
     // HTML editors
 
 
-/*
     document.getElementById('onlineChatEdit').setAttribute("contentEditable","true");
     document.getElementById('onlineChatEdit').setAttribute("contentEditable","true");
     document.getElementById('onlineChatEdit').onkeydown = chatEditor;
     document.getElementById('onlineChatEdit').onkeydown = chatEditor;
     document.getElementById("onlineChatEdit").style.display = 'none';
     document.getElementById("onlineChatEdit").style.display = 'none';
@@ -89,7 +117,7 @@ function PatchSVG()
     document.getElementById('edit').onkeydown = chatEditor;
     document.getElementById('edit').onkeydown = chatEditor;
     document.getElementById('edit').setAttribute("xmlns:data","Chat");
     document.getElementById('edit').setAttribute("xmlns:data","Chat");
     document.getElementById("edit").style.display = '';
     document.getElementById("edit").style.display = '';
-*/
+
     // showOnlineList ctor
     // showOnlineList ctor
 
 
     var onlineListOnClick = [
     var onlineListOnClick = [
@@ -99,11 +127,11 @@ function PatchSVG()
         "Users-Online-Message",
         "Users-Online-Message",
         "Users-Online-Number" ];
         "Users-Online-Number" ];
 
 
-//       onlineListOnClick.map(function(x) { 
-//           console.log(x);
-//            document.getElementById(x).onclick = showOnlineList; });
+       onlineListOnClick.map(function(x) { 
+            document.getElementById(x).onclick = showOnlineList; });
 
 
     initDiscards();
     initDiscards();
+    initChat();
 
 
     Core(ControllerScope);
     Core(ControllerScope);
     Core(DragScope);
     Core(DragScope);
@@ -114,8 +142,20 @@ function PatchSVG()
     Core(CardScope);
     Core(CardScope);
     Core(HandScope);
     Core(HandScope);
     Core(DeckScope);
     Core(DeckScope);
+    Core(RosterScope);
+
+
+        chatMessage("Chat","1","Maxim2","Joe:\nHello There!".encodeHTML());
+        chatMessage("Chat","2","Maxim2","Alice:\nYou got new Design. Eh?".encodeHTML());
+        chatMessage("Chat","3","Maxim","Maxim So:\nThis was made with pure SVG".encodeHTML());
+
+        barHover();
+        mouseWheelHandler({'detail':-100000,'wheelDelta':-100000});
+        barHoverOut();
+
+//    document.addEventListener('touchmove',function(e) {e.preventDefault();},false);
 
 
-    $svg.attr({preserveAspectRatio:"xMidYMin meet",class:"svg",width:"100%",height:"100%"});
+    $svg.attr({preserveAspectRatio:"xMidYMid meet",class:"svg",width:"100%",height:"100%"});
 }
 }
 
 
 function onPlayerInfo(evt) {
 function onPlayerInfo(evt) {

+ 120 - 1
apps/web/priv/static/app/js/chat.js

@@ -6,6 +6,7 @@ var scroll_left = 5;
 var scroll_left_chat = 5;
 var scroll_left_chat = 5;
 var scroll_right = -10000;
 var scroll_right = -10000;
 var currentChat = null;
 var currentChat = null;
+var user_count = 0;
 
 
 function barHover(evt) { document.getElementById("Right-Bar").setAttribute("fill","skyblue"); }
 function barHover(evt) { document.getElementById("Right-Bar").setAttribute("fill","skyblue"); }
 function barHoverOut(evt) { document.getElementById("Right-Bar").setAttribute("fill","lightblue"); }
 function barHoverOut(evt) { document.getElementById("Right-Bar").setAttribute("fill","lightblue"); }
@@ -127,7 +128,7 @@ function showOnlineList(evt)
 {
 {
     document.getElementById("onlineChatEdit").style.display = 'none';
     document.getElementById("onlineChatEdit").style.display = 'none';
     if (null != currentChat) { document.getElementById(currentChat).style.display = 'none'; }
     if (null != currentChat) { document.getElementById(currentChat).style.display = 'none'; }
-    document.getElementById("Online-List").style.display = '';
+    document.getElementById("Online-List").style.display = 'block';
     currentChat = null;
     currentChat = null;
 
 
     scroll_left = 0;
     scroll_left = 0;
@@ -136,3 +137,121 @@ function showOnlineList(evt)
     onlineHoverOut();
     onlineHoverOut();
 }
 }
 
 
+if (!String.prototype.encodeHTML) {
+  String.prototype.encodeHTML = function () {
+    return this.replace(/&/g, '&amp;')
+               .replace(/</g, '&lt;')
+               .replace(/>/g, '&gt;')
+               .replace(/"/g, '&quot;')
+               .replace(/'/g, '&apos;'); // "
+  };
+}
+
+function addOnlineUser(name,full_name,insertMode) {
+    var listElement = document.getElementById("Online-List");
+    var clickEvent = ' onclick="openChat(evt);" '; 
+    var events = ' onmouseover="onlineHover(evt);" onmouseout="onlineHoverOut(evt);" ' + clickEvent;
+    var eventsColor = ' onmouseover="onlineHoverColor(evt);" onmouseout="onlineHoverOutColor(evt);" ' + clickEvent;
+    var color = insertMode == "insertTop" ? "red" : "green";
+    var y = (insertMode == "insertTop") ? "0" : listElement.getBBox().height;
+    var html = '<g xmlns="http://www.w3.org/2000/svg" height="60" transform="translate(0, '+y+')">' +
+            '<g xmlns:data="'+name+'" fill="#DBEBED" '+eventsColor+'>' +
+            '    <rect cursor="pointer" xmlns:data="'+name+'" fill="#DBEBED" id="'+name+'" x="10" y="0" width="196" height="48" ' +'></rect></g>' +
+            '<text xmlns:data="'+name+'" '+eventsColor+' '+
+            'font-family="Exo 2" font-size="18" cursor="pointer" font-weight="normal" line-spacing="18"'+
+            ' fill="#3B5998">' +
+                '<tspan xmlns:data="'+name+'" font-weight="normal" fill="'+color+'" x="19" y="22">'+full_name+'</tspan>' + 
+                '<tspan xmlns:data="'+name+'" font-size="14" x="19" y="40">Score: 1043 Pos: 13</tspan></text>'+
+            '<rect '+
+            '  x="10" y="48" width="196" height="8"></rect></g>';
+    var element = svg(html);
+    if (insertMode == "insertTop") {
+        var firstElement = listElement.firstElementChild;
+        if (null == firstElement) listElement.appendChild(element); else {
+            var first = firstElement.firstElementChild.getAttribute("xmlns:data");
+            shiftTranslate(first,0);
+            listElement.insertBefore(element,firstElement);
+        }
+    } else listElement.appendChild(element);
+}
+
+function shiftTranslate(name,shiftValue) {
+    var rect = document.getElementById(name);
+    if (null == rect) return;
+    var remove = rect.parentNode.parentNode;
+    var children = document.getElementById("Online-List").childNodes;
+    var removeIndex = -1;
+    for(var i = 0; i<children.length; ++i) { 
+        var child = children[i];
+        if (child == remove) removeIndex = i;
+        if (removeIndex != -1 && i>=removeIndex)
+            child.setAttribute("transform","translate(0,"+(parseFloat(i)+parseFloat(shiftValue))
+                *remove.getBBox().height+")");
+    }
+    return rect.parentNode.parentNode;
+}
+
+function removeOnlineUser(name) {
+    shiftTranslate(name,-2).remove();
+}
+
+function openChat(evt) {
+    document.getElementById("Online-List").style.display = 'none';
+    document.getElementById("onlineChatEdit").style.display = '';
+    var name = evt.target.getAttribute("xmlns:data");
+    currentChat = "Chat+"+name;
+    var chatElement = document.getElementById(currentChat);
+    if (null == chatElement) {
+        // read from local KVS
+        var html = '<g xmlns="http://www.w3.org/2000/svg" id="'+currentChat+'" y="0" clip-path="url(#myClip3)" transform="translate(1.000000, 107.000000)"></g>';
+        document.getElementById("Page-1").appendChild(svg(html));
+        chatMessage(currentChat,"1","System","You can chat with\n"+name);
+    } else {
+        document.getElementById(currentChat).style.display = '';
+    }
+    document.getElementById("onlineChatEdit").setAttribute("xmlns:data",currentChat);
+    scroll_left = -1000000;
+
+    onlineHover();
+    mouseWheelHandler({'detail':-100000,'wheelDelta':-100000});
+    onlineHoverOut();
+
+//    document.getElementById("users-online-text").textContent = currentChat;
+}
+
+function create_multiline(target) {
+    var text_element = target; // evt.target;
+    var width = 190; //target.getAttribute("width");
+    var words = text_element.firstChild.data.split('');
+//    console.log(words);
+//    var words = [].concat.apply([],lines.map(function(line) { return line.split(' '); }));;
+    var start_x = 15; //text_element.getAttribute('x');
+    text_element.firstChild.data = '';
+
+    var tspan_element = document.createElementNS(svgNS, "tspan");
+    tspan_element.setAttribute("x", start_x);
+    tspan_element.setAttribute("xmlns:data", text_element.getAttribute("xmlns:data"));
+    tspan_element.setAttribute("dy", 18);
+    var text_node = document.createTextNode(words[0]);
+
+    tspan_element.appendChild(text_node);
+    text_element.appendChild(tspan_element);
+
+    for(var i=1; i<words.length; i++) {
+        if (words[i]=="") continue; 
+        var len = tspan_element.firstChild.data.length;
+        tspan_element.firstChild.data += words[i];
+
+        if (tspan_element.getComputedTextLength() > width || words[i]=="\n") {
+            if (words[i]=='\n') words[i]="";
+            tspan_element.firstChild.data = tspan_element.firstChild.data.slice(0, len);
+            var tspan_element = document.createElementNS(svgNS, "tspan");
+            tspan_element.setAttribute("x", start_x);
+            tspan_element.setAttribute("xmlns:data", text_element.getAttribute("xmlns:data"));
+            tspan_element.setAttribute("dy", 18);
+            text_node = document.createTextNode(words[i]);
+            tspan_element.appendChild(text_node);
+            text_element.appendChild(tspan_element);
+        }
+    }
+}

+ 19 - 12
apps/web/priv/static/app/js/okey/okey.js

@@ -12,6 +12,8 @@ function PostLoad()
     var centralCard,
     var centralCard,
         apiProvider = new scope.ApiProvider({url: scope.apiUrl, gameId: scope.gameId });
         apiProvider = new scope.ApiProvider({url: scope.apiUrl, gameId: scope.gameId });
 
 
+    scope.apiProvider = apiProvider;
+
     function fadeOut()       { $(this).animate({ attributeName: "opacity", from: 1, to: 0, dur: .3}); }
     function fadeOut()       { $(this).animate({ attributeName: "opacity", from: 1, to: 0, dur: .3}); }
     function fadeIn()        { $(this).animate({ attributeName: "opacity", from: 0, to: 1, dur: .3}); }
     function fadeIn()        { $(this).animate({ attributeName: "opacity", from: 0, to: 1, dur: .3}); }
     function addFadeOut()    { $(this).on (document.createTouch ? "touchend" : "mouseup", fadeOut); }
     function addFadeOut()    { $(this).on (document.createTouch ? "touchend" : "mouseup", fadeOut); }
@@ -69,7 +71,8 @@ function PostLoad()
         playersRightHandsMap = {},
         playersRightHandsMap = {},
         playersLeftHandsMap = {};
         playersLeftHandsMap = {};
 
 
-    apiProvider.on("okey_game_info", function(e) {
+    apiProvider.on("okey_game_info", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
         scope.user = document.user;
         scope.user = document.user;
         if (!scope.started) {
         if (!scope.started) {
             for (var playerInfo, players = e.detail.players, i = 0; i < players.length; i++) 
             for (var playerInfo, players = e.detail.players, i = 0; i < players.length; i++) 
@@ -106,12 +109,10 @@ function PostLoad()
 
 
     var playerTurn = !1;
     var playerTurn = !1;
 
 
-    apiProvider.on("online_number", function (e) {
-//        console.log("Online Number");
-    });
-
-    apiProvider.on("okey_next_turn", function(e) {
+    new scope.Roster(scope);
 
 
+    apiProvider.on("okey_next_turn", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
         for (var playerName in playersMap) playersMap[playerName].unselect();
         for (var playerName in playersMap) playersMap[playerName].unselect();
         if (playersMap[e.detail.player].select(), e.detail.player == scope.user)
         if (playersMap[e.detail.player].select(), e.detail.player == scope.user)
         {
         {
@@ -134,7 +135,8 @@ function PostLoad()
         }
         }
     });
     });
 
 
-    apiProvider.on("okey_tile_discarded", function(e) {
+    apiProvider.on("okey_tile_discarded", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
         if ("object" == typeof e.detail.tile) {
         if ("object" == typeof e.detail.tile) {
             var c = new scope.Card({
             var c = new scope.Card({
                 color: scope.CARD_COLORS[e.detail.tile[1] - 1],
                 color: scope.CARD_COLORS[e.detail.tile[1] - 1],
@@ -150,7 +152,8 @@ function PostLoad()
         $wholeCards = $("#Stupid-Cards"),
         $wholeCards = $("#Stupid-Cards"),
         $fullWholeCards = $("#Stupid-Cards > g").clone();
         $fullWholeCards = $("#Stupid-Cards > g").clone();
 
 
-    apiProvider.on("okey_tile_taken", function(e) {
+    apiProvider.on("okey_tile_taken", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
         if ("object" == typeof e.detail.revealed) {
         if ("object" == typeof e.detail.revealed) {
             var c = new scope.Card({
             var c = new scope.Card({
                 color: scope.CARD_COLORS[e.detail.revealed[1] - 1],
                 color: scope.CARD_COLORS[e.detail.revealed[1] - 1],
@@ -184,14 +187,16 @@ function PostLoad()
         }
         }
     });
     });
 
 
-    apiProvider.on("okey_revealed", function(e) {
+    apiProvider.on("okey_revealed", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
         ended = !0, alert(e.detail.player), deck.fill([]);
         ended = !0, alert(e.detail.player), deck.fill([]);
         for (var hand in playersLeftHandsMap) playersLeftHandsMap[hand].clear();
         for (var hand in playersLeftHandsMap) playersLeftHandsMap[hand].clear();
         for (var playerName in playersMap) playersMap[playerName].unselect();
         for (var playerName in playersMap) playersMap[playerName].unselect();
 //        $gosterme.remove();
 //        $gosterme.remove();
     });
     });
 
 
-    apiProvider.on("player_left", function(e) {
+    apiProvider.on("player_left", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
         var playerInfo = e.detail.replacement.PlayerInfo;
         var playerInfo = e.detail.replacement.PlayerInfo;
         playersMap[playerInfo[0]] = new scope.Player({
         playersMap[playerInfo[0]] = new scope.Player({
             position: playersMap[e.detail.player].position,
             position: playersMap[e.detail.player].position,
@@ -211,7 +216,8 @@ function PostLoad()
     $overlay = $("#overlay");
     $overlay = $("#overlay");
     $overlay.on("click", function() { whoPausedGame == scope.user && apiProvider.pause(!0); });
     $overlay.on("click", function() { whoPausedGame == scope.user && apiProvider.pause(!0); });
 
 
-    apiProvider.on("game_paused", function(e) {
+    apiProvider.on("game_paused", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
         if (whoPausedGame = e.detail[3], "pause" == e.detail[2]) {
         if (whoPausedGame = e.detail[3], "pause" == e.detail[2]) {
             $overlay.show();
             $overlay.show();
             for (var player in playersMap) playersMap[player].timer.pause();
             for (var player in playersMap) playersMap[player].timer.pause();
@@ -233,8 +239,9 @@ function PostLoad()
         }
         }
     });
     });
 
 
-function initOkeyScene(e)
+function initOkeyScene(x)
 {
 {
+    var e = {detail: x.detail.json, raw: x.detail.bert};
     if (ended = !1, 
     if (ended = !1, 
         scope.deck.fill(e.detail.tiles),
         scope.deck.fill(e.detail.tiles),
         scope.deck.render(),
         scope.deck.render(),

+ 15 - 4
apps/web/priv/static/app/js/okey/okey_protocol.js

@@ -16,7 +16,17 @@ function OkeyApiProviderScope(scope) {
     }
     }
 
 
     var eventMap = [
     var eventMap = [
+        // general events
+        "stats_event",
+        // roster protocol
         "online_number",
         "online_number",
+        "online",
+        "offline",
+        "roster_item",
+        "roster_group",
+        "roster_end",
+        "chat_message",
+        // okey game protocol
         "okey_game_info",
         "okey_game_info",
         "okey_game_started",
         "okey_game_started",
         "okey_game_player_state",
         "okey_game_player_state",
@@ -25,7 +35,8 @@ function OkeyApiProviderScope(scope) {
         "okey_tile_taken",
         "okey_tile_taken",
         "okey_revealed",
         "okey_revealed",
         "player_left",
         "player_left",
-        "game_paused" ];
+        "game_paused"
+    ];
 
 
     $.extend(ApiProvider.prototype, {
     $.extend(ApiProvider.prototype, {
         proxy: function(func) {
         proxy: function(func) {
@@ -50,7 +61,7 @@ function OkeyApiProviderScope(scope) {
             var msg = JSON.parse(e.data);
             var msg = JSON.parse(e.data);
 
 
             if (msg.eval) { try{eval(msg.eval)}catch(e){console.log(e);} }
             if (msg.eval) { try{eval(msg.eval)}catch(e){console.log(e);} }
-            if (msg.data) { this.emitEvent(this.beutify(this.parse(dec(msg.data)))); }
+            if (msg.data) { this.emitEvent(msg.data,this.beutify(this.parse(dec(msg.data)))); }
 
 
         },
         },
         parse: function(msg) {
         parse: function(msg) {
@@ -88,10 +99,10 @@ function OkeyApiProviderScope(scope) {
             }
             }
             return msg;
             return msg;
         },
         },
-        emitEvent: function(msg) {
+        emitEvent: function(raw,msg) {
 //            console.log(JSON.stringify(msg));
 //            console.log(JSON.stringify(msg));
             for (var event, i = eventMap.length; i--; ) event = eventMap[i], msg[event] && this.$socket.trigger(event, {
             for (var event, i = eventMap.length; i--; ) event = eventMap[i], msg[event] && this.$socket.trigger(event, {
-                detail: msg[event]
+                detail: {json:msg[event],bert:raw}
             });
             });
         },
         },
         actionTake: function(card) {
         actionTake: function(card) {

+ 57 - 0
apps/web/priv/static/app/js/roster.js

@@ -0,0 +1,57 @@
+
+function RosterScope(scope)
+{
+    function Roster(scope) { RosterHandlers(scope); }
+    scope.Roster = Roster;
+}
+
+function RosterHandlers(scope) {
+
+    scope.apiProvider.on("online_number", function(x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
+        document.getElementById("Users-Online-Number").firstElementChild.textContent = e.detail.toString(); 
+    });
+
+    scope.apiProvider.on("online", function (x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
+        var msg = e.detail, id = msg[0], name = msg[1], surname = msg[2];
+        console.log(id);
+        try{removeOnlineUser(id)}catch(ex){}
+        addOnlineUser(id,name+" "+surname,"insertTop");
+    });
+
+    scope.apiProvider.on("offline", function (x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
+        var msg = e.detail, id = msg[0], name = msg[1], surname = msg[2];
+        try{removeOnlineUser(id)}catch(ex){}
+        addOnlineUser(id,name+" "+surname,"appendChild");
+    });
+
+    scope.apiProvider.on("roster_item", function (x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
+        var msg = e.detail, id = msg[0], name = msg[1], surname = msg[2];
+        addOnlineUser(id,name+" "+surname,"appendChild");
+    });
+
+    scope.apiProvider.on("roster_end", function (x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
+        onlineHover();
+        mouseWheelHandler({'detail':5,'wheelDelta':5});
+        onlineHoverOut();
+        document.getElementById("Online-List").style.display = '';
+    });
+
+    scope.apiProvider.on("roster_group", function (x) {
+        var e = {detail: x.detail.json, raw: x.detail.bert};
+        var list     = dec(e.raw).value[0][1];
+        for (var i=0;i<list.length;i++) {
+            var item = list[i],
+                id = item.value[0][0].value,
+                names    = item.value[0][1].value,
+                surnames = item.value[0][2].value;
+            addOnlineUser(id,names+" "+surnames+ " "+user_count++,'appendChild');
+        }
+    });
+
+}
+

+ 29 - 30
apps/web/priv/static/app/js/selector.js

@@ -4,7 +4,8 @@ var scope = {
     CARD_SOURCE: "svg/Card.svg",
     CARD_SOURCE: "svg/Card.svg",
     CARD_SMALL_SOURCE: "svg/Card-Small.svg",
     CARD_SMALL_SOURCE: "svg/Card-Small.svg",
     CARD_COLORS: [ "#CE290F", "#3B5998", "#48AF5E", "#F8E81C" ],
     CARD_COLORS: [ "#CE290F", "#3B5998", "#48AF5E", "#F8E81C" ],
-    SKIN_NAMES: [ "Alina", "Gabrielo", "Mustafa" ]
+    SKIN_NAMES: [ "Alina", "Gabrielo", "Mustafa" ],
+    version: 0906201401
 };
 };
 
 
 var $ = function(_undefind)
 var $ = function(_undefind)
@@ -32,7 +33,7 @@ var $ = function(_undefind)
     fn.each = function(callback) { for (var i = 0, l = this.length; l > i; i++) callback(this[i], i); return this; },
     fn.each = function(callback) { for (var i = 0, l = this.length; l > i; i++) callback(this[i], i); return this; },
     fn.on = function(eventName, eventHandler) { return this.each(function(el) { el.addEventListener(eventName, eventHandler); }); },
     fn.on = function(eventName, eventHandler) { return this.each(function(el) { el.addEventListener(eventName, eventHandler); }); },
     fn.off = function(eventName, eventHandler) { return this.each(function(el) { el.removeEventListener(eventName, eventHandler); }); },
     fn.off = function(eventName, eventHandler) { return this.each(function(el) { el.removeEventListener(eventName, eventHandler); }); },
-    fn.trigger = function(eventName, data) { return this.each(function(el) { event = new CustomEvent(eventName, data), el.dispatchEvent(event); }); },
+    fn.trigger = function(eventName, data, raw) { return this.each(function(el) { event = new CustomEvent(eventName, data), el.dispatchEvent(event); }); },
     fn.show = function() { return this.css("display", "block"); },
     fn.show = function() { return this.css("display", "block"); },
     fn.hide = function() { return this.css("display", "none"); },
     fn.hide = function() { return this.css("display", "none"); },
     fn.text = function(text) { return null != text ? this.each(function(el) { el.textContent = text; }) : this.length ? this[0].textContent : _undefind; },
     fn.text = function(text) { return null != text ? this.each(function(el) { el.textContent = text; }) : this.length ? this[0].textContent : _undefind; },
@@ -57,7 +58,6 @@ var $ = function(_undefind)
             node = node.nextSibling;
             node = node.nextSibling;
         }) : this.length ? this[0].innerHTML : _undefind;
         }) : this.length ? this[0].innerHTML : _undefind;
     },
     },
-    
 
 
     fn.attr = function(name, value) {
     fn.attr = function(name, value) {
         if (Object(name) === name) {
         if (Object(name) === name) {
@@ -68,7 +68,7 @@ var $ = function(_undefind)
             el.setAttribute(name, value);
             el.setAttribute(name, value);
         }) : this.length ? this[0].getAttribute(name) : _undefind;
         }) : this.length ? this[0].getAttribute(name) : _undefind;
     },
     },
-    
+
     fn.removeAttr = function(name) { return this.each(function(el) { el.removeAttribute(name); }); },
     fn.removeAttr = function(name) { return this.each(function(el) { el.removeAttribute(name); }); },
 
 
     fn.append = function(target) {
     fn.append = function(target) {
@@ -84,7 +84,7 @@ var $ = function(_undefind)
             for (;el.firstChild; ) el.removeChild(el.firstChild);
             for (;el.firstChild; ) el.removeChild(el.firstChild);
         });
         });
     },
     },
-    
+
     fn.eq = function(idx) { return new Selector(idx >= this.length ? [] : [ this[idx] ]); },
     fn.eq = function(idx) { return new Selector(idx >= this.length ? [] : [ this[idx] ]); },
     fn.find = function(selector) {
     fn.find = function(selector) {
         var result = [];
         var result = [];
@@ -101,7 +101,7 @@ var $ = function(_undefind)
     fn.first = function() {
     fn.first = function() {
         return new Selector(this.length ? [ this[0] ] : []);
         return new Selector(this.length ? [ this[0] ] : []);
     },
     },
-    
+
     fn.last = function() { return new Selector(this.length ? [ this[this.length - 1] ] : []); },
     fn.last = function() { return new Selector(this.length ? [ this[this.length - 1] ] : []); },
     fn.clone = function() { var result = []; return this.each(function(el) { result.push(el.cloneNode(!0)); }), new Selector(result); },
     fn.clone = function() { var result = []; return this.each(function(el) { result.push(el.cloneNode(!0)); }), new Selector(result); },
     fn.width = function() { return this.length ? this[0].getBoundingClientRect().width : _undefind; },
     fn.width = function() { return this.length ? this[0].getBoundingClientRect().width : _undefind; },
@@ -186,36 +186,33 @@ var $ = function(_undefind)
                 }), callbacks = [];
                 }), callbacks = [];
             }, 1e3 * parseFloat(trfs.dur) - 20), $el.attr("animated", !0), $anim[0].beginElement();
             }, 1e3 * parseFloat(trfs.dur) - 20), $el.attr("animated", !0), $anim[0].beginElement();
         }), thenable;
         }), thenable;
-    }, fn.stop = function() {
+    },
+
+    fn.stop = function() {
         return this.each(function(el) {
         return this.each(function(el) {
             $(el).find(".anim, .trf").each(function(anim) {
             $(el).find(".anim, .trf").each(function(anim) {
-                anim.endElement();
-            }), clearTimeout(el.timerId), clearInterval(el.timer);
-        });
-    }, fn.pause = function() {
-        return $("svg")[0].pauseAnimations(), this.each(function(el) {
-            el.paused = !0;
-        });
-    }, fn.resume = function() {
-        return $("svg")[0].unpauseAnimations(), this.each(function(el) {
-            el.paused = !1;
-        });
-    };
+            anim.endElement(); }), clearTimeout(el.timerId), clearInterval(el.timer); }); },
+
+    fn.pause = function() { return $("svg")[0].pauseAnimations(), this.each(function(el) { el.paused = !0; }); },
+    fn.resume = function() { return $("svg")[0].unpauseAnimations(), this.each(function(el) { el.paused = !1; }); };
+
     var tag = /^<(.+)\/>$/;
     var tag = /^<(.+)\/>$/;
+
     return $.extend = function(target) {
     return $.extend = function(target) {
         for (var obj, properties, i = 1, l = arguments.length; l > i; i++) {
         for (var obj, properties, i = 1, l = arguments.length; l > i; i++) {
             obj = arguments[i], properties = Object.keys(obj);
             obj = arguments[i], properties = Object.keys(obj);
             for (var property, j = properties.length; j--; ) property = properties[j], target[property] = obj[property];
             for (var property, j = properties.length; j--; ) property = properties[j], target[property] = obj[property];
         }
         }
         return target;
         return target;
-    }, $.inherit = function(child, parent) {
-        function ctor() {
-            this.constructor = child, this.__super__ = parent.prototype;
-        }
-        return ctor.prototype = parent.prototype, child.prototype = new ctor(), child;
-    }, $.mixin = function(plagin) {
-        $.extend(fn, plagin);
-    }, $.timestamp = 1400668550599,
+    },
+
+    $.inherit = function(child, parent) {
+        function ctor() { this.constructor = child, this.__super__ = parent.prototype; }
+        return ctor.prototype = parent.prototype, child.prototype = new ctor(), child; },
+
+    $.mixin = function(plagin) { $.extend(fn, plagin); },
+
+    $.timestamp = scope.version,
 
 
     $.load = function(url, complete) {
     $.load = function(url, complete) {
         url = url + "?q=" + $.timestamp;
         url = url + "?q=" + $.timestamp;
@@ -227,9 +224,11 @@ var $ = function(_undefind)
                 complete(xhr.responseText);
                 complete(xhr.responseText);
             }, xhr.send();
             }, xhr.send();
         } else complete(result);
         } else complete(result);
-    }, $.rand = function(min, max) {
-        return min + Math.floor(Math.random() * (max - min + 1));
-    }, $;
+    },
+
+    $.rand = function(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); },
+
+    $;
 }();
 }();
 
 
 Core = function() {
 Core = function() {

BIN
apps/web/priv/static/doc/Kakaranet-Scene.sketch/Data


+ 1 - 1
apps/web/priv/static/doc/Kakaranet-Scene.sketch/metadata

@@ -15,7 +15,7 @@
 		<string>LucidaGrande-Bold</string>
 		<string>LucidaGrande-Bold</string>
 	</array>
 	</array>
 	<key>length</key>
 	<key>length</key>
-	<integer>2574994</integer>
+	<integer>2575020</integer>
 	<key>version</key>
 	<key>version</key>
 	<integer>37</integer>
 	<integer>37</integer>
 </dict>
 </dict>

+ 2 - 2
apps/web/src/logallow.erl

@@ -3,9 +3,9 @@
 
 
 log_modules() -> [
 log_modules() -> [
 %    wf_core,
 %    wf_core,
-%    n2o_bullet,
+    n2o_bullet,
     game_session,
     game_session,
-%    bullet_handler,
+    bullet_handler,
 %    n2o_secret,
 %    n2o_secret,
 %    js_session,
 %    js_session,
     okey
     okey