From bb066ecb027da53462fb69143a4aadb4bb3ea42b Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 6 Mar 2018 13:29:28 +0200 Subject: [PATCH] Do not listen to touch events until client is initialized Fixes #2148 --- client/js/libs/slideout.js | 103 -------------------------------- client/js/lounge.js | 13 ++-- client/js/slideout.js | 99 ++++++++++++++++++++++++++++++ client/js/socket-events/init.js | 3 + 4 files changed, 108 insertions(+), 110 deletions(-) delete mode 100644 client/js/libs/slideout.js create mode 100644 client/js/slideout.js diff --git a/client/js/libs/slideout.js b/client/js/libs/slideout.js deleted file mode 100644 index 5d833b5d..00000000 --- a/client/js/libs/slideout.js +++ /dev/null @@ -1,103 +0,0 @@ -"use strict"; - -/** - * Simple slideout menu implementation. - */ -module.exports = function slideoutMenu(viewport, menu) { - let touchStartPos = null; - let touchCurPos = null; - let touchStartTime = 0; - let menuWidth = 0; - let menuIsOpen = false; - let menuIsMoving = false; - - function toggleMenu(state) { - menuIsOpen = state; - viewport.classList.toggle("menu-open", state); - } - - function disableSlideout() { - viewport.removeEventListener("ontouchstart", onTouchStart); - } - - function onTouchStart(e) { - if (e.touches.length !== 1) { - onTouchEnd(); - return; - } - - const touch = e.touches.item(0); - viewport.classList.toggle("menu-dragging", true); - - menuWidth = parseFloat(window.getComputedStyle(menu).width); - - if ((!menuIsOpen && touch.screenX < 50) || (menuIsOpen && touch.screenX > menuWidth)) { - touchStartPos = touch; - touchCurPos = touch; - touchStartTime = Date.now(); - - viewport.addEventListener("touchmove", onTouchMove); - viewport.addEventListener("touchend", onTouchEnd, {passive: true}); - } - } - - function onTouchMove(e) { - const touch = touchCurPos = e.touches.item(0); - let setX = touch.screenX - touchStartPos.screenX; - - if (Math.abs(setX > 30)) { - menuIsMoving = true; - } - - if (!menuIsMoving && Math.abs(touch.screenY - touchStartPos.screenY) > 30) { - onTouchEnd(); - return; - } - - if (menuIsOpen) { - setX += menuWidth; - } - - if (setX > menuWidth) { - setX = menuWidth; - } else if (setX < 0) { - setX = 0; - } - - viewport.style.transform = "translate3d(" + setX + "px, 0, 0)"; - - if (menuIsMoving) { - e.preventDefault(); - e.stopPropagation(); - } - } - - function onTouchEnd() { - const diff = touchCurPos.screenX - touchStartPos.screenX; - const absDiff = Math.abs(diff); - - if (absDiff > menuWidth / 2 || Date.now() - touchStartTime < 180 && absDiff > 50) { - toggleMenu(diff > 0); - } - - viewport.removeEventListener("touchmove", onTouchMove); - viewport.removeEventListener("touchend", onTouchEnd); - viewport.classList.toggle("menu-dragging", false); - viewport.style.transform = null; - - touchStartPos = null; - touchCurPos = null; - touchStartTime = 0; - menuIsMoving = false; - } - - viewport.addEventListener("touchstart", onTouchStart, {passive: true}); - - return { - disable: disableSlideout, - toggle: toggleMenu, - isOpen: function() { - return menuIsOpen; - }, - }; -}; diff --git a/client/js/lounge.js b/client/js/lounge.js index 0cc67053..22560ece 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -9,7 +9,7 @@ const URI = require("urijs"); // our libraries require("./libs/jquery/inputhistory"); require("./libs/jquery/stickyscroll"); -const slideoutMenu = require("./libs/slideout"); +const slideoutMenu = require("./slideout"); const templates = require("../views"); const socket = require("./socket"); const render = require("./render"); @@ -29,15 +29,14 @@ $(function() { $(document.body).data("app-name", document.title); const viewport = $("#viewport"); - const sidebarSlide = slideoutMenu(viewport[0], sidebar[0]); const contextMenuContainer = $("#context-menu-container"); const contextMenu = $("#context-menu"); $("#main").on("click", function(e) { - if ($(e.target).is(".lt")) { - sidebarSlide.toggle(!sidebarSlide.isOpen()); - } else if (sidebarSlide.isOpen()) { - sidebarSlide.toggle(false); + const isOpen = slideoutMenu.isOpen(); + + if (isOpen || $(e.target).is(".lt")) { + slideoutMenu.toggle(!isOpen); } }); @@ -376,7 +375,7 @@ $(function() { utils.toggleNotificationMarkers(false); } - sidebarSlide.toggle(false); + slideoutMenu.toggle(false); } const lastActive = $("#windows > .active"); diff --git a/client/js/slideout.js b/client/js/slideout.js new file mode 100644 index 00000000..d9244e8f --- /dev/null +++ b/client/js/slideout.js @@ -0,0 +1,99 @@ +"use strict"; + +const viewport = document.getElementById("viewport"); +const menu = document.getElementById("sidebar"); + +let touchStartPos = null; +let touchCurPos = null; +let touchStartTime = 0; +let menuWidth = 0; +let menuIsOpen = false; +let menuIsMoving = false; + +class SlideoutMenu { + static enable() { + viewport.addEventListener("touchstart", onTouchStart, {passive: true}); + } + + static toggle(state) { + menuIsOpen = state; + viewport.classList.toggle("menu-open", state); + } + + static isOpen() { + return menuIsOpen; + } +} + +function onTouchStart(e) { + if (e.touches.length !== 1) { + onTouchEnd(); + return; + } + + const touch = e.touches.item(0); + + menuWidth = parseFloat(window.getComputedStyle(menu).width); + + if ((!menuIsOpen && touch.screenX < 50) || (menuIsOpen && touch.screenX > menuWidth)) { + touchStartPos = touch; + touchCurPos = touch; + touchStartTime = Date.now(); + + viewport.classList.toggle("menu-dragging", true); + viewport.addEventListener("touchmove", onTouchMove); + viewport.addEventListener("touchend", onTouchEnd, {passive: true}); + } +} + +function onTouchMove(e) { + const touch = touchCurPos = e.touches.item(0); + let setX = touch.screenX - touchStartPos.screenX; + + if (Math.abs(setX > 30)) { + menuIsMoving = true; + } + + if (!menuIsMoving && Math.abs(touch.screenY - touchStartPos.screenY) > 30) { + onTouchEnd(); + return; + } + + if (menuIsOpen) { + setX += menuWidth; + } + + if (setX > menuWidth) { + setX = menuWidth; + } else if (setX < 0) { + setX = 0; + } + + viewport.style.transform = "translate3d(" + setX + "px, 0, 0)"; + + if (menuIsMoving) { + e.preventDefault(); + e.stopPropagation(); + } +} + +function onTouchEnd() { + const diff = touchCurPos.screenX - touchStartPos.screenX; + const absDiff = Math.abs(diff); + + if (absDiff > menuWidth / 2 || Date.now() - touchStartTime < 180 && absDiff > 50) { + SlideoutMenu.toggle(diff > 0); + } + + viewport.removeEventListener("touchmove", onTouchMove); + viewport.removeEventListener("touchend", onTouchEnd); + viewport.classList.toggle("menu-dragging", false); + viewport.style.transform = null; + + touchStartPos = null; + touchCurPos = null; + touchStartTime = 0; + menuIsMoving = false; +} + +module.exports = SlideoutMenu; diff --git a/client/js/socket-events/init.js b/client/js/socket-events/init.js index b9b284d1..009f7a1a 100644 --- a/client/js/socket-events/init.js +++ b/client/js/socket-events/init.js @@ -5,6 +5,7 @@ const escape = require("css.escape"); const socket = require("../socket"); const render = require("../render"); const webpush = require("../webpush"); +const slideoutMenu = require("../slideout"); const sidebar = $("#sidebar"); const storage = require("../localStorage"); const utils = require("../utils"); @@ -45,6 +46,8 @@ socket.on("init", function(data) { $("#loading").remove(); $("#sign-in").remove(); + slideoutMenu.enable(); + if (window.g_LoungeErrorHandler) { window.removeEventListener("error", window.g_LoungeErrorHandler); window.g_LoungeErrorHandler = null;