From f521f30e923c8fdac94de6a372d806224547fe14 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Sat, 11 Apr 2020 22:30:19 +0200 Subject: [PATCH] improve mobile layout - only works in portrait mode for now - initial-scale meta tag is missing!!! --- public/chat.html | 10 +- public/css/chat.css | 63 +++++++--- public/css/snackbar.css | 45 ++++++++ public/js/chat.js | 33 ++++-- public/js/jquery.ui.touch-punch.js | 180 +++++++++++++++++++++++++++++ public/js/snackbar.js | 4 +- 6 files changed, 306 insertions(+), 29 deletions(-) create mode 100644 public/js/jquery.ui.touch-punch.js diff --git a/public/chat.html b/public/chat.html index 3784220..b39ab4f 100644 --- a/public/chat.html +++ b/public/chat.html @@ -1,7 +1,10 @@ + + + ZipChat @@ -12,6 +15,7 @@ > +
-
- -
+
+ +
diff --git a/public/css/chat.css b/public/css/chat.css index c719365..74efa46 100644 --- a/public/css/chat.css +++ b/public/css/chat.css @@ -359,8 +359,11 @@ button:hover { /* Begin mobile layout */ @media (max-width: 1000px) { +/* @media (min-width: 320px) and (max-width: 480px) { */ html, body { + width: 100%; + height: 100%; font-size: 2.5em; } @@ -386,14 +389,24 @@ button:hover { position: fixed; top: 5rem; left: 5rem; + min-width: 5rem; + min-height: 2rem; + width: auto; + height: auto; + } + + #moveable #local-video { + height: 7rem; + width: auto; } #moveable p { + text-align: center; z-index: 101; position: absolute; color: white; font-family: "Heebo", sans-serif; - white-space: nowrap; + white-space: pre-wrap; top: 50%; left: 50%; -ms-transform: translate(-50%, -50%); @@ -403,18 +416,33 @@ button:hover { background: rgba(0, 0, 0, 0.12); padding: 10px; border-radius: 5px; + margin: 0; + } + + #remote-video-text { + position: fixed; + top: initial !important; + left: initial; + bottom: 40%; + width: 80%; + height: auto; + margin: 0; + margin-left: 10%; + text-align: center; } .multi-button { - position: absolute; + position: fixed; left: 0; - top: calc(90vh - 3rem - 3vh); + top: initial; + bottom: 0; width: 80vw; height: 3rem; margin: 0 10vw; -ms-transform: translate(0%, 0%); transform: translate(0%, 0%); z-index: 999; + box-shadow: none; border-radius: 10px; padding: 0; display: flex; @@ -445,36 +473,41 @@ button:hover { } .HoverState { - display: none; + display: none !important; } - #entire-chat { + #entire-chat { position: absolute; - top: 20vh; - left: 0; - height: 50vh; - width: 100vw; - padding: 1rem 0; + top: 3rem; + right: 0; + height: calc(100% - 3rem - 3rem); + width: 60vw; + /* padding: 1rem 0; */ + padding: 0; /* border: 3px solid green; */ text-align: center; + /* background: #16171a; */ } #chat-zone { position: relative; padding-top: 20px; width: 90%; - height: 100%; + height: calc(100% - 2rem); margin-left: 5%; - box-shadow: 4px 4px 12px #030506, -4px -4px 12px #292a30; + /* box-shadow: 4px 4px 12px #030506, -4px -4px 12px #292a30; */ /* border: 5px solid blue */ border-radius: 10px; - background: #16171a; + /* background: #16171a; */ } .compose { position: absolute; - left: 5%; - width: 90%; + font-size: 1rem; + right: 2%; + /* bottom: calc(3rem + 2rem); */ + bottom: 0; + width: 60vw; height: 2rem; margin: .5rem 0; } diff --git a/public/css/snackbar.css b/public/css/snackbar.css index 9a072c7..3a84233 100644 --- a/public/css/snackbar.css +++ b/public/css/snackbar.css @@ -99,3 +99,48 @@ transform: none; } } + +/* Mobile Styles Start */ + +@media (max-width: 1000px) { + + .snackbar-container { + display: flex; + width: 80vw !important; + min-width: 80vw; + max-width: 80vw; + height: auto; + word-wrap: break-word; + line-height: 1.2rem; + font-size: 1rem; + position: fixed; + justify-content: space-between; + align-items: center; + padding: .5rem; + bottom: initial; + top: 5rem; + margin: 0; + margin-top: 1rem; + } + + .snackbar-container p { + width: 80%; + } + + .snackbar-container .action { + width: 15%; + padding: .2rem; + border-radius: 10px; + display: inline-block; + border: none; + font-size: 1rem; + text-transform: uppercase; + color: #000000; + margin: 0 0 0 24px; + /*padding: 0;*/ + cursor: pointer; + } + +} + +/* Mobile Styles End */ diff --git a/public/js/chat.js b/public/js/chat.js index e50d814..bc5cb9d 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -357,8 +357,14 @@ function chatRoomFull() { function rePositionLocalVideo() { // Get position of remote video var bounds = remoteVideo.position(); - bounds.top += 10; - bounds.left += 10; + let localVideo = $("#local-video"); + if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { + bounds.top = $(window).height() - localVideo.height()*1.5; + bounds.left += 10; + } else { + bounds.top += 10; + bounds.left += 10; + } // Set position of local video $("#moveable").css(bounds); } @@ -469,10 +475,14 @@ function pauseVideo() { const videoButtonText = document.getElementById("video-text"); // update pause button icon and text if (videoIsPaused) { + localVideoText.text("Video is paused"); + localVideoText.show(); videoButtonIcon.classList.remove("fa-video"); videoButtonIcon.classList.add("fa-video-slash"); videoButtonText.innerText = "Unpause Video"; } else { + localVideoText.text("Video unpaused"); + setTimeout(() => localVideoText.fadeOut(), 2000); videoButtonIcon.classList.add("fa-video"); videoButtonIcon.classList.remove("fa-video-slash"); videoButtonText.innerText = "Pause Video"; @@ -824,7 +834,7 @@ function togglePictureInPicture() { function startUp() { // Redirect mobile browsers if ( - /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + /webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ) { @@ -874,19 +884,24 @@ function startUp() { var timedelay = 1; function delayCheck() { if (timedelay === 5) { - // $(".multi-button").fadeOut(); - // $("#header").fadeOut(); + $(".multi-button").fadeOut(); + $("#header").fadeOut(); $(".multi-button").style = "display: none;"; - $("#header").style = "display: none;"; + // $("#header").style = "display: none;"; timedelay = 1; } timedelay = timedelay + 1; } $(document).mousemove(function () { - // $(".multi-button").fadeIn(); - // $("#header").fadeIn(); + $(".multi-button").fadeIn(function() { + // fix layout on mobile + if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { + $(this).css("display", "flex"); + } + }); + $("#header").fadeIn(); $(".multi-button").style = ""; - $("#header").style = ""; + // $("#header").style = ""; timedelay = 1; clearInterval(_delay); _delay = setInterval(delayCheck, 500); diff --git a/public/js/jquery.ui.touch-punch.js b/public/js/jquery.ui.touch-punch.js new file mode 100644 index 0000000..16ce41d --- /dev/null +++ b/public/js/jquery.ui.touch-punch.js @@ -0,0 +1,180 @@ +/*! + * jQuery UI Touch Punch 0.2.3 + * + * Copyright 2011–2014, Dave Furfero + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Depends: + * jquery.ui.widget.js + * jquery.ui.mouse.js + */ +(function ($) { + + // Detect touch support + $.support.touch = 'ontouchend' in document; + + // Ignore browsers without touch support + if (!$.support.touch) { + return; + } + + var mouseProto = $.ui.mouse.prototype, + _mouseInit = mouseProto._mouseInit, + _mouseDestroy = mouseProto._mouseDestroy, + touchHandled; + + /** + * Simulate a mouse event based on a corresponding touch event + * @param {Object} event A touch event + * @param {String} simulatedType The corresponding mouse event + */ + function simulateMouseEvent (event, simulatedType) { + + // Ignore multi-touch events + if (event.originalEvent.touches.length > 1) { + return; + } + + event.preventDefault(); + + var touch = event.originalEvent.changedTouches[0], + simulatedEvent = document.createEvent('MouseEvents'); + + // Initialize the simulated mouse event using the touch event's coordinates + simulatedEvent.initMouseEvent( + simulatedType, // type + true, // bubbles + true, // cancelable + window, // view + 1, // detail + touch.screenX, // screenX + touch.screenY, // screenY + touch.clientX, // clientX + touch.clientY, // clientY + false, // ctrlKey + false, // altKey + false, // shiftKey + false, // metaKey + 0, // button + null // relatedTarget + ); + + // Dispatch the simulated event to the target element + event.target.dispatchEvent(simulatedEvent); + } + + /** + * Handle the jQuery UI widget's touchstart events + * @param {Object} event The widget element's touchstart event + */ + mouseProto._touchStart = function (event) { + + var self = this; + + // Ignore the event if another widget is already being handled + if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) { + return; + } + + // Set the flag to prevent other widgets from inheriting the touch event + touchHandled = true; + + // Track movement to determine if interaction was a click + self._touchMoved = false; + + // Simulate the mouseover event + simulateMouseEvent(event, 'mouseover'); + + // Simulate the mousemove event + simulateMouseEvent(event, 'mousemove'); + + // Simulate the mousedown event + simulateMouseEvent(event, 'mousedown'); + }; + + /** + * Handle the jQuery UI widget's touchmove events + * @param {Object} event The document's touchmove event + */ + mouseProto._touchMove = function (event) { + + // Ignore event if not handled + if (!touchHandled) { + return; + } + + // Interaction was not a click + this._touchMoved = true; + + // Simulate the mousemove event + simulateMouseEvent(event, 'mousemove'); + }; + + /** + * Handle the jQuery UI widget's touchend events + * @param {Object} event The document's touchend event + */ + mouseProto._touchEnd = function (event) { + + // Ignore event if not handled + if (!touchHandled) { + return; + } + + // Simulate the mouseup event + simulateMouseEvent(event, 'mouseup'); + + // Simulate the mouseout event + simulateMouseEvent(event, 'mouseout'); + + // If the touch interaction did not move, it should trigger a click + if (!this._touchMoved) { + + // Simulate the click event + simulateMouseEvent(event, 'click'); + } + + // Unset the flag to allow other widgets to inherit the touch event + touchHandled = false; + }; + + /** + * A duck punch of the $.ui.mouse _mouseInit method to support touch events. + * This method extends the widget with bound touch event handlers that + * translate touch events to mouse events and pass them to the widget's + * original mouse event handling methods. + */ + mouseProto._mouseInit = function () { + + var self = this; + + // Delegate the touch handlers to the widget's element + self.element.bind({ + touchstart: $.proxy(self, '_touchStart'), + touchmove: $.proxy(self, '_touchMove'), + touchend: $.proxy(self, '_touchEnd') + }); + + // Call the original $.ui.mouse init method + _mouseInit.call(self); + }; + + /** + * Remove the touch event handlers + */ + mouseProto._mouseDestroy = function () { + + var self = this; + + // Delegate the touch handlers to the widget's element + self.element.unbind({ + touchstart: $.proxy(self, '_touchStart'), + touchmove: $.proxy(self, '_touchMove'), + touchend: $.proxy(self, '_touchEnd') + }); + + // Call the original $.ui.mouse destroy method + _mouseDestroy.call(self); + }; + +})(jQuery); \ No newline at end of file diff --git a/public/js/snackbar.js b/public/js/snackbar.js index b607f22..c8ddb2a 100755 --- a/public/js/snackbar.js +++ b/public/js/snackbar.js @@ -70,9 +70,9 @@ $p.style.margin = 0; $p.style.padding = 0; $p.style.color = options.textColor; - $p.style.fontSize = "14px"; $p.style.fontWeight = 300; - $p.style.lineHeight = "1em"; + // $p.style.fontSize = "14px"; + // $p.style.lineHeight = "1em"; $p.innerHTML = options.text; Snackbar.snackbar.appendChild($p); // Snackbar.snackbar.style.background = options.backgroundColor;