commit
c3fc445f39
|
@ -29,9 +29,7 @@
|
||||||
</a>
|
</a>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
|
||||||
<ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(fetchEvents())">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreEvents($event)"></core-infinite-loading>
|
||||||
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
|
||||||
</ion-infinite-scroll>
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
</core-split-view>
|
</core-split-view>
|
|
@ -179,6 +179,18 @@ export class AddonCalendarListPage implements OnDestroy {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to load more events.
|
||||||
|
*
|
||||||
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
|
* @return {Promise<any>} Resolved when done.
|
||||||
|
*/
|
||||||
|
loadMoreEvents(infiniteComplete?: any): Promise<any> {
|
||||||
|
return this.fetchEvents().finally(() => {
|
||||||
|
infiniteComplete && infiniteComplete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get filtered events.
|
* Get filtered events.
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
<ion-content class="has-footer">
|
<ion-content class="has-footer">
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<!-- Load previous messages. -->
|
<!-- Load previous messages. -->
|
||||||
<ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="loadPrevious($event)" position="top">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadPrevious($event)" position="top"></core-infinite-loading>
|
||||||
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
|
||||||
</ion-infinite-scroll>
|
|
||||||
<ion-list class="addon-messages-discussion-container" [attr.aria-live]="polite">
|
<ion-list class="addon-messages-discussion-container" [attr.aria-live]="polite">
|
||||||
<ng-container *ngFor="let message of messages; index as index; last as last">
|
<ng-container *ngFor="let message of messages; index as index; last as last">
|
||||||
<ion-chip *ngIf="showDate(message, messages[index - 1])" class="addon-messages-date" color="light">
|
<ion-chip *ngIf="showDate(message, messages[index - 1])" class="addon-messages-date" color="light">
|
||||||
|
|
|
@ -543,10 +543,10 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
/**
|
/**
|
||||||
* Function to load previous messages.
|
* Function to load previous messages.
|
||||||
*
|
*
|
||||||
* @param {any} [infiniteScroll] Infinite scroll object.
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
* @return {Promise<any>} Resolved when done.
|
* @return {Promise<any>} Resolved when done.
|
||||||
*/
|
*/
|
||||||
loadPrevious(infiniteScroll: any): Promise<any> {
|
loadPrevious(infiniteComplete?: any): Promise<any> {
|
||||||
// If there is an ongoing fetch, wait for it to finish.
|
// If there is an ongoing fetch, wait for it to finish.
|
||||||
return this.waitForFetch().finally(() => {
|
return this.waitForFetch().finally(() => {
|
||||||
this.pagesLoaded++;
|
this.pagesLoaded++;
|
||||||
|
@ -555,7 +555,7 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
this.pagesLoaded--;
|
this.pagesLoaded--;
|
||||||
this.domUtils.showErrorModalDefault(error, 'addon.messages.errorwhileretrievingmessages', true);
|
this.domUtils.showErrorModalDefault(error, 'addon.messages.errorwhileretrievingmessages', true);
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
infiniteScroll.complete();
|
infiniteComplete && infiniteComplete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,9 +88,7 @@
|
||||||
</div>
|
</div>
|
||||||
</core-empty-box>
|
</core-empty-box>
|
||||||
|
|
||||||
<ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(fetchMoreDiscussions())">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="fetchMoreDiscussions($event)"></core-infinite-loading>
|
||||||
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
|
||||||
</ion-infinite-scroll>
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<ion-fab bottom end *ngIf="forum && forum.cancreatediscussions">
|
<ion-fab bottom end *ngIf="forum && forum.cancreatediscussions">
|
||||||
|
|
|
@ -305,13 +305,16 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
/**
|
/**
|
||||||
* Convenience function to load more forum discussions.
|
* Convenience function to load more forum discussions.
|
||||||
*
|
*
|
||||||
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
* @return {Promise<any>} Promise resolved when done.
|
* @return {Promise<any>} Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected fetchMoreDiscussions(): Promise<any> {
|
fetchMoreDiscussions(infiniteComplete?: any): Promise<any> {
|
||||||
return this.fetchDiscussions(false).catch((message) => {
|
return this.fetchDiscussions(false).catch((message) => {
|
||||||
this.domUtils.showErrorModalDefault(message, 'addon.mod_forum.errorgetforum', true);
|
this.domUtils.showErrorModalDefault(message, 'addon.mod_forum.errorgetforum', true);
|
||||||
|
|
||||||
this.canLoadMore = false; // Set to false to prevent infinite calls with infinite-loading.
|
this.canLoadMore = false; // Set to false to prevent infinite calls with infinite-loading.
|
||||||
|
}).finally(() => {
|
||||||
|
infiniteComplete && infiniteComplete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,7 @@
|
||||||
|
|
||||||
<core-empty-box *ngIf="!entries.length && !offlineEntries.length" icon="list" [message]="'addon.mod_glossary.noentriesfound' | translate"></core-empty-box>
|
<core-empty-box *ngIf="!entries.length && !offlineEntries.length" icon="list" [message]="'addon.mod_glossary.noentriesfound' | translate"></core-empty-box>
|
||||||
|
|
||||||
<ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(loadMoreEntries())">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreEntries($event)"></core-infinite-loading>
|
||||||
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
|
||||||
</ion-infinite-scroll>
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<ion-fab bottom end *ngIf="canAdd">
|
<ion-fab bottom end *ngIf="canAdd">
|
||||||
|
|
|
@ -289,11 +289,14 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
|
||||||
/**
|
/**
|
||||||
* Convenience function to load more forum discussions.
|
* Convenience function to load more forum discussions.
|
||||||
*
|
*
|
||||||
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
* @return {Promise<any>} Promise resolved when done.
|
* @return {Promise<any>} Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
loadMoreEntries(): Promise<any> {
|
loadMoreEntries(infiniteComplete?: any): Promise<any> {
|
||||||
return this.fetchEntries(true).catch((error) => {
|
return this.fetchEntries(true).catch((error) => {
|
||||||
this.domUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingentries', true);
|
this.domUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingentries', true);
|
||||||
|
}).finally(() => {
|
||||||
|
infiniteComplete && infiniteComplete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
<addon-notifications-actions [contextUrl]="notification.contexturl" [courseId]="notification.courseid"></addon-notifications-actions>
|
<addon-notifications-actions [contextUrl]="notification.contexturl" [courseId]="notification.courseid"></addon-notifications-actions>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
<core-empty-box *ngIf="!notifications || notifications.length <= 0" icon="notifications" [message]="'addon.notifications.therearentnotificationsyet' | translate"></core-empty-box>
|
<core-empty-box *ngIf="!notifications || notifications.length <= 0" icon="notifications" [message]="'addon.notifications.therearentnotificationsyet' | translate"></core-empty-box>
|
||||||
<ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="loadMoreNotifications($event)">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreNotifications($event)"></core-infinite-loading>
|
||||||
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
|
||||||
</ion-infinite-scroll>
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -204,11 +204,11 @@ export class AddonNotificationsListPage {
|
||||||
/**
|
/**
|
||||||
* Load more results.
|
* Load more results.
|
||||||
*
|
*
|
||||||
* @param {any} infiniteScroll The infinit scroll instance.
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
*/
|
*/
|
||||||
loadMoreNotifications(infiniteScroll: any): void {
|
loadMoreNotifications(infiniteComplete?: any): void {
|
||||||
this.fetchNotifications().finally(() => {
|
this.fetchNotifications().finally(() => {
|
||||||
infiniteScroll.complete();
|
infiniteComplete && infiniteComplete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ import { CoreNavigationBarComponent } from './navigation-bar/navigation-bar';
|
||||||
import { CoreAttachmentsComponent } from './attachments/attachments';
|
import { CoreAttachmentsComponent } from './attachments/attachments';
|
||||||
import { CoreIonTabsComponent } from './ion-tabs/ion-tabs';
|
import { CoreIonTabsComponent } from './ion-tabs/ion-tabs';
|
||||||
import { CoreIonTabComponent } from './ion-tabs/ion-tab';
|
import { CoreIonTabComponent } from './ion-tabs/ion-tab';
|
||||||
|
import { CoreInfiniteLoadingComponent } from './infinite-loading/infinite-loading';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -83,7 +84,8 @@ import { CoreIonTabComponent } from './ion-tabs/ion-tab';
|
||||||
CoreNavigationBarComponent,
|
CoreNavigationBarComponent,
|
||||||
CoreAttachmentsComponent,
|
CoreAttachmentsComponent,
|
||||||
CoreIonTabsComponent,
|
CoreIonTabsComponent,
|
||||||
CoreIonTabComponent
|
CoreIonTabComponent,
|
||||||
|
CoreInfiniteLoadingComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
CoreContextMenuPopoverComponent,
|
CoreContextMenuPopoverComponent,
|
||||||
|
@ -125,7 +127,8 @@ import { CoreIonTabComponent } from './ion-tabs/ion-tab';
|
||||||
CoreNavigationBarComponent,
|
CoreNavigationBarComponent,
|
||||||
CoreAttachmentsComponent,
|
CoreAttachmentsComponent,
|
||||||
CoreIonTabsComponent,
|
CoreIonTabsComponent,
|
||||||
CoreIonTabComponent
|
CoreIonTabComponent,
|
||||||
|
CoreInfiniteLoadingComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class CoreComponentsModule {}
|
export class CoreComponentsModule {}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<div *ngIf="enabled && !loadingMore && position != 'top'" padding-horizontal>
|
||||||
|
<button ion-button block (click)="loadMore()" color="light">
|
||||||
|
{{'core.loadmore' | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ion-infinite-scroll [enabled]="enabled && !loadingMore" (ionInfinite)="loadMore($event)" [position]="position">
|
||||||
|
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
||||||
|
</ion-infinite-scroll>
|
||||||
|
|
||||||
|
<div *ngIf="enabled && !loadingMore && position == 'top'" padding-horizontal>
|
||||||
|
<button ion-button block (click)="loadMore()" color="light">
|
||||||
|
{{'core.loadmore' | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="loadingMore" padding text-center>
|
||||||
|
<ion-spinner></ion-spinner>
|
||||||
|
</div>
|
|
@ -0,0 +1,68 @@
|
||||||
|
// (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 { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { InfiniteScroll } from 'ionic-angular';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to show a infinite loading trigger and spinner while more data is being loaded.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* <core-infinite-loading [action]="loadingAction" [enabled]="dataLoaded"></core-inifinite-loading>
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'core-infinite-loading',
|
||||||
|
templateUrl: 'core-infinite-loading.html',
|
||||||
|
})
|
||||||
|
export class CoreInfiniteLoadingComponent {
|
||||||
|
@Input() enabled: boolean;
|
||||||
|
@Input() position = 'bottom';
|
||||||
|
@Output() action: EventEmitter<() => void>; // Will emit an event when triggered.
|
||||||
|
|
||||||
|
loadingMore = false; // Hide button and avoid loading more.
|
||||||
|
|
||||||
|
protected infiniteScroll: InfiniteScroll;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.action = new EventEmitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load More items calling the action provided.
|
||||||
|
*
|
||||||
|
* @param {InfiniteScroll} [infiniteScroll] Infinite scroll object only if triggered from the scroll.
|
||||||
|
*/
|
||||||
|
loadMore(infiniteScroll?: InfiniteScroll): void {
|
||||||
|
if (this.loadingMore) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (infiniteScroll) {
|
||||||
|
this.infiniteScroll = infiniteScroll;
|
||||||
|
}
|
||||||
|
this.loadingMore = true;
|
||||||
|
|
||||||
|
this.action.emit(this.complete.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete loading.
|
||||||
|
*/
|
||||||
|
complete(): void {
|
||||||
|
this.loadingMore = false;
|
||||||
|
this.infiniteScroll && this.infiniteScroll.complete();
|
||||||
|
this.infiniteScroll = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -44,10 +44,14 @@
|
||||||
<!-- Multiple sections. -->
|
<!-- Multiple sections. -->
|
||||||
<div *ngIf="selectedSection && selectedSection.id == allSectionsId">
|
<div *ngIf="selectedSection && selectedSection.id == allSectionsId">
|
||||||
<core-dynamic-component [component]="allSectionsComponent" [data]="data">
|
<core-dynamic-component [component]="allSectionsComponent" [data]="data">
|
||||||
<ng-container *ngFor="let section of sections">
|
<ng-container *ngFor="let section of sections; index as i">
|
||||||
|
<ng-container *ngIf="i <= showSectionId">
|
||||||
<ng-container *ngTemplateOutlet="sectionTemplate; context: {section: section}"></ng-container>
|
<ng-container *ngTemplateOutlet="sectionTemplate; context: {section: section}"></ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
</core-dynamic-component>
|
</core-dynamic-component>
|
||||||
|
|
||||||
|
<core-infinite-loading [enabled]="canLoadMore" (action)="showMoreActivities($event)"></core-infinite-loading>
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
<ion-buttons padding end class="core-course-section-nav-buttons" *ngIf="displaySectionSelector && sections && sections.length">
|
<ion-buttons padding end class="core-course-section-nav-buttons" *ngIf="displaySectionSelector && sections && sections.length">
|
||||||
|
|
|
@ -41,6 +41,8 @@ import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-comp
|
||||||
templateUrl: 'core-course-format.html'
|
templateUrl: 'core-course-format.html'
|
||||||
})
|
})
|
||||||
export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
static LOAD_MORE_ACTIVITIES = 20; // How many activities should load each time showMoreActivities is called.
|
||||||
|
|
||||||
@Input() course: any; // The course to render.
|
@Input() course: any; // The course to render.
|
||||||
@Input() sections: any[]; // List of course sections.
|
@Input() sections: any[]; // List of course sections.
|
||||||
@Input() downloadEnabled?: boolean; // Whether the download of sections and modules is enabled.
|
@Input() downloadEnabled?: boolean; // Whether the download of sections and modules is enabled.
|
||||||
|
@ -57,6 +59,8 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
sectionSelectorComponent: any;
|
sectionSelectorComponent: any;
|
||||||
singleSectionComponent: any;
|
singleSectionComponent: any;
|
||||||
allSectionsComponent: any;
|
allSectionsComponent: any;
|
||||||
|
canLoadMore = false;
|
||||||
|
showSectionId = 0;
|
||||||
|
|
||||||
// Data to pass to the components.
|
// Data to pass to the components.
|
||||||
data: any = {};
|
data: any = {};
|
||||||
|
@ -273,6 +277,9 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
} else {
|
} else {
|
||||||
this.previousSection = null;
|
this.previousSection = null;
|
||||||
this.nextSection = null;
|
this.nextSection = null;
|
||||||
|
this.canLoadMore = false;
|
||||||
|
this.showSectionId = 0;
|
||||||
|
this.showMoreActivities();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.moduleId && typeof previousValue == 'undefined') {
|
if (this.moduleId && typeof previousValue == 'undefined') {
|
||||||
|
@ -363,6 +370,46 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show more activities (only used when showing all the sections at the same time).
|
||||||
|
*
|
||||||
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
|
*/
|
||||||
|
showMoreActivities(infiniteComplete?: any): void {
|
||||||
|
this.canLoadMore = false;
|
||||||
|
|
||||||
|
let modulesLoaded = 0,
|
||||||
|
i;
|
||||||
|
for (i = this.showSectionId + 1; i < this.sections.length; i++) {
|
||||||
|
if (this.sections[i].hasContent && this.sections[i].modules) {
|
||||||
|
modulesLoaded += this.sections[i].modules.reduce((total, module) => {
|
||||||
|
return module.visibleoncoursepage !== 0 ? total + 1 : total;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
if (modulesLoaded >= CoreCourseFormatComponent.LOAD_MORE_ACTIVITIES) {
|
||||||
|
this.showSectionId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.canLoadMore = i < this.sections.length;
|
||||||
|
|
||||||
|
if (this.canLoadMore) {
|
||||||
|
// Check if any of the following sections have any content.
|
||||||
|
let thereAreMore = false;
|
||||||
|
for (i++; i < this.sections.length; i++) {
|
||||||
|
if (this.sections[i].hasContent && this.sections[i].modules && this.sections[i].modules.length > 0) {
|
||||||
|
thereAreMore = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.canLoadMore = thereAreMore;
|
||||||
|
}
|
||||||
|
|
||||||
|
infiniteComplete && infiniteComplete();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component destroyed.
|
* Component destroyed.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -47,8 +47,8 @@ export class CoreCourseFormatWeeksHandler implements CoreCourseFormatHandler {
|
||||||
const now = this.timeUtils.timestamp();
|
const now = this.timeUtils.timestamp();
|
||||||
|
|
||||||
if (now < course.startdate || (course.enddate && now > course.enddate)) {
|
if (now < course.startdate || (course.enddate && now > course.enddate)) {
|
||||||
// Course hasn't started yet or it has ended already. Return the first section.
|
// Course hasn't started yet or it has ended already. Return all sections.
|
||||||
return sections[1];
|
return sections[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < sections.length; i++) {
|
for (let i = 0; i < sections.length; i++) {
|
||||||
|
@ -63,8 +63,8 @@ export class CoreCourseFormatWeeksHandler implements CoreCourseFormatHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The section wasn't found, return the first section.
|
// The section wasn't found, return all sections.
|
||||||
return sections[1];
|
return sections[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { Injectable } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
||||||
import { CoreCourseFormatHandler } from './format-delegate';
|
import { CoreCourseFormatHandler } from './format-delegate';
|
||||||
import { CoreCourseProvider } from './course';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default handler used when the course format doesn't have a specific implementation.
|
* Default handler used when the course format doesn't have a specific implementation.
|
||||||
|
@ -98,38 +97,28 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler {
|
||||||
*/
|
*/
|
||||||
getCurrentSection(course: any, sections: any[]): any | Promise<any> {
|
getCurrentSection(course: any, sections: any[]): any | Promise<any> {
|
||||||
if (!this.coursesProvider.isGetCoursesByFieldAvailable()) {
|
if (!this.coursesProvider.isGetCoursesByFieldAvailable()) {
|
||||||
// Cannot get the current section, return the first one.
|
// Cannot get the current section, return all of them.
|
||||||
if (sections[0].id != CoreCourseProvider.ALL_SECTIONS_ID) {
|
|
||||||
return sections[0];
|
return sections[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return sections[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need the "marker" to determine the current section.
|
// We need the "marker" to determine the current section.
|
||||||
return this.coursesProvider.getCoursesByField('id', course.id).catch(() => {
|
return this.coursesProvider.getCoursesByField('id', course.id).catch(() => {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}).then((courses) => {
|
}).then((courses) => {
|
||||||
if (courses && courses[0]) {
|
if (courses && courses[0] && courses[0].marker > 0) {
|
||||||
// Find the marked section.
|
// Find the marked section.
|
||||||
const course = courses[0];
|
const course = courses[0],
|
||||||
for (let i = 0; i < sections.length; i++) {
|
section = sections.find((sect) => {
|
||||||
const section = sections[i];
|
return sect.section == course.marker;
|
||||||
if (section.section == course.marker) {
|
});
|
||||||
return section;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marked section not found or we couldn't retrieve the marker. Return the first section.
|
if (section) {
|
||||||
for (let i = 0; i < sections.length; i++) {
|
|
||||||
const section = sections[i];
|
|
||||||
if (section.id != CoreCourseProvider.ALL_SECTIONS_ID) {
|
|
||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(null);
|
// Marked section not found or we couldn't retrieve the marker. Return all sections.
|
||||||
|
return sections[0];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ import { NavController } from 'ionic-angular';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreCourseProvider } from './course';
|
|
||||||
import { CoreCourseFormatDefaultHandler } from './default-format';
|
import { CoreCourseFormatDefaultHandler } from './default-format';
|
||||||
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
|
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
|
||||||
|
|
||||||
|
@ -285,14 +284,11 @@ export class CoreCourseFormatDelegate extends CoreDelegate {
|
||||||
* @return {Promise<any>} Promise resolved with current section.
|
* @return {Promise<any>} Promise resolved with current section.
|
||||||
*/
|
*/
|
||||||
getCurrentSection(course: any, sections: any[]): Promise<any> {
|
getCurrentSection(course: any, sections: any[]): Promise<any> {
|
||||||
|
|
||||||
// Convert the result to a Promise if it isn't.
|
// Convert the result to a Promise if it isn't.
|
||||||
return Promise.resolve(this.executeFunctionOnEnabled(course.format, 'getCurrentSection', [course, sections])).catch(() => {
|
return Promise.resolve(this.executeFunctionOnEnabled(course.format, 'getCurrentSection', [course, sections])).catch(() => {
|
||||||
// This function should never fail. Just return the first section.
|
// This function should never fail. Just return all the sections.
|
||||||
if (sections[0].id != CoreCourseProvider.ALL_SECTIONS_ID) {
|
|
||||||
return sections[0];
|
return sections[0];
|
||||||
}
|
|
||||||
|
|
||||||
return sections[1];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,7 @@
|
||||||
<ion-item-divider color="light">{{ 'core.courses.totalcoursesearchresults' | translate:{$a: total} }}</ion-item-divider>
|
<ion-item-divider color="light">{{ 'core.courses.totalcoursesearchresults' | translate:{$a: total} }}</ion-item-divider>
|
||||||
<core-empty-box *ngIf="total == 0" icon="search" [message]="'core.courses.nosearchresults' | translate"></core-empty-box>
|
<core-empty-box *ngIf="total == 0" icon="search" [message]="'core.courses.nosearchresults' | translate"></core-empty-box>
|
||||||
<core-courses-course-list-item *ngFor="let course of courses" [course]="course"></core-courses-course-list-item>
|
<core-courses-course-list-item *ngFor="let course of courses" [course]="course"></core-courses-course-list-item>
|
||||||
<ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="loadMoreResults($event)">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreResults($event)"></core-infinite-loading>
|
||||||
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
|
||||||
</ion-infinite-scroll>
|
|
||||||
</div>
|
</div>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,11 @@ export class CoreCoursesSearchPage {
|
||||||
/**
|
/**
|
||||||
* Load more results.
|
* Load more results.
|
||||||
*
|
*
|
||||||
* @param {any} infiniteScroll The infinit scroll instance.
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
*/
|
*/
|
||||||
loadMoreResults(infiniteScroll: any): void {
|
loadMoreResults(infiniteComplete?: any): void {
|
||||||
this.searchCourses().finally(() => {
|
this.searchCourses().finally(() => {
|
||||||
infiniteScroll.complete();
|
infiniteComplete && infiniteComplete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,7 @@ export class CoreCoursesProvider {
|
||||||
* @param {any} [value] The value to match.
|
* @param {any} [value] The value to match.
|
||||||
* @param {string} [siteId] Site ID. If not defined, use current site.
|
* @param {string} [siteId] Site ID. If not defined, use current site.
|
||||||
* @return {Promise<any[]>} Promise resolved with the courses.
|
* @return {Promise<any[]>} Promise resolved with the courses.
|
||||||
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
getCoursesByField(field?: string, value?: any, siteId?: string): Promise<any[]> {
|
getCoursesByField(field?: string, value?: any, siteId?: string): Promise<any[]> {
|
||||||
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
||||||
|
@ -473,6 +474,7 @@ export class CoreCoursesProvider {
|
||||||
* Check if get courses by field WS is available.
|
* Check if get courses by field WS is available.
|
||||||
*
|
*
|
||||||
* @return {boolean} Whether get courses by field is available.
|
* @return {boolean} Whether get courses by field is available.
|
||||||
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
isGetCoursesByFieldAvailable(): boolean {
|
isGetCoursesByFieldAvailable(): boolean {
|
||||||
return this.sitesProvider.wsAvailableInCurrentSite('core_course_get_courses_by_field');
|
return this.sitesProvider.wsAvailableInCurrentSite('core_course_get_courses_by_field');
|
||||||
|
|
|
@ -16,10 +16,7 @@
|
||||||
<p *ngIf="participant.lastaccess"><strong>{{ 'core.lastaccess' | translate }}: </strong>{{ participant.lastaccess * 1000 | coreFormatDate:"dfmediumdate"}}</p>
|
<p *ngIf="participant.lastaccess"><strong>{{ 'core.lastaccess' | translate }}: </strong>{{ participant.lastaccess * 1000 | coreFormatDate:"dfmediumdate"}}</p>
|
||||||
</a>
|
</a>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreData($event)"></core-infinite-loading>
|
||||||
<ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(fetchData())">
|
|
||||||
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
|
||||||
</ion-infinite-scroll>
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
</core-split-view>
|
</core-split-view>
|
|
@ -82,6 +82,18 @@ export class CoreUserParticipantsComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to load more data.
|
||||||
|
*
|
||||||
|
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||||
|
* @return {Promise<any>} Resolved when done.
|
||||||
|
*/
|
||||||
|
loadMoreData(infiniteComplete?: any): Promise<any> {
|
||||||
|
return this.fetchData().finally(() => {
|
||||||
|
infiniteComplete && infiniteComplete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh data.
|
* Refresh data.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue