Merge pull request #7898 from opf/feature/scroll-mobile-header

[31699] Feature: Scroll mobile header with content
pull/7923/head
Henriette Dinger 5 years ago committed by GitHub
commit 40fdee5a1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/assets/stylesheets/layout/_base.sass
  2. 12
      app/assets/stylesheets/layout/_base_mobile.sass
  3. 8
      app/assets/stylesheets/layout/_top_menu_mobile.sass
  4. 8
      frontend/src/app/globals/global-listeners.ts
  5. 53
      frontend/src/app/globals/global-listeners/top-menu-scroll.ts
  6. 6
      frontend/src/app/modules/work_packages/routing/wp-list/wp-list.component.ts

@ -32,7 +32,6 @@
display: grid
grid-template-rows: auto 1fr
#main
display: grid
grid-template-columns: auto 1fr

@ -36,6 +36,18 @@
#main-menu ~ #content-wrapper
padding: 15px
#content-wrapper
transition: height .4s
// Slide header in and out on scroll (see also: _top_menu_mobile.sass)
.-header-scrolled &
height: 100vh
body.-browser-safari
#content-wrapper
// Needed for smooth scrolling on Safari mobile
transition: height 0s
#main
grid-template-columns: auto

@ -34,6 +34,14 @@
background-color: transparent
#top-menu
margin-top: 0px
transition: margin-top .4s
// Slide header in and out on scroll (see also: _base_mobile.sass)
.-header-scrolled &
margin-top: -55px
transition: margin-top .4s
#nav-login-content
float: none
padding: 15px 20px

@ -30,6 +30,8 @@ import {performAnchorHijacking} from "./global-listeners/link-hijacking";
import {augmentedDatePicker} from "./global-listeners/augmented-date-picker";
import {refreshOnFormChanges} from 'core-app/globals/global-listeners/refresh-on-form-changes';
import {registerRequestForConfirmation} from "core-app/globals/global-listeners/request-for-confirmation";
import {DeviceService} from "core-app/modules/common/browser/device.service";
import {scrollHeaderOnMobile} from "core-app/globals/global-listeners/top-menu-scroll";
/**
* A set of listeners that are relevant on every page to set sensible defaults
@ -94,6 +96,12 @@ import {registerRequestForConfirmation} from "core-app/globals/global-listeners/
// Allow forms with [request-for-confirmation]
// to show the password confirmation dialog
registerRequestForConfirmation($);
const deviceService:DeviceService = new DeviceService();
// Register scroll handler on mobile header
if (deviceService.isMobile) {
scrollHeaderOnMobile(jQuery('#content-wrapper'));
}
});
}(jQuery));

@ -0,0 +1,53 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
// ++
// Scroll header on mobile in and out when user scrolls the container
export function scrollHeaderOnMobile(elem:JQuery) {
const headerHeight = 55;
let prevScrollPos = elem.scrollTop()!;
elem.on('scroll', function() {
// Condition needed for safari browser to avoid negative positions
let currentScrollPos = elem.scrollTop()! < 0 ? 0 : elem.scrollTop()!;
// Only if sidebar is not opened or search bar is opened
if (!(jQuery('#main').hasClass('hidden-navigation')) ||
jQuery('#top-menu').hasClass('-global-search-expanded') ||
Math.abs(currentScrollPos - prevScrollPos) <= headerHeight) { // to avoid flickering at the end of the page
return;
}
if (prevScrollPos !== undefined && currentScrollPos !== undefined && (prevScrollPos > currentScrollPos)) {
// Slide top menu in or out of viewport and change viewport height
jQuery('#wrapper').removeClass('-header-scrolled');
} else {
jQuery('#wrapper').addClass('-header-scrolled');
}
prevScrollPos = currentScrollPos;
});
}

@ -39,6 +39,7 @@ import {wpDisplayCardRepresentation} from "core-app/modules/work_packages/routin
import {WorkPackageTableConfigurationObject} from "core-components/wp-table/wp-table-configuration";
import {HalResourceNotificationService} from "core-app/modules/hal/services/hal-resource-notification.service";
import {WorkPackageNotificationService} from "core-app/modules/work_packages/notifications/work-package-notification.service";
import {scrollHeaderOnMobile} from "core-app/globals/global-listeners/top-menu-scroll";
@Component({
selector: 'wp-list',
@ -132,6 +133,11 @@ export class WorkPackagesListComponent extends WorkPackagesViewBase implements O
}
this.cdRef.detectChanges();
// Register scroll handler on mobile header
if (this.deviceService.isMobile) {
scrollHeaderOnMobile(jQuery('.work-packages--card-view-container'));
}
});
}

Loading…
Cancel
Save