Merge pull request #2158 from thelounge/xpaw/slideout

Do not listen to touch events until client is initialized
This commit is contained in:
Pavel Djundik 2018-03-07 10:13:50 +02:00 committed by GitHub
commit d5c9fb5536
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 108 additions and 110 deletions

View File

@ -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;
},
};
};

View File

@ -9,7 +9,7 @@ const URI = require("urijs");
// our libraries // our libraries
require("./libs/jquery/inputhistory"); require("./libs/jquery/inputhistory");
require("./libs/jquery/stickyscroll"); require("./libs/jquery/stickyscroll");
const slideoutMenu = require("./libs/slideout"); const slideoutMenu = require("./slideout");
const templates = require("../views"); const templates = require("../views");
const socket = require("./socket"); const socket = require("./socket");
const render = require("./render"); const render = require("./render");
@ -29,15 +29,14 @@ $(function() {
$(document.body).data("app-name", document.title); $(document.body).data("app-name", document.title);
const viewport = $("#viewport"); const viewport = $("#viewport");
const sidebarSlide = slideoutMenu(viewport[0], sidebar[0]);
const contextMenuContainer = $("#context-menu-container"); const contextMenuContainer = $("#context-menu-container");
const contextMenu = $("#context-menu"); const contextMenu = $("#context-menu");
$("#main").on("click", function(e) { $("#main").on("click", function(e) {
if ($(e.target).is(".lt")) { const isOpen = slideoutMenu.isOpen();
sidebarSlide.toggle(!sidebarSlide.isOpen());
} else if (sidebarSlide.isOpen()) { if (isOpen || $(e.target).is(".lt")) {
sidebarSlide.toggle(false); slideoutMenu.toggle(!isOpen);
} }
}); });
@ -376,7 +375,7 @@ $(function() {
utils.toggleNotificationMarkers(false); utils.toggleNotificationMarkers(false);
} }
sidebarSlide.toggle(false); slideoutMenu.toggle(false);
} }
const lastActive = $("#windows > .active"); const lastActive = $("#windows > .active");

99
client/js/slideout.js Normal file
View File

@ -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;

View File

@ -5,6 +5,7 @@ const escape = require("css.escape");
const socket = require("../socket"); const socket = require("../socket");
const render = require("../render"); const render = require("../render");
const webpush = require("../webpush"); const webpush = require("../webpush");
const slideoutMenu = require("../slideout");
const sidebar = $("#sidebar"); const sidebar = $("#sidebar");
const storage = require("../localStorage"); const storage = require("../localStorage");
const utils = require("../utils"); const utils = require("../utils");
@ -45,6 +46,8 @@ socket.on("init", function(data) {
$("#loading").remove(); $("#loading").remove();
$("#sign-in").remove(); $("#sign-in").remove();
slideoutMenu.enable();
if (window.g_LoungeErrorHandler) { if (window.g_LoungeErrorHandler) {
window.removeEventListener("error", window.g_LoungeErrorHandler); window.removeEventListener("error", window.g_LoungeErrorHandler);
window.g_LoungeErrorHandler = null; window.g_LoungeErrorHandler = null;