From 6e6f8297dca0dfb052d27a2b76ec895b60747f3a Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 16 Jun 2017 11:30:02 -0300 Subject: [PATCH] sidebar --- .../client/imports/general/utils.css | 27 ++- .../client/imports/sidebar.css | 38 ++++- packages/rocketchat-ui-master/client/main.js | 102 +----------- .../client/accountBox.html | 88 +++++----- .../rocketchat-ui-sidenav/client/sideNav.html | 39 ++--- .../rocketchat-ui/client/lib/RoomManager.js | 5 +- packages/rocketchat-ui/client/lib/menu.js | 155 ++++++++++++++++-- 7 files changed, 263 insertions(+), 191 deletions(-) diff --git a/packages/rocketchat-theme/client/imports/general/utils.css b/packages/rocketchat-theme/client/imports/general/utils.css index 7e2dbdf6450..b2a59071601 100644 --- a/packages/rocketchat-theme/client/imports/general/utils.css +++ b/packages/rocketchat-theme/client/imports/general/utils.css @@ -54,13 +54,17 @@ :root { --rc-popover-open: { display: flex; + align-items: flex-start; + width: 100vw; + height: 100vh; + /*background: rgba(0,0,0,.5);*/ animation: dropdown-show 0.1s cubic-bezier(0.45, 0.05, 0.55, 0.95); } --rc-popover-open-mobile: { position: fixed; - top: 85px; - left: 25px; - right: 25px; + top: 0; + left: 0; + width: 100vw; } } @@ -73,16 +77,21 @@ } + .rc-popover { display: none; position: absolute; + will-change: transform; z-index: 9999; - padding: 24px; - border-radius: 2px; - background-color: #ffffff; - box-shadow: 0 0 2px 0 rgba(47, 52, 61, 0.08), 0 0 12px 0 rgba(47, 52, 61, 0.12); - cursor: default; - + &__content { + width: 100%; + display: flex; + padding: 24px; + border-radius: 2px; + background-color: #ffffff; + box-shadow: 0 0 2px 0 rgba(47, 52, 61, 0.08), 0 0 12px 0 rgba(47, 52, 61, 0.12); + cursor: default; + } &--show { @apply --rc-popover-open; } diff --git a/packages/rocketchat-theme/client/imports/sidebar.css b/packages/rocketchat-theme/client/imports/sidebar.css index 01fd073b5b2..5d660bcdfc3 100644 --- a/packages/rocketchat-theme/client/imports/sidebar.css +++ b/packages/rocketchat-theme/client/imports/sidebar.css @@ -5,12 +5,25 @@ --room-item-height: 32px; } + /* Sidebar */ .sidebar { width: var(--rooms-box-width); height: auto; display: flex; flex-direction: column; + z-index: 9999; + + &-wrap { + z-index: -1; + height: 100%; + position: absolute; + top: 0; + touch-action: pan-y; + user-select: none; + -webkit-user-drag: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + } &__header { padding: 24px 24px 32px; @@ -19,6 +32,23 @@ & .unread-rooms { display: none; } + &__footer { + padding: 24px; + & img { + width: 100%; + } + } +} + +@media (width < 780px) { + .sidebar { + transform: translateX(-280px); + will-change: transform; + touch-action: pan-y; + user-select: none; + -webkit-user-drag: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + } } /* Sidebar Account */ @@ -212,11 +242,3 @@ margin-right: 10px; } } - -.sidebar__footer { - padding: 24px; - - & img { - width: 100%; - } -} diff --git a/packages/rocketchat-ui-master/client/main.js b/packages/rocketchat-ui-master/client/main.js index e959887cc4d..2374dd8e1af 100644 --- a/packages/rocketchat-ui-master/client/main.js +++ b/packages/rocketchat-ui-master/client/main.js @@ -1,15 +1,6 @@ /* globals toolbarSearch, menu, isRtl, fireGlobalEvent, CachedChatSubscription, DynamicCss */ import Clipboard from 'clipboard'; -const map = (x, in_min, in_max, out_min, out_max) => (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; RocketChat.settings.collection.find({_id:/theme/}, {fields:{ value: 1, properties: 1, type: 1 }}).observe({changed: () => { DynamicCss.run(); }}); -const sideNavW = menu.sideNavW; - -menu.onClose(function() { - this.mainContent.css('opacity', '1'); -}); -menu.onOpen(function() { - this.mainContent.css('opacity', '.5'); -}); Template.body.onRendered(function() { new Clipboard('.clipboard'); @@ -92,10 +83,11 @@ Template.body.onRendered(function() { } } - if (target.closest('[data-popover="label"], [data-popover="popover"]').length === 0 && target.data('popover') !== 'anchor') { + if ([...target[0].classList].includes('rc-popover') || target.closest('[data-popover="label"], [data-popover="popover"]').length === 0 && target.data('popover') !== 'anchor') { $('[data-popover="anchor"]:checked').prop('checked', false); } }); + Tracker.autorun(function(c) { const w = window; const d = document; @@ -184,96 +176,6 @@ Template.main.events({ console.log('room click .burger'); } return menu.toggle(); - }, - 'touchstart'(e, t) { - if (document.body.clientWidth > 780) { - return; - } - t.touchstartX = undefined; - t.touchstartY = undefined; - t.movestarted = false; - t.blockmove = false; - t.isRtl = isRtl(localStorage.getItem('userLanguage')); - if ($(e.currentTarget).closest('.main-content').length > 0) { - t.touchstartX = e.originalEvent.touches[0].clientX; - t.touchstartY = e.originalEvent.touches[0].clientY; - t.mainContent = $('.main-content'); - return t.wrapper = $('.messages-box > .wrapper'); - } - }, - 'touchmove':(e, t) => { - - if (t.touchstartX == null) { - return; - } - const [touch] = e.originalEvent.touches; - const diffX = touch.clientX - t.touchstartX; - const diffY = touch.clientY - t.touchstartY; - const absX = Math.abs(diffX); - const absY = Math.abs(diffY); - if (t.movestarted !== true && t.blockmove !== true && absY > 5) { - t.blockmove = true; - } - if (t.blockmove !== true && (t.movestarted === true || absX > 5)) { - t.movestarted = true; - if (t.isRtl) { - if (menu.isOpen()) { - t.diff = -sideNavW + diffX; - } else { - t.diff = diffX; - } - if (t.diff < -sideNavW) { - t.diff = -sideNavW; - } - if (t.diff > 0) { - t.diff = 0; - } - } else { - if (menu.isOpen()) { - t.diff = sideNavW + diffX; - } else { - t.diff = diffX; - } - if (t.diff > sideNavW) { - t.diff = sideNavW; - } - if (t.diff < 0) { - t.diff = 0; - } - } - t.mainContent.addClass('notransition'); - t.mainContent.css('transition', 'none'); - t.mainContent.css('opacity', `${ map(1 -(t.diff / sideNavW), 0, 1, .5, 1) }`); - t.mainContent.css('transform', `translate(${ t.diff }px)`); - return t.wrapper.css('overflow', 'hidden'); - } - }, - 'touchend'(e, t) { - const [max, min] = [sideNavW * .76, sideNavW * .24]; - if (t.movestarted !== true) { - return; - } - t.mainContent[0].style.transition = null; - t.wrapper.css('overflow', ''); - if (t.isRtl) { - if (menu.isOpen()) { - return t.diff >= -max ? menu.close() : menu.open(); - } else if (t.diff <= -min) { - return menu.open(); - } else { - return menu.close(); - } - } else if (menu.isOpen()) { - if (t.diff >= max) { - return menu.open(); - } else { - return menu.close(); - } - } else if (t.diff >= min) { - return menu.open(); - } else { - return menu.close(); - } } }); diff --git a/packages/rocketchat-ui-sidenav/client/accountBox.html b/packages/rocketchat-ui-sidenav/client/accountBox.html index f1380629f22..899a2e5cb8f 100644 --- a/packages/rocketchat-ui-sidenav/client/accountBox.html +++ b/packages/rocketchat-ui-sidenav/client/accountBox.html @@ -16,54 +16,56 @@
-
-

{{_ "User"}}

-
    -
  • - - {{_ "Online"}} -
  • -
  • - - {{_ "Away" context="male"}} -
  • -
  • - - {{_ "Busy" context="male"}} -
  • -
  • - - {{_ "Invisible"}} -
  • -
- -
    - {{#each registeredMenus}} -
  • - {{name}} -
  • - {{/each}} - {{!--
  • - {{_ "My_Account"}} -
  • --}} -
  • - {{_ "Logout"}} -
  • -
-
- {{#if showAdminOption}} +
-

{{_ "Team"}}

+

{{_ "User"}}

    -
  • - - - - {{_ "Administration"}} +
  • + + {{_ "Online"}} +
  • +
  • + + {{_ "Away" context="male"}} +
  • +
  • + + {{_ "Busy" context="male"}} +
  • +
  • + + {{_ "Invisible"}} +
  • +
+ +
    + {{#each registeredMenus}} +
  • + {{name}} +
  • + {{/each}} + {{!--
  • + {{_ "My_Account"}} +
  • --}} +
  • + {{_ "Logout"}}
- {{/if}} + {{#if showAdminOption}} +
+

{{_ "Team"}}

+
    +
  • + + + + {{_ "Administration"}} +
  • +
+
+ {{/if}} +
{{/if}} diff --git a/packages/rocketchat-ui-sidenav/client/sideNav.html b/packages/rocketchat-ui-sidenav/client/sideNav.html index edc9ed738f9..13c25ca51c7 100644 --- a/packages/rocketchat-ui-sidenav/client/sideNav.html +++ b/packages/rocketchat-ui-sidenav/client/sideNav.html @@ -1,28 +1,28 @@ diff --git a/packages/rocketchat-ui/client/lib/RoomManager.js b/packages/rocketchat-ui/client/lib/RoomManager.js index 85ac43ee63b..7292a2e36a4 100644 --- a/packages/rocketchat-ui/client/lib/RoomManager.js +++ b/packages/rocketchat-ui/client/lib/RoomManager.js @@ -259,7 +259,10 @@ Tracker.autorun(() => { if ((currentUsername === undefined) && ((user != null ? user.username : undefined) != null)) { currentUsername = user.username; RoomManager.closeAllRooms(); - return FlowRouter._current.route.callAction(FlowRouter._current); + if (FlowRouter._current.route) { + return FlowRouter._current.route.callAction(FlowRouter._current); + + } } }); diff --git a/packages/rocketchat-ui/client/lib/menu.js b/packages/rocketchat-ui/client/lib/menu.js index 323998b26db..b0ef48df4b8 100644 --- a/packages/rocketchat-ui/client/lib/menu.js +++ b/packages/rocketchat-ui/client/lib/menu.js @@ -1,5 +1,6 @@ import EventEmitter from 'wolfy87-eventemitter'; const sideNavW = 280; +const map = (x, in_min, in_max, out_min, out_max) => (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; window.addEventListener('resize', _.debounce(((event) => { let lastState = window.matchMedia('(min-width: 700px)').matches ? 'mini' : 'large'; @@ -47,34 +48,153 @@ this.menu = new class extends EventEmitter { }, 200); this.sideNavW = sideNavW; } + get isRtl() { + return isRtl(localStorage.getItem('userLanguage')); + } + touchstart(e) { + this.movestarted = false; + this.blockmove = false; + this.touchstartX = undefined; + this.touchstartY = undefined; + this.diff = 0; + if (e.target === this.sidebarWrap[0] || $(e.target).closest('.main-content').length > 0) { + this.closePopover(); + this.touchstartX = e.touches[0].clientX; + this.touchstartY = e.touches[0].clientY; + this.mainContent = $('.main-content'); + this.wrapper = $('.messages-box > .wrapper'); + } + } + touchmove(e) { + if (this.touchstartX == null) { + return; + } + const [touch] = e.touches; + const diffX = touch.clientX - this.touchstartX; + const diffY = touch.clientY - this.touchstartY; + const absX = Math.abs(diffX); + const absY = Math.abs(diffY); + + if (!this.movestarted && absY > 5) { + this.blockmove = true; + } + if (this.blockmove) { + return; + } + + if (this.movestarted === true || absX > 5) { + this.movestarted = true; + if (this.isRtl) { + if (menu.isOpen()) { + this.diff = -sideNavW + diffX; + } else { + this.diff = diffX; + } + if (this.diff < -sideNavW) { + this.diff = -sideNavW; + } + if (this.diff > 0) { + this.diff = 0; + } + } else { + if (menu.isOpen()) { + this.diff = sideNavW + diffX; + } else { + this.diff = diffX; + } + if (this.diff > sideNavW) { + this.diff = sideNavW; + } + if (this.diff < 0) { + this.diff = 0; + } + } + if (map((this.diff / sideNavW), 0, 1, -.1, .8) > 0) { + this.sidebar.css('box-shadow', '0 0 15px 1px rgba(0,0,0,.3)'); + this.sidebarWrap.css('z-index', '9998'); + this.translate(this.diff); + } + } + } + translate(diff, width = sideNavW) { + this.sidebarWrap.css('width', '100%'); + this.wrapper.css('overflow', 'hidden'); + this.sidebarWrap.css('background-color', '#000'); + this.sidebarWrap.css('opacity', map((diff / width), 0, 1, -.1, .8).toFixed(2)); + this.sidebar.css('transform', `translate3d(${ (diff - sideNavW).toFixed(3) }px, 0 , 0`); + } + touchend(e) { + const [max, min] = [sideNavW * .76, sideNavW * .24]; + if (this.movestarted !== true) { + return; + } + this.movestarted = false; + this.mainContent[0].style.transition = null; + this.wrapper.css('overflow', ''); + if (this.isRtl) { + if (this.isOpen()) { + return this.diff >= -max ? this.close() : this.open(); + } else if (this.diff <= -min) { + return this.open(); + } + return this.close(); + } + if (this.isOpen()) { + if (this.diff >= max) { + return this.open(); + } + return this.close(); + } + if (this.diff >= min) { + return this.open(); + } + return this.close(); + } init() { - this.menu = $('.sidebar'); + this.sidebar = this.menu = $('.sidebar'); + this.sidebarWrap = $('.sidebar-wrap'); + const ignore = (fn) => (event) => document.body.clientWidth <= 780 && fn(event); + + document.body.addEventListener('touchstart', ignore((e) => this.touchstart(e))); + document.body.addEventListener('touchmove', ignore((e) => this.touchmove(e))); + document.body.addEventListener('touchend', ignore((e) => this.touchend(e))); + this.sidebarWrap.on('click', ignore((e) => { + e.target === this.sidebarWrap[0] && this.isOpen() && this.emit('clickOut', e); + })); + this.on('close', () => { + this.sidebarWrap.css('width', ''); + this.sidebarWrap.css('z-index', ''); + this.sidebarWrap.css('background-color', ''); + this.sidebar.css('transform', ''); + this.sidebar.css('box-shadow', ''); + }); + this.on('open', () => { + this.sidebar.css('box-shadow', '0 0 15px 1px rgba(0,0,0,.3)'); + this.sidebarWrap.css('z-index', '9998'); + this.translate(sideNavW); + }); this.mainContent = $('.main-content'); this.list = $('.rooms-list'); this._open = false; Session.set('isMenuOpen', this._open); - - this.mainContent[0].addEventListener('click', _.debounce(() => { - this._open && this.close(); - }, 300)); } - + closePopover() { + return this.menu.find('[data-popover="anchor"]:checked').prop('checked', false).length > 0; + } isOpen() { return Session.get('isMenuOpen'); } open() { this._open = true; Session.set('isMenuOpen', this._open); - this.mainContent && this.mainContent.css('transform', `translateX(${ isRtl(localStorage.getItem('userLanguage'))?'-':'' }${ this.sideNavW }px)`); - setTimeout(() => this.emit('open'), 10); + this.emit('open'); } close() { this._open = false; Session.set('isMenuOpen', this._open); - this.mainContent && this.mainContent .css('transform', 'translateX(0)'); - setTimeout(() => this.emit('close'), 10); + this.emit('close'); } toggle() { @@ -82,8 +202,21 @@ this.menu = new class extends EventEmitter { } }; +let passClosePopover = false; + +menu.on('clickOut', function(event) { + if (!this.closePopover()) { + passClosePopover = true; + this.close(); + } +}); + menu.on('close', function() { - this.menu.find('[data-popover="anchor"]:checked').prop('checked', false); + if (passClosePopover) { + passClosePopover = false; + return; + } + this.closePopover(); }); RocketChat.on('grid', size => {