MOBILE-3025 blocks: Rollback scroll follow implementation
parent
51403efcca
commit
6269849dff
|
@ -3,14 +3,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="blocks && blocks.length > 0" [class.core-hide-blocks]="hideBlocks" class="core-course-blocks-side">
|
<div *ngIf="blocks && blocks.length > 0" [class.core-hide-blocks]="hideBlocks" class="core-course-blocks-side">
|
||||||
<div class="core-course-blocks-side-scroll">
|
<core-loading [hideUntil]="dataLoaded" class="core-loading-center">
|
||||||
<core-loading [hideUntil]="dataLoaded" class="core-loading-center">
|
<ion-list>
|
||||||
<ion-list>
|
<!-- Course blocks. -->
|
||||||
<!-- Course blocks. -->
|
<ng-container *ngFor="let block of blocks">
|
||||||
<ng-container *ngFor="let block of blocks">
|
<core-block [block]="block" contextLevel="course" [instanceId]="courseId" [extraData]="{'downloadEnabled': downloadEnabled}"></core-block>
|
||||||
<core-block [block]="block" contextLevel="course" [instanceId]="courseId" [extraData]="{'downloadEnabled': downloadEnabled}"></core-block>
|
</ng-container>
|
||||||
</ng-container>
|
</ion-list>
|
||||||
</ion-list>
|
</core-loading>
|
||||||
</core-loading>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,10 +13,6 @@ ion-app.app-root core-block-course-blocks {
|
||||||
|
|
||||||
&.core-has-blocks {
|
&.core-has-blocks {
|
||||||
@include media-breakpoint-up(md) {
|
@include media-breakpoint-up(md) {
|
||||||
@include position(0, 0, 0, 0);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -29,46 +25,20 @@ ion-app.app-root core-block-course-blocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
div.core-course-blocks-side {
|
div.core-course-blocks-side {
|
||||||
position: relative;
|
|
||||||
@include position(auto, 0, auto, auto);
|
|
||||||
max-width: $core-side-blocks-max-width;
|
max-width: $core-side-blocks-max-width;
|
||||||
min-width: $core-side-blocks-min-width;
|
min-width: $core-side-blocks-min-width;
|
||||||
@include border-start(1px, solid, $list-md-border-color);
|
@include border-start(1px, solid, $list-md-border-color);
|
||||||
|
|
||||||
.core-course-blocks-side-scroll {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
min-width: 100%;
|
|
||||||
|
|
||||||
&.core-course-blocks-fixed-bottom {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
top: auto;
|
|
||||||
transform: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
core-block {
|
|
||||||
max-width: $core-side-blocks-max-width;
|
|
||||||
min-width: $core-side-blocks-min-width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-down(sm) {
|
@include media-breakpoint-down(sm) {
|
||||||
// Disable scroll on individual columns.
|
// Disable scroll on individual columns.
|
||||||
div.core-course-blocks-side {
|
div.core-course-blocks-side {
|
||||||
transform: none !important;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
||||||
&.core-hide-blocks {
|
&.core-hide-blocks {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-course-blocks-side-scroll {
|
|
||||||
transform: none !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,9 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, ViewChildren, Input, OnInit, QueryList, ElementRef, OnDestroy } from '@angular/core';
|
import { Component, ViewChildren, Input, OnInit, QueryList, ElementRef } from '@angular/core';
|
||||||
import { Content } from 'ionic-angular';
|
import { Content } from 'ionic-angular';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
|
||||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||||
import { CoreBlockComponent } from '../block/block';
|
import { CoreBlockComponent } from '../block/block';
|
||||||
import { CoreBlockHelperProvider } from '../../providers/helper';
|
import { CoreBlockHelperProvider } from '../../providers/helper';
|
||||||
|
@ -27,7 +26,7 @@ import { CoreBlockHelperProvider } from '../../providers/helper';
|
||||||
selector: 'core-block-course-blocks',
|
selector: 'core-block-course-blocks',
|
||||||
templateUrl: 'core-block-course-blocks.html',
|
templateUrl: 'core-block-course-blocks.html',
|
||||||
})
|
})
|
||||||
export class CoreBlockCourseBlocksComponent implements OnInit, OnDestroy {
|
export class CoreBlockCourseBlocksComponent implements OnInit {
|
||||||
|
|
||||||
@Input() courseId: number;
|
@Input() courseId: number;
|
||||||
@Input() hideBlocks = false;
|
@Input() hideBlocks = false;
|
||||||
|
@ -39,16 +38,10 @@ export class CoreBlockCourseBlocksComponent implements OnInit, OnDestroy {
|
||||||
blocks = [];
|
blocks = [];
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
protected lastScroll;
|
|
||||||
protected translationY = 0;
|
|
||||||
protected blocksScrollHeight = 0;
|
|
||||||
protected sideScroll: HTMLElement;
|
|
||||||
protected vpHeight = 0; // Viewport height.
|
|
||||||
protected scrollWorking = false;
|
|
||||||
|
|
||||||
constructor(private domUtils: CoreDomUtilsProvider, private courseProvider: CoreCourseProvider,
|
constructor(private domUtils: CoreDomUtilsProvider, private courseProvider: CoreCourseProvider,
|
||||||
protected blockHelper: CoreBlockHelperProvider, element: ElementRef,
|
protected blockHelper: CoreBlockHelperProvider, element: ElementRef,
|
||||||
protected content: Content, protected appProvider: CoreAppProvider) {
|
protected content: Content) {
|
||||||
this.element = element.nativeElement;
|
this.element = element.nativeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,83 +51,9 @@ export class CoreBlockCourseBlocksComponent implements OnInit, OnDestroy {
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.loadContent().finally(() => {
|
this.loadContent().finally(() => {
|
||||||
this.dataLoaded = true;
|
this.dataLoaded = true;
|
||||||
|
|
||||||
window.addEventListener('resize', this.initScroll.bind(this));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup scrolling.
|
|
||||||
*/
|
|
||||||
protected initScroll(): void {
|
|
||||||
if (this.blocks.length <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scroll: HTMLElement = this.content && this.content.getScrollElement();
|
|
||||||
|
|
||||||
this.domUtils.waitElementToExist(() => scroll && scroll.querySelector('.core-course-blocks-side')).then((sideElement) => {
|
|
||||||
const contentHeight = parseInt(this.content.getNativeElement().querySelector('.scroll-content').scrollHeight, 10);
|
|
||||||
|
|
||||||
this.sideScroll = scroll.querySelector('.core-course-blocks-side-scroll');
|
|
||||||
this.blocksScrollHeight = this.sideScroll.scrollHeight;
|
|
||||||
this.vpHeight = sideElement.clientHeight;
|
|
||||||
|
|
||||||
// Check if needed and event was not init before.
|
|
||||||
if (this.appProvider.isWide() && this.vpHeight && contentHeight > this.vpHeight &&
|
|
||||||
this.blocksScrollHeight > this.vpHeight) {
|
|
||||||
if (typeof this.lastScroll == 'undefined') {
|
|
||||||
this.lastScroll = 0;
|
|
||||||
scroll.addEventListener('scroll', this.scrollFunction.bind(this));
|
|
||||||
}
|
|
||||||
this.scrollWorking = true;
|
|
||||||
} else {
|
|
||||||
this.sideScroll.style.transform = 'translate(0, 0)';
|
|
||||||
this.sideScroll.classList.remove('core-course-blocks-fixed-bottom');
|
|
||||||
this.scrollWorking = false;
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
// Ignore errors.
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll function that moves the sidebar if needed.
|
|
||||||
*
|
|
||||||
* @param {Event} e Event to get the target from.
|
|
||||||
*/
|
|
||||||
protected scrollFunction(e: Event): void {
|
|
||||||
if (!this.scrollWorking) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const target: any = e.target,
|
|
||||||
top = parseInt(target.scrollTop, 10),
|
|
||||||
goingUp = top < this.lastScroll;
|
|
||||||
if (goingUp) {
|
|
||||||
this.sideScroll.classList.remove('core-course-blocks-fixed-bottom');
|
|
||||||
if (top <= this.translationY ) {
|
|
||||||
// Fixed to top.
|
|
||||||
this.translationY = top;
|
|
||||||
this.sideScroll.style.transform = 'translate(0, ' + this.translationY + 'px)';
|
|
||||||
}
|
|
||||||
} else if (top - this.translationY >= (this.blocksScrollHeight - this.vpHeight)) {
|
|
||||||
// Fixed to bottom.
|
|
||||||
this.sideScroll.classList.add('core-course-blocks-fixed-bottom');
|
|
||||||
this.translationY = top - (this.blocksScrollHeight - this.vpHeight);
|
|
||||||
this.sideScroll.style.transform = 'translate(0, ' + this.translationY + 'px)';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lastScroll = top;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component destroyed.
|
|
||||||
*/
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
window.removeEventListener('resize', this.initScroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate blocks data.
|
* Invalidate blocks data.
|
||||||
*
|
*
|
||||||
|
@ -175,8 +94,6 @@ export class CoreBlockCourseBlocksComponent implements OnInit, OnDestroy {
|
||||||
this.element.classList.remove('core-no-blocks');
|
this.element.classList.remove('core-no-blocks');
|
||||||
|
|
||||||
this.content.getElementRef().nativeElement.classList.add('core-course-block-with-blocks');
|
this.content.getElementRef().nativeElement.classList.add('core-course-block-with-blocks');
|
||||||
|
|
||||||
this.initScroll();
|
|
||||||
} else {
|
} else {
|
||||||
this.element.classList.remove('core-has-blocks');
|
this.element.classList.remove('core-has-blocks');
|
||||||
this.element.classList.add('core-no-blocks');
|
this.element.classList.add('core-no-blocks');
|
||||||
|
|
Loading…
Reference in New Issue