commit
814491afdb
|
@ -16,7 +16,7 @@
|
|||
<ion-card>
|
||||
<ion-item class="core-course-module-handler ion-text-wrap" detail="false" (click)="action($event, item)" button>
|
||||
<core-mod-icon slot="start" *ngIf="item.iconUrl" [modicon]="item.iconUrl" [modname]="item.modname"
|
||||
[componentId]="item.cmid" [showAlt]="false">
|
||||
[componentId]="item.cmid" [showAlt]="false" [purpose]="item.purpose">
|
||||
</core-mod-icon>
|
||||
<ion-label>
|
||||
<!-- Add the icon title so accessibility tools read it. -->
|
||||
|
|
|
@ -103,6 +103,8 @@ export const AddonBlockRecentlyAccessedItems = makeSingleton(AddonBlockRecentlyA
|
|||
|
||||
/**
|
||||
* Result of WS block_recentlyaccesseditems_get_recent_items.
|
||||
*
|
||||
* The most recently accessed activities/resources by the logged user.
|
||||
*/
|
||||
export type AddonBlockRecentlyAccessedItemsItem = {
|
||||
id: number; // Id.
|
||||
|
@ -116,6 +118,7 @@ export type AddonBlockRecentlyAccessedItemsItem = {
|
|||
viewurl: string; // Viewurl.
|
||||
courseviewurl: string; // Courseviewurl.
|
||||
icon: string; // Icon.
|
||||
purpose?: string; // Purpose. @since 4.0
|
||||
} & AddonBlockRecentlyAccessedItemsItemCalculatedData;
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<ion-col class="addon-block-timeline-activity-time ion-no-padding">
|
||||
<small>{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }}</small>
|
||||
<core-mod-icon *ngIf="event.iconUrl" [modicon]="event.iconUrl" [componentId]="event.instance"
|
||||
[modname]="event.modulename">
|
||||
[modname]="event.modulename" [purpose]="event.purpose">
|
||||
</core-mod-icon>
|
||||
</ion-col>
|
||||
<ion-col class="addon-block-timeline-activity-name ion-no-padding">
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
</div>
|
||||
</ng-container>
|
||||
<p *ngIf="day.filteredEvents.length > 4" class="addon-calendar-day-more">
|
||||
<b>{{ 'core.nummore' | translate:{$a: day.filteredEvents.length - 3} }}</b>
|
||||
<strong>{{ 'core.nummore' | translate:{$a: day.filteredEvents.length - 3} }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
</ion-col>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button
|
||||
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]" [detail]="false">
|
||||
<core-mod-icon *ngIf="event.moduleIcon" [modicon]="event.moduleIcon" slot="start" [modname]="event.modulename"
|
||||
[componentId]="event.instance" [showAlt]="false"></core-mod-icon>
|
||||
[componentId]="event.instance" [showAlt]="false" [purpose]="event.purpose"></core-mod-icon>
|
||||
<ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true">
|
||||
</ion-icon>
|
||||
<ion-label>
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
(click)="gotoEvent(event.id, day)" [class.item-dimmed]="event.ispast"
|
||||
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button [detail]="false">
|
||||
<core-mod-icon *ngIf="event.moduleIcon" [modicon]="event.moduleIcon" slot="start" [showAlt]="false"
|
||||
[modname]="event.modulename" [componentId]="event.instance">
|
||||
[modname]="event.modulename" [componentId]="event.instance" [purpose]="event.purpose">
|
||||
</core-mod-icon>
|
||||
<ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start"
|
||||
aria-hidden="true">
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<ion-list *ngIf="event">
|
||||
<ion-item class="ion-text-wrap addon-calendar-event" collapsible [ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
|
||||
<core-mod-icon *ngIf="event.moduleIcon" [modicon]="event.moduleIcon" [showAlt]="false" [modname]="event.modulename"
|
||||
[componentId]="event.instance" slot="start"></core-mod-icon>
|
||||
[componentId]="event.instance" slot="start" [purpose]="event.purpose"></core-mod-icon>
|
||||
<ion-icon *ngIf=" event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" aria-hidden="true" slot="start">
|
||||
</ion-icon>
|
||||
<ion-label>
|
||||
|
|
|
@ -178,6 +178,7 @@ export class AddonCalendarHelperProvider {
|
|||
format: 1,
|
||||
visible: 1,
|
||||
offline: false,
|
||||
purpose: 'purpose' in event ? event.purpose : undefined,
|
||||
};
|
||||
|
||||
if (event.modulename) {
|
||||
|
@ -660,7 +661,7 @@ export class AddonCalendarHelperProvider {
|
|||
const finalPromises: Promise<unknown>[] =[AddonCalendar.invalidateAllUpcomingEvents()];
|
||||
|
||||
// Fetch months and days.
|
||||
fetchTimestarts.map((fetchTime) => {
|
||||
fetchTimestarts.forEach((fetchTime) => {
|
||||
const day = moment(fetchTime * 1000);
|
||||
|
||||
const monthId = this.getMonthId(day);
|
||||
|
@ -696,7 +697,7 @@ export class AddonCalendarHelperProvider {
|
|||
});
|
||||
|
||||
// Invalidate months and days.
|
||||
invalidateTimestarts.map((fetchTime) => {
|
||||
invalidateTimestarts.forEach((fetchTime) => {
|
||||
const day = moment(fetchTime * 1000);
|
||||
|
||||
const monthId = this.getMonthId(day);
|
||||
|
|
|
@ -529,7 +529,7 @@ export class AddonCalendarProvider {
|
|||
// Convert the array to an object.
|
||||
const result = {};
|
||||
if (response.allowedeventtypes) {
|
||||
response.allowedeventtypes.map((type) => {
|
||||
response.allowedeventtypes.forEach((type) => {
|
||||
result[type] = true;
|
||||
});
|
||||
}
|
||||
|
@ -1949,6 +1949,7 @@ export type AddonCalendarEventBase = {
|
|||
*/
|
||||
export type AddonCalendarEvent = AddonCalendarEventBase & {
|
||||
url: string; // Url.
|
||||
purpose?: string; // Purpose. @since 4.0
|
||||
action?: {
|
||||
name: string; // Name.
|
||||
url: string; // Url.
|
||||
|
@ -2302,6 +2303,7 @@ export type AddonCalendarEventToDisplay = Partial<AddonCalendarCalendarEvent> &
|
|||
ispast?: boolean; // Calculated in the app. Whether the event is in the past.
|
||||
contextLevel?: ContextLevel;
|
||||
contextInstanceId?: number;
|
||||
purpose?: string; // Purpose. @since 4.0
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
|
||||
<ng-container *ngIf="isSelf && !canLoadMore">
|
||||
<p class="ion-text-center">{{ 'addon.messages.selfconversation' | translate }}</p>
|
||||
<p class="ion-text-center"><i>{{ 'addon.messages.selfconversationdefaultmessage' | translate }}</i></p>
|
||||
<p class="ion-text-center"><em>{{ 'addon.messages.selfconversationdefaultmessage' | translate }}</em></p>
|
||||
</ng-container>
|
||||
|
||||
<h2 class="sr-only">{{ title }}</h2>
|
||||
|
|
|
@ -126,7 +126,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
|
|||
CoreSites.getCurrentSiteId(),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors, probably user is offline or sync is blocked.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -525,7 +525,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
|
|||
submitId: this.submitId,
|
||||
}, this.siteId);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors, probably user is offline or sync is blocked.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -565,7 +565,7 @@ export class AddonModAssignProvider {
|
|||
};
|
||||
|
||||
try {
|
||||
return this.getSubmissionStatus(assign.id, newOptions);
|
||||
return await this.getSubmissionStatus(assign.id, newOptions);
|
||||
} catch {
|
||||
// Error, return the first result even if it doesn't have the user submission.
|
||||
return response;
|
||||
|
|
|
@ -220,7 +220,7 @@ export class AddonModChatChatPage implements OnInit, OnDestroy, CanLeave {
|
|||
}
|
||||
|
||||
return id;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,9 @@ export class AddonModChatHelperProvider {
|
|||
if (!formattedMessage.special && formattedMessage.message.match(patternTo)) {
|
||||
const matches = formattedMessage.message.match(patternTo);
|
||||
|
||||
formattedMessage.message = `<i><b>${Translate.instant('addon.mod_chat.saidto')} </b>${matches![1]}</i>: ${matches![2]}`;
|
||||
formattedMessage.message = `<em>
|
||||
<strong>${Translate.instant('addon.mod_chat.saidto')} </strong>
|
||||
${matches![1]}</em>: ${matches![2]}`;
|
||||
}
|
||||
|
||||
formattedMessage.showUserData = this.showUserData(currentUserId, message, prevMessage);
|
||||
|
|
|
@ -723,7 +723,7 @@ export class AddonModDataHelperProvider {
|
|||
try {
|
||||
await AddonModData.invalidateEntryData(dataId, entryId, siteId);
|
||||
await AddonModData.invalidateEntriesData(dataId, siteId);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
|
|
|
@ -987,7 +987,7 @@ export class AddonModDataProvider {
|
|||
|
||||
options.groupId = options.groupId || 0;
|
||||
options.sort = options.sort || 0;
|
||||
options.order || options.order || 'DESC';
|
||||
options.order = options.order || 'DESC';
|
||||
options.page = options.page || 0;
|
||||
options.perPage = options.perPage || AddonModDataProvider.PER_PAGE;
|
||||
options.readingStrategy = options.readingStrategy || CoreSitesReadingStrategy.PREFER_NETWORK;
|
||||
|
|
|
@ -66,9 +66,9 @@ export class AddonModFeedbackAttemptPage implements OnInit, OnDestroy {
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
async ngOnInit(): Promise<void> {
|
||||
try {
|
||||
this.attempts.start();
|
||||
await this.attempts.start();
|
||||
} catch (error) {
|
||||
CoreDomUtils.showErrorModal(error);
|
||||
|
||||
|
|
|
@ -292,7 +292,7 @@ export class AddonModForumDiscussionsSource extends CoreRoutedItemsManagerSource
|
|||
|
||||
discussion.userfullname = user.fullname;
|
||||
discussion.userpictureurl = user.profileimageurl;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
});
|
||||
|
|
|
@ -358,7 +358,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
|||
// Not set, use default sort.
|
||||
// @TODO add fallback to $CFG->forum_displaymode.
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
@ -511,7 +511,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
|||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ class AddonModGlossaryEntriesManager extends CoreListItemsManager<AddonModGlossa
|
|||
await AddonModGlossary.logView(glossary.id, viewMode, glossary.name);
|
||||
|
||||
CoreCourse.checkModuleCompletion(this.page.courseId, this.page.module.completiondata);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -663,13 +663,12 @@ export class AddonModGlossaryProvider {
|
|||
|
||||
// No more pages and the entry wasn't found. Reject.
|
||||
throw new CoreError('Entry not found.');
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the whole fetch of the entries using the proper function and arguments.
|
||||
*
|
||||
* @param fetchFunction Function to fetch.
|
||||
* @param fetchArguments Arguments to call the fetching.
|
||||
* @param options Other options.
|
||||
* @return Promise resolved with all entrries.
|
||||
*/
|
||||
|
@ -682,7 +681,7 @@ export class AddonModGlossaryProvider {
|
|||
const entries: AddonModGlossaryEntry[] = [];
|
||||
|
||||
const fetchMoreEntries = async (): Promise<AddonModGlossaryEntry[]> => {
|
||||
const result = await fetchFunction({
|
||||
const result = fetchFunction({
|
||||
from: entries.length,
|
||||
...options, // Include all options.
|
||||
});
|
||||
|
@ -915,7 +914,14 @@ export class AddonModGlossaryProvider {
|
|||
|
||||
try {
|
||||
// Try to add it in online.
|
||||
return this.addEntryOnline(glossaryId, concept, definition, entryOptions, <number> attachments, otherOptions.siteId);
|
||||
return await this.addEntryOnline(
|
||||
glossaryId,
|
||||
concept,
|
||||
definition,
|
||||
entryOptions,
|
||||
<number> attachments,
|
||||
otherOptions.siteId,
|
||||
);
|
||||
} catch (error) {
|
||||
if (otherOptions.allowOffline && !CoreUtils.isWebServiceError(error)) {
|
||||
// Couldn't connect to server, store in offline.
|
||||
|
|
|
@ -459,7 +459,7 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
|
|||
try {
|
||||
// Invalidate attempts.
|
||||
await AddonModH5PActivity.invalidateUserAttempts(this.h5pActivity.id, undefined, this.siteId);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ export class AddonModH5PActivityAttemptResultsPage implements OnInit {
|
|||
|
||||
try {
|
||||
this.user = await CoreUser.getProfile(this.attempt.userid, this.courseId, true);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ export class AddonModH5PActivityUserAttemptsPage implements OnInit {
|
|||
protected async fetchUserProfile(): Promise<void> {
|
||||
try {
|
||||
this.user = await CoreUser.getProfile(this.userId, this.courseId, true);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
|||
|
||||
if (password) {
|
||||
try {
|
||||
return this.validatePassword(lessonId, accessInfo, password, options);
|
||||
return await this.validatePassword(lessonId, accessInfo, password, options);
|
||||
} catch {
|
||||
// Error validating it.
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
|||
* @param lesson Lesson.
|
||||
* @param password Password (if needed).
|
||||
* @param retake Retake to prefetch.
|
||||
* @param options Options.
|
||||
* @param modOptions Options.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
protected async prefetchPlayData(
|
||||
|
@ -364,12 +364,7 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
|||
const promises = pages.map(async (data) => {
|
||||
// Check if any page has a RANDOMBRANCH jump.
|
||||
if (!hasRandomBranch) {
|
||||
for (let i = 0; i < data.jumps.length; i++) {
|
||||
if (data.jumps[i] == AddonModLessonProvider.LESSON_RANDOMBRANCH) {
|
||||
hasRandomBranch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hasRandomBranch = data.jumps.some((jump) => jump === AddonModLessonProvider.LESSON_RANDOMBRANCH);
|
||||
}
|
||||
|
||||
// Get the page data. We don't pass accessInfo because we don't need to calculate the offline data.
|
||||
|
@ -499,8 +494,8 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
|||
* Validate the password.
|
||||
*
|
||||
* @param lessonId Lesson ID.
|
||||
* @param info Lesson access info.
|
||||
* @param pwd Password to check.
|
||||
* @param accessInfo Lesson access info.
|
||||
* @param password Password to check.
|
||||
* @param options Other options.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
|
|
|
@ -118,7 +118,7 @@ export class AddonModLtiHelperProvider {
|
|||
await AddonModLti.logView(ltiId, name, siteId);
|
||||
|
||||
CoreCourse.checkModuleCompletion(courseId, module.completiondata);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
</article>
|
||||
|
||||
<div class="ion-margin-top" *ngIf="tagsEnabled && tags.length > 0">
|
||||
<b>{{ 'core.tag.tags' | translate }}:</b>
|
||||
<strong>{{ 'core.tag.tags' | translate }}:</strong>
|
||||
<core-tag-list [tags]="tags"></core-tag-list>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -723,7 +723,7 @@ export class AddonModWikiProvider {
|
|||
|
||||
try {
|
||||
// Try to create it in online.
|
||||
return this.newPageOnline(title, content, options);
|
||||
return await this.newPageOnline(title, content, options);
|
||||
} catch (error) {
|
||||
if (CoreUtils.isWebServiceError(error)) {
|
||||
// The WebService has thrown an error, this means that the page cannot be added.
|
||||
|
|
|
@ -119,7 +119,7 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit, OnDe
|
|||
|
||||
// Load Weights selector.
|
||||
if (this.edit && this.access.canallocate) {
|
||||
this.weights;
|
||||
this.weights = [];
|
||||
for (let i = 16; i >= 0; i--) {
|
||||
this.weights[i] = i;
|
||||
}
|
||||
|
@ -347,8 +347,6 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit, OnDe
|
|||
this.workshop.course,
|
||||
assessmentData,
|
||||
);
|
||||
|
||||
gradeUpdated = false;
|
||||
} else {
|
||||
|
||||
// Try to send it to server.
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
:host-context(ion-item.md) ion-icon {
|
||||
&[slot] {
|
||||
font-size: 1.6em;
|
||||
color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);
|
||||
font-size: 24px;
|
||||
margin-top: 12px;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreConstants } from '@/core/constants';
|
||||
import { CoreConstants, ModPurpose } from '@/core/constants';
|
||||
import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChange } from '@angular/core';
|
||||
import { CoreCourse } from '@features/course/services/course';
|
||||
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||
|
@ -31,10 +31,11 @@ const fallbackModName = 'external-tool';
|
|||
})
|
||||
export class CoreModIconComponent implements OnInit, OnChanges {
|
||||
|
||||
@Input() modname?; // The module name. Used also as component if set.
|
||||
@Input() componentId?; // Component Id for external icons.
|
||||
@Input() modname?: string; // The module name. Used also as component if set.
|
||||
@Input() componentId?: number; // Component Id for external icons.
|
||||
@Input() modicon?: string; // Module icon url or local url.
|
||||
@Input() showAlt = true; // Show alt otherwise it's only presentation icon.
|
||||
@Input() purpose: ModPurpose = ModPurpose.MOD_PURPOSE_OTHER; // Purpose of the module.
|
||||
|
||||
icon = '';
|
||||
modNameTranslated = '';
|
||||
|
@ -62,10 +63,15 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
this.modNameTranslated = this.modname ? CoreCourse.translateModuleName(this.modname) || '' : '';
|
||||
if (CoreSites.getCurrentSite()?.isVersionGreaterEqualThan('4.0')) {
|
||||
this.legacyIcon = false;
|
||||
const purposeClass =
|
||||
CoreCourseModuleDelegate.supportsFeature<string>(this.modname, CoreConstants.FEATURE_MOD_PURPOSE, '');
|
||||
|
||||
if (purposeClass != '') {
|
||||
const purposeClass =
|
||||
CoreCourseModuleDelegate.supportsFeature<ModPurpose>(
|
||||
this.modname || '',
|
||||
CoreConstants.FEATURE_MOD_PURPOSE,
|
||||
this.purpose,
|
||||
);
|
||||
|
||||
if (purposeClass) {
|
||||
const element: HTMLElement = this.el.nativeElement;
|
||||
element.classList.add(purposeClass);
|
||||
}
|
||||
|
@ -94,8 +100,8 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
// If modname is not set icon won't be cached.
|
||||
// Also if the url matches the regexp (the theme will manage the image so it's not cached).
|
||||
this.linkIconWithComponent =
|
||||
this.modname &&
|
||||
this.componentId &&
|
||||
!!this.modname &&
|
||||
!!this.componentId &&
|
||||
!this.isLocalUrl &&
|
||||
!this.icon.match('/theme/image.php/[^/]+/' + this.modname + '/[-0-9]*/');
|
||||
}
|
||||
|
|
|
@ -52,10 +52,8 @@ export abstract class CoreBlockBaseComponent implements OnInit, ICoreBlockCompon
|
|||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
if (this.block.configs && this.block.configs.length > 0) {
|
||||
this.block.configs.map((config) => {
|
||||
this.block.configs.forEach((config) => {
|
||||
config.value = CoreTextUtils.parseJSON(config.value);
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
this.block.configsRecord = CoreUtils.arrayToObject(this.block.configs, 'name');
|
||||
|
|
|
@ -47,13 +47,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
getActions(
|
||||
siteIds: string[],
|
||||
|
@ -103,17 +97,10 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabled(siteId: string, url: string, params: Params, courseId?: number): Promise<boolean> {
|
||||
courseId = parseInt(params.id, 10);
|
||||
async isEnabled(siteId: string, url: string, params: Params): Promise<boolean> {
|
||||
const courseId = parseInt(params.id, 10);
|
||||
|
||||
if (!courseId) {
|
||||
return false;
|
||||
|
@ -333,7 +320,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
|
|||
|
||||
await CoreUtils.wait(5000);
|
||||
|
||||
return await this.waitForEnrolled(courseId);
|
||||
return this.waitForEnrolled(courseId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -973,7 +973,7 @@ export class CoreEditorRichTextEditorComponent implements OnInit, AfterViewInit,
|
|||
this.showMessage('core.editor.textrecovered', this.RESTORE_MESSAGE_CLEAR_TIME);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors, shouldn't happen.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ export class CoreEditorOfflineProvider {
|
|||
const params = this.fixDraftPrimaryData(contextLevel, contextInstanceId, elementId, extraParams);
|
||||
|
||||
await db.deleteRecords(DRAFT_TABLE, params);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors, probably no draft stored.
|
||||
}
|
||||
}
|
||||
|
@ -149,12 +149,12 @@ export class CoreEditorOfflineProvider {
|
|||
}
|
||||
|
||||
await db.insertRecord(DRAFT_TABLE, entry);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors saving the draft. It shouldn't happen.
|
||||
}
|
||||
|
||||
return entry;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// No draft stored. Store an empty draft to save the pageinstance.
|
||||
await this.saveDraft(
|
||||
contextLevel,
|
||||
|
|
|
@ -812,7 +812,7 @@ export class CoreFileUploaderHelperProvider {
|
|||
file = await CoreFile.getFileObjectFromFileEntry(fileEntry);
|
||||
|
||||
size = file.size;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore failures.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,14 +30,7 @@ export class CoreGradesReportLinkHandlerService extends CoreContentLinksHandlerB
|
|||
pattern = /\/grade\/report(\/user)?\/index.php/;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
getActions(
|
||||
siteIds: string[],
|
||||
|
@ -60,14 +53,7 @@ export class CoreGradesReportLinkHandlerService extends CoreContentLinksHandlerB
|
|||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
||||
if (!courseId && !params.id) {
|
||||
|
|
|
@ -30,14 +30,7 @@ export class CoreGradesUserLinkHandlerService extends CoreContentLinksHandlerBas
|
|||
pattern = /\/course\/user\.php.*[?&]mode=grade/;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
getActions(
|
||||
siteIds: string[],
|
||||
|
@ -60,14 +53,7 @@ export class CoreGradesUserLinkHandlerService extends CoreContentLinksHandlerBas
|
|||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
||||
if (!courseId && !params.id) {
|
||||
|
|
|
@ -191,7 +191,7 @@ export class CoreH5PContentValidator {
|
|||
/**
|
||||
* Validate given value against number semantics.
|
||||
*
|
||||
* @param num Number to validate.
|
||||
* @param value Number to validate.
|
||||
* @param semantics Semantics.
|
||||
* @return Validated number.
|
||||
*/
|
||||
|
@ -497,9 +497,7 @@ export class CoreH5PContentValidator {
|
|||
let validateFunction: undefined | ((...args: unknown[]) => unknown);
|
||||
let field: CoreH5PSemantics | undefined;
|
||||
|
||||
for (let i = 0; i < semantics.fields.length; i++) {
|
||||
field = semantics.fields[i];
|
||||
|
||||
for (const field of semantics.fields) {
|
||||
if (field.name == key) {
|
||||
if (semantics.optional) {
|
||||
field.optional = true;
|
||||
|
@ -778,8 +776,7 @@ export class CoreH5PContentValidator {
|
|||
if (matches && matches.length > 1) {
|
||||
if (allowedStyles && attrName === 'style') {
|
||||
// Allow certain styles.
|
||||
for (let i = 0; i < allowedStyles.length; i++) {
|
||||
const pattern = allowedStyles[i];
|
||||
for (const pattern of allowedStyles) {
|
||||
if (matches[1].match(pattern)) {
|
||||
// All patterns are start to end patterns, and CKEditor adds one span per style.
|
||||
attrArray.push('style="' + matches[1] + '"');
|
||||
|
@ -1122,7 +1119,7 @@ export class CoreH5PContentValidator {
|
|||
},
|
||||
];
|
||||
|
||||
return this.metadataSemantics!;
|
||||
return this.metadataSemantics;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1266,7 +1263,7 @@ export class CoreH5PContentValidator {
|
|||
],
|
||||
};
|
||||
|
||||
return this.copyrightSemantics!;
|
||||
return this.copyrightSemantics;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -292,7 +292,7 @@ export class CoreH5PCore {
|
|||
// Update library usage.
|
||||
try {
|
||||
await this.h5pFramework.deleteLibraryUsage(content.id, siteId);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ export class CoreH5PFileStorage {
|
|||
try {
|
||||
// Delete the index.html.
|
||||
await this.deleteContentIndex(entry.foldername, site.getId());
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
});
|
||||
|
@ -463,7 +463,7 @@ export class CoreH5PFileStorage {
|
|||
// Delete existing library version.
|
||||
try {
|
||||
await CoreFile.removeDir(folderPath);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors, maybe it doesn't exist.
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ export class CoreH5PHelper {
|
|||
// Remove tmp folder.
|
||||
try {
|
||||
await CoreFile.removeDir(destFolder);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors, it will be deleted eventually.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,7 +273,7 @@ export class CoreH5PValidator {
|
|||
|
||||
const parts = entry.name.split('.'); // The language code is in parts[0].
|
||||
langIndex[parts[0]] = langFileData;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore this language.
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -47,7 +47,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
canDownload$ = new BehaviorSubject(false);
|
||||
calculating$ = new BehaviorSubject(true);
|
||||
displayOptions?: CoreH5PDisplayOptions;
|
||||
urlParams?: {[name: string]: string};
|
||||
urlParams: {[name: string]: string} = {};
|
||||
|
||||
protected site: CoreSite;
|
||||
protected siteId: string;
|
||||
|
@ -60,7 +60,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
) {
|
||||
|
||||
this.logger = CoreLogger.getInstance('CoreH5PPlayerComponent');
|
||||
this.site = CoreSites.getCurrentSite()!;
|
||||
this.site = CoreSites.getRequiredCurrentSite();
|
||||
this.siteId = this.site.getId();
|
||||
this.siteCanDownload = this.site.canDownloadFiles() && !CoreH5P.isOfflineDisabledInSite();
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
// Download the package in background if the size is low.
|
||||
try {
|
||||
this.attemptDownloadInBg();
|
||||
await this.attemptDownloadInBg();
|
||||
} catch (error) {
|
||||
this.logger.error('Error downloading H5P in background', error);
|
||||
}
|
||||
|
@ -120,12 +120,12 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
try {
|
||||
// Get the file size and ask the user to confirm.
|
||||
const size = await CorePluginFileDelegate.getFileSize({ fileurl: this.urlParams!.url }, this.siteId);
|
||||
const size = await CorePluginFileDelegate.getFileSize({ fileurl: this.urlParams.url }, this.siteId);
|
||||
|
||||
await CoreDomUtils.confirmDownloadSize({ size: size, total: true });
|
||||
|
||||
// User confirmed, add to the queue.
|
||||
await CoreFilepool.addToQueueByUrl(this.siteId, this.urlParams!.url, this.component, this.componentId);
|
||||
await CoreFilepool.addToQueueByUrl(this.siteId, this.urlParams.url, this.component, this.componentId);
|
||||
|
||||
} catch (error) {
|
||||
if (CoreDomUtils.isCanceledError(error)) {
|
||||
|
@ -191,7 +191,6 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
/**
|
||||
* Calculate state of the file.
|
||||
*
|
||||
* @param fileUrl The H5P file URL.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
protected async calculateState(): Promise<void> {
|
||||
|
@ -199,7 +198,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
// Get the status of the file.
|
||||
try {
|
||||
const state = await CoreFilepool.getFileStateByUrl(this.siteId, this.urlParams!.url);
|
||||
const state = await CoreFilepool.getFileStateByUrl(this.siteId, this.urlParams.url);
|
||||
|
||||
this.canDownload$.next(true);
|
||||
this.state = state;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<ion-list>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2><b>{{ 'core.login.faqcannotfindmysitequestion' | translate }}</b></h2>
|
||||
<h2><strong>{{ 'core.login.faqcannotfindmysitequestion' | translate }}</strong></h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
|
@ -24,7 +24,7 @@
|
|||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2><b>{{ 'core.login.faqwhatisurlquestion' | translate }}</b></h2>
|
||||
<h2><strong>{{ 'core.login.faqwhatisurlquestion' | translate }}</strong></h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap core-login-faqwhatisurlanswer">
|
||||
|
@ -34,7 +34,7 @@
|
|||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2><b>{{ 'core.login.faqcannotconnectquestion' | translate }}</b></h2>
|
||||
<h2><strong>{{ 'core.login.faqcannotconnectquestion' | translate }}</strong></h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
|
@ -44,7 +44,7 @@
|
|||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2><b>{{ 'core.login.faqsetupsitequestion' | translate }}</b></h2>
|
||||
<h2><strong>{{ 'core.login.faqsetupsitequestion' | translate }}</strong></h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
|
@ -57,7 +57,7 @@
|
|||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2><b>{{ 'core.login.faqtestappquestion' | translate }}</b></h2>
|
||||
<h2><strong>{{ 'core.login.faqtestappquestion' | translate }}</strong></h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
|
@ -67,7 +67,7 @@
|
|||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="canScanQR">
|
||||
<ion-label>
|
||||
<h2><b>{{ 'core.login.faqwhereisqrcode' | translate }}</b></h2>
|
||||
<h2><strong>{{ 'core.login.faqwhereisqrcode' | translate }}</strong></h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap core-login-faqwhereisqrcodeanswer" *ngIf="canScanQR">
|
||||
|
|
|
@ -360,7 +360,7 @@ export class CoreLoginSitePage implements OnInit {
|
|||
params: pageParams,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
@ -546,7 +546,7 @@ export class CoreLoginSitePage implements OnInit {
|
|||
},
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
} finally {
|
||||
modal.dismiss();
|
||||
|
|
|
@ -625,14 +625,11 @@ export class CorePushNotificationsProvider {
|
|||
|
||||
const total = counters.reduce((previous, counter) => previous + counter, 0);
|
||||
|
||||
if (!CorePlatform.isMobile()) {
|
||||
// Browser doesn't have an app badge, stop.
|
||||
return total;
|
||||
if (CorePlatform.isMobile()) {
|
||||
// Set the app badge on mobile.
|
||||
await Badge.set(total);
|
||||
}
|
||||
|
||||
// Set the app badge.
|
||||
await Badge.set(total);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
|
|
@ -404,17 +404,15 @@ export class CoreRatingProvider {
|
|||
true,
|
||||
));
|
||||
|
||||
const ratingsResults = await Promise.all(promises);
|
||||
|
||||
if (!site.isVersionGreaterEqualThan([' 3.6.5', '3.7.1', '3.8'])) {
|
||||
promises.map((promise) => promise.then(async (ratings) => {
|
||||
const userIds = ratings.map((rating: CoreRatingItemRating) => rating.userid);
|
||||
const ratings: CoreRatingItemRating[] = [].concat.apply([], ratingsResults);
|
||||
|
||||
await CoreUser.prefetchProfiles(userIds, courseId, site.id);
|
||||
const userIds = ratings.map((rating) => rating.userid);
|
||||
|
||||
return;
|
||||
}));
|
||||
await CoreUser.prefetchProfiles(userIds, courseId, site.id);
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -53,8 +53,9 @@ export class CoreSiteHomeIndexLinkHandlerService extends CoreContentLinksHandler
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
||||
courseId = parseInt(params.id, 10);
|
||||
async isEnabled(siteId: string, url: string, params: Record<string, string>): Promise<boolean> {
|
||||
const courseId = parseInt(params.id, 10);
|
||||
|
||||
if (!courseId) {
|
||||
return url.includes('index.php');
|
||||
}
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
.contact-status {
|
||||
width: 24px !important;
|
||||
height: 24px !important;
|
||||
right: calc(50% - 12px - var(--core-avatar-size) / 2) !important;
|
||||
right: calc(50% - 12px - var(--core-avatar-size) / 2) !important;
|
||||
}
|
||||
|
||||
.edit-avatar {
|
||||
position: absolute;
|
||||
right: calc(50% - 15px - var(--core-avatar-size) / 2);
|
||||
right: calc(50% - 15px - var(--core-avatar-size) / 2);
|
||||
bottom: -12px;
|
||||
|
||||
:host-context([dir="rtl"]) & {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
.contact-status {
|
||||
width: 24px !important;
|
||||
height: 24px !important;
|
||||
right: calc(50% - 12px - var(--core-avatar-size) / 2) !important;
|
||||
right: calc(50% - 12px - var(--core-avatar-size) / 2) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,21 +30,12 @@ export class CoreUserProfileLinkHandlerService extends CoreContentLinksHandlerBa
|
|||
pattern = /((\/user\/view\.php)|(\/user\/profile\.php)).*([?&]id=\d+)/;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
getActions(
|
||||
siteIds: string[],
|
||||
url: string,
|
||||
params: Record<string, string>,
|
||||
courseId?: number, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
data?: unknown, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
||||
return [{
|
||||
action: (siteId): void => {
|
||||
|
@ -59,17 +50,9 @@ export class CoreUserProfileLinkHandlerService extends CoreContentLinksHandlerBa
|
|||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @inheritdoc
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
||||
async isEnabled(siteId: string, url: string): Promise<boolean> {
|
||||
return url.indexOf('/grade/report/') == -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ export class CoreUserProfileFieldDelegateService extends CoreDelegate<CoreUserPr
|
|||
if (data) {
|
||||
result.push(data);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -43,7 +43,7 @@ export class CoreFormatDatePipe implements PipeTransform {
|
|||
timestamp = timestamp || Date.now();
|
||||
format = format || 'strftimedaydatetime';
|
||||
|
||||
if (typeof timestamp == 'string') {
|
||||
if (typeof timestamp === 'string') {
|
||||
// Convert the value to a number.
|
||||
const numberTimestamp = parseInt(timestamp, 10);
|
||||
if (isNaN(numberTimestamp)) {
|
||||
|
@ -55,7 +55,7 @@ export class CoreFormatDatePipe implements PipeTransform {
|
|||
}
|
||||
|
||||
// Add "core." if needed.
|
||||
if (format.indexOf('strf') == 0 || format.indexOf('df') == 0) {
|
||||
if (format.indexOf('strf') === 0 || format.indexOf('df') === 0) {
|
||||
format = 'core.' + format;
|
||||
}
|
||||
|
||||
|
|
|
@ -1205,7 +1205,7 @@ export class CoreFileProvider {
|
|||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore errors, maybe it doesn't exist.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1467,7 +1467,7 @@ export class CoreFilepoolProvider {
|
|||
const fileSize = await CoreFile.getFileSize(file.path);
|
||||
|
||||
size += fileSize;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Ignore failures, maybe some file was deleted.
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -200,10 +200,8 @@ export class CorePluginFileDelegateService extends CoreDelegate<CorePluginFileHa
|
|||
|
||||
if (handler && handler.getFileSize) {
|
||||
try {
|
||||
const size = handler.getFileSize(downloadableFile, siteId);
|
||||
|
||||
return size;
|
||||
} catch (error) {
|
||||
return await handler.getFileSize(downloadableFile, siteId);
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,14 +302,12 @@ export class CoreMimetypeUtilsProvider {
|
|||
*/
|
||||
guessExtensionFromUrl(fileUrl: string): string | undefined {
|
||||
const split = fileUrl.split('.');
|
||||
let candidate;
|
||||
let extension;
|
||||
let position;
|
||||
let extension: string | undefined;
|
||||
|
||||
if (split.length > 1) {
|
||||
candidate = split[split.length - 1].toLowerCase();
|
||||
let candidate = split[split.length - 1].toLowerCase();
|
||||
// Remove params if any.
|
||||
position = candidate.indexOf('?');
|
||||
let position = candidate.indexOf('?');
|
||||
if (position > -1) {
|
||||
candidate = candidate.substring(0, position);
|
||||
}
|
||||
|
@ -343,7 +341,7 @@ export class CoreMimetypeUtilsProvider {
|
|||
*/
|
||||
getFileExtension(filename: string): string | undefined {
|
||||
const dot = filename.lastIndexOf('.');
|
||||
let ext;
|
||||
let ext: string | undefined;
|
||||
|
||||
if (dot > -1) {
|
||||
ext = filename.substring(dot + 1).toLowerCase();
|
||||
|
@ -582,11 +580,10 @@ export class CoreMimetypeUtilsProvider {
|
|||
*/
|
||||
removeExtension(path: string): string {
|
||||
const position = path.lastIndexOf('.');
|
||||
let extension;
|
||||
|
||||
if (position > -1) {
|
||||
// Check extension corresponds to a mimetype to know if it's valid.
|
||||
extension = path.substring(position + 1).toLowerCase();
|
||||
const extension = path.substring(position + 1).toLowerCase();
|
||||
if (this.getMimeType(extension) !== undefined) {
|
||||
return path.substring(0, position); // Remove extension.
|
||||
}
|
||||
|
|
|
@ -741,7 +741,7 @@ export class CoreTextUtilsProvider {
|
|||
* @returns Treated text.
|
||||
*/
|
||||
replaceArguments(text: string, replacements: Record<string, string> = {}, encoding?: 'uri'): string {
|
||||
let match;
|
||||
let match: RegExpMatchArray | null = null;
|
||||
|
||||
while ((match = text.match(/\{\{([^}]+)\}\}/))) {
|
||||
const argument = match[1].trim();
|
||||
|
@ -829,7 +829,7 @@ export class CoreTextUtilsProvider {
|
|||
/**
|
||||
* Replace @@PLUGINFILE@@ wildcards with the real URL in a text.
|
||||
*
|
||||
* @param Text to treat.
|
||||
* @param text to treat.
|
||||
* @param files Files to extract the pluginfile URL from. They need to have the URL in a url or fileurl attribute.
|
||||
* @return Treated text.
|
||||
*/
|
||||
|
@ -847,8 +847,10 @@ export class CoreTextUtilsProvider {
|
|||
/**
|
||||
* Restore original draftfile URLs.
|
||||
*
|
||||
* @param text Text to treat, including pluginfile URLs.
|
||||
* @param replaceMap Map of the replacements that were done.
|
||||
* @param siteUrl Site URL.
|
||||
* @param treatedText Treated text with replacements.
|
||||
* @param originalText Original text.
|
||||
* @param files List of files to search and replace.
|
||||
* @return Treated text.
|
||||
*/
|
||||
restoreDraftfileUrls(siteUrl: string, treatedText: string, originalText: string, files: CoreWSFile[]): string {
|
||||
|
@ -1053,7 +1055,6 @@ export class CoreTextUtilsProvider {
|
|||
*
|
||||
* @param title Title of the new state.
|
||||
* @param content Content of the text to be expanded.
|
||||
* @param component Component to link the embedded files to.
|
||||
* @param options Options.
|
||||
* @return Promise resolved when the modal is displayed.
|
||||
*/
|
||||
|
|
|
@ -170,7 +170,7 @@ export class CoreTimeUtilsProvider {
|
|||
/**
|
||||
* Converts a number of seconds into a short human readable format: minutes and seconds, in fromat: 3' 27''.
|
||||
*
|
||||
* @param seconds Seconds
|
||||
* @param duration Seconds
|
||||
* @return Short human readable text.
|
||||
* @deprecated since app 4.0. Use CoreTime.formatTimeShort instead.
|
||||
*/
|
||||
|
|
|
@ -544,7 +544,7 @@ export class CoreUrlUtilsProvider {
|
|||
url = url.replace(/\/webservice\/pluginfile\.php\//, '/pluginfile.php/');
|
||||
|
||||
// Make sure the URL doesn't contain the token.
|
||||
url.replace(/([?&])token=[^&]*&?/, '$1');
|
||||
url = url.replace(/([?&])token=[^&]*&?/, '$1');
|
||||
|
||||
return url;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import { CoreColors } from '@singletons/colors';
|
|||
import { CorePromisedValue } from '@classes/promised-value';
|
||||
import { CorePlatform } from '@services/platform';
|
||||
|
||||
type TreeNode<T> = T & { children: TreeNode<T>[] };
|
||||
export type TreeNode<T> = T & { children: TreeNode<T>[] };
|
||||
|
||||
/*
|
||||
* "Utils" service with helper functions.
|
||||
|
@ -486,7 +486,7 @@ export class CoreUtilsProvider {
|
|||
* @param ...args All the params sent after checkAll will be passed to isEnabledFn.
|
||||
* @return Promise resolved with the list of enabled sites.
|
||||
*/
|
||||
filterEnabledSites<P extends unknown[]>(
|
||||
async filterEnabledSites<P extends unknown[]>(
|
||||
siteIds: string[],
|
||||
isEnabledFn: (siteId, ...args: P) => boolean | Promise<boolean>,
|
||||
checkAll?: boolean,
|
||||
|
@ -507,16 +507,14 @@ export class CoreUtilsProvider {
|
|||
}
|
||||
}
|
||||
|
||||
return this.allPromises(promises).catch(() => {
|
||||
// Ignore errors.
|
||||
}).then(() => {
|
||||
if (!checkAll) {
|
||||
// Checking 1 was enough, so it will either return all the sites or none.
|
||||
return enabledSites.length ? siteIds : [];
|
||||
} else {
|
||||
return enabledSites;
|
||||
}
|
||||
});
|
||||
await CoreUtils.ignoreErrors(this.allPromises(promises));
|
||||
|
||||
if (!checkAll) {
|
||||
// Checking 1 was enough, so it will either return all the sites or none.
|
||||
return enabledSites.length ? siteIds : [];
|
||||
} else {
|
||||
return enabledSites;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -562,18 +560,30 @@ export class CoreUtilsProvider {
|
|||
const mapDepth = {};
|
||||
const tree: TreeNode<T>[] = [];
|
||||
|
||||
// Create a map first to avoid problems with not sorted.
|
||||
list.forEach((node: TreeNode<T>, index): void => {
|
||||
const id = node[idFieldName];
|
||||
const parent = node[parentFieldName];
|
||||
node.children = [];
|
||||
|
||||
if (!id || !parent) {
|
||||
if (id === undefined) {
|
||||
this.logger.error(`Node with incorrect ${idFieldName}:${id} found on formatTree`);
|
||||
}
|
||||
|
||||
if (node.children === undefined) {
|
||||
node.children = [];
|
||||
}
|
||||
map[id] = index;
|
||||
});
|
||||
|
||||
list.forEach((node: TreeNode<T>): void => {
|
||||
const id = node[idFieldName];
|
||||
const parent = node[parentFieldName];
|
||||
|
||||
if (id === undefined || parent === undefined) {
|
||||
this.logger.error(`Node with incorrect ${idFieldName}:${id} or ${parentFieldName}:${parent} found on formatTree`);
|
||||
}
|
||||
|
||||
// Use map to look-up the parents.
|
||||
map[id] = index;
|
||||
if (parent != rootParentId) {
|
||||
if (parent !== rootParentId) {
|
||||
const parentNode = list[map[parent]] as TreeNode<T>;
|
||||
if (parentNode) {
|
||||
if (mapDepth[parent] == maxDepth) {
|
||||
|
@ -627,21 +637,21 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @return Promise resolved with the list of countries.
|
||||
*/
|
||||
getCountryList(): Promise<Record<string, string>> {
|
||||
async getCountryList(): Promise<Record<string, string>> {
|
||||
// Get the keys of the countries.
|
||||
return this.getCountryKeysList().then((keys) => {
|
||||
// Now get the code and the translated name.
|
||||
const countries = {};
|
||||
const keys = await this.getCountryKeysList();
|
||||
|
||||
keys.forEach((key) => {
|
||||
if (key.indexOf('assets.countries.') === 0) {
|
||||
const code = key.replace('assets.countries.', '');
|
||||
countries[code] = Translate.instant(key);
|
||||
}
|
||||
});
|
||||
// Now get the code and the translated name.
|
||||
const countries: Record<string, string> = {};
|
||||
|
||||
return countries;
|
||||
keys.forEach((key) => {
|
||||
if (key.indexOf('assets.countries.') === 0) {
|
||||
const code = key.replace('assets.countries.', '');
|
||||
countries[code] = Translate.instant(key);
|
||||
}
|
||||
});
|
||||
|
||||
return countries;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,18 +659,14 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @return Promise resolved with the list of countries.
|
||||
*/
|
||||
getCountryListSorted(): Promise<CoreCountry[]> {
|
||||
async getCountryListSorted(): Promise<CoreCountry[]> {
|
||||
// Get the keys of the countries.
|
||||
return this.getCountryList().then((countries) => {
|
||||
// Sort translations.
|
||||
const sortedCountries: { code: string; name: string }[] = [];
|
||||
const countries = await this.getCountryList();
|
||||
|
||||
Object.keys(countries).sort((a, b) => countries[a].localeCompare(countries[b])).forEach((key) => {
|
||||
sortedCountries.push({ code: key, name: countries[key] });
|
||||
});
|
||||
|
||||
return sortedCountries;
|
||||
});
|
||||
// Sort translations.
|
||||
return Object.keys(countries)
|
||||
.sort((a, b) => countries[a].localeCompare(countries[b]))
|
||||
.map((code) => ({ code, name: countries[code] }));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -668,11 +674,13 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @return Promise resolved with the countries list. Rejected if not translated.
|
||||
*/
|
||||
protected getCountryKeysList(): Promise<string[]> {
|
||||
protected async getCountryKeysList(): Promise<string[]> {
|
||||
// It's possible that the current language isn't translated, so try with default language first.
|
||||
const defaultLang = CoreLang.getDefaultLanguage();
|
||||
|
||||
return this.getCountryKeysListForLanguage(defaultLang).catch(() => {
|
||||
try {
|
||||
return await this.getCountryKeysListForLanguage(defaultLang);
|
||||
} catch {
|
||||
// Not translated, try to use the fallback language.
|
||||
const fallbackLang = CoreLang.getFallbackLanguage();
|
||||
|
||||
|
@ -681,8 +689,8 @@ export class CoreUtilsProvider {
|
|||
throw new Error('Countries not found.');
|
||||
}
|
||||
|
||||
return this.getCountryKeysListForLanguage(fallbackLang);
|
||||
});
|
||||
return await this.getCountryKeysListForLanguage(fallbackLang);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -720,17 +728,19 @@ export class CoreUtilsProvider {
|
|||
* @param url The URL of the file.
|
||||
* @return Promise resolved with the mimetype.
|
||||
*/
|
||||
getMimeTypeFromUrl(url: string): Promise<string> {
|
||||
async getMimeTypeFromUrl(url: string): Promise<string> {
|
||||
// First check if it can be guessed from the URL.
|
||||
const extension = CoreMimetypeUtils.guessExtensionFromUrl(url);
|
||||
const mimetype = extension && CoreMimetypeUtils.getMimeType(extension);
|
||||
let mimetype = extension && CoreMimetypeUtils.getMimeType(extension);
|
||||
|
||||
if (mimetype) {
|
||||
return Promise.resolve(mimetype);
|
||||
return mimetype;
|
||||
}
|
||||
|
||||
// Can't be guessed, get the remote mimetype.
|
||||
return CoreWS.getRemoteFileMimeType(url).then(mimetype => mimetype || '');
|
||||
mimetype = await CoreWS.getRemoteFileMimeType(url);
|
||||
|
||||
return mimetype || '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -760,7 +770,7 @@ export class CoreUtilsProvider {
|
|||
/**
|
||||
* Check if an unknown value is a FileEntry.
|
||||
*
|
||||
* @param value Value to check.
|
||||
* @param file Object to check.
|
||||
* @return Type guard indicating if the file is a FileEntry.
|
||||
*/
|
||||
valueIsFileEntry(file: unknown): file is FileEntry {
|
||||
|
@ -1017,7 +1027,7 @@ export class CoreUtilsProvider {
|
|||
this.iabInstance = InAppBrowser.create(url, '_blank', options);
|
||||
|
||||
if (CorePlatform.isMobile()) {
|
||||
let loadStopSubscription;
|
||||
let loadStopSubscription: Subscription | undefined;
|
||||
const loadStartUrls: string[] = [];
|
||||
|
||||
// Trigger global events when a url is loaded or the window is closed. This is to make it work like in Ionic 1.
|
||||
|
@ -1708,7 +1718,7 @@ export class CoreUtilsProvider {
|
|||
* Ignore errors from a promise.
|
||||
*
|
||||
* @param promise Promise to ignore errors.
|
||||
* @param fallbackResult Value to return if the promise is rejected.
|
||||
* @param fallback Value to return if the promise is rejected.
|
||||
* @return Promise with ignored errors, resolving to the fallback result if provided.
|
||||
*/
|
||||
async ignoreErrors<Result>(promise: Promise<Result>): Promise<Result | undefined>;
|
||||
|
|
Loading…
Reference in New Issue