MOBILE-3565 contentlinks: Add content links delegate structure
parent
f3ae7e5e4a
commit
dd43b9460b
|
@ -0,0 +1,116 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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 { Params } from '@angular/router';
|
||||
import { CoreContentLinksHandler, CoreContentLinksAction } from '../services/contentlinks.delegate';
|
||||
|
||||
/**
|
||||
* Base handler to be registered in CoreContentLinksHandler. It is useful to minimize the amount of
|
||||
* functions that handlers need to implement.
|
||||
*
|
||||
* It allows you to specify a "pattern" (RegExp) that will be used to check if the handler handles a URL and to get its site URL.
|
||||
*/
|
||||
export class CoreContentLinksHandlerBase implements CoreContentLinksHandler {
|
||||
|
||||
/**
|
||||
* A name to identify the handler.
|
||||
*/
|
||||
name = 'CoreContentLinksHandlerBase';
|
||||
|
||||
/**
|
||||
* Handler's priority. The highest priority is treated first.
|
||||
*/
|
||||
priority = 0;
|
||||
|
||||
/**
|
||||
* Whether the isEnabled function should be called for all the users in a site. It should be true only if the isEnabled call
|
||||
* can return different values for different users in same site.
|
||||
*/
|
||||
checkAllUsers = false;
|
||||
|
||||
/**
|
||||
* Name of the feature this handler is related to.
|
||||
* It will be used to check if the feature is disabled (@see CoreSite.isFeatureDisabled).
|
||||
*/
|
||||
featureName = '';
|
||||
|
||||
/**
|
||||
* A pattern to use to detect if the handler handles a URL and to get its site URL. Required if "handles" and
|
||||
* "getSiteUrl" functions aren't overridden.
|
||||
*/
|
||||
pattern?: RegExp;
|
||||
|
||||
/**
|
||||
* Get the list of actions for a link (url).
|
||||
*
|
||||
* @param siteIds List of sites the URL belongs to.
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @return List of (or promise resolved with list of) actions.
|
||||
*/
|
||||
getActions(
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
siteIds: string[],
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
url: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
params: Params,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
courseId?: number,
|
||||
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a URL is handled by this handler.
|
||||
*
|
||||
* @param url The URL to check.
|
||||
* @return Whether the URL is handled by this handler
|
||||
*/
|
||||
handles(url: string): boolean {
|
||||
return !!this.pattern && url.search(this.pattern) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the URL is handled by this handler, return the site URL.
|
||||
*
|
||||
* @param url The URL to check.
|
||||
* @return Site URL if it is handled, undefined otherwise.
|
||||
*/
|
||||
getSiteUrl(url: string): string | undefined {
|
||||
if (this.pattern) {
|
||||
const position = url.search(this.pattern);
|
||||
if (position > -1) {
|
||||
return url.substr(0, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled for a certain site (site + user) and a URL.
|
||||
* If not defined, defaults to true.
|
||||
*
|
||||
* @param siteId The site ID.
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @return Whether the handler is enabled for the URL and site.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
isEnabled(siteId: string, url: string, params: Params, courseId?: number): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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 { CoreContentLinksAction } from '../services/contentlinks.delegate';
|
||||
import { CoreContentLinksHandlerBase } from './base-handler';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
// import { CoreCourseHelperProvider } from '@core/course/providers/helper';
|
||||
import { Params } from '@angular/router';
|
||||
|
||||
/**
|
||||
* Handler to handle URLs pointing to the grade of a module.
|
||||
*/
|
||||
export class CoreContentLinksModuleGradeHandler extends CoreContentLinksHandlerBase {
|
||||
|
||||
/**
|
||||
* Whether the module can be reviewed in the app. If true, the handler needs to implement the goToReview function.
|
||||
*/
|
||||
canReview = false;
|
||||
|
||||
/**
|
||||
* If this boolean is set to true, the app will retrieve all modules with this modName with a single WS call.
|
||||
* This reduces the number of WS calls, but it isn't recommended for modules that can return a lot of contents.
|
||||
*/
|
||||
protected useModNameToGetModule = false;
|
||||
|
||||
/**
|
||||
* Construct the handler.
|
||||
*
|
||||
* @param addon Name of the addon as it's registered in course delegate. It'll be used to check if it's disabled.
|
||||
* @param modName Name of the module (assign, book, ...).
|
||||
*/
|
||||
constructor(
|
||||
public addon: string,
|
||||
public modName: string,
|
||||
) {
|
||||
super();
|
||||
|
||||
// Match the grade.php URL with an id param.
|
||||
this.pattern = new RegExp('/mod/' + modName + '/grade.php.*([&?]id=\\d+)');
|
||||
this.featureName = 'CoreCourseModuleDelegate_' + addon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of actions for a link (url).
|
||||
*
|
||||
* @param siteIds Unused. List of sites the URL belongs to.
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @return List of (or promise resolved with list of) actions.
|
||||
*/
|
||||
getActions(
|
||||
siteIds: string[],
|
||||
url: string,
|
||||
params: Params,
|
||||
courseId?: number,
|
||||
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
||||
|
||||
courseId = courseId || params.courseid || params.cid;
|
||||
|
||||
return [{
|
||||
action: async (siteId): Promise<void> => {
|
||||
// Check if userid is the site's current user.
|
||||
const modal = await CoreDomUtils.instance.showModalLoading();
|
||||
const site = await CoreSites.instance.getSite(siteId);
|
||||
if (!params.userid || params.userid == site.getUserId()) {
|
||||
// No user specified or current user. Navigate to module.
|
||||
// @todo this.courseHelper.navigateToModule(parseInt(params.id, 10), siteId, courseId, undefined,
|
||||
// this.useModNameToGetModule ? this.modName : undefined, undefined, navCtrl);
|
||||
} else if (this.canReview) {
|
||||
// Use the goToReview function.
|
||||
this.goToReview(url, params, courseId!, siteId);
|
||||
} else {
|
||||
// Not current user and cannot review it in the app, open it in browser.
|
||||
site.openInBrowserWithAutoLogin(url);
|
||||
}
|
||||
|
||||
modal.dismiss();
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to the page to review.
|
||||
*
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL.
|
||||
* @param siteId Site to use.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
protected async goToReview(
|
||||
url: string, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
params: Params, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
courseId: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
siteId: string, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
): Promise<void> {
|
||||
// This function should be overridden.
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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 { CoreContentLinksHandlerBase } from './base-handler';
|
||||
import { Params } from '@angular/router';
|
||||
import { CoreContentLinksAction } from '../services/contentlinks.delegate';
|
||||
|
||||
/**
|
||||
* Handler to handle URLs pointing to the index of a module.
|
||||
*/
|
||||
export class CoreContentLinksModuleIndexHandler extends CoreContentLinksHandlerBase {
|
||||
|
||||
/**
|
||||
* If this boolean is set to true, the app will retrieve all modules with this modName with a single WS call.
|
||||
* This reduces the number of WS calls, but it isn't recommended for modules that can return a lot of contents.
|
||||
*/
|
||||
protected useModNameToGetModule = false;
|
||||
|
||||
/**
|
||||
* Construct the handler.
|
||||
*
|
||||
* @param addon Name of the addon as it's registered in course delegate. It'll be used to check if it's disabled.
|
||||
* @param modName Name of the module (assign, book, ...).
|
||||
* @param instanceIdParam Param name for instance ID gathering. Only if set.
|
||||
*/
|
||||
constructor(
|
||||
public addon: string,
|
||||
public modName: string,
|
||||
protected instanceIdParam?: string,
|
||||
) {
|
||||
super();
|
||||
|
||||
const pattern = instanceIdParam ?
|
||||
'/mod/' + modName + '/view.php.*([&?](' + instanceIdParam + '|id)=\\d+)' :
|
||||
'/mod/' + modName + '/view.php.*([&?]id=\\d+)';
|
||||
|
||||
// Match the view.php URL with an id param.
|
||||
this.pattern = new RegExp(pattern);
|
||||
this.featureName = 'CoreCourseModuleDelegate_' + addon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mod params necessary to open an activity.
|
||||
*
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @return List of params to pass to navigateToModule / navigateToModuleByInstance.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
getPageParams(url: string, params: Params, courseId?: number): Params {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of actions for a link (url).
|
||||
*
|
||||
* @param siteIds List of sites the URL belongs to.
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @return List of (or promise resolved with list of) actions.
|
||||
*/
|
||||
getActions(
|
||||
siteIds: string[], // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
url: string, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
params: Params, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
courseId?: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
||||
return [];
|
||||
/*
|
||||
courseId = courseId || params.courseid || params.cid;
|
||||
const pageParams = this.getPageParams(url, params, courseId);
|
||||
|
||||
if (this.instanceIdParam && typeof params[this.instanceIdParam] != 'undefined') {
|
||||
const instanceId = parseInt(params[this.instanceIdParam], 10);
|
||||
|
||||
return [{
|
||||
action: (siteId): void => {
|
||||
this.courseHelper.navigateToModuleByInstance(instanceId, this.modName, siteId, courseId, undefined,
|
||||
this.useModNameToGetModule, pageParams);
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
return [{
|
||||
action: (siteId): void => {
|
||||
this.courseHelper.navigateToModule(parseInt(params.id, 10), siteId, courseId, undefined,
|
||||
this.useModNameToGetModule ? this.modName : undefined, pageParams);
|
||||
},
|
||||
}];
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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 { CoreContentLinksHelper } from '../services/contentlinks.helper';
|
||||
import { CoreContentLinksHandlerBase } from './base-handler';
|
||||
import { Translate } from '@/app/singletons/core.singletons';
|
||||
import { Params } from '@angular/router';
|
||||
import { CoreContentLinksAction } from '../services/contentlinks.delegate';
|
||||
|
||||
/**
|
||||
* Handler to handle URLs pointing to a list of a certain type of modules.
|
||||
*/
|
||||
export class CoreContentLinksModuleListHandler extends CoreContentLinksHandlerBase {
|
||||
|
||||
/**
|
||||
* The title to use in the new page. If not defined, the app will try to calculate it.
|
||||
*/
|
||||
protected title = '';
|
||||
|
||||
/**
|
||||
* Construct the handler.
|
||||
*
|
||||
* @param linkHelper The CoreContentLinksHelperProvider instance.
|
||||
* @param translate The TranslateService instance.
|
||||
* @param addon Name of the addon as it's registered in course delegate. It'll be used to check if it's disabled.
|
||||
* @param modName Name of the module (assign, book, ...).
|
||||
*/
|
||||
constructor(
|
||||
public addon: string,
|
||||
public modName: string,
|
||||
) {
|
||||
super();
|
||||
|
||||
// Match the view.php URL with an id param.
|
||||
this.pattern = new RegExp('/mod/' + modName + '/index.php.*([&?]id=\\d+)');
|
||||
this.featureName = 'CoreCourseModuleDelegate_' + addon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of actions for a link (url).
|
||||
*
|
||||
* @param siteIds List of sites the URL belongs to.
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @return List of (or promise resolved with list of) actions.
|
||||
*/
|
||||
getActions(siteIds: string[], url: string, params: Params): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
||||
|
||||
return [{
|
||||
action: (siteId): void => {
|
||||
const stateParams = {
|
||||
courseId: params.id,
|
||||
modName: this.modName,
|
||||
title: this.title || Translate.instance.instant('addon.mod_' + this.modName + '.modulenameplural'),
|
||||
};
|
||||
|
||||
CoreContentLinksHelper.instance.goInSite('CoreCourseListModTypePage @todo', stateParams, siteId);
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"chooseaccount": "Choose account",
|
||||
"chooseaccounttoopenlink": "Choose an account to open the link with.",
|
||||
"confirmurlothersite": "This link belongs to another site. Do you want to open it?",
|
||||
"errornoactions": "Couldn't find an action to perform with this link.",
|
||||
"errornosites": "Couldn't find any site to handle this link.",
|
||||
"errorredirectothersite": "The redirect URL cannot point to a different site."
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ 'core.contentlinks.chooseaccount' | translate }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<core-loading [hideUntil]="loaded">
|
||||
<ion-list>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<p class="item-heading">{{ 'core.contentlinks.chooseaccounttoopenlink' | translate }}</p>
|
||||
<p>{{ url }}</p>
|
||||
</ion-item>
|
||||
<ion-item *ngFor="let site of sites" (click)="siteClicked(site.id)" detail="false">
|
||||
<ion-avatar slot="start">
|
||||
<img [src]="site.avatar" core-external-content [siteId]="site.id"
|
||||
alt="{{ 'core.pictureof' | translate:{$a: site.fullName} }}" role="presentation"
|
||||
onError="this.src='assets/img/user-avatar.png'">
|
||||
</ion-avatar>
|
||||
<h2>{{site.fullName}}</h2>
|
||||
<p><core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text></p>
|
||||
<p>{{site.siteUrl}}</p>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-button expand="block" (click)="cancel()">{{ 'core.login.cancel' | translate }}</ion-button>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -0,0 +1,47 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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 { NgModule } from '@angular/core';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
import { CoreContentLinksChooseSitePage } from './choose-site.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: CoreContentLinksChooseSitePage,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
CoreContentLinksChooseSitePage,
|
||||
],
|
||||
imports: [
|
||||
RouterModule.forChild(routes),
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
],
|
||||
})
|
||||
export class CoreContentLinksChooseSitePageModule {}
|
|
@ -0,0 +1,122 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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, OnInit } from '@angular/core';
|
||||
import { NavController } from '@ionic/angular';
|
||||
import { CoreSiteBasicInfo, CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { Translate } from '@singletons/core.singletons';
|
||||
import { CoreLoginHelper } from '@core/login/services/helper';
|
||||
import { CoreContentLinksAction } from '../../services/contentlinks.delegate';
|
||||
import { CoreContentLinksHelper } from '../../services/contentlinks.helper';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
|
||||
/**
|
||||
* Page to display the list of sites to choose one to perform a content link action.
|
||||
*
|
||||
* @todo Include routing and testing.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'page-core-content-links-choose-site',
|
||||
templateUrl: 'choose-site.html',
|
||||
})
|
||||
export class CoreContentLinksChooseSitePage implements OnInit {
|
||||
|
||||
url: string;
|
||||
sites: CoreSiteBasicInfo[] = [];
|
||||
loaded = false;
|
||||
protected action?: CoreContentLinksAction;
|
||||
protected isRootURL = false;
|
||||
|
||||
constructor(
|
||||
route: ActivatedRoute,
|
||||
protected navCtrl: NavController,
|
||||
) {
|
||||
this.url = route.snapshot.queryParamMap.get('url')!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
if (!this.url) {
|
||||
return this.leaveView();
|
||||
}
|
||||
|
||||
let siteIds: string[] | undefined = [];
|
||||
|
||||
try {
|
||||
// Check if it's the root URL.
|
||||
const data = await CoreSites.instance.isStoredRootURL(this.url);
|
||||
if (data.site) {
|
||||
// It's the root URL.
|
||||
this.isRootURL = true;
|
||||
|
||||
siteIds = data.siteIds;
|
||||
} else if (data.siteIds.length) {
|
||||
// Not root URL, but the URL belongs to at least 1 site. Check if there is any action to treat the link.
|
||||
this.action = await CoreContentLinksHelper.instance.getFirstValidActionFor(this.url);
|
||||
if (!this.action) {
|
||||
throw new CoreError(Translate.instance.instant('core.contentlinks.errornoactions'));
|
||||
}
|
||||
|
||||
siteIds = this.action.sites;
|
||||
} else {
|
||||
// No sites to treat the URL.
|
||||
throw new CoreError(Translate.instance.instant('core.contentlinks.errornosites'));
|
||||
}
|
||||
|
||||
// Get the sites that can perform the action.
|
||||
this.sites = await CoreSites.instance.getSites(siteIds);
|
||||
} catch (error) {
|
||||
CoreDomUtils.instance.showErrorModalDefault(error, 'core.contentlinks.errornosites', true);
|
||||
this.leaveView();
|
||||
}
|
||||
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel.
|
||||
*/
|
||||
cancel(): void {
|
||||
this.leaveView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the action on a certain site.
|
||||
*
|
||||
* @param siteId Site ID.
|
||||
*/
|
||||
siteClicked(siteId: string): void {
|
||||
if (this.isRootURL) {
|
||||
CoreLoginHelper.instance.redirect('', {}, siteId);
|
||||
} else if (this.action) {
|
||||
this.action.action(siteId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel and leave the view.
|
||||
*/
|
||||
protected async leaveView(): Promise<void> {
|
||||
try {
|
||||
await CoreSites.instance.logout();
|
||||
} finally {
|
||||
await this.navCtrl.navigateRoot('/login/sites');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,309 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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 { CoreLogger } from '@singletons/logger';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreUrlUtils } from '@services/utils/url';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { Params } from '@angular/router';
|
||||
|
||||
/**
|
||||
* Interface that all handlers must implement.
|
||||
*/
|
||||
export interface CoreContentLinksHandler {
|
||||
/**
|
||||
* A name to identify the handler.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Handler's priority. The highest priority is treated first.
|
||||
*/
|
||||
priority?: number;
|
||||
|
||||
/**
|
||||
* Whether the isEnabled function should be called for all the users in a site. It should be true only if the isEnabled call
|
||||
* can return different values for different users in same site.
|
||||
*/
|
||||
checkAllUsers?: boolean;
|
||||
|
||||
/**
|
||||
* Name of the feature this handler is related to.
|
||||
* It will be used to check if the feature is disabled (@see CoreSite.isFeatureDisabled).
|
||||
*/
|
||||
featureName?: string;
|
||||
|
||||
/**
|
||||
* Get the list of actions for a link (url).
|
||||
*
|
||||
* @param siteIds List of sites the URL belongs to.
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @param data Extra data to handle the URL.
|
||||
* @return List of (or promise resolved with list of) actions.
|
||||
*/
|
||||
getActions(siteIds: string[], url: string, params: Params, courseId?: number, data?: unknown):
|
||||
CoreContentLinksAction[] | Promise<CoreContentLinksAction[]>;
|
||||
|
||||
/**
|
||||
* Check if a URL is handled by this handler.
|
||||
*
|
||||
* @param url The URL to check.
|
||||
* @return Whether the URL is handled by this handler
|
||||
*/
|
||||
handles(url: string): boolean;
|
||||
|
||||
/**
|
||||
* If the URL is handled by this handler, return the site URL.
|
||||
*
|
||||
* @param url The URL to check.
|
||||
* @return Site URL if it is handled, undefined otherwise.
|
||||
*/
|
||||
getSiteUrl(url: string): string | undefined;
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled for a certain site (site + user) and a URL.
|
||||
* If not defined, defaults to true.
|
||||
*
|
||||
* @param siteId The site ID.
|
||||
* @param url The URL to treat.
|
||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @return Whether the handler is enabled for the URL and site.
|
||||
*/
|
||||
isEnabled?(siteId: string, url: string, params: Params, courseId?: number): boolean | Promise<boolean>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to perform when a link is clicked.
|
||||
*/
|
||||
export interface CoreContentLinksAction {
|
||||
/**
|
||||
* A message to identify the action. Default: 'core.view'.
|
||||
*/
|
||||
message?: string;
|
||||
|
||||
/**
|
||||
* Name of the icon of the action. Default: 'fas-eye'.
|
||||
*/
|
||||
icon?: string;
|
||||
|
||||
/**
|
||||
* IDs of the sites that support the action.
|
||||
*/
|
||||
sites?: string[];
|
||||
|
||||
/**
|
||||
* Action to perform when the link is clicked.
|
||||
*
|
||||
* @param siteId The site ID.
|
||||
*/
|
||||
action(siteId: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions and priority for a handler and URL.
|
||||
*/
|
||||
export interface CoreContentLinksHandlerActions {
|
||||
/**
|
||||
* Handler's priority.
|
||||
*/
|
||||
priority: number;
|
||||
|
||||
/**
|
||||
* List of actions.
|
||||
*/
|
||||
actions: CoreContentLinksAction[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate to register handlers to handle links.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CoreContentLinksDelegate {
|
||||
|
||||
protected logger: CoreLogger;
|
||||
protected handlers: { [s: string]: CoreContentLinksHandler } = {}; // All registered handlers.
|
||||
|
||||
constructor() {
|
||||
this.logger = CoreLogger.getInstance('CoreContentLinksDelegate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of possible actions to do for a URL.
|
||||
*
|
||||
* @param url URL to handle.
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @param username Username to use to filter sites.
|
||||
* @param data Extra data to handle the URL.
|
||||
* @return Promise resolved with the actions.
|
||||
*/
|
||||
async getActionsFor(url: string, courseId?: number, username?: string, data?: unknown): Promise<CoreContentLinksAction[]> {
|
||||
if (!url) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Get the list of sites the URL belongs to.
|
||||
const siteIds = await CoreSites.instance.getSiteIdsFromUrl(url, true, username);
|
||||
const linkActions: CoreContentLinksHandlerActions[] = [];
|
||||
const promises: Promise<void>[] = [];
|
||||
const params = CoreUrlUtils.instance.extractUrlParams(url);
|
||||
for (const name in this.handlers) {
|
||||
const handler = this.handlers[name];
|
||||
const checkAll = handler.checkAllUsers;
|
||||
const isEnabledFn = this.isHandlerEnabled.bind(this, handler, url, params, courseId);
|
||||
|
||||
if (!handler.handles(url)) {
|
||||
// Invalid handler or it doesn't handle the URL. Stop.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filter the site IDs using the isEnabled function.
|
||||
promises.push(CoreUtils.instance.filterEnabledSites(siteIds, isEnabledFn, checkAll).then(async (siteIds) => {
|
||||
if (!siteIds.length) {
|
||||
// No sites supported, no actions.
|
||||
return;
|
||||
}
|
||||
|
||||
const actions = await handler.getActions(siteIds, url, params, courseId, data);
|
||||
|
||||
if (actions && actions.length) {
|
||||
// Set default values if any value isn't supplied.
|
||||
actions.forEach((action) => {
|
||||
action.message = action.message || 'core.view';
|
||||
action.icon = action.icon || 'fas-eye';
|
||||
action.sites = action.sites || siteIds;
|
||||
});
|
||||
|
||||
// Add them to the list.
|
||||
linkActions.push({
|
||||
priority: handler.priority || 0,
|
||||
actions: actions,
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}));
|
||||
}
|
||||
try {
|
||||
await CoreUtils.instance.allPromises(promises);
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
// Sort link actions by priority.
|
||||
return this.sortActionsByPriority(linkActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the site URL if the URL is supported by any handler.
|
||||
*
|
||||
* @param url URL to handle.
|
||||
* @return Site URL if the URL is supported by any handler, undefined otherwise.
|
||||
*/
|
||||
getSiteUrl(url: string): string | void {
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if any handler supports this URL.
|
||||
for (const name in this.handlers) {
|
||||
const handler = this.handlers[name];
|
||||
const siteUrl = handler.getSiteUrl(url);
|
||||
|
||||
if (siteUrl) {
|
||||
return siteUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a handler is enabled for a certain site and URL.
|
||||
*
|
||||
* @param handler Handler to check.
|
||||
* @param url The URL to check.
|
||||
* @param params The params of the URL
|
||||
* @param courseId Course ID the URL belongs to (can be undefined).
|
||||
* @param siteId The site ID to check.
|
||||
* @return Promise resolved with boolean: whether the handler is enabled.
|
||||
*/
|
||||
protected async isHandlerEnabled(
|
||||
handler: CoreContentLinksHandler,
|
||||
url: string,
|
||||
params: Params,
|
||||
courseId: number,
|
||||
siteId: string,
|
||||
): Promise<boolean> {
|
||||
|
||||
let disabled = false;
|
||||
if (handler.featureName) {
|
||||
// Check if the feature is disabled.
|
||||
disabled = await CoreSites.instance.isFeatureDisabled(handler.featureName, siteId);
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!handler.isEnabled) {
|
||||
// Handler doesn't implement isEnabled, assume it's enabled.
|
||||
return true;
|
||||
}
|
||||
|
||||
return handler.isEnabled(siteId, url, params, courseId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler.
|
||||
*
|
||||
* @param handler The handler to register.
|
||||
* @return True if registered successfully, false otherwise.
|
||||
*/
|
||||
registerHandler(handler: CoreContentLinksHandler): boolean {
|
||||
if (typeof this.handlers[handler.name] !== 'undefined') {
|
||||
this.logger.log(`Addon '${handler.name}' already registered`);
|
||||
|
||||
return false;
|
||||
}
|
||||
this.logger.log(`Registered addon '${handler.name}'`);
|
||||
this.handlers[handler.name] = handler;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort actions by priority.
|
||||
*
|
||||
* @param actions Actions to sort.
|
||||
* @return Sorted actions.
|
||||
*/
|
||||
protected sortActionsByPriority(actions: CoreContentLinksHandlerActions[]): CoreContentLinksAction[] {
|
||||
let sorted: CoreContentLinksAction[] = [];
|
||||
|
||||
// Sort by priority.
|
||||
actions = actions.sort((a, b) => (a.priority || 0) <= (b.priority || 0) ? 1 : -1);
|
||||
|
||||
// Fill result array.
|
||||
actions.forEach((entry) => {
|
||||
sorted = sorted.concat(entry.actions);
|
||||
});
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// 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 { NavController } from '@ionic/angular';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreLoginHelper } from '@core/login/services/helper';
|
||||
import { CoreContentLinksDelegate, CoreContentLinksAction } from './contentlinks.delegate';
|
||||
import { CoreSite } from '@classes/site';
|
||||
import { CoreMainMenu } from '@core/mainmenu/services/mainmenu';
|
||||
import { makeSingleton, NgZone, Translate } from '@singletons/core.singletons';
|
||||
import { Params } from '@angular/router';
|
||||
|
||||
/**
|
||||
* Service that provides some features regarding content links.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CoreContentLinksHelperProvider {
|
||||
|
||||
constructor(
|
||||
protected contentLinksDelegate: CoreContentLinksDelegate,
|
||||
protected navCtrl: NavController,
|
||||
) { }
|
||||
|
||||
/**
|
||||
* Check whether a link can be handled by the app.
|
||||
*
|
||||
* @param url URL to handle.
|
||||
* @param courseId Unused param: Course ID related to the URL.
|
||||
* @param username Username to use to filter sites.
|
||||
* @param checkRoot Whether to check if the URL is the root URL of a site.
|
||||
* @return Promise resolved with a boolean: whether the URL can be handled.
|
||||
*/
|
||||
async canHandleLink(url: string, courseId?: number, username?: string, checkRoot?: boolean): Promise<boolean> {
|
||||
try {
|
||||
if (checkRoot) {
|
||||
const data = await CoreSites.instance.isStoredRootURL(url, username);
|
||||
|
||||
if (data.site) {
|
||||
// URL is the root of the site, can handle it.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const action = await this.getFirstValidActionFor(url, undefined, username);
|
||||
|
||||
return !!action;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first valid action in the list of possible actions to do for a URL.
|
||||
*
|
||||
* @param url URL to handle.
|
||||
* @param courseId Course ID related to the URL. Optional but recommended.
|
||||
* @param username Username to use to filter sites.
|
||||
* @param data Extra data to handle the URL.
|
||||
* @return Promise resolved with the first valid action. Returns undefined if no valid action found..
|
||||
*/
|
||||
async getFirstValidActionFor(
|
||||
url: string,
|
||||
courseId?: number,
|
||||
username?: string,
|
||||
data?: unknown,
|
||||
): Promise<CoreContentLinksAction | undefined> {
|
||||
const actions = await this.contentLinksDelegate.getActionsFor(url, courseId, username, data);
|
||||
if (!actions) {
|
||||
return;
|
||||
}
|
||||
|
||||
return actions.find((action) => action && action.sites && action.sites.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes to a certain page in a certain site. If the site is current site it will perform a regular navigation,
|
||||
* otherwise it will 'redirect' to the other site.
|
||||
*
|
||||
* @param pageName Name of the page to go.
|
||||
* @param pageParams Params to send to the page.
|
||||
* @param siteId Site ID. If not defined, current site.
|
||||
* @param checkMenu If true, check if the root page of a main menu tab. Only the page name will be checked.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
goInSite(
|
||||
pageName: string,
|
||||
pageParams: Params,
|
||||
siteId?: string,
|
||||
checkMenu?: boolean,
|
||||
): Promise<void> {
|
||||
siteId = siteId || CoreSites.instance.getCurrentSiteId();
|
||||
|
||||
const deferred = CoreUtils.instance.promiseDefer<void>();
|
||||
|
||||
// Execute the code in the Angular zone, so change detection doesn't stop working.
|
||||
NgZone.instance.run(async () => {
|
||||
try {
|
||||
if (siteId == CoreSites.instance.getCurrentSiteId()) {
|
||||
if (checkMenu) {
|
||||
let isInMenu = false;
|
||||
// Check if the page is in the main menu.
|
||||
try {
|
||||
isInMenu = await CoreMainMenu.instance.isCurrentMainMenuHandler(pageName);
|
||||
} catch {
|
||||
isInMenu = false;
|
||||
}
|
||||
|
||||
if (isInMenu) {
|
||||
// Just select the tab. @todo test.
|
||||
CoreLoginHelper.instance.loadPageInMainMenu(pageName, pageParams);
|
||||
} else {
|
||||
await this.navCtrl.navigateForward(pageName, { queryParams: pageParams });
|
||||
}
|
||||
} else {
|
||||
await this.navCtrl.navigateForward(pageName, { queryParams: pageParams });
|
||||
}
|
||||
} else {
|
||||
await CoreLoginHelper.instance.redirect(pageName, pageParams, siteId);
|
||||
}
|
||||
|
||||
deferred.resolve();
|
||||
} catch (error) {
|
||||
deferred.reject(error);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to the page to choose a site.
|
||||
*
|
||||
* @param url URL to treat.
|
||||
* @todo set correct root.
|
||||
*/
|
||||
async goToChooseSite(url: string): Promise<void> {
|
||||
await this.navCtrl.navigateRoot('CoreContentLinksChooseSitePage @todo', { queryParams: { url } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a link.
|
||||
*
|
||||
* @param url URL to handle.
|
||||
* @param 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.
|
||||
* @param checkRoot Whether to check if the URL is the root URL of a site.
|
||||
* @param openBrowserRoot Whether to open in browser if it's root URL and it belongs to current site.
|
||||
* @return Promise resolved with a boolean: true if URL was treated, false otherwise.
|
||||
*/
|
||||
async handleLink(
|
||||
url: string,
|
||||
username?: string,
|
||||
checkRoot?: boolean,
|
||||
openBrowserRoot?: boolean,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
if (checkRoot) {
|
||||
const data = await CoreSites.instance.isStoredRootURL(url, username);
|
||||
|
||||
if (data.site) {
|
||||
// URL is the root of the site.
|
||||
this.handleRootURL(data.site, openBrowserRoot);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the link should be treated by some component/addon.
|
||||
const action = await this.getFirstValidActionFor(url, undefined, username);
|
||||
if (!action) {
|
||||
return false;
|
||||
}
|
||||
if (!CoreSites.instance.isLoggedIn()) {
|
||||
// No current site. Perform the action if only 1 site found, choose the site otherwise.
|
||||
if (action.sites?.length == 1) {
|
||||
action.action(action.sites[0]);
|
||||
} else {
|
||||
this.goToChooseSite(url);
|
||||
}
|
||||
} else if (action.sites?.length == 1 && action.sites[0] == CoreSites.instance.getCurrentSiteId()) {
|
||||
// Current site.
|
||||
action.action(action.sites[0]);
|
||||
} else {
|
||||
try {
|
||||
// Not current site or more than one site. Ask for confirmation.
|
||||
await CoreDomUtils.instance.showConfirm(Translate.instance.instant('core.contentlinks.confirmurlothersite'));
|
||||
if (action.sites?.length == 1) {
|
||||
action.action(action.sites[0]);
|
||||
} else {
|
||||
this.goToChooseSite(url);
|
||||
}
|
||||
} catch {
|
||||
// User canceled.
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a root URL of a site.
|
||||
*
|
||||
* @param site Site to handle.
|
||||
* @param openBrowserRoot Whether to open in browser if it's root URL and it belongs to current site.
|
||||
* @param checkToken Whether to check that token is the same to verify it's current site. If false or not defined,
|
||||
* only the URL will be checked.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async handleRootURL(site: CoreSite, openBrowserRoot?: boolean, checkToken?: boolean): Promise<void> {
|
||||
const currentSite = CoreSites.instance.getCurrentSite();
|
||||
|
||||
if (currentSite && currentSite.getURL() == site.getURL() && (!checkToken || currentSite.getToken() == site.getToken())) {
|
||||
// Already logged in.
|
||||
if (openBrowserRoot) {
|
||||
return site.openInBrowserWithAutoLogin(site.getURL());
|
||||
}
|
||||
} else {
|
||||
// Login in the site.
|
||||
return CoreLoginHelper.instance.redirect('', {}, site.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class CoreContentLinksHelper extends makeSingleton(CoreContentLinksHelperProvider) {}
|
|
@ -26,6 +26,7 @@ import { CoreConfig } from '@services/config';
|
|||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
// import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { makeSingleton, Translate } from '@singletons/core.singletons';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
|
||||
/**
|
||||
* Object with space usage and cache entries that can be erased.
|
||||
|
@ -281,12 +282,12 @@ export class CoreSettingsHelperProvider {
|
|||
|
||||
if (site.isLoggedOut()) {
|
||||
// Cannot sync logged out sites.
|
||||
throw Translate.instance.instant('core.settings.cannotsyncloggedout');
|
||||
throw new CoreError(Translate.instance.instant('core.settings.cannotsyncloggedout'));
|
||||
} else if (hasSyncHandlers && !CoreApp.instance.isOnline()) {
|
||||
// We need connection to execute sync.
|
||||
throw Translate.instance.instant('core.settings.cannotsyncoffline');
|
||||
throw new CoreError(Translate.instance.instant('core.settings.cannotsyncoffline'));
|
||||
} else if (hasSyncHandlers && syncOnlyOnWifi && CoreApp.instance.isNetworkAccessLimited()) {
|
||||
throw Translate.instance.instant('core.settings.cannotsyncwithoutwifi');
|
||||
throw new CoreError(Translate.instance.instant('core.settings.cannotsyncwithoutwifi'));
|
||||
}
|
||||
|
||||
const syncPromise = Promise.all([
|
||||
|
@ -329,7 +330,7 @@ export class CoreSettingsHelperProvider {
|
|||
// Local mobile was added. Throw invalid session to force reconnect and create a new token.
|
||||
CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, {}, site.getId());
|
||||
|
||||
throw Translate.instance.instant('core.lostconnection');
|
||||
throw new CoreError(Translate.instance.instant('core.lostconnection'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -231,7 +231,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
|
|||
if (!site.canDownloadFiles() && CoreUrlUtils.instance.isPluginFileUrl(url)) {
|
||||
this.element.parentElement?.removeChild(this.element); // Remove element since it'll be broken.
|
||||
|
||||
throw 'Site doesn\'t allow downloading files.';
|
||||
throw new CoreError('Site doesn\'t allow downloading files.');
|
||||
}
|
||||
|
||||
// Download images, tracks and posters if size is unknown.
|
||||
|
|
|
@ -353,6 +353,12 @@
|
|||
"core.considereddigitalminor": "You are too young to create an account on this site.",
|
||||
"core.content": "Content",
|
||||
"core.contenteditingsynced": "The content you are editing has been synced.",
|
||||
"core.contentlinks.chooseaccount": "Choose account",
|
||||
"core.contentlinks.chooseaccounttoopenlink": "Choose an account to open the link with.",
|
||||
"core.contentlinks.confirmurlothersite": "This link belongs to another site. Do you want to open it?",
|
||||
"core.contentlinks.errornoactions": "Couldn't find an action to perform with this link.",
|
||||
"core.contentlinks.errornosites": "Couldn't find any site to handle this link.",
|
||||
"core.contentlinks.errorredirectothersite": "The redirect URL cannot point to a different site.",
|
||||
"core.continue": "Continue",
|
||||
"core.copiedtoclipboard": "Text copied to clipboard",
|
||||
"core.copytoclipboard": "Copy to clipboard",
|
||||
|
|
Loading…
Reference in New Issue