From c4e179782ba74474c065008ac9dc336973643e6b Mon Sep 17 00:00:00 2001
From: Zayd Radha <radhazay@msu.edu>
Date: Sat, 10 Mar 2018 15:51:19 -0500
Subject: [PATCH] Fixed url icons

---
 bower.json            |   2 +
 configuration.json    |   2 +-
 numpad.json           | 147 ++++++++++++++++++++++++++++++++++++++++++
 public/client.html    |  81 ++++++++++-------------
 public/js/client.js   | 125 +++++++++++++++++++++++++++++++----
 public/js/desktop.js  |   2 +-
 public/style/main.css | 115 ++++++++++++++++++++++++++-------
 server.js             |  20 +++++-
 url.json              |  42 ++++++++++++
 9 files changed, 448 insertions(+), 88 deletions(-)
 create mode 100644 numpad.json
 create mode 100644 url.json

diff --git a/bower.json b/bower.json
index f75daa7..1513897 100755
--- a/bower.json
+++ b/bower.json
@@ -16,6 +16,8 @@
     "hammerjs": "~2.0.4",
     "l20n": "~1.0.2",
     "bootstrap": "~3.3.5",
+    "swiper": "^4.1.6",
+    "favicon": "^0.0.3",
     "jquery-qrcode": "*"
   }
 }
diff --git a/configuration.json b/configuration.json
index f9820f3..dab1186 100644
--- a/configuration.json
+++ b/configuration.json
@@ -35,7 +35,7 @@
         "0"
     ],
     "button8": [
-        "W",
+        "i",
         "70",
         "0"
     ],
diff --git a/numpad.json b/numpad.json
new file mode 100644
index 0000000..dab1186
--- /dev/null
+++ b/numpad.json
@@ -0,0 +1,147 @@
+{
+    "button1": [
+        "q",
+        "0",
+        "0"
+    ],
+    "button2": [
+        "w",
+        "10",
+        "0"
+    ],
+    "button3": [
+        "e",
+        "20",
+        "0"
+    ],
+    "button4": [
+        "r",
+        "30",
+        "0"
+    ],
+    "button5": [
+        "t",
+        "40",
+        "0"
+    ],
+    "button6": [
+        "y",
+        "50",
+        "0"
+    ],
+    "button7": [
+        "u",
+        "60",
+        "0"
+    ],
+    "button8": [
+        "i",
+        "70",
+        "0"
+    ],
+    "button9": [
+        "o",
+        "80",
+        "0"
+    ],
+    "button10": [
+        "p",
+        "90",
+        "0"
+    ],
+    "button11": [
+        "a",
+        "0",
+        "30"
+    ],
+    "button12": [
+        "s",
+        "10",
+        "30"
+    ],
+    "button13": [
+        "d",
+        "20",
+        "30"
+    ],
+    "button14": [
+        "f",
+        "30",
+        "30"
+    ],
+    "button15": [
+        "g",
+        "40",
+        "30"
+    ],
+    "button16": [
+        "h",
+        "50",
+        "30"
+    ],
+    "button17": [
+        "j",
+        "60",
+        "30"
+    ],
+    "button18": [
+        "k",
+        "70",
+        "30"
+    ],
+    "button19": [
+        "l",
+        "80",
+        "30"
+    ],
+    "button20": [
+        "z",
+        "0",
+        "60"
+    ],
+    "button21": [
+        "x",
+        "10",
+        "60"
+    ],
+    "button22": [
+        "c",
+        "20",
+        "60"
+    ],
+    "button23": [
+        "v",
+        "30",
+        "60"
+    ],
+    "button24": [
+        "b",
+        "40",
+        "60"
+    ],
+    "button25": [
+        "n",
+        "50",
+        "60"
+    ],
+    "button26": [
+        "m",
+        "60",
+        "60"
+    ],
+    "button27": [
+        "#",
+        "70",
+        "60"
+    ],
+    "button28": [
+        "@",
+        "80",
+        "60"
+    ],
+    "button29": [
+        "*",
+        "90",
+        "60"
+    ]
+}
\ No newline at end of file
diff --git a/public/client.html b/public/client.html
index 56f7f07..9ed337f 100755
--- a/public/client.html
+++ b/public/client.html
@@ -13,54 +13,38 @@
     <title>UBoard</title>
   </head>
   <body>
-    <header class="navbar navbar-inverse navbar-fixed-top shadow-z-2" role="navigation">
-      <div class="navbar-header">
-        <button type="button" class="navbar-toggle pull-left" data-toggle="collapse" data-target="#pushMenu">
-          <span class="sr-only">Toggle navigation</span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-        </button>
-        <a class="navbar-brand" href="#" data-l10n-id="projectName">uBoard</a>
-      </div>
-      <div class="collapse navbar-collapse" id="pushMenu">
-        <ul class="nav navbar-nav">
-          <!--<li>
-            <div class="togglebutton">
-            <label class="navbar-item">
-            <input type="checkbox" name="checkbox" id="fullscreen-toggle" autocomplete="off"></input>
-            Touchpad <span class="toggle pull-right"></span>
-            </label>
-            </div>
-          </li>--> 
-          <li>
-            <div class="togglebutton">
-            <label class="navbar-item">
-            <input type="checkbox" name="checkbox" id="move-toggle" autocomplete="off"></input>
-            Move Buttons <span class="toggle pull-right"></span>
-            </label>
-            </div>
-          </li>
-          <li class="hidden" id="portrait">
-            <a href="#">
-            <i class="mdi-communication-stay-current-portrait"></i> Portrait
-            </a>
-          </li>
-          <li class="hidden" id="landscape">
-            <a href="#">
-              <i class="mdi-communication-stay-current-landscape"></i> Landscape
-            </a>
-          </li>
-          <li class="divider"></li>
-          <li><a href="#" id="passcode"><i class="mdi-notification-vpn-lock"></i> Pass Code</a></li>
-          <li class="divider"></li>
-        </ul>
-      </div>
-    </header>
     <div class="wrapper">
       <div class="touchpad" id="touchpad">
-      </div> 
-      <div class = "keyboard" id="keyboard">
+        <div class="touchpad" id="leftClick"> </div>
+        <div class="touchpad" id="scrollWheel"> </div> 
+        <div class="touchpad" id="rightClick"> </div> 
+        <div class="touchpad" id="mousepad"> </div>  
+      </div>
+      
+      <div class="swiper-container">
+        <div class="swiper-wrapper"> 
+          <div class = "keyboard swiper-slide" id="keyboard"> </div>
+          <div class = "numpad swiper-slide" id="numpad"> </div>
+          <div class = "hotkeys swiper-slide" id="hotkeys"> </div>
+          <div class = "custom swiper-slide" id="custom"> </div>
+        </div>
+      </div>
+      <div class = "navbar" id="navbar">
+        <div class = "icon-selection" id="s0">
+          <i class="material-icons">keyboard</i>
+        </div>
+        <div class = "icon-selection" id="s1">
+          <i class="material-icons">grid_on</i>
+        </div>
+        <div class = "icon-selection" id="s2">
+          <i class="material-icons">link</i>
+        </div>
+        <div class = "icon-selection" id="s3">
+          <i class="material-icons">build</i>
+        </div>
+        <div class = "icon-selection" id= "settings-select">
+          <i class="material-icons">settings</i>
+        </div>
       </div>
     </div>
 
@@ -89,8 +73,11 @@
     <script defer src="https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.8/interact.min.js"></script>
     <script defer src="/socket.io/socket.io.js"></script>
     <script defer src="/public/vendor/hammerjs/hammer.min.js"></script>
-    <script defer src="/public/style/style.js"></script>
+    <script defer src="/public/vendor/swiper/dist/js/swiper.min.js"></script>
+    <script defer src="/public/vendor/favicon/favicon.js"></script>
     <script defer src="/public/js/client.js"></script>
+    <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
+      rel="stylesheet">
   </body>
 </html>
 
diff --git a/public/js/client.js b/public/js/client.js
index ec2c698..a89ab99 100755
--- a/public/js/client.js
+++ b/public/js/client.js
@@ -13,6 +13,15 @@ var keyboardWidth = document.getElementById('keyboard').offsetWidth;// Width pix
 var keyboardHeight = document.getElementById('keyboard').offsetHeight;// Height pixel of
 //$("#touchpad").hide();
 
+/*
+-----------SWIPING FUNCTIONALITY---------------
+*/
+var swiper = new Swiper('.swiper-container', {
+  onlyExternal:true
+  });
+
+var swipeIndex = 0;
+
 /*
 -----------KEYBOARD CONTROLS---------------
 The Following Functions Control the KEYBOARD FUNCTIONALITY
@@ -23,10 +32,28 @@ The Following Functions Control the KEYBOARD FUNCTIONALITY
 socket.on('updateKeys', function(newVals) {
   console.log(newVals);
     for (var i = 0; i < newVals.x.length; i++){
+      $('#keyboard').append('<button class = "draggable key-button" id="button' + (i+1).toString() + '">' + newVals.k[i] + '</button>');
       var ele = $('#button' + (i+1).toString())
       ele.text(newVals.k[i])
-      ele.css({position:'absolute', left:newVals.x[i] + '%', top:(newVals.y[i]) + '%'});
+      ele.css({position:'absolute', left:newVals.x[i] + '%', top:(newVals.y[i]) + '%', minHeight: (keyboardWidth*.02).toString() + "px"});
     }
+    $('#loading').html('');
+  });
+
+//Purpose: Receives information from the server to update the presentation of the keys on the client
+socket.on('updateUrls', function(newVals) {
+  console.log(newVals);
+    for (var i = 0; i < newVals.x.length; i++){
+      $('#hotkeys').append('<button class = "draggable url-button" id="url' + (i+1).toString() + '">' + newVals.k[i] + '</button>');
+      var ele = $('#url' + (i+1).toString())
+      ele.text(newVals.k[i])
+      ele.css({position:'absolute', left:newVals.x[i] + '%', top:(newVals.y[i]) + '%', minHeight: (keyboardWidth*.02).toString() + "px", width: '20%', 'text-indent': '-9999px'});
+      ele.append('<button id="url-icon' +(i+1).toString() +'"> </button>')
+      var urlIcon = $('#url-icon' + (i+1).toString())
+      var favicon_url = getFavicon(newVals.k[i]);
+      urlIcon.css({position: 'absolute', left: '35%', bottom: '20%', width: '30%', height: '60%', background: 'url(' + favicon_url + ')', 'background-size': 'contain', 'border-radius': '0px', border:'0px', 'background-repeat': 'no-repeat'});
+    }
+    $('#loading').html('');
   });
 
 
@@ -38,6 +65,13 @@ var emitKey = function(str) {
     }
 };
 
+var emitUrl = function(str) {
+    if (move === false){
+      socket.emit('url', str);
+      console.log(str);
+    }
+};
+
 //Purpose: Uses interact.js library to enable keys to move around
 interact('.draggable').draggable({
     snap: {
@@ -75,8 +109,12 @@ interact('.draggable').draggable({
     }
 
 //Purpose: Event listener on tapping the keys
-interact('.draggable').on('tap', function (event) {
+interact('.key-button').on('tap', function (event) {
     emitKey(event.target.innerText);
+  });
+
+interact('.url-button').on('tap', function (event) {
+    emitUrl(event.target.innerText);
   }).on('hold', function (event) { 
     if (move == true){
       modal.style.display = "block"; //Allows the modal to be displayed to User
@@ -113,7 +151,11 @@ window.dragMoveListener = dragMoveListener;
 -----------MOUSE CONTROLS---------------
 The Following Functions Control the Mouse
 */
-var touchElem = document.getElementById('touchpad');
+var touchElem = document.getElementById('mousepad');
+var lcElem = document.getElementById('leftClick');
+var scrollElem = document.getElementById('scrollWheel');
+var rcElem = document.getElementById('rightClick');
+
 var delta = null;
 var moving = false;
 var control = 'touch';
@@ -150,20 +192,28 @@ var handlePan = function(eventName, e) {
 
 //Purpose: Using Hammer.js library to add different touching functionality
 var mc = new Hammer.Manager(touchElem);
+var mcRc = new Hammer.Manager(rcElem);
+var mcLc = new Hammer.Manager(lcElem);
+var mcScroll = new Hammer.Manager(scrollElem);
+
 mc.add(new Hammer.Pan({event: 'move', threshold: 0, pointers: 1, direction: Hammer.DIRECTION_ALL}));
 mc.add(new Hammer.Pan({event: 'scroll', threshold: 0, pointers: 2,direction: Hammer.DIRECTION_ALL}));
+mcScroll.add(new Hammer.Pan({event: 'scroll', threshold: 0, pointers: 1,direction: Hammer.DIRECTION_ALL}));
 mc.add(new Hammer.Pan({event: 'drag', threshold: 0, pointers: 3, direction: Hammer.DIRECTION_ALL}));
+mcLc.add(new Hammer.Pan({event: 'drag', threshold: 0, pointers: 1,direction: Hammer.DIRECTION_ALL}));
 
 //Purpose: Tapping functionality
 var singleTap = new Hammer.Tap({event: 'click', pointers: 1});
 var doubleTap = new Hammer.Tap({event: 'doubleclick', pointers: 1, taps: 2});
 var tripleTap = new Hammer.Tap({event: 'tripleclick', pointers: 1, taps: 3});
 mc.add([tripleTap, doubleTap, singleTap]);
+mcLc.add([tripleTap, doubleTap, singleTap]);
 tripleTap.recognizeWith([doubleTap, singleTap]);
 doubleTap.recognizeWith(singleTap);
 doubleTap.requireFailure(tripleTap);
 singleTap.requireFailure([tripleTap, doubleTap]);
 mc.add(new Hammer.Tap({event: 'rightclick', pointers: 2}));
+mcRc.add(new Hammer.Tap({event: 'rightclick', pointers: 1}));
 
 //Purpose: Using Hammer.js event listeners to trigger functionality by sending data to 
 mc.on('movestart moveend moveup movedown moveleft moveright', function(e) {
@@ -174,24 +224,68 @@ mc.on('scrollstart scrollend scrollup scrolldown scrollleft scrollright',
   function(e) {
     handlePan('scroll', e);
 });
+mcScroll.on('scrollstart scrollend scrollup scrolldown scrollleft scrollright',
+  function(e) {
+    handlePan('scroll', e);
+});
 
 mc.on('dragstart dragend dragup dragdown dragleft dragright', function(e) {
   handlePan('drag', e);
 });
+mcLc.on('dragstart dragend dragup dragdown dragleft dragright', function(e) {
+  handlePan('drag', e);
+});
 mc.on('click', function(e) {
   console.log('click');
   emitMouse(0, 0, 'click');
 });
+mcLc.on('click', function(e) {
+  console.log('click');
+  emitMouse(0, 0, 'click');
+});
 mc.on('rightclick', function(e) {
   console.info('rightclick');
   emitMouse(0, 0, 'rightclick');
 });
+mcRc.on('rightclick', function(e) {
+  console.info('rightclick');
+  emitMouse(0, 0, 'rightclick');
+});
 mc.on('doubleclick', function(e) {
   console.log('doubleclick');
   emitMouse(0, 0, 'doubleclick');
 });
+mcLc.on('doubleclick', function(e) {
+  console.log('doubleclick');
+  emitMouse(0, 0, 'doubleclick');
+});
+
 
+/*
+-----------SWIPING FUNCTIONALITY---------------
+*/
+var swiper = new Swiper('.swiper-container', {
+  });
 
+var swipeIndex = 0;
+$('#s0').css("background-color", "green")
+
+$('.icon-selection').click(function() {
+  if (this.id == 'settings-select') {
+    // Bring up setting menu
+    return;
+  }
+  var newId = parseInt(this.id[1])
+  if (newId == swipeIndex) {
+    return;
+  }
+  console.log(newId)
+  console.log(swipeIndex)
+  $('#s'+swipeIndex.toString()).css("background-color", "turquoise")
+  $(this).css("background-color", "green")
+  swipeIndex = newId;
+  swiper.slideTo(newId, 1000, false);
+});
 
 /*
 -----------MENU CONTROLS---------------
@@ -223,6 +317,21 @@ $('#fullscreen-toggle').click(function() {
   }
 });
 
+//PURPOSE: Toggle movement functionality
+$('.selection').click(function() {
+  if (this.checked) {
+    $('.draggable').hide();
+    $('#keyboard').hide();
+    $("#touchpad").show();
+    //document.body.requestFullscreen();
+  } else {
+    $('.draggable').show();
+    $('#keyboard').show();
+    $("#touchpad").hide();
+    //document.cancelFullscreen();
+  }
+});
+
 //PURPOSE: Toggle movement functionality
 $('#move-toggle').click(function() {
   if (this.checked) {
@@ -244,13 +353,3 @@ $('#about').click(function() {
   }
 });
 
-
-
-
-
-
-
-
-
-
-
diff --git a/public/js/desktop.js b/public/js/desktop.js
index a00d6ee..97d2bfd 100755
--- a/public/js/desktop.js
+++ b/public/js/desktop.js
@@ -57,7 +57,7 @@ var os = require('os');
     tooltip: 'UBoard', title: 'UBoard'  
   });
 
-  var menu = new gui.Menu();
+  var menu = new nw.Menu();
   menu.append(new gui.MenuItem({
     label: 'About UBoard',
     click: function() {
diff --git a/public/style/main.css b/public/style/main.css
index e9e0b66..5aa3757 100755
--- a/public/style/main.css
+++ b/public/style/main.css
@@ -8,22 +8,12 @@ mark {
 .hidden {
     display: none;
 }
-body {
-    padding-top: 50px;
-}
-@media screen and (max-width: 768px) {
-    body {
-        padding-top: 50px;
-    }
-}
-
 
 .draggable {
 
   /*Button Positioning and Size*/
-  width: 2%;
-  height: 2%;
-  min-height: 20%;
+  width: 8%;
+  height: 25%;
   margin: 1%;
   margin-top: 3%;
   border-radius: 2em;
@@ -50,32 +40,107 @@ body {
           transform: translate(0px, 0px);
 }
 
+.draggable:active:hover {
+  -ms-transform: translate(0px, -40%); /* IE 9 */
+  -webkit-transform: translate(0px, -40%); /* Safari */
+  transform: translate(0px, -40%);
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #00bbd4), color-stop(1, #3f51b5));
+  background-image: -webkit-linear-gradient(top, #00bbd4 0%, #3f51b5 100%);
+  background-image: linear-gradient(to bottom, #00bbd4 0%, #3f51b5 100%);
+  background-image: -webkit-linear-gradient(273deg, #3f51b5 0%, #00bbd4 100%);
+  color: #fff;
+}
+
 #drag-me::before {
   content: "#" attr(id);
   font-weight: bold;
 }
-#keyboard{
-    height: 60%;
+
+.swiper-container{
+   height: 50%;
+   width: 100%;
+   position: relative;
+   overflow: hidden;
+}
+
+.swiper-wrapper{
+   height: 100%;
+   width: 400%;
+   position: relative;
+}
+
+.swiper-slide{
+    float: left;
+    height: 100%;
+    width: 25%;
     background-color: white;
     position: relative;
 }
+
 #touchpad{
-    flex: 1 1 0px;
+    resize: vertical;
+    overflow: auto;
+    height: 40%;
+    width: 100%;
     background-color: grey;
+    position: relative;
+}
+
+#numpad{
+  background-color: purple;
+}
+
+#leftClick{
+  width: 40%;
+  height: 40%;
+  background-color: blue;
+  float: left;
+}
+
+#scrollWheel{
+  width: 20%;
+  height: 40%;
+  background-color: red;
+  float: left;
+}
+
+#rightClick{
+  width: 40%;
+  height: 40%;
+  background-color: blue;
+  float: left;
+}
+
+#mousepad{
+  width: 100%;
+  height: 60%;
+  background-color: grey;
+  float: left;
 }
 .wrapper{
-   display: flex;
-   flex-direction: column;
-   height: calc(100% - 50px);
-   width: 100%;
-   position: fixed;
+  height: 100%;
+  width: 100%;
+  position: absolute;
+}
+
+#navbar{
+  height: 10%;
+  background-color: turquoise;
+}
+
+.icon-selection{
+  float: left;
+  min-height: 100%;
+  min-width: 20%;
+  position: relative;
+  transition: background-color 300ms linear;
 }
 
-.navbar-item {
-    display: block;
-    padding: 5px 5px;
-    clear: both;
-    font-weight: 400;
+
+.material-icons{
+  position: absolute;
+  top: 40%;
+  left: 40%;
 }
 
 .modal {
diff --git a/server.js b/server.js
index ed27b0e..f7e342a 100755
--- a/server.js
+++ b/server.js
@@ -65,6 +65,8 @@ io.on('connection', function(socket) {
   var xpos = []
   var ypos = []
 
+  //Load default keyboard
+  
   var file = fs.readFileSync("configuration.json")  
   var content = JSON.parse(file)
 
@@ -73,9 +75,25 @@ io.on('connection', function(socket) {
     xpos.push(content[key][1]);
     ypos.push(content[key][2]);
   }
+  socket.emit('updateKeys', {k: keys, x: xpos, y: ypos});
+   
+  content = []
+  //Load default urls
+  var file = fs.readFileSync("url.json")  
+  content = JSON.parse(file)
+  
+  var keys = []
+  var xpos = []
+  var ypos = []
+  
+  for (var key in content) {
+    keys.push(content[key][0]);
+    xpos.push(content[key][1]);
+    ypos.push(content[key][2]);
+  }
+  socket.emit('updateUrls', {k: keys, x: xpos, y: ypos}); 
 
   //Keyboard Functionality
-  socket.emit('updateKeys', {k: keys, x: xpos, y: ypos}); 
   socket.on('string', function(str) {
     console.log("Trying to type")
     console.log(str);
diff --git a/url.json b/url.json
new file mode 100644
index 0000000..fc63680
--- /dev/null
+++ b/url.json
@@ -0,0 +1,42 @@
+{
+    "url1": [
+        "https://www.google.com",
+        "0",
+        "0"
+    ],
+    "url2": [
+        "https://www.facebook.com",
+        "25",
+        "0"
+    ],
+    "url3": [
+        "https://www.google.com",
+        "50",
+        "0"
+    ],
+    "url4": [
+        "https://www.umich.instructure.com",
+        "75",
+        "0"
+    ],
+    "url5": [
+        "https://www.netflix.com",
+        "0",
+        "30"
+    ],
+    "url6": [
+        "https://www.amazon.com",
+        "25",
+        "30"
+    ],
+    "url7": [
+        "https://www.amazon.com/Prime-Movies/b?ie=UTF8&node=7613704011&ref=dvm_us_dl_sl_sitelink3%7Cc_163705074697_m_vHxbIxqC-dc_s_E9l9qm8j_&gclid=EAIaIQobChMI3Z3gq9ff2QIVQbjACh2kTgNeEAAYASABEgJdJvD_BwE",
+        "50",
+        "30"
+    ],
+    "url8": [
+        "https://www.youtube.com",
+        "75",
+        "30"
+    ]
+}
\ No newline at end of file
-- 
GitLab