MOBILE-3833 core: Fix movement of the navigation bar

main
Pau Ferrer Ocaña 2021-12-09 12:29:01 +01:00
parent bb2361458a
commit c666d3f36b
3 changed files with 34 additions and 20 deletions

View File

@ -495,7 +495,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
/** /**
* Set the new message badge number and set scroll listener if needed. * Set the new message badge number and set scroll listener if needed.
* *
* @param addMessages NUmber of messages still to be read. * @param addMessages Number of messages still to be read.
*/ */
protected setNewMessagesBadge(addMessages: number): void { protected setNewMessagesBadge(addMessages: number): void {
if (this.newMessages == 0 && addMessages > 0) { if (this.newMessages == 0 && addMessages > 0) {

View File

@ -23,6 +23,7 @@ import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreMath } from '@singletons/math';
/** /**
* Component to show a button to go to the next resource/activity. * Component to show a button to go to the next resource/activity.
@ -50,6 +51,8 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
protected initialHeight = 0; protected initialHeight = 0;
protected initialPaddingBottom = 0; protected initialPaddingBottom = 0;
protected previousTop = 0; protected previousTop = 0;
protected previousHeight = 0;
protected stickTimeout?: number;
protected content?: HTMLIonContentElement | null; protected content?: HTMLIonContentElement | null;
protected completionObserver: CoreEventObserver; protected completionObserver: CoreEventObserver;
@ -102,6 +105,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
} }
// Set a minimum height value. // Set a minimum height value.
this.initialHeight = this.initialHeight || 56; this.initialHeight = this.initialHeight || 56;
this.previousHeight = this.initialHeight;
this.content = this.element.closest('ion-content'); this.content = this.element.closest('ion-content');
@ -118,6 +122,8 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
return; return;
} }
this.content.classList.add('has-core-course-module-navigation');
// Move element to the nearest ion-content if it's not the parent. // Move element to the nearest ion-content if it's not the parent.
if (this.element.parentElement?.nodeName != 'ION-CONTENT') { if (this.element.parentElement?.nodeName != 'ION-CONTENT') {
this.content.appendChild(this.element); this.content.appendChild(this.element);
@ -135,7 +141,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
return; return;
} }
this.onScroll(e.detail.scrollTop, scroll.scrollHeight - scroll.offsetHeight); this.onScroll(e.detail, scroll);
}); });
} }
@ -304,19 +310,21 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
/** /**
* On scroll function. * On scroll function.
* *
* @param top Scroll top measure. * @param scrollDetail Scroll detail object.
* @param maxScroll Scroll height. * @param scrollElement Scroll element to calculate maxScroll.
*/ */
protected onScroll(top: number, maxScroll: number): void { protected onScroll(scrollDetail: ScrollDetail, scrollElement: HTMLElement): void {
if (top == 0 || top == maxScroll) { const maxScroll = scrollElement.scrollHeight - scrollElement.offsetHeight;
if (scrollDetail.scrollTop <= 0 || scrollDetail.scrollTop >= maxScroll) {
// Reset. // Reset.
this.setBarHeight(this.initialHeight); this.setBarHeight(this.initialHeight);
} else { } else {
const diffHeight = this.element.clientHeight - (top - this.previousTop); let newHeight = this.previousHeight - (scrollDetail.scrollTop - this.previousTop);
this.setBarHeight(diffHeight); newHeight = CoreMath.clamp(newHeight, 0, this.initialHeight);
}
this.previousTop = top; this.setBarHeight(newHeight);
}
this.previousTop = scrollDetail.scrollTop;
} }
/** /**
@ -325,14 +333,20 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
* @param height The new bar height. * @param height The new bar height.
*/ */
protected setBarHeight(height: number): void { protected setBarHeight(height: number): void {
if (height <= 0) { if (this.stickTimeout) {
height = 0; clearTimeout(this.stickTimeout);
} else if (height > this.initialHeight) {
height = this.initialHeight;
} }
this.element.style.opacity = height == 0 ? '0' : '1'; this.element.style.opacity = height <= 0 ? '0' : '1';
this.content?.style.setProperty('--core-course-module-navigation-height', height + 'px'); this.content?.style.setProperty('--core-course-module-navigation-height', height + 'px');
this.previousHeight = height;
if (height > 0 && height < this.initialHeight) {
// Finish opening or closing the bar.
const newHeight = height < this.initialHeight / 2 ? 0 : this.initialHeight;
this.stickTimeout = window.setTimeout(() => this.setBarHeight(newHeight), 500);
}
} }
} }

View File

@ -913,7 +913,7 @@ ion-fab[core-fab] {
} }
} }
core-course-module-navigation + ion-fab { ion-content.has-core-course-module-navigation ion-fab {
bottom: calc(var(--core-course-module-navigation-height, 0px) + 10px); bottom: calc(var(--core-course-module-navigation-height, 0px) + 10px);
@include core-transition(all, 200ms); @include core-transition(all, 200ms);
} }