Merge pull request #2019 from crazyserver/MOBILE-3025

MOBILE-3025 blocks: Show blocks on sidebar
main
Juan Leyva 2019-07-31 12:03:19 +02:00 committed by GitHub
commit c1147d5451
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 299 additions and 270 deletions

View File

@ -23,6 +23,12 @@ ion-app.app-root core-ion-tabs {
background-color: $ion-tabs-badge-color; background-color: $ion-tabs-badge-color;
} }
&[tabsplacement="bottom"] {
.ion-page > ion-content > .scroll-content {
margin-bottom: $navbar-md-height !important;
}
}
&[tabsplacement="side"] { &[tabsplacement="side"] {
.tabbar { .tabbar {
@include float(start); @include float(start);
@ -53,6 +59,10 @@ ion-app.app-root core-ion-tabs {
position: relative; position: relative;
} }
} }
.scroll-content, .fixed-content {
margin-bottom: 0 !important;
}
} }
} }

View File

@ -14,9 +14,8 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CoreBlockDelegate } from './providers/delegate'; import { CoreBlockDelegate } from './providers/delegate';
import { CoreBlockHelperProvider } from './providers/helper';
import { CoreBlockDefaultHandler } from './providers/default-block-handler'; import { CoreBlockDefaultHandler } from './providers/default-block-handler';
import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delegate';
import { CoreBlockCourseBlocksCourseOptionHandler } from './providers/course-option-handler';
import { CoreBlockComponentsModule } from './components/components.module'; import { CoreBlockComponentsModule } from './components/components.module';
// List of providers (without handlers). // List of providers (without handlers).
@ -31,14 +30,10 @@ export const CORE_BLOCK_PROVIDERS: any[] = [
], ],
providers: [ providers: [
CoreBlockDelegate, CoreBlockDelegate,
CoreBlockDefaultHandler, CoreBlockHelperProvider,
CoreBlockCourseBlocksCourseOptionHandler CoreBlockDefaultHandler
], ],
exports: [] exports: []
}) })
export class CoreBlockModule { export class CoreBlockModule {
constructor(courseOptionHandler: CoreBlockCourseBlocksCourseOptionHandler,
courseOptionsDelegate: CoreCourseOptionsDelegate) {
courseOptionsDelegate.registerHandler(courseOptionHandler);
}
} }

View File

@ -1,15 +1,14 @@
<ion-content> <div class="core-course-blocks-content">
<ion-refresher [enabled]="dataLoaded" (ionRefresh)="doRefresh($event)"> <ng-content></ng-content>
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> </div>
</ion-refresher>
<ion-content *ngIf="blocks && blocks.length > 0" [class.core-hide-blocks]="hideBlocks" class="core-course-blocks-side">
<core-loading [hideUntil]="dataLoaded" class="core-loading-center"> <core-loading [hideUntil]="dataLoaded" class="core-loading-center">
<ion-list *ngIf="hasSupportedBlock"> <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"></core-block> <core-block [block]="block" contextLevel="course" [instanceId]="courseId" [extraData]="{'downloadEnabled': downloadEnabled}"></core-block>
</ng-container> </ng-container>
</ion-list> </ion-list>
<core-empty-box *ngIf="!hasSupportedBlock" icon="qr-scanner" [message]="'core.course.nocontentavailable' | translate"></core-empty-box>
</core-loading> </core-loading>
</ion-content> </ion-content>

View File

@ -0,0 +1,74 @@
$core-side-blocks-max-width: 320px;
$core-side-blocks-min-width: 30%;
.core-course-block-with-blocks > .scroll-content {
overflow-y: visible;
}
ion-app.app-root core-block-course-blocks {
&.core-no-blocks {
.core-course-blocks-content > ion-content {
height: auto;
contain: content;
> .scroll-content {
overflow-y: visible;
position: relative;
contain: content;
}
}
}
&.core-has-blocks {
@include media-breakpoint-up(md) {
@include position(0, 0, 0, 0);
position: absolute;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
contain: strict;
.core-course-blocks-content {
min-width: calc(100% - #{($core-side-blocks-max-width)});
max-width: calc(100% - #{($core-side-blocks-min-width)});
z-index: 0;
flex: 1;
box-shadow: none !important;
}
ion-content.core-course-blocks-side {
transform: none !important;
position: sticky;
@include position(0, 0, 0, auto);
z-index: 30;
max-width: $core-side-blocks-max-width;
min-width: $core-side-blocks-min-width;
@include border-start(1px, solid, $list-md-border-color);
}
}
@include media-breakpoint-down(sm) {
// Disable scroll on individual columns.
.core-course-blocks-content > ion-content,
ion-content.core-course-blocks-side {
height: auto;
contain: content;
&.core-hide-blocks {
display: none;
}
> .scroll-content {
overflow-y: visible;
position: relative;
contain: content;
}
}
}
}
}

View File

@ -12,11 +12,12 @@
// 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 } from '@angular/core'; import { Component, ViewChildren, Input, OnInit, QueryList, ElementRef, Optional } from '@angular/core';
import { Content } from 'ionic-angular';
import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreBlockComponent } from '../block/block';
import { CoreBlockDelegate } from '../../providers/delegate';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreBlockComponent } from '../block/block';
import { CoreBlockHelperProvider } from '../../providers/helper';
/** /**
* Component that displays the list of course blocks. * Component that displays the list of course blocks.
@ -28,16 +29,22 @@ import { CoreCourseProvider } from '@core/course/providers/course';
export class CoreBlockCourseBlocksComponent implements OnInit { export class CoreBlockCourseBlocksComponent implements OnInit {
@Input() courseId: number; @Input() courseId: number;
@Input() hideBlocks = false;
@Input() downloadEnabled: boolean;
@ViewChildren(CoreBlockComponent) blocksComponents: QueryList<CoreBlockComponent>; @ViewChildren(CoreBlockComponent) blocksComponents: QueryList<CoreBlockComponent>;
dataLoaded = false; dataLoaded = false;
hasContent: boolean;
hasSupportedBlock: boolean;
blocks = []; blocks = [];
protected element: HTMLElement;
protected parentContent: HTMLElement;
constructor(private domUtils: CoreDomUtilsProvider, private courseProvider: CoreCourseProvider, constructor(private domUtils: CoreDomUtilsProvider, private courseProvider: CoreCourseProvider,
private blockDelegate: CoreBlockDelegate) { protected blockHelper: CoreBlockHelperProvider, element: ElementRef,
@Optional() content: Content) {
this.element = element.nativeElement;
this.parentContent = content.getElementRef().nativeElement;
} }
/** /**
@ -50,14 +57,14 @@ export class CoreBlockCourseBlocksComponent implements OnInit {
} }
/** /**
* Refresh the data. * Invalidate blocks data.
* *
* @param {any} refresher Refresher. * @return {Promise<any>} Promise resolved when done.
*/ */
doRefresh(refresher: any): void { invalidateBlocks(): Promise<any> {
const promises = []; const promises = [];
if (this.courseProvider.canGetCourseBlocks()) { if (this.blockHelper.canGetCourseBlocks()) {
promises.push(this.courseProvider.invalidateCourseBlocks(this.courseId)); promises.push(this.courseProvider.invalidateCourseBlocks(this.courseId));
} }
@ -68,11 +75,7 @@ export class CoreBlockCourseBlocksComponent implements OnInit {
})); }));
}); });
Promise.all(promises).finally(() => { return Promise.all(promises);
this.loadContent().finally(() => {
refresher.complete();
});
});
} }
/** /**
@ -80,21 +83,24 @@ export class CoreBlockCourseBlocksComponent implements OnInit {
* *
* @return {Promise<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
protected loadContent(): Promise<any> { loadContent(): Promise<any> {
// Get site home blocks. return this.blockHelper.getCourseBlocks(this.courseId).then((blocks) => {
const canGetBlocks = this.courseProvider.canGetCourseBlocks(),
promise = canGetBlocks ? this.courseProvider.getCourseBlocks(this.courseId) : Promise.reject(null);
return promise.then((blocks) => {
this.blocks = blocks; this.blocks = blocks;
this.hasSupportedBlock = this.blockDelegate.hasSupportedBlock(blocks);
}).catch((error) => { }).catch((error) => {
if (canGetBlocks) {
this.domUtils.showErrorModal(error); this.domUtils.showErrorModal(error);
}
this.blocks = [];
});
this.blocks = [];
}).finally(() => {
if (this.blocks.length > 0) {
this.element.classList.add('core-has-blocks');
this.element.classList.remove('core-no-blocks');
this.parentContent.classList.add('core-course-block-with-blocks');
} else {
this.element.classList.remove('core-has-blocks');
this.element.classList.add('core-no-blocks');
this.parentContent.classList.remove('core-course-block-with-blocks');
}
});
} }
} }

View File

@ -1,3 +1,3 @@
<ion-item-divider text-wrap detail-push (click)="gotoBlock($event)"> <ion-item-divider text-wrap detail-push (click)="gotoBlock($event)">
<h2>{{ title | translate }}</h2> <h2><core-format-text [text]="title | translate"></core-format-text></h2>
</ion-item-divider> </ion-item-divider>

View File

@ -1,91 +0,0 @@
// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreBlockCourseBlocksComponent } from '../components/course-blocks/course-blocks';
import { CoreBlockDelegate } from './delegate';
/**
* Course nav handler.
*/
@Injectable()
export class CoreBlockCourseBlocksCourseOptionHandler implements CoreCourseOptionsHandler {
name = 'CoreCourseBlocks';
priority = 700;
constructor(private courseProvider: CoreCourseProvider, private blockDelegate: CoreBlockDelegate) {}
/**
* Should invalidate the data to determine if the handler is enabled for a certain course.
*
* @param {number} courseId The course ID.
* @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
* @return {Promise<any>} Promise resolved when done.
*/
invalidateEnabledForCourse(courseId: number, navOptions?: any, admOptions?: any): Promise<any> {
return this.courseProvider.invalidateCourseBlocks(courseId);
}
/**
* Check if the handler is enabled on a site level.
*
* @return {boolean} Whether or not the handler is enabled on a site level.
*/
isEnabled(): boolean | Promise<boolean> {
return this.courseProvider.canGetCourseBlocks() && !this.blockDelegate.areBlocksDisabledInCourses();
}
/**
* Whether or not the handler is enabled for a certain course.
*
* @param {number} courseId The course ID.
* @param {any} accessData Access type and data. Default, guest, ...
* @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
*/
isEnabledForCourse(courseId: number, accessData: any, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
return this.courseProvider.getCourseBlocks(courseId).then((blocks) => {
return blocks && blocks.length > 0;
});
}
/**
* Returns the data needed to render the handler.
*
* @param {Injector} injector Injector.
* @param {number} courseId The course ID.
* @return {CoreCourseOptionsHandlerData|Promise<CoreCourseOptionsHandlerData>} Data or promise resolved with the data.
*/
getDisplayData(injector: Injector, courseId: number): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> {
return {
title: 'core.block.blocks',
class: 'core-course-blocks-handler',
component: CoreBlockCourseBlocksComponent
};
}
/**
* Called when a course is downloaded. It should prefetch all the data to be able to see the addon in offline.
*
* @param {any} course The course.
* @return {Promise<any>} Promise resolved when done.
*/
prefetch(course: any): Promise<any> {
return this.courseProvider.getCourseBlocks(course.id);
}
}

View File

@ -0,0 +1,59 @@
// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreBlockDelegate } from '@core/block/providers/delegate';
/**
* Service that provides helper functions for blocks.
*/
@Injectable()
export class CoreBlockHelperProvider {
constructor(protected courseProvider: CoreCourseProvider, protected blockDelegate: CoreBlockDelegate) {}
/**
* Return if it get course blocks options is enabled for the current site.
*
* @return {boolean} true if enabled, false otherwise.
*/
canGetCourseBlocks(): boolean {
return this.courseProvider.canGetCourseBlocks() && !this.blockDelegate.areBlocksDisabledInCourses();
}
/**
* Returns the list of blocks for the selected course.
*
* @param {number} courseId Course ID.
* @return {Promise<any>} List of supported blocks.
*/
getCourseBlocks(courseId: number): Promise<any> {
const canGetBlocks = this.canGetCourseBlocks();
if (!canGetBlocks) {
return Promise.resolve([]);
}
return this.courseProvider.getCourseBlocks(courseId).then((blocks) => {
const hasSupportedBlock = this.blockDelegate.hasSupportedBlock(blocks);
if (!hasSupportedBlock) {
return [];
}
return blocks;
});
}
}

View File

@ -18,6 +18,7 @@ import { IonicModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module'; import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives/directives.module'; import { CoreDirectivesModule } from '@directives/directives.module';
import { CoreBlockComponentsModule } from '@core/block/components/components.module';
import { CoreCourseFormatComponent } from './format/format'; import { CoreCourseFormatComponent } from './format/format';
import { CoreCourseModuleComponent } from './module/module'; import { CoreCourseModuleComponent } from './module/module';
import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion'; import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion';
@ -33,6 +34,7 @@ import { CoreCourseUnsupportedModuleComponent } from './unsupported-module/unsup
CoreCourseUnsupportedModuleComponent CoreCourseUnsupportedModuleComponent
], ],
imports: [ imports: [
CoreBlockComponentsModule,
CommonModule, CommonModule,
IonicModule, IonicModule,
TranslateModule.forChild(), TranslateModule.forChild(),

View File

@ -5,6 +5,8 @@
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>
<core-block-course-blocks [courseId]="course.id" [hideBlocks]="selectedSection && selectedSection.id == allSectionsId && canLoadMore" [downloadEnabled]="downloadEnabled">
<ion-content>
<!-- Default course format. --> <!-- Default course format. -->
<core-dynamic-component [component]="courseFormatComponent" [data]="data"> <core-dynamic-component [component]="courseFormatComponent" [data]="data">
<core-loading [hideUntil]="loaded"> <core-loading [hideUntil]="loaded">
@ -66,6 +68,8 @@
</ion-buttons> </ion-buttons>
</core-dynamic-component> </core-dynamic-component>
</ion-content>
</core-block-course-blocks>
<!-- Template to render a section. --> <!-- Template to render a section. -->
<ng-template #sectionTemplate let-section="section"> <ng-template #sectionTemplate let-section="section">

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { import {
Component, Input, OnInit, OnChanges, OnDestroy, SimpleChange, Output, EventEmitter, ViewChildren, QueryList, Injector Component, Input, OnInit, OnChanges, OnDestroy, SimpleChange, Output, EventEmitter, ViewChildren, QueryList, Injector, ViewChild
} from '@angular/core'; } from '@angular/core';
import { Content, ModalController } from 'ionic-angular'; import { Content, ModalController } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -24,6 +24,7 @@ import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreCourseFormatDelegate } from '@core/course/providers/format-delegate'; import { CoreCourseFormatDelegate } from '@core/course/providers/format-delegate';
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate'; import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
import { CoreBlockCourseBlocksComponent } from '@core/block/components/course-blocks/course-blocks';
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
/** /**
@ -52,6 +53,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
@Output() completionChanged?: EventEmitter<any>; // Will emit an event when any module completion changes. @Output() completionChanged?: EventEmitter<any>; // Will emit an event when any module completion changes.
@ViewChildren(CoreDynamicComponent) dynamicComponents: QueryList<CoreDynamicComponent>; @ViewChildren(CoreDynamicComponent) dynamicComponents: QueryList<CoreDynamicComponent>;
@ViewChild(CoreBlockCourseBlocksComponent) courseBlocksComponent: CoreBlockCourseBlocksComponent;
// All the possible component classes. // All the possible component classes.
courseFormatComponent: any; courseFormatComponent: any;
@ -420,6 +422,10 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
promises.push(Promise.resolve(component.callComponentFunction('doRefresh', [refresher, done, afterCompletionChange]))); promises.push(Promise.resolve(component.callComponentFunction('doRefresh', [refresher, done, afterCompletionChange])));
}); });
promises.push(this.courseBlocksComponent.invalidateBlocks().finally(() => {
return this.courseBlocksComponent.loadContent();
}));
return Promise.all(promises); return Promise.all(promises);
} }

View File

@ -20,6 +20,8 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreTabsComponent } from '@components/tabs/tabs';
import { CoreCoursesProvider } from '@core/courses/providers/courses';
import { CoreCourseProvider } from '../../providers/course'; import { CoreCourseProvider } from '../../providers/course';
import { CoreCourseHelperProvider } from '../../providers/helper'; import { CoreCourseHelperProvider } from '../../providers/helper';
import { CoreCourseFormatDelegate } from '../../providers/format-delegate'; import { CoreCourseFormatDelegate } from '../../providers/format-delegate';
@ -28,8 +30,6 @@ import { CoreCourseOptionsDelegate, CoreCourseOptionsHandlerToDisplay,
CoreCourseOptionsMenuHandlerToDisplay } from '../../providers/options-delegate'; CoreCourseOptionsMenuHandlerToDisplay } from '../../providers/options-delegate';
import { CoreCourseSyncProvider } from '../../providers/sync'; import { CoreCourseSyncProvider } from '../../providers/sync';
import { CoreCourseFormatComponent } from '../../components/format/format'; import { CoreCourseFormatComponent } from '../../components/format/format';
import { CoreCoursesProvider } from '@core/courses/providers/courses';
import { CoreTabsComponent } from '@components/tabs/tabs';
/** /**
* Page that displays the list of courses the user is enrolled in. * Page that displays the list of courses the user is enrolled in.

View File

@ -1,5 +1,6 @@
<core-block-course-blocks [courseId]="siteHomeId" [downloadEnabled]="downloadEnabled">
<ion-content>
<core-loading [hideUntil]="dataLoaded"> <core-loading [hideUntil]="dataLoaded">
<ion-list> <ion-list>
<!-- Site home main contents. --> <!-- Site home main contents. -->
<ng-container *ngIf="section && section.hasContent"> <ng-container *ngIf="section && section.hasContent">
@ -21,12 +22,9 @@
<core-sitehome-news *ngIf="item == 'news'"></core-sitehome-news> <core-sitehome-news *ngIf="item == 'news'"></core-sitehome-news>
</ng-container> </ng-container>
</ng-container> </ng-container>
<!-- Site home blocks. -->
<ng-container *ngFor="let block of blocks">
<core-block [block]="block" contextLevel="course" [instanceId]="siteHomeId" [extraData]="{'downloadEnabled': downloadEnabled}"></core-block>
</ng-container>
</ion-list> </ion-list>
<core-empty-box *ngIf="!hasContent && !hasSupportedBlock" icon="qr-scanner" [message]="'core.course.nocontentavailable' | translate"></core-empty-box> <core-empty-box *ngIf="!hasContent" icon="qr-scanner" [message]="'core.course.nocontentavailable' | translate"></core-empty-box>
</core-loading> </core-loading>
</ion-content>
</core-block-course-blocks>

View File

@ -12,14 +12,13 @@
// 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, OnInit, ViewChildren, QueryList, Input } from '@angular/core'; import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate'; import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
import { CoreBlockDelegate } from '@core/block/providers/delegate'; import { CoreBlockCourseBlocksComponent } from '@core/block/components/course-blocks/course-blocks';
import { CoreBlockComponent } from '@core/block/components/block/block';
import { CoreSite } from '@classes/site'; import { CoreSite } from '@classes/site';
/** /**
@ -30,21 +29,19 @@ import { CoreSite } from '@classes/site';
templateUrl: 'core-sitehome-index.html', templateUrl: 'core-sitehome-index.html',
}) })
export class CoreSiteHomeIndexComponent implements OnInit { export class CoreSiteHomeIndexComponent implements OnInit {
@ViewChildren(CoreBlockComponent) blocksComponents: QueryList<CoreBlockComponent>;
@Input() downloadEnabled: boolean; @Input() downloadEnabled: boolean;
@ViewChild(CoreBlockCourseBlocksComponent) courseBlocksComponent: CoreBlockCourseBlocksComponent;
dataLoaded = false; dataLoaded = false;
section: any; section: any;
hasContent: boolean; hasContent: boolean;
hasSupportedBlock: boolean;
items: any[] = []; items: any[] = [];
siteHomeId: number; siteHomeId: number;
currentSite: CoreSite; currentSite: CoreSite;
blocks = [];
constructor(private domUtils: CoreDomUtilsProvider, sitesProvider: CoreSitesProvider, constructor(private domUtils: CoreDomUtilsProvider, sitesProvider: CoreSitesProvider,
private courseProvider: CoreCourseProvider, private courseHelper: CoreCourseHelperProvider, private courseProvider: CoreCourseProvider, private courseHelper: CoreCourseHelperProvider,
private prefetchDelegate: CoreCourseModulePrefetchDelegate, private blockDelegate: CoreBlockDelegate) { private prefetchDelegate: CoreCourseModulePrefetchDelegate) {
this.currentSite = sitesProvider.getCurrentSite(); this.currentSite = sitesProvider.getCurrentSite();
this.siteHomeId = this.currentSite.getSiteHomeId(); this.siteHomeId = this.currentSite.getSiteHomeId();
} }
@ -79,19 +76,15 @@ export class CoreSiteHomeIndexComponent implements OnInit {
promises.push(this.prefetchDelegate.invalidateModules(this.section.modules, this.siteHomeId)); promises.push(this.prefetchDelegate.invalidateModules(this.section.modules, this.siteHomeId));
} }
if (this.courseProvider.canGetCourseBlocks()) { promises.push(this.courseBlocksComponent.invalidateBlocks());
promises.push(this.courseProvider.invalidateCourseBlocks(this.siteHomeId));
}
// Invalidate the blocks.
this.blocksComponents.forEach((blockComponent) => {
promises.push(blockComponent.invalidate().catch(() => {
// Ignore errors.
}));
});
Promise.all(promises).finally(() => { Promise.all(promises).finally(() => {
this.loadContent().finally(() => { const p2 = [];
p2.push(this.loadContent());
p2.push(this.courseBlocksComponent.loadContent());
return Promise.all(p2).finally(() => {
refresher.complete(); refresher.complete();
}); });
}); });
@ -149,32 +142,6 @@ export class CoreSiteHomeIndexComponent implements OnInit {
this.currentSite && this.currentSite.getInfo().sitename).catch(() => { this.currentSite && this.currentSite.getInfo().sitename).catch(() => {
// Ignore errors. // Ignore errors.
}); });
// Get site home blocks.
const canGetBlocks = this.courseProvider.canGetCourseBlocks(),
promise = canGetBlocks ? this.courseProvider.getCourseBlocks(this.siteHomeId) : Promise.reject(null);
return promise.then((blocks) => {
this.blocks = blocks;
this.hasSupportedBlock = this.blockDelegate.hasSupportedBlock(blocks);
}).catch((error) => {
if (canGetBlocks) {
this.domUtils.showErrorModal(error);
}
this.blocks = [];
// Cannot get the blocks, just show site main menu if needed.
const section = sections.find((section) => section.section == 0);
if (section && this.courseHelper.sectionHasContent(section)) {
this.blocks.push({
name: 'site_main_menu'
});
this.hasSupportedBlock = true;
} else {
this.hasSupportedBlock = false;
}
});
}).catch((error) => { }).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'core.course.couldnotloadsectioncontent', true); this.domUtils.showErrorModalDefault(error, 'core.course.couldnotloadsectioncontent', true);
}); });