MOBILE-2309 contentlinks: Implement some handlers and handle links
parent
b3d0457540
commit
3cb62c748c
|
@ -58,6 +58,7 @@ import { CoreFileUploaderModule } from '../core/fileuploader/fileuploader.module
|
||||||
import { CoreSharedFilesModule } from '../core/sharedfiles/sharedfiles.module';
|
import { CoreSharedFilesModule } from '../core/sharedfiles/sharedfiles.module';
|
||||||
import { CoreCourseModule } from '../core/course/course.module';
|
import { CoreCourseModule } from '../core/course/course.module';
|
||||||
import { CoreSiteHomeModule } from '../core/sitehome/sitehome.module';
|
import { CoreSiteHomeModule } from '../core/sitehome/sitehome.module';
|
||||||
|
import { CoreContentLinksModule } from '../core/contentlinks/contentlinks.module';
|
||||||
|
|
||||||
// Addon modules.
|
// Addon modules.
|
||||||
import { AddonCalendarModule } from '../addon/calendar/calendar.module';
|
import { AddonCalendarModule } from '../addon/calendar/calendar.module';
|
||||||
|
@ -94,6 +95,7 @@ export function createTranslateLoader(http: HttpClient) {
|
||||||
CoreSharedFilesModule,
|
CoreSharedFilesModule,
|
||||||
CoreCourseModule,
|
CoreCourseModule,
|
||||||
CoreSiteHomeModule,
|
CoreSiteHomeModule,
|
||||||
|
CoreContentLinksModule,
|
||||||
AddonCalendarModule
|
AddonCalendarModule
|
||||||
],
|
],
|
||||||
bootstrap: [IonicApp],
|
bootstrap: [IonicApp],
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// 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 { NavController } from 'ionic-angular';
|
||||||
import { CoreContentLinksAction } from '../providers/delegate';
|
import { CoreContentLinksAction } from '../providers/delegate';
|
||||||
import { CoreContentLinksHandlerBase } from './base-handler';
|
import { CoreContentLinksHandlerBase } from './base-handler';
|
||||||
import { CoreSitesProvider } from '../../../providers/sites';
|
import { CoreSitesProvider } from '../../../providers/sites';
|
||||||
|
@ -64,7 +65,7 @@ export class CoreContentLinksModuleGradeHandler extends CoreContentLinksHandlerB
|
||||||
|
|
||||||
courseId = courseId || params.courseid || params.cid;
|
courseId = courseId || params.courseid || params.cid;
|
||||||
return [{
|
return [{
|
||||||
action: (siteId) : void => {
|
action: (siteId, navCtrl?) : void => {
|
||||||
// Check if userid is the site's current user.
|
// Check if userid is the site's current user.
|
||||||
const modal = this.domUtils.showModalLoading();
|
const modal = this.domUtils.showModalLoading();
|
||||||
this.sitesProvider.getSite(siteId).then((site) => {
|
this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
@ -73,7 +74,7 @@ export class CoreContentLinksModuleGradeHandler extends CoreContentLinksHandlerB
|
||||||
this.courseHelper.navigateToModule(parseInt(params.id, 10), siteId, courseId);
|
this.courseHelper.navigateToModule(parseInt(params.id, 10), siteId, courseId);
|
||||||
} else if (this.canReview) {
|
} else if (this.canReview) {
|
||||||
// Use the goToReview function.
|
// Use the goToReview function.
|
||||||
this.goToReview(url, params, courseId, siteId);
|
this.goToReview(url, params, courseId, siteId, navCtrl);
|
||||||
} else {
|
} else {
|
||||||
// Not current user and cannot review it in the app, open it in browser.
|
// Not current user and cannot review it in the app, open it in browser.
|
||||||
site.openInBrowserWithAutoLogin(url);
|
site.openInBrowserWithAutoLogin(url);
|
||||||
|
@ -91,10 +92,11 @@ export class CoreContentLinksModuleGradeHandler extends CoreContentLinksHandlerB
|
||||||
* @param {string} url The URL to treat.
|
* @param {string} url The URL to treat.
|
||||||
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
* @param {number} courseId Course ID related to the URL.
|
* @param {number} courseId Course ID related to the URL.
|
||||||
* @param {string} siteId List of sites the URL belongs to.
|
* @param {string} siteId Site to use.
|
||||||
|
* @param {NavController} [navCtrl] Nav Controller to use to navigate.
|
||||||
* @return {Promise<any>} Promise resolved when done.
|
* @return {Promise<any>} Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected goToReview(url: string, params: any, courseId: number, siteId: string) : Promise<any> {
|
protected goToReview(url: string, params: any, courseId: number, siteId: string, navCtrl?: NavController) : Promise<any> {
|
||||||
// This function should be overridden.
|
// This function should be overridden.
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ export class CoreContentLinksModuleIndexHandler extends CoreContentLinksHandlerB
|
||||||
|
|
||||||
courseId = courseId || params.courseid || params.cid;
|
courseId = courseId || params.courseid || params.cid;
|
||||||
return [{
|
return [{
|
||||||
action: (siteId) => {
|
action: (siteId, navCtrl?) => {
|
||||||
this.courseHelper.navigateToModule(parseInt(params.id, 10), siteId, courseId);
|
this.courseHelper.navigateToModule(parseInt(params.id, 10), siteId, courseId);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -80,7 +80,7 @@ export class CoreContentLinksChooseSitePage implements OnInit {
|
||||||
* @param {string} siteId Site ID.
|
* @param {string} siteId Site ID.
|
||||||
*/
|
*/
|
||||||
siteClicked(siteId: string) : void {
|
siteClicked(siteId: string) : void {
|
||||||
this.action.action(siteId);
|
this.action.action(siteId, this.navCtrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreLoggerProvider } from '../../../providers/logger';
|
import { CoreLoggerProvider } from '../../../providers/logger';
|
||||||
import { CoreSitesProvider } from '../../../providers/sites';
|
import { CoreSitesProvider } from '../../../providers/sites';
|
||||||
import { CoreUrlUtilsProvider } from '../../../providers/utils/url';
|
import { CoreUrlUtilsProvider } from '../../../providers/utils/url';
|
||||||
|
@ -115,8 +116,9 @@ export interface CoreContentLinksAction {
|
||||||
* Action to perform when the link is clicked.
|
* Action to perform when the link is clicked.
|
||||||
*
|
*
|
||||||
* @param {string} siteId The site ID.
|
* @param {string} siteId The site ID.
|
||||||
|
* @param {NavController} [navCtrl] Nav Controller to use to navigate.
|
||||||
*/
|
*/
|
||||||
action(siteId: string) : void;
|
action(siteId: string, navCtrl?: NavController) : void;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -202,9 +202,10 @@ export class CoreContentLinksHelperProvider {
|
||||||
* @param {string} url URL to handle.
|
* @param {string} url URL to handle.
|
||||||
* @param {string} [username] Username related with the URL. E.g. in 'http://myuser@m.com', url would be 'http://m.com' and
|
* @param {string} [username] Username related with the URL. E.g. in 'http://myuser@m.com', url would be 'http://m.com' and
|
||||||
* the username 'myuser'. Don't use it if you don't want to filter by username.
|
* the username 'myuser'. Don't use it if you don't want to filter by username.
|
||||||
|
* @param {NavController} [navCtrl] Nav Controller to use to navigate.
|
||||||
* @return {Promise<boolean>} Promise resolved with a boolean: true if URL was treated, false otherwise.
|
* @return {Promise<boolean>} Promise resolved with a boolean: true if URL was treated, false otherwise.
|
||||||
*/
|
*/
|
||||||
handleLink(url: string, username?: string) : Promise<boolean> {
|
handleLink(url: string, username?: string, navCtrl?: NavController) : Promise<boolean> {
|
||||||
// Check if the link should be treated by some component/addon.
|
// Check if the link should be treated by some component/addon.
|
||||||
return this.contentLinksDelegate.getActionsFor(url, undefined, username).then((actions) => {
|
return this.contentLinksDelegate.getActionsFor(url, undefined, username).then((actions) => {
|
||||||
const action = this.getFirstValidAction(actions);
|
const action = this.getFirstValidAction(actions);
|
||||||
|
@ -212,18 +213,18 @@ export class CoreContentLinksHelperProvider {
|
||||||
if (!this.sitesProvider.isLoggedIn()) {
|
if (!this.sitesProvider.isLoggedIn()) {
|
||||||
// No current site. Perform the action if only 1 site found, choose the site otherwise.
|
// No current site. Perform the action if only 1 site found, choose the site otherwise.
|
||||||
if (action.sites.length == 1) {
|
if (action.sites.length == 1) {
|
||||||
action.action(action.sites[0]);
|
action.action(action.sites[0], navCtrl);
|
||||||
} else {
|
} else {
|
||||||
this.goToChooseSite(url);
|
this.goToChooseSite(url);
|
||||||
}
|
}
|
||||||
} else if (action.sites.length == 1 && action.sites[0] == this.sitesProvider.getCurrentSiteId()) {
|
} else if (action.sites.length == 1 && action.sites[0] == this.sitesProvider.getCurrentSiteId()) {
|
||||||
// Current site.
|
// Current site.
|
||||||
action.action(action.sites[0]);
|
action.action(action.sites[0], navCtrl);
|
||||||
} else {
|
} else {
|
||||||
// Not current site or more than one site. Ask for confirmation.
|
// Not current site or more than one site. Ask for confirmation.
|
||||||
this.domUtils.showConfirm(this.translate.instant('core.contentlinks.confirmurlothersite')).then(() => {
|
this.domUtils.showConfirm(this.translate.instant('core.contentlinks.confirmurlothersite')).then(() => {
|
||||||
if (action.sites.length == 1) {
|
if (action.sites.length == 1) {
|
||||||
action.action(action.sites[0]);
|
action.action(action.sites[0], navCtrl);
|
||||||
} else {
|
} else {
|
||||||
this.goToChooseSite(url);
|
this.goToChooseSite(url);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,8 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
@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.
|
||||||
@Input() initialSectionId: number; // The section to load first.
|
@Input() initialSectionId?: number; // The section to load first (by ID).
|
||||||
|
@Input() initialSectionNumber?: number; // The section to load first (by number).
|
||||||
@Output() completionChanged?: EventEmitter<void>; // Will emit an event when any module completion changes.
|
@Output() completionChanged?: EventEmitter<void>; // Will emit an event when any module completion changes.
|
||||||
|
|
||||||
// Get the containers where to inject dynamic components. We use a setter because they might be inside a *ngIf.
|
// Get the containers where to inject dynamic components. We use a setter because they might be inside a *ngIf.
|
||||||
|
@ -144,11 +145,11 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
if (changes.sections && this.sections) {
|
if (changes.sections && this.sections) {
|
||||||
if (!this.selectedSection) {
|
if (!this.selectedSection) {
|
||||||
// There is no selected section yet, calculate which one to load.
|
// There is no selected section yet, calculate which one to load.
|
||||||
if (this.initialSectionId) {
|
if (this.initialSectionId || this.initialSectionNumber) {
|
||||||
// We have an input indicating the section ID to load. Search the section.
|
// We have an input indicating the section ID to load. Search the section.
|
||||||
for (let i = 0; i < this.sections.length; i++) {
|
for (let i = 0; i < this.sections.length; i++) {
|
||||||
let section = this.sections[i];
|
let section = this.sections[i];
|
||||||
if (section.id == this.initialSectionId) {
|
if (section.id == this.initialSectionId || section.section == this.initialSectionNumber) {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
this.sectionChanged(section);
|
this.sectionChanged(section);
|
||||||
break;
|
break;
|
||||||
|
@ -229,6 +230,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
this.componentInstances[type].course = this.course;
|
this.componentInstances[type].course = this.course;
|
||||||
this.componentInstances[type].sections = this.sections;
|
this.componentInstances[type].sections = this.sections;
|
||||||
this.componentInstances[type].initialSectionId = this.initialSectionId;
|
this.componentInstances[type].initialSectionId = this.initialSectionId;
|
||||||
|
this.componentInstances[type].initialSectionNumber = this.initialSectionNumber;
|
||||||
this.componentInstances[type].downloadEnabled = this.downloadEnabled;
|
this.componentInstances[type].downloadEnabled = this.downloadEnabled;
|
||||||
|
|
||||||
this.cdr.detectChanges(); // The instances are used in ngIf, tell Angular that something has changed.
|
this.cdr.detectChanges(); // The instances are used in ngIf, tell Angular that something has changed.
|
||||||
|
|
|
@ -21,6 +21,6 @@
|
||||||
<a aria-selected="true">{{ 'core.course.contents' | translate }}</a>
|
<a aria-selected="true">{{ 'core.course.contents' | translate }}</a>
|
||||||
<a *ngFor="let handler of courseHandlers">{{ handler.data.title || translate }}</a>
|
<a *ngFor="let handler of courseHandlers">{{ handler.data.title || translate }}</a>
|
||||||
</div>
|
</div>
|
||||||
<core-course-format [course]="course" [sections]="sections" [initialSectionId]="sectionId" [downloadEnabled]="downloadEnabled" (completionChanged)="onCompletionChange()"></core-course-format>
|
<core-course-format [course]="course" [sections]="sections" [initialSectionId]="sectionId" [initialSectionNumber]="sectionNumber" [downloadEnabled]="downloadEnabled" (completionChanged)="onCompletionChange()"></core-course-format>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -40,6 +40,7 @@ export class CoreCourseSectionPage implements OnDestroy {
|
||||||
course: any;
|
course: any;
|
||||||
sections: any[];
|
sections: any[];
|
||||||
sectionId: number;
|
sectionId: number;
|
||||||
|
sectionNumber: number;
|
||||||
courseHandlers: CoreCoursesHandlerToDisplay[];
|
courseHandlers: CoreCoursesHandlerToDisplay[];
|
||||||
dataLoaded: boolean;
|
dataLoaded: boolean;
|
||||||
downloadEnabled: boolean;
|
downloadEnabled: boolean;
|
||||||
|
@ -59,6 +60,7 @@ export class CoreCourseSectionPage implements OnDestroy {
|
||||||
sitesProvider: CoreSitesProvider, private navCtrl: NavController) {
|
sitesProvider: CoreSitesProvider, private navCtrl: NavController) {
|
||||||
this.course = navParams.get('course');
|
this.course = navParams.get('course');
|
||||||
this.sectionId = navParams.get('sectionId');
|
this.sectionId = navParams.get('sectionId');
|
||||||
|
this.sectionNumber = navParams.get('sectionNumber');
|
||||||
|
|
||||||
// Get the title to display. We dont't have sections yet.
|
// Get the title to display. We dont't have sections yet.
|
||||||
this.title = courseFormatDelegate.getCourseTitle(this.course);
|
this.title = courseFormatDelegate.getCourseTitle(this.course);
|
||||||
|
|
|
@ -13,11 +13,13 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, Output, OnChanges, EventEmitter, SimpleChange } from '@angular/core';
|
import { Component, Input, Output, OnChanges, EventEmitter, SimpleChange } from '@angular/core';
|
||||||
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreSitesProvider } from '../../../../providers/sites';
|
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 { CoreCourseProvider } from '../../../course/providers/course';
|
import { CoreCourseProvider } from '../../../course/providers/course';
|
||||||
|
import { CoreContentLinksHelperProvider } from '../../../contentlinks/providers/helper';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,9 +43,9 @@ export class CoreCoursesOverviewEventsComponent implements OnChanges {
|
||||||
next30Days: any[] = [];
|
next30Days: any[] = [];
|
||||||
future: any[] = [];
|
future: any[] = [];
|
||||||
|
|
||||||
constructor(private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider,
|
constructor(private navCtrl: NavController, private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider,
|
||||||
private domUtils: CoreDomUtilsProvider, private sitesProvider: CoreSitesProvider,
|
private domUtils: CoreDomUtilsProvider, private sitesProvider: CoreSitesProvider,
|
||||||
private courseProvider: CoreCourseProvider) {
|
private courseProvider: CoreCourseProvider, private contentLinksHelper: CoreContentLinksHelperProvider) {
|
||||||
this.loadMore = new EventEmitter();
|
this.loadMore = new EventEmitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,9 +102,6 @@ export class CoreCoursesOverviewEventsComponent implements OnChanges {
|
||||||
loadMoreEvents() {
|
loadMoreEvents() {
|
||||||
this.loadingMore = true;
|
this.loadingMore = true;
|
||||||
this.loadMore.emit();
|
this.loadMore.emit();
|
||||||
// this.loadMore().finally(function() {
|
|
||||||
// scope.loadingMore = false;
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,19 +118,14 @@ export class CoreCoursesOverviewEventsComponent implements OnChanges {
|
||||||
url = this.textUtils.decodeHTMLEntities(url);
|
url = this.textUtils.decodeHTMLEntities(url);
|
||||||
|
|
||||||
let modal = this.domUtils.showModalLoading();
|
let modal = this.domUtils.showModalLoading();
|
||||||
this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(url).finally(() => {
|
this.contentLinksHelper.handleLink(url, undefined, this.navCtrl).then((treated) => {
|
||||||
|
if (!treated) {
|
||||||
|
return this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(url);
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
modal.dismiss();
|
modal.dismiss();
|
||||||
});
|
});
|
||||||
|
|
||||||
// @todo
|
|
||||||
// $mmContentLinksHelper.handleLink(url).then((treated) => {
|
|
||||||
// if (!treated) {
|
|
||||||
// return this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(url);
|
|
||||||
// }
|
|
||||||
// }).finally(() => {
|
|
||||||
// modal.dismiss();
|
|
||||||
// });
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,11 @@ import { CoreCoursesProvider } from './providers/courses';
|
||||||
import { CoreCoursesMainMenuHandler } from './providers/mainmenu-handler';
|
import { CoreCoursesMainMenuHandler } from './providers/mainmenu-handler';
|
||||||
import { CoreCoursesMyOverviewProvider } from './providers/my-overview';
|
import { CoreCoursesMyOverviewProvider } from './providers/my-overview';
|
||||||
import { CoreCoursesDelegate } from './providers/delegate';
|
import { CoreCoursesDelegate } from './providers/delegate';
|
||||||
|
import { CoreCoursesCourseLinkHandler } from './providers/course-link-handler';
|
||||||
|
import { CoreCoursesIndexLinkHandler } from './providers/courses-index-link-handler';
|
||||||
|
import { CoreCoursesMyOverviewLinkHandler } from './providers/my-overview-link-handler';
|
||||||
import { CoreMainMenuDelegate } from '../mainmenu/providers/delegate';
|
import { CoreMainMenuDelegate } from '../mainmenu/providers/delegate';
|
||||||
|
import { CoreContentLinksDelegate } from '../contentlinks/providers/delegate';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [],
|
declarations: [],
|
||||||
|
@ -27,12 +31,21 @@ import { CoreMainMenuDelegate } from '../mainmenu/providers/delegate';
|
||||||
CoreCoursesProvider,
|
CoreCoursesProvider,
|
||||||
CoreCoursesMainMenuHandler,
|
CoreCoursesMainMenuHandler,
|
||||||
CoreCoursesMyOverviewProvider,
|
CoreCoursesMyOverviewProvider,
|
||||||
CoreCoursesDelegate
|
CoreCoursesDelegate,
|
||||||
|
CoreCoursesCourseLinkHandler,
|
||||||
|
CoreCoursesIndexLinkHandler,
|
||||||
|
CoreCoursesMyOverviewLinkHandler
|
||||||
],
|
],
|
||||||
exports: []
|
exports: []
|
||||||
})
|
})
|
||||||
export class CoreCoursesModule {
|
export class CoreCoursesModule {
|
||||||
constructor(mainMenuDelegate: CoreMainMenuDelegate, mainMenuHandler: CoreCoursesMainMenuHandler) {
|
constructor(mainMenuDelegate: CoreMainMenuDelegate, contentLinksDelegate: CoreContentLinksDelegate,
|
||||||
|
mainMenuHandler: CoreCoursesMainMenuHandler, courseLinkHandler: CoreCoursesCourseLinkHandler,
|
||||||
|
indexLinkHandler: CoreCoursesIndexLinkHandler, myOverviewLinkHandler: CoreCoursesMyOverviewLinkHandler) {
|
||||||
mainMenuDelegate.registerHandler(mainMenuHandler);
|
mainMenuDelegate.registerHandler(mainMenuHandler);
|
||||||
|
|
||||||
|
contentLinksDelegate.registerHandler(courseLinkHandler);
|
||||||
|
contentLinksDelegate.registerHandler(indexLinkHandler);
|
||||||
|
contentLinksDelegate.registerHandler(myOverviewLinkHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,267 @@
|
||||||
|
// (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 { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { CoreSitesProvider } from '../../../providers/sites';
|
||||||
|
import { CoreDomUtilsProvider } from '../../../providers/utils/dom';
|
||||||
|
import { CoreContentLinksHandlerBase } from '../../contentlinks/classes/base-handler';
|
||||||
|
import { CoreContentLinksAction } from '../../contentlinks/providers/delegate';
|
||||||
|
import { CoreLoginHelperProvider } from '../../login/providers/helper';
|
||||||
|
import { CoreCourseProvider } from '../../course/providers/course';
|
||||||
|
import { CoreCoursesProvider } from './courses';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to treat links to course view or enrol (except site home).
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase {
|
||||||
|
name = 'CoreCoursesCourseLinkHandler';
|
||||||
|
pattern = /((\/enrol\/index\.php)|(\/course\/enrol\.php)|(\/course\/view\.php)).*([\?\&]id=\d+)/;
|
||||||
|
|
||||||
|
protected waitStart = 0;
|
||||||
|
|
||||||
|
constructor(private sitesProvider: CoreSitesProvider, private coursesProvider: CoreCoursesProvider,
|
||||||
|
private loginHelper: CoreLoginHelperProvider, private domUtils: CoreDomUtilsProvider,
|
||||||
|
private translate: TranslateService, private courseProvider: CoreCourseProvider) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of actions for a link (url).
|
||||||
|
*
|
||||||
|
* @param {string[]} siteIds List of sites the URL belongs to.
|
||||||
|
* @param {string} url The URL to treat.
|
||||||
|
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
|
* @param {number} [courseId] Course ID related to the URL. Optional but recommended.
|
||||||
|
* @return {CoreContentLinksAction[]|Promise<CoreContentLinksAction[]>} List of (or promise resolved with list of) actions.
|
||||||
|
*/
|
||||||
|
getActions(siteIds: string[], url: string, params: any, courseId?: number) :
|
||||||
|
CoreContentLinksAction[]|Promise<CoreContentLinksAction[]> {
|
||||||
|
courseId = parseInt(params.id, 10);
|
||||||
|
|
||||||
|
let sectionId = params.sectionid ? parseInt(params.sectionid, 10) : null,
|
||||||
|
sectionNumber = typeof params.section != 'undefined' ? parseInt(params.section, 10) : NaN,
|
||||||
|
pageParams: any = {
|
||||||
|
course: {id: courseId},
|
||||||
|
sectionId: sectionId || null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isNaN(sectionNumber)) {
|
||||||
|
pageParams.sectionNumber = sectionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [{
|
||||||
|
action: (siteId, navCtrl?) => {
|
||||||
|
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
||||||
|
if (siteId == this.sitesProvider.getCurrentSiteId()) {
|
||||||
|
this.actionEnrol(courseId, url, pageParams).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Use redirect to make the course the new history root (to avoid "loops" in history).
|
||||||
|
this.loginHelper.redirect('CoreCourseSectionPage', pageParams, siteId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the handler is enabled for a certain site (site + user) and a URL.
|
||||||
|
* If not defined, defaults to true.
|
||||||
|
*
|
||||||
|
* @param {string} siteId The site ID.
|
||||||
|
* @param {string} url The URL to treat.
|
||||||
|
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
|
* @param {number} [courseId] Course ID related to the URL. Optional but recommended.
|
||||||
|
* @return {boolean|Promise<boolean>} Whether the handler is enabled for the URL and site.
|
||||||
|
*/
|
||||||
|
isEnabled(siteId: string, url: string, params: any, courseId?: number) : boolean|Promise<boolean> {
|
||||||
|
courseId = parseInt(params.id, 10);
|
||||||
|
|
||||||
|
if (!courseId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the course id of Site Home.
|
||||||
|
return this.sitesProvider.getSiteHomeId(siteId).then((siteHomeId) => {
|
||||||
|
return courseId != siteHomeId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to perform when an enrol link is clicked.
|
||||||
|
*
|
||||||
|
* @param {number} courseId Course ID.
|
||||||
|
* @param {string} url Treated URL.
|
||||||
|
* @param {any} pageParams Params to send to the new page.
|
||||||
|
* @return {Promise<any>} Promise resolved when done.
|
||||||
|
*/
|
||||||
|
protected actionEnrol(courseId: number, url: string, pageParams: any) : Promise<any> {
|
||||||
|
let modal = this.domUtils.showModalLoading(),
|
||||||
|
isEnrolUrl = !!url.match(/(\/enrol\/index\.php)|(\/course\/enrol\.php)/);
|
||||||
|
|
||||||
|
// Check if user is enrolled in the course.
|
||||||
|
return this.coursesProvider.getUserCourse(courseId).catch(() => {
|
||||||
|
// User is not enrolled in the course. Check if can self enrol.
|
||||||
|
return this.canSelfEnrol(courseId).then(() => {
|
||||||
|
modal.dismiss();
|
||||||
|
|
||||||
|
// The user can self enrol. If it's not a enrolment URL we'll ask for confirmation.
|
||||||
|
let promise = isEnrolUrl ? Promise.resolve() :
|
||||||
|
this.domUtils.showConfirm(this.translate.instant('core.courses.confirmselfenrol'));
|
||||||
|
|
||||||
|
return promise.then(() => {
|
||||||
|
// Enrol URL or user confirmed.
|
||||||
|
return this.selfEnrol(courseId).catch((error) => {
|
||||||
|
if (error) {
|
||||||
|
this.domUtils.showErrorModal(error);
|
||||||
|
}
|
||||||
|
return Promise.reject(null);
|
||||||
|
});
|
||||||
|
}, () => {
|
||||||
|
// User cancelled. Check if the user can view the course contents (guest access or similar).
|
||||||
|
return this.courseProvider.getSections(courseId, false, true);
|
||||||
|
});
|
||||||
|
}, (error) => {
|
||||||
|
// Can't self enrol. Check if the user can view the course contents (guest access or similar).
|
||||||
|
return this.courseProvider.getSections(courseId, false, true).catch(() => {
|
||||||
|
// Error. Show error message and allow the user to open the link in browser.
|
||||||
|
modal.dismiss();
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
error = error.message || error.error || error.content || error.body || error;
|
||||||
|
}
|
||||||
|
if (!error) {
|
||||||
|
error = this.translate.instant('core.courses.notenroled');
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = this.translate.instant('core.twoparagraphs',
|
||||||
|
{p1: error, p2: this.translate.instant('core.confirmopeninbrowser')});
|
||||||
|
this.domUtils.showConfirm(body).then(() => {
|
||||||
|
this.sitesProvider.getCurrentSite().openInBrowserWithAutoLogin(url);
|
||||||
|
}).catch(() => {
|
||||||
|
// User cancelled.
|
||||||
|
});
|
||||||
|
return Promise.reject(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).then(() => {
|
||||||
|
modal.dismiss();
|
||||||
|
|
||||||
|
// Use redirect to make the course the new history root (to avoid "loops" in history).
|
||||||
|
this.loginHelper.redirect('CoreCourseSectionPage', pageParams, this.sitesProvider.getCurrentSiteId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a user can be "automatically" self enrolled in a course.
|
||||||
|
*
|
||||||
|
* @param {number} courseId Course ID.
|
||||||
|
* @return {Promise<any>} Promise resolved if user can be enrolled in a course, rejected otherwise.
|
||||||
|
*/
|
||||||
|
protected canSelfEnrol(courseId: number) : Promise<any> {
|
||||||
|
// Check that the course has self enrolment enabled.
|
||||||
|
return this.coursesProvider.getCourseEnrolmentMethods(courseId).then((methods) => {
|
||||||
|
let isSelfEnrolEnabled = false,
|
||||||
|
instances = 0;
|
||||||
|
|
||||||
|
methods.forEach((method) => {
|
||||||
|
if (method.type == 'self' && method.status) {
|
||||||
|
isSelfEnrolEnabled = true;
|
||||||
|
instances++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isSelfEnrolEnabled || instances != 1) {
|
||||||
|
// Self enrol not enabled or more than one instance.
|
||||||
|
return Promise.reject(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to self enrol a user in a course.
|
||||||
|
*
|
||||||
|
* @param {number} courseId Course ID.
|
||||||
|
* @param {string} [password] Password.
|
||||||
|
* @return {Promise<any>} Promise resolved when the user is enrolled, rejected otherwise.
|
||||||
|
*/
|
||||||
|
protected selfEnrol(courseId: number, password?: string) : Promise<any> {
|
||||||
|
const modal = this.domUtils.showModalLoading();
|
||||||
|
return this.coursesProvider.selfEnrol(courseId, password).then(() => {
|
||||||
|
// Success self enrolling the user, invalidate the courses list.
|
||||||
|
return this.coursesProvider.invalidateUserCourses().catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
}).then(() => {
|
||||||
|
// Sometimes the list of enrolled courses takes a while to be updated. Wait for it.
|
||||||
|
return this.waitForEnrolled(courseId, true).finally(() => {
|
||||||
|
modal.dismiss();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}).catch((error) => {
|
||||||
|
modal.dismiss();
|
||||||
|
if (error && error.code === CoreCoursesProvider.ENROL_INVALID_KEY) {
|
||||||
|
// Invalid password. Allow the user to input password.
|
||||||
|
let title = this.translate.instant('core.courses.selfenrolment'),
|
||||||
|
body = ' ', // Empty message.
|
||||||
|
placeholder = this.translate.instant('core.courses.password');
|
||||||
|
|
||||||
|
if (typeof password != 'undefined') {
|
||||||
|
// The user attempted a password. Show an error message.
|
||||||
|
this.domUtils.showErrorModal(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.domUtils.showPrompt(body, title, placeholder).then((password) => {
|
||||||
|
return this.selfEnrol(courseId, password);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for the user to be enrolled in a course.
|
||||||
|
*
|
||||||
|
* @param {number} courseId The course ID.
|
||||||
|
* @param {boolean} first If it's the first call (true) or it's a recursive call (false).
|
||||||
|
* @return {Promise<any>} Promise resolved when enrolled or timeout.
|
||||||
|
*/
|
||||||
|
protected waitForEnrolled(courseId: number, first?: boolean) : Promise<any> {
|
||||||
|
if (first) {
|
||||||
|
this.waitStart = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is enrolled in the course.
|
||||||
|
return this.coursesProvider.invalidateUserCourses().catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
}).then(() => {
|
||||||
|
return this.coursesProvider.getUserCourse(courseId);
|
||||||
|
}).catch(() => {
|
||||||
|
// Not enrolled, wait a bit and try again.
|
||||||
|
if (Date.now() - this.waitStart > 60000) {
|
||||||
|
// Max time reached, stop.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.waitForEnrolled(courseId).then(resolve);
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
// (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 { CoreContentLinksHandlerBase } from '../../contentlinks/classes/base-handler';
|
||||||
|
import { CoreContentLinksAction } from '../../contentlinks/providers/delegate';
|
||||||
|
import { CoreLoginHelperProvider } from '../../login/providers/helper';
|
||||||
|
import { CoreCoursesProvider } from './courses';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to treat links to course index (list of courses).
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class CoreCoursesIndexLinkHandler extends CoreContentLinksHandlerBase {
|
||||||
|
name = 'CoreCoursesIndexLinkHandler';
|
||||||
|
featureName = '$mmSideMenuDelegate_mmCourses';
|
||||||
|
pattern = /\/course\/?(index\.php.*)?$/;
|
||||||
|
|
||||||
|
constructor(private coursesProvider: CoreCoursesProvider, private loginHelper: CoreLoginHelperProvider) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of actions for a link (url).
|
||||||
|
*
|
||||||
|
* @param {string[]} siteIds List of sites the URL belongs to.
|
||||||
|
* @param {string} url The URL to treat.
|
||||||
|
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
|
* @param {number} [courseId] Course ID related to the URL. Optional but recommended.
|
||||||
|
* @return {CoreContentLinksAction[]|Promise<CoreContentLinksAction[]>} List of (or promise resolved with list of) actions.
|
||||||
|
*/
|
||||||
|
getActions(siteIds: string[], url: string, params: any, courseId?: number) :
|
||||||
|
CoreContentLinksAction[]|Promise<CoreContentLinksAction[]> {
|
||||||
|
return [{
|
||||||
|
action: (siteId, navCtrl?) => {
|
||||||
|
var page = 'CoreCoursesMyCoursesPage', // By default, go to My Courses.
|
||||||
|
pageParams: any = {};
|
||||||
|
|
||||||
|
if (this.coursesProvider.isGetCoursesByFieldAvailable()) {
|
||||||
|
if (params.categoryid) {
|
||||||
|
page = 'CoreCoursesCategoriesPage';
|
||||||
|
pageParams.categoryId = parseInt(params.categoryid, 10);
|
||||||
|
} else {
|
||||||
|
page = 'CoreCoursesAvailableCoursesPage';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always use redirect to make it the new history root (to avoid "loops" in history).
|
||||||
|
this.loginHelper.redirect(page, pageParams, siteId);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
// (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 { CoreContentLinksHandlerBase } from '../../contentlinks/classes/base-handler';
|
||||||
|
import { CoreContentLinksAction } from '../../contentlinks/providers/delegate';
|
||||||
|
import { CoreLoginHelperProvider } from '../../login/providers/helper';
|
||||||
|
import { CoreCoursesProvider } from './courses';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to treat links to my overview.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class CoreCoursesMyOverviewLinkHandler extends CoreContentLinksHandlerBase {
|
||||||
|
name = 'CoreCoursesMyOverviewLinkHandler';
|
||||||
|
featureName = '$mmSideMenuDelegate_mmCourses';
|
||||||
|
pattern = /\/my\/?$/;
|
||||||
|
|
||||||
|
constructor(private coursesProvider: CoreCoursesProvider, private loginHelper: CoreLoginHelperProvider) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of actions for a link (url).
|
||||||
|
*
|
||||||
|
* @param {string[]} siteIds List of sites the URL belongs to.
|
||||||
|
* @param {string} url The URL to treat.
|
||||||
|
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
|
* @param {number} [courseId] Course ID related to the URL. Optional but recommended.
|
||||||
|
* @return {CoreContentLinksAction[]|Promise<CoreContentLinksAction[]>} List of (or promise resolved with list of) actions.
|
||||||
|
*/
|
||||||
|
getActions(siteIds: string[], url: string, params: any, courseId?: number) :
|
||||||
|
CoreContentLinksAction[]|Promise<CoreContentLinksAction[]> {
|
||||||
|
return [{
|
||||||
|
action: (siteId, navCtrl?) => {
|
||||||
|
// Always use redirect to make it the new history root (to avoid "loops" in history).
|
||||||
|
this.loginHelper.redirect('CoreCoursesMyOverviewPage', undefined, siteId);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ import { CoreSitesProvider } from '../../../../providers/sites';
|
||||||
import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
|
import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
|
||||||
import { CoreUtilsProvider } from '../../../../providers/utils/utils';
|
import { CoreUtilsProvider } from '../../../../providers/utils/utils';
|
||||||
import { CoreLoginHelperProvider } from '../../providers/helper';
|
import { CoreLoginHelperProvider } from '../../providers/helper';
|
||||||
|
import { CoreContentLinksDelegate } from '../../../contentlinks/providers/delegate';
|
||||||
|
import { CoreContentLinksHelperProvider } from '../../../contentlinks/providers/helper';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,7 +54,8 @@ export class CoreLoginCredentialsPage {
|
||||||
constructor(private navCtrl: NavController, navParams: NavParams, fb: FormBuilder, private appProvider: CoreAppProvider,
|
constructor(private navCtrl: NavController, navParams: NavParams, fb: FormBuilder, private appProvider: CoreAppProvider,
|
||||||
private sitesProvider: CoreSitesProvider, private loginHelper: CoreLoginHelperProvider,
|
private sitesProvider: CoreSitesProvider, private loginHelper: CoreLoginHelperProvider,
|
||||||
private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private utils: CoreUtilsProvider,
|
private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private utils: CoreUtilsProvider,
|
||||||
private eventsProvider: CoreEventsProvider) {
|
private eventsProvider: CoreEventsProvider, private contentLinksDelegate: CoreContentLinksDelegate,
|
||||||
|
private contentLinksHelper: CoreContentLinksHelperProvider) {
|
||||||
|
|
||||||
this.siteUrl = navParams.get('siteUrl');
|
this.siteUrl = navParams.get('siteUrl');
|
||||||
this.siteConfig = navParams.get('siteConfig');
|
this.siteConfig = navParams.get('siteConfig');
|
||||||
|
@ -203,16 +206,15 @@ export class CoreLoginCredentialsPage {
|
||||||
|
|
||||||
if (this.urlToOpen) {
|
if (this.urlToOpen) {
|
||||||
// There's a content link to open.
|
// There's a content link to open.
|
||||||
// @todo: Implement this once content links delegate is implemented.
|
return this.contentLinksDelegate.getActionsFor(this.urlToOpen, undefined, username).then((actions) => {
|
||||||
// return $mmContentLinksDelegate.getActionsFor(urlToOpen, undefined, username).then((actions) => {
|
const action = this.contentLinksHelper.getFirstValidAction(actions);
|
||||||
// action = $mmContentLinksHelper.getFirstValidAction(actions);
|
if (action && action.sites.length) {
|
||||||
// if (action && action.sites.length) {
|
// Action should only have 1 site because we're filtering by username.
|
||||||
// // Action should only have 1 site because we're filtering by username.
|
action.action(action.sites[0]);
|
||||||
// action.action(action.sites[0]);
|
} else {
|
||||||
// } else {
|
return this.loginHelper.goToSiteInitialPage();
|
||||||
// return $mmLoginHelper.goToSiteInitialPage();
|
}
|
||||||
// }
|
});
|
||||||
// });
|
|
||||||
} else {
|
} else {
|
||||||
return this.loginHelper.goToSiteInitialPage();
|
return this.loginHelper.goToSiteInitialPage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
// (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 { CoreSitesProvider } from '../../../providers/sites';
|
||||||
|
import { CoreContentLinksHandlerBase } from '../../contentlinks/classes/base-handler';
|
||||||
|
import { CoreContentLinksAction } from '../../contentlinks/providers/delegate';
|
||||||
|
import { CoreLoginHelperProvider } from '../../login/providers/helper';
|
||||||
|
import { CoreSiteHomeProvider } from './sitehome';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to treat links to site home index.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class CoreSiteHomeIndexLinkHandler extends CoreContentLinksHandlerBase {
|
||||||
|
name = 'CoreSiteHomeIndexLinkHandler';
|
||||||
|
featureName = '$mmSideMenuDelegate_mmaFrontpage';
|
||||||
|
pattern = /\/course\/view\.php.*([\?\&]id=\d+)/;
|
||||||
|
|
||||||
|
constructor(private sitesProvider: CoreSitesProvider, private siteHomeProvider: CoreSiteHomeProvider,
|
||||||
|
private loginHelper: CoreLoginHelperProvider) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of actions for a link (url).
|
||||||
|
*
|
||||||
|
* @param {string[]} siteIds List of sites the URL belongs to.
|
||||||
|
* @param {string} url The URL to treat.
|
||||||
|
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
|
* @param {number} [courseId] Course ID related to the URL. Optional but recommended.
|
||||||
|
* @return {CoreContentLinksAction[]|Promise<CoreContentLinksAction[]>} List of (or promise resolved with list of) actions.
|
||||||
|
*/
|
||||||
|
getActions(siteIds: string[], url: string, params: any, courseId?: number) :
|
||||||
|
CoreContentLinksAction[]|Promise<CoreContentLinksAction[]> {
|
||||||
|
return [{
|
||||||
|
action: (siteId, navCtrl?) => {
|
||||||
|
// Always use redirect to make it the new history root (to avoid "loops" in history).
|
||||||
|
this.loginHelper.redirect('CoreSiteHomeIndexPage', undefined, siteId);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the handler is enabled for a certain site (site + user) and a URL.
|
||||||
|
* If not defined, defaults to true.
|
||||||
|
*
|
||||||
|
* @param {string} siteId The site ID.
|
||||||
|
* @param {string} url The URL to treat.
|
||||||
|
* @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
|
* @param {number} [courseId] Course ID related to the URL. Optional but recommended.
|
||||||
|
* @return {boolean|Promise<boolean>} Whether the handler is enabled for the URL and site.
|
||||||
|
*/
|
||||||
|
isEnabled(siteId: string, url: string, params: any, courseId?: number) : boolean|Promise<boolean> {
|
||||||
|
courseId = parseInt(params.id, 10);
|
||||||
|
if (!courseId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
if (courseId != site.getSiteHomeId()) {
|
||||||
|
// The course is not site home.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.siteHomeProvider.isAvailable(siteId).then(() => {
|
||||||
|
return true;
|
||||||
|
}).catch(() => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,9 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CoreSiteHomeProvider } from './providers/sitehome';
|
import { CoreSiteHomeProvider } from './providers/sitehome';
|
||||||
import { CoreSiteHomeMainMenuHandler } from './providers/mainmenu-handler';
|
import { CoreSiteHomeMainMenuHandler } from './providers/mainmenu-handler';
|
||||||
|
import { CoreSiteHomeIndexLinkHandler } from './providers/index-link-handler';
|
||||||
import { CoreMainMenuDelegate } from '../mainmenu/providers/delegate';
|
import { CoreMainMenuDelegate } from '../mainmenu/providers/delegate';
|
||||||
|
import { CoreContentLinksDelegate } from '../contentlinks/providers/delegate';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [],
|
declarations: [],
|
||||||
|
@ -23,12 +25,15 @@ import { CoreMainMenuDelegate } from '../mainmenu/providers/delegate';
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
CoreSiteHomeProvider,
|
CoreSiteHomeProvider,
|
||||||
CoreSiteHomeMainMenuHandler
|
CoreSiteHomeMainMenuHandler,
|
||||||
|
CoreSiteHomeIndexLinkHandler
|
||||||
],
|
],
|
||||||
exports: []
|
exports: []
|
||||||
})
|
})
|
||||||
export class CoreSiteHomeModule {
|
export class CoreSiteHomeModule {
|
||||||
constructor(mainMenuDelegate: CoreMainMenuDelegate, mainMenuHandler: CoreSiteHomeMainMenuHandler) {
|
constructor(mainMenuDelegate: CoreMainMenuDelegate, contentLinksDelegate: CoreContentLinksDelegate,
|
||||||
|
mainMenuHandler: CoreSiteHomeMainMenuHandler, indexLinkHandler: CoreSiteHomeIndexLinkHandler) {
|
||||||
mainMenuDelegate.registerHandler(mainMenuHandler);
|
mainMenuDelegate.registerHandler(mainMenuHandler);
|
||||||
|
contentLinksDelegate.registerHandler(indexLinkHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Directive, ElementRef, Input, Output, EventEmitter, OnChanges, SimpleChange } from '@angular/core';
|
import { Directive, ElementRef, Input, Output, EventEmitter, OnChanges, SimpleChange } from '@angular/core';
|
||||||
import { Platform } from 'ionic-angular';
|
import { Platform, NavController } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreAppProvider } from '../providers/app';
|
import { CoreAppProvider } from '../providers/app';
|
||||||
import { CoreFilepoolProvider } from '../providers/filepool';
|
import { CoreFilepoolProvider } from '../providers/filepool';
|
||||||
|
@ -26,6 +26,7 @@ import { CoreUtilsProvider } from '../providers/utils/utils';
|
||||||
import { CoreSite } from '../classes/site';
|
import { CoreSite } from '../classes/site';
|
||||||
import { CoreLinkDirective } from '../directives/link';
|
import { CoreLinkDirective } from '../directives/link';
|
||||||
import { CoreExternalContentDirective } from '../directives/external-content';
|
import { CoreExternalContentDirective } from '../directives/external-content';
|
||||||
|
import { CoreContentLinksHelperProvider } from '../core/contentlinks/providers/helper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to format text rendered. It renders the HTML and treats all links and media, using CoreLinkDirective
|
* Directive to format text rendered. It renders the HTML and treats all links and media, using CoreLinkDirective
|
||||||
|
@ -60,7 +61,8 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
constructor(element: ElementRef, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
|
constructor(element: ElementRef, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
|
||||||
private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private platform: Platform,
|
private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private platform: Platform,
|
||||||
private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider, private loggerProvider: CoreLoggerProvider,
|
private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider, private loggerProvider: CoreLoggerProvider,
|
||||||
private filepoolProvider: CoreFilepoolProvider, private appProvider: CoreAppProvider) {
|
private filepoolProvider: CoreFilepoolProvider, private appProvider: CoreAppProvider,
|
||||||
|
private contentLinksHelper: CoreContentLinksHelperProvider, private navCtrl: NavController) {
|
||||||
this.element = element.nativeElement;
|
this.element = element.nativeElement;
|
||||||
this.element.classList.add('opacity-hide'); // Hide contents until they're treated.
|
this.element.classList.add('opacity-hide'); // Hide contents until they're treated.
|
||||||
this.afterRender = new EventEmitter();
|
this.afterRender = new EventEmitter();
|
||||||
|
@ -274,7 +276,8 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
// Important: We need to look for links first because in 'img' we add new links without core-link.
|
// Important: We need to look for links first because in 'img' we add new links without core-link.
|
||||||
anchors.forEach((anchor) => {
|
anchors.forEach((anchor) => {
|
||||||
// Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
|
// Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
|
||||||
let linkDir = new CoreLinkDirective(anchor, this.domUtils, this.utils, this.sitesProvider, this.urlUtils);
|
let linkDir = new CoreLinkDirective(anchor, this.domUtils, this.utils, this.sitesProvider, this.urlUtils,
|
||||||
|
this.contentLinksHelper, this.navCtrl);
|
||||||
linkDir.capture = true;
|
linkDir.capture = true;
|
||||||
linkDir.ngOnInit();
|
linkDir.ngOnInit();
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
|
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
|
||||||
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreSitesProvider } from '../providers/sites';
|
import { CoreSitesProvider } from '../providers/sites';
|
||||||
import { CoreDomUtilsProvider } from '../providers/utils/dom';
|
import { CoreDomUtilsProvider } from '../providers/utils/dom';
|
||||||
import { CoreUrlUtilsProvider } from '../providers/utils/url';
|
import { CoreUrlUtilsProvider } from '../providers/utils/url';
|
||||||
import { CoreUtilsProvider } from '../providers/utils/utils';
|
import { CoreUtilsProvider } from '../providers/utils/utils';
|
||||||
|
import { CoreContentLinksHelperProvider } from '../core/contentlinks/providers/helper';
|
||||||
import { CoreConfigConstants } from '../configconstants';
|
import { CoreConfigConstants } from '../configconstants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +38,8 @@ export class CoreLinkDirective implements OnInit {
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
|
|
||||||
constructor(element: ElementRef, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider,
|
constructor(element: ElementRef, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider,
|
||||||
private sitesProvider: CoreSitesProvider, private urlUtils: CoreUrlUtilsProvider) {
|
private sitesProvider: CoreSitesProvider, private urlUtils: CoreUrlUtilsProvider,
|
||||||
|
private contentLinksHelper: CoreContentLinksHelperProvider, private navCtrl: NavController) {
|
||||||
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement || element;
|
||||||
}
|
}
|
||||||
|
@ -56,12 +59,11 @@ export class CoreLinkDirective implements OnInit {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
if (this.utils.isTrueOrOne(this.capture)) {
|
if (this.utils.isTrueOrOne(this.capture)) {
|
||||||
// @todo: Handle link using content links helper.
|
this.contentLinksHelper.handleLink(href, undefined, this.navCtrl).then((treated) => {
|
||||||
// $mmContentLinksHelper.handleLink(href).then((treated) => {
|
if (!treated) {
|
||||||
// if (!treated) {
|
|
||||||
this.navigate(href);
|
this.navigate(href);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
} else {
|
} else {
|
||||||
this.navigate(href);
|
this.navigate(href);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue