MOBILE-4081 chore: Fixtures on types and async functions
parent
17add1f0fb
commit
68a4a4e75f
|
@ -93,7 +93,7 @@
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<p *ngIf="day.filteredEvents.length > 4" class="addon-calendar-day-more">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
|
|
@ -661,7 +661,7 @@ export class AddonCalendarHelperProvider {
|
||||||
const finalPromises: Promise<unknown>[] =[AddonCalendar.invalidateAllUpcomingEvents()];
|
const finalPromises: Promise<unknown>[] =[AddonCalendar.invalidateAllUpcomingEvents()];
|
||||||
|
|
||||||
// Fetch months and days.
|
// Fetch months and days.
|
||||||
fetchTimestarts.map((fetchTime) => {
|
fetchTimestarts.forEach((fetchTime) => {
|
||||||
const day = moment(fetchTime * 1000);
|
const day = moment(fetchTime * 1000);
|
||||||
|
|
||||||
const monthId = this.getMonthId(day);
|
const monthId = this.getMonthId(day);
|
||||||
|
@ -697,7 +697,7 @@ export class AddonCalendarHelperProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Invalidate months and days.
|
// Invalidate months and days.
|
||||||
invalidateTimestarts.map((fetchTime) => {
|
invalidateTimestarts.forEach((fetchTime) => {
|
||||||
const day = moment(fetchTime * 1000);
|
const day = moment(fetchTime * 1000);
|
||||||
|
|
||||||
const monthId = this.getMonthId(day);
|
const monthId = this.getMonthId(day);
|
||||||
|
|
|
@ -529,7 +529,7 @@ export class AddonCalendarProvider {
|
||||||
// Convert the array to an object.
|
// Convert the array to an object.
|
||||||
const result = {};
|
const result = {};
|
||||||
if (response.allowedeventtypes) {
|
if (response.allowedeventtypes) {
|
||||||
response.allowedeventtypes.map((type) => {
|
response.allowedeventtypes.forEach((type) => {
|
||||||
result[type] = true;
|
result[type] = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
<ng-container *ngIf="isSelf && !canLoadMore">
|
<ng-container *ngIf="isSelf && !canLoadMore">
|
||||||
<p class="ion-text-center">{{ 'addon.messages.selfconversation' | translate }}</p>
|
<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>
|
</ng-container>
|
||||||
|
|
||||||
<h2 class="sr-only">{{ title }}</h2>
|
<h2 class="sr-only">{{ title }}</h2>
|
||||||
|
|
|
@ -126,7 +126,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
|
||||||
CoreSites.getCurrentSiteId(),
|
CoreSites.getCurrentSiteId(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors, probably user is offline or sync is blocked.
|
// Ignore errors, probably user is offline or sync is blocked.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -525,7 +525,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
|
||||||
submitId: this.submitId,
|
submitId: this.submitId,
|
||||||
}, this.siteId);
|
}, this.siteId);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors, probably user is offline or sync is blocked.
|
// Ignore errors, probably user is offline or sync is blocked.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,7 +565,7 @@ export class AddonModAssignProvider {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this.getSubmissionStatus(assign.id, newOptions);
|
return await this.getSubmissionStatus(assign.id, newOptions);
|
||||||
} catch {
|
} catch {
|
||||||
// Error, return the first result even if it doesn't have the user submission.
|
// Error, return the first result even if it doesn't have the user submission.
|
||||||
return response;
|
return response;
|
||||||
|
|
|
@ -220,7 +220,7 @@ export class AddonModChatChatPage implements OnInit, OnDestroy, CanLeave {
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,9 @@ export class AddonModChatHelperProvider {
|
||||||
if (!formattedMessage.special && formattedMessage.message.match(patternTo)) {
|
if (!formattedMessage.special && formattedMessage.message.match(patternTo)) {
|
||||||
const matches = 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);
|
formattedMessage.showUserData = this.showUserData(currentUserId, message, prevMessage);
|
||||||
|
|
|
@ -723,7 +723,7 @@ export class AddonModDataHelperProvider {
|
||||||
try {
|
try {
|
||||||
await AddonModData.invalidateEntryData(dataId, entryId, siteId);
|
await AddonModData.invalidateEntryData(dataId, entryId, siteId);
|
||||||
await AddonModData.invalidateEntriesData(dataId, siteId);
|
await AddonModData.invalidateEntriesData(dataId, siteId);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -987,7 +987,7 @@ export class AddonModDataProvider {
|
||||||
|
|
||||||
options.groupId = options.groupId || 0;
|
options.groupId = options.groupId || 0;
|
||||||
options.sort = options.sort || 0;
|
options.sort = options.sort || 0;
|
||||||
options.order || options.order || 'DESC';
|
options.order = options.order || 'DESC';
|
||||||
options.page = options.page || 0;
|
options.page = options.page || 0;
|
||||||
options.perPage = options.perPage || AddonModDataProvider.PER_PAGE;
|
options.perPage = options.perPage || AddonModDataProvider.PER_PAGE;
|
||||||
options.readingStrategy = options.readingStrategy || CoreSitesReadingStrategy.PREFER_NETWORK;
|
options.readingStrategy = options.readingStrategy || CoreSitesReadingStrategy.PREFER_NETWORK;
|
||||||
|
|
|
@ -66,9 +66,9 @@ export class AddonModFeedbackAttemptPage implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
async ngOnInit(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
this.attempts.start();
|
await this.attempts.start();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CoreDomUtils.showErrorModal(error);
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ export class AddonModForumDiscussionsSource extends CoreRoutedItemsManagerSource
|
||||||
|
|
||||||
discussion.userfullname = user.fullname;
|
discussion.userfullname = user.fullname;
|
||||||
discussion.userpictureurl = user.profileimageurl;
|
discussion.userpictureurl = user.profileimageurl;
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -358,7 +358,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
// Not set, use default sort.
|
// Not set, use default sort.
|
||||||
// @TODO add fallback to $CFG->forum_displaymode.
|
// @TODO add fallback to $CFG->forum_displaymode.
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,7 +511,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -474,7 +474,7 @@ class AddonModGlossaryEntriesManager extends CoreListItemsManager<AddonModGlossa
|
||||||
await AddonModGlossary.logView(glossary.id, viewMode, glossary.name);
|
await AddonModGlossary.logView(glossary.id, viewMode, glossary.name);
|
||||||
|
|
||||||
CoreCourse.checkModuleCompletion(this.page.courseId, this.page.module.completiondata);
|
CoreCourse.checkModuleCompletion(this.page.courseId, this.page.module.completiondata);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -663,13 +663,12 @@ export class AddonModGlossaryProvider {
|
||||||
|
|
||||||
// No more pages and the entry wasn't found. Reject.
|
// No more pages and the entry wasn't found. Reject.
|
||||||
throw new CoreError('Entry not found.');
|
throw new CoreError('Entry not found.');
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the whole fetch of the entries using the proper function and arguments.
|
* Performs the whole fetch of the entries using the proper function and arguments.
|
||||||
*
|
*
|
||||||
* @param fetchFunction Function to fetch.
|
* @param fetchFunction Function to fetch.
|
||||||
* @param fetchArguments Arguments to call the fetching.
|
|
||||||
* @param options Other options.
|
* @param options Other options.
|
||||||
* @return Promise resolved with all entrries.
|
* @return Promise resolved with all entrries.
|
||||||
*/
|
*/
|
||||||
|
@ -682,7 +681,7 @@ export class AddonModGlossaryProvider {
|
||||||
const entries: AddonModGlossaryEntry[] = [];
|
const entries: AddonModGlossaryEntry[] = [];
|
||||||
|
|
||||||
const fetchMoreEntries = async (): Promise<AddonModGlossaryEntry[]> => {
|
const fetchMoreEntries = async (): Promise<AddonModGlossaryEntry[]> => {
|
||||||
const result = await fetchFunction({
|
const result = fetchFunction({
|
||||||
from: entries.length,
|
from: entries.length,
|
||||||
...options, // Include all options.
|
...options, // Include all options.
|
||||||
});
|
});
|
||||||
|
@ -915,7 +914,14 @@ export class AddonModGlossaryProvider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try to add it in online.
|
// 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) {
|
} catch (error) {
|
||||||
if (otherOptions.allowOffline && !CoreUtils.isWebServiceError(error)) {
|
if (otherOptions.allowOffline && !CoreUtils.isWebServiceError(error)) {
|
||||||
// Couldn't connect to server, store in offline.
|
// Couldn't connect to server, store in offline.
|
||||||
|
|
|
@ -459,7 +459,7 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
|
||||||
try {
|
try {
|
||||||
// Invalidate attempts.
|
// Invalidate attempts.
|
||||||
await AddonModH5PActivity.invalidateUserAttempts(this.h5pActivity.id, undefined, this.siteId);
|
await AddonModH5PActivity.invalidateUserAttempts(this.h5pActivity.id, undefined, this.siteId);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ export class AddonModH5PActivityAttemptResultsPage implements OnInit {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.user = await CoreUser.getProfile(this.attempt.userid, this.courseId, true);
|
this.user = await CoreUser.getProfile(this.attempt.userid, this.courseId, true);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ export class AddonModH5PActivityUserAttemptsPage implements OnInit {
|
||||||
protected async fetchUserProfile(): Promise<void> {
|
protected async fetchUserProfile(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
this.user = await CoreUser.getProfile(this.userId, this.courseId, true);
|
this.user = await CoreUser.getProfile(this.userId, this.courseId, true);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
||||||
|
|
||||||
if (password) {
|
if (password) {
|
||||||
try {
|
try {
|
||||||
return this.validatePassword(lessonId, accessInfo, password, options);
|
return await this.validatePassword(lessonId, accessInfo, password, options);
|
||||||
} catch {
|
} catch {
|
||||||
// Error validating it.
|
// Error validating it.
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
||||||
* @param lesson Lesson.
|
* @param lesson Lesson.
|
||||||
* @param password Password (if needed).
|
* @param password Password (if needed).
|
||||||
* @param retake Retake to prefetch.
|
* @param retake Retake to prefetch.
|
||||||
* @param options Options.
|
* @param modOptions Options.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async prefetchPlayData(
|
protected async prefetchPlayData(
|
||||||
|
@ -364,12 +364,7 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
||||||
const promises = pages.map(async (data) => {
|
const promises = pages.map(async (data) => {
|
||||||
// Check if any page has a RANDOMBRANCH jump.
|
// Check if any page has a RANDOMBRANCH jump.
|
||||||
if (!hasRandomBranch) {
|
if (!hasRandomBranch) {
|
||||||
for (let i = 0; i < data.jumps.length; i++) {
|
hasRandomBranch = data.jumps.some((jump) => jump === AddonModLessonProvider.LESSON_RANDOMBRANCH);
|
||||||
if (data.jumps[i] == AddonModLessonProvider.LESSON_RANDOMBRANCH) {
|
|
||||||
hasRandomBranch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the page data. We don't pass accessInfo because we don't need to calculate the offline data.
|
// 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.
|
* Validate the password.
|
||||||
*
|
*
|
||||||
* @param lessonId Lesson ID.
|
* @param lessonId Lesson ID.
|
||||||
* @param info Lesson access info.
|
* @param accessInfo Lesson access info.
|
||||||
* @param pwd Password to check.
|
* @param password Password to check.
|
||||||
* @param options Other options.
|
* @param options Other options.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -118,7 +118,7 @@ export class AddonModLtiHelperProvider {
|
||||||
await AddonModLti.logView(ltiId, name, siteId);
|
await AddonModLti.logView(ltiId, name, siteId);
|
||||||
|
|
||||||
CoreCourse.checkModuleCompletion(courseId, module.completiondata);
|
CoreCourse.checkModuleCompletion(courseId, module.completiondata);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<div class="ion-margin-top" *ngIf="tagsEnabled && tags.length > 0">
|
<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>
|
<core-tag-list [tags]="tags"></core-tag-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -723,7 +723,7 @@ export class AddonModWikiProvider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try to create it in online.
|
// Try to create it in online.
|
||||||
return this.newPageOnline(title, content, options);
|
return await this.newPageOnline(title, content, options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (CoreUtils.isWebServiceError(error)) {
|
if (CoreUtils.isWebServiceError(error)) {
|
||||||
// The WebService has thrown an error, this means that the page cannot be added.
|
// 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.
|
// Load Weights selector.
|
||||||
if (this.edit && this.access.canallocate) {
|
if (this.edit && this.access.canallocate) {
|
||||||
this.weights;
|
this.weights = [];
|
||||||
for (let i = 16; i >= 0; i--) {
|
for (let i = 16; i >= 0; i--) {
|
||||||
this.weights[i] = i;
|
this.weights[i] = i;
|
||||||
}
|
}
|
||||||
|
@ -347,8 +347,6 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit, OnDe
|
||||||
this.workshop.course,
|
this.workshop.course,
|
||||||
assessmentData,
|
assessmentData,
|
||||||
);
|
);
|
||||||
|
|
||||||
gradeUpdated = false;
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Try to send it to server.
|
// Try to send it to server.
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
:host-context(ion-item.md) ion-icon {
|
:host-context(ion-item.md) ion-icon {
|
||||||
&[slot] {
|
&[slot] {
|
||||||
font-size: 1.6em;
|
|
||||||
color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);
|
color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
|
|
|
@ -52,10 +52,8 @@ export abstract class CoreBlockBaseComponent implements OnInit, ICoreBlockCompon
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
if (this.block.configs && this.block.configs.length > 0) {
|
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);
|
config.value = CoreTextUtils.parseJSON(config.value);
|
||||||
|
|
||||||
return config;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.block.configsRecord = CoreUtils.arrayToObject(this.block.configs, 'name');
|
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).
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @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(
|
getActions(
|
||||||
siteIds: string[],
|
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.
|
* @inheritdoc
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
async isEnabled(siteId: string, url: string, params: Params, courseId?: number): Promise<boolean> {
|
async isEnabled(siteId: string, url: string, params: Params): Promise<boolean> {
|
||||||
courseId = parseInt(params.id, 10);
|
const courseId = parseInt(params.id, 10);
|
||||||
|
|
||||||
if (!courseId) {
|
if (!courseId) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -333,7 +320,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
|
||||||
|
|
||||||
await CoreUtils.wait(5000);
|
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);
|
this.showMessage('core.editor.textrecovered', this.RESTORE_MESSAGE_CLEAR_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors, shouldn't happen.
|
// Ignore errors, shouldn't happen.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ export class CoreEditorOfflineProvider {
|
||||||
const params = this.fixDraftPrimaryData(contextLevel, contextInstanceId, elementId, extraParams);
|
const params = this.fixDraftPrimaryData(contextLevel, contextInstanceId, elementId, extraParams);
|
||||||
|
|
||||||
await db.deleteRecords(DRAFT_TABLE, params);
|
await db.deleteRecords(DRAFT_TABLE, params);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors, probably no draft stored.
|
// Ignore errors, probably no draft stored.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,12 +149,12 @@ export class CoreEditorOfflineProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.insertRecord(DRAFT_TABLE, entry);
|
await db.insertRecord(DRAFT_TABLE, entry);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors saving the draft. It shouldn't happen.
|
// Ignore errors saving the draft. It shouldn't happen.
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
} catch (error) {
|
} catch {
|
||||||
// No draft stored. Store an empty draft to save the pageinstance.
|
// No draft stored. Store an empty draft to save the pageinstance.
|
||||||
await this.saveDraft(
|
await this.saveDraft(
|
||||||
contextLevel,
|
contextLevel,
|
||||||
|
|
|
@ -812,7 +812,7 @@ export class CoreFileUploaderHelperProvider {
|
||||||
file = await CoreFile.getFileObjectFromFileEntry(fileEntry);
|
file = await CoreFile.getFileObjectFromFileEntry(fileEntry);
|
||||||
|
|
||||||
size = file.size;
|
size = file.size;
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore failures.
|
// Ignore failures.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,14 +30,7 @@ export class CoreGradesReportLinkHandlerService extends CoreContentLinksHandlerB
|
||||||
pattern = /\/grade\/report(\/user)?\/index.php/;
|
pattern = /\/grade\/report(\/user)?\/index.php/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of actions for a link (url).
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @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(
|
getActions(
|
||||||
siteIds: string[],
|
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.
|
* @inheritdoc
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
||||||
if (!courseId && !params.id) {
|
if (!courseId && !params.id) {
|
||||||
|
|
|
@ -30,14 +30,7 @@ export class CoreGradesUserLinkHandlerService extends CoreContentLinksHandlerBas
|
||||||
pattern = /\/course\/user\.php.*[?&]mode=grade/;
|
pattern = /\/course\/user\.php.*[?&]mode=grade/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of actions for a link (url).
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @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(
|
getActions(
|
||||||
siteIds: string[],
|
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.
|
* @inheritdoc
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
||||||
if (!courseId && !params.id) {
|
if (!courseId && !params.id) {
|
||||||
|
|
|
@ -191,7 +191,7 @@ export class CoreH5PContentValidator {
|
||||||
/**
|
/**
|
||||||
* Validate given value against number semantics.
|
* Validate given value against number semantics.
|
||||||
*
|
*
|
||||||
* @param num Number to validate.
|
* @param value Number to validate.
|
||||||
* @param semantics Semantics.
|
* @param semantics Semantics.
|
||||||
* @return Validated number.
|
* @return Validated number.
|
||||||
*/
|
*/
|
||||||
|
@ -497,9 +497,7 @@ export class CoreH5PContentValidator {
|
||||||
let validateFunction: undefined | ((...args: unknown[]) => unknown);
|
let validateFunction: undefined | ((...args: unknown[]) => unknown);
|
||||||
let field: CoreH5PSemantics | undefined;
|
let field: CoreH5PSemantics | undefined;
|
||||||
|
|
||||||
for (let i = 0; i < semantics.fields.length; i++) {
|
for (const field of semantics.fields) {
|
||||||
field = semantics.fields[i];
|
|
||||||
|
|
||||||
if (field.name == key) {
|
if (field.name == key) {
|
||||||
if (semantics.optional) {
|
if (semantics.optional) {
|
||||||
field.optional = true;
|
field.optional = true;
|
||||||
|
@ -778,8 +776,7 @@ export class CoreH5PContentValidator {
|
||||||
if (matches && matches.length > 1) {
|
if (matches && matches.length > 1) {
|
||||||
if (allowedStyles && attrName === 'style') {
|
if (allowedStyles && attrName === 'style') {
|
||||||
// Allow certain styles.
|
// Allow certain styles.
|
||||||
for (let i = 0; i < allowedStyles.length; i++) {
|
for (const pattern of allowedStyles) {
|
||||||
const pattern = allowedStyles[i];
|
|
||||||
if (matches[1].match(pattern)) {
|
if (matches[1].match(pattern)) {
|
||||||
// All patterns are start to end patterns, and CKEditor adds one span per style.
|
// All patterns are start to end patterns, and CKEditor adds one span per style.
|
||||||
attrArray.push('style="' + matches[1] + '"');
|
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.
|
// Update library usage.
|
||||||
try {
|
try {
|
||||||
await this.h5pFramework.deleteLibraryUsage(content.id, siteId);
|
await this.h5pFramework.deleteLibraryUsage(content.id, siteId);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,7 @@ export class CoreH5PFileStorage {
|
||||||
try {
|
try {
|
||||||
// Delete the index.html.
|
// Delete the index.html.
|
||||||
await this.deleteContentIndex(entry.foldername, site.getId());
|
await this.deleteContentIndex(entry.foldername, site.getId());
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -463,7 +463,7 @@ export class CoreH5PFileStorage {
|
||||||
// Delete existing library version.
|
// Delete existing library version.
|
||||||
try {
|
try {
|
||||||
await CoreFile.removeDir(folderPath);
|
await CoreFile.removeDir(folderPath);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors, maybe it doesn't exist.
|
// Ignore errors, maybe it doesn't exist.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,7 @@ export class CoreH5PHelper {
|
||||||
// Remove tmp folder.
|
// Remove tmp folder.
|
||||||
try {
|
try {
|
||||||
await CoreFile.removeDir(destFolder);
|
await CoreFile.removeDir(destFolder);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors, it will be deleted eventually.
|
// 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].
|
const parts = entry.name.split('.'); // The language code is in parts[0].
|
||||||
langIndex[parts[0]] = langFileData;
|
langIndex[parts[0]] = langFileData;
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore this language.
|
// Ignore this language.
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -47,7 +47,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
canDownload$ = new BehaviorSubject(false);
|
canDownload$ = new BehaviorSubject(false);
|
||||||
calculating$ = new BehaviorSubject(true);
|
calculating$ = new BehaviorSubject(true);
|
||||||
displayOptions?: CoreH5PDisplayOptions;
|
displayOptions?: CoreH5PDisplayOptions;
|
||||||
urlParams?: {[name: string]: string};
|
urlParams: {[name: string]: string} = {};
|
||||||
|
|
||||||
protected site: CoreSite;
|
protected site: CoreSite;
|
||||||
protected siteId: string;
|
protected siteId: string;
|
||||||
|
@ -60,7 +60,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
) {
|
) {
|
||||||
|
|
||||||
this.logger = CoreLogger.getInstance('CoreH5PPlayerComponent');
|
this.logger = CoreLogger.getInstance('CoreH5PPlayerComponent');
|
||||||
this.site = CoreSites.getCurrentSite()!;
|
this.site = CoreSites.getRequiredCurrentSite();
|
||||||
this.siteId = this.site.getId();
|
this.siteId = this.site.getId();
|
||||||
this.siteCanDownload = this.site.canDownloadFiles() && !CoreH5P.isOfflineDisabledInSite();
|
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.
|
// Download the package in background if the size is low.
|
||||||
try {
|
try {
|
||||||
this.attemptDownloadInBg();
|
await this.attemptDownloadInBg();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('Error downloading H5P in background', error);
|
this.logger.error('Error downloading H5P in background', error);
|
||||||
}
|
}
|
||||||
|
@ -120,12 +120,12 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Get the file size and ask the user to confirm.
|
// 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 });
|
await CoreDomUtils.confirmDownloadSize({ size: size, total: true });
|
||||||
|
|
||||||
// User confirmed, add to the queue.
|
// 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) {
|
} catch (error) {
|
||||||
if (CoreDomUtils.isCanceledError(error)) {
|
if (CoreDomUtils.isCanceledError(error)) {
|
||||||
|
@ -191,7 +191,6 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* Calculate state of the file.
|
* Calculate state of the file.
|
||||||
*
|
*
|
||||||
* @param fileUrl The H5P file URL.
|
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async calculateState(): Promise<void> {
|
protected async calculateState(): Promise<void> {
|
||||||
|
@ -199,7 +198,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
// Get the status of the file.
|
// Get the status of the file.
|
||||||
try {
|
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.canDownload$.next(true);
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><b>{{ 'core.login.faqcannotfindmysitequestion' | translate }}</b></h2>
|
<h2><strong>{{ 'core.login.faqcannotfindmysitequestion' | translate }}</strong></h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><b>{{ 'core.login.faqwhatisurlquestion' | translate }}</b></h2>
|
<h2><strong>{{ 'core.login.faqwhatisurlquestion' | translate }}</strong></h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap core-login-faqwhatisurlanswer">
|
<ion-item class="ion-text-wrap core-login-faqwhatisurlanswer">
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><b>{{ 'core.login.faqcannotconnectquestion' | translate }}</b></h2>
|
<h2><strong>{{ 'core.login.faqcannotconnectquestion' | translate }}</strong></h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><b>{{ 'core.login.faqsetupsitequestion' | translate }}</b></h2>
|
<h2><strong>{{ 'core.login.faqsetupsitequestion' | translate }}</strong></h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><b>{{ 'core.login.faqtestappquestion' | translate }}</b></h2>
|
<h2><strong>{{ 'core.login.faqtestappquestion' | translate }}</strong></h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap" *ngIf="canScanQR">
|
<ion-item class="ion-text-wrap" *ngIf="canScanQR">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><b>{{ 'core.login.faqwhereisqrcode' | translate }}</b></h2>
|
<h2><strong>{{ 'core.login.faqwhereisqrcode' | translate }}</strong></h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap core-login-faqwhereisqrcodeanswer" *ngIf="canScanQR">
|
<ion-item class="ion-text-wrap core-login-faqwhereisqrcodeanswer" *ngIf="canScanQR">
|
||||||
|
|
|
@ -360,7 +360,7 @@ export class CoreLoginSitePage implements OnInit {
|
||||||
params: pageParams,
|
params: pageParams,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,7 +546,7 @@ export class CoreLoginSitePage implements OnInit {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
} finally {
|
} finally {
|
||||||
modal.dismiss();
|
modal.dismiss();
|
||||||
|
|
|
@ -625,13 +625,10 @@ export class CorePushNotificationsProvider {
|
||||||
|
|
||||||
const total = counters.reduce((previous, counter) => previous + counter, 0);
|
const total = counters.reduce((previous, counter) => previous + counter, 0);
|
||||||
|
|
||||||
if (!CorePlatform.isMobile()) {
|
if (CorePlatform.isMobile()) {
|
||||||
// Browser doesn't have an app badge, stop.
|
// Set the app badge on mobile.
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the app badge.
|
|
||||||
await Badge.set(total);
|
await Badge.set(total);
|
||||||
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,17 +404,15 @@ export class CoreRatingProvider {
|
||||||
true,
|
true,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
const ratingsResults = await Promise.all(promises);
|
||||||
|
|
||||||
if (!site.isVersionGreaterEqualThan([' 3.6.5', '3.7.1', '3.8'])) {
|
if (!site.isVersionGreaterEqualThan([' 3.6.5', '3.7.1', '3.8'])) {
|
||||||
promises.map((promise) => promise.then(async (ratings) => {
|
const ratings: CoreRatingItemRating[] = [].concat.apply([], ratingsResults);
|
||||||
const userIds = ratings.map((rating: CoreRatingItemRating) => rating.userid);
|
|
||||||
|
const userIds = ratings.map((rating) => rating.userid);
|
||||||
|
|
||||||
await CoreUser.prefetchProfiles(userIds, courseId, site.id);
|
await CoreUser.prefetchProfiles(userIds, courseId, site.id);
|
||||||
|
|
||||||
return;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(promises);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,8 +53,9 @@ export class CoreSiteHomeIndexLinkHandlerService extends CoreContentLinksHandler
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
async isEnabled(siteId: string, url: string, params: Record<string, string>): Promise<boolean> {
|
||||||
courseId = parseInt(params.id, 10);
|
const courseId = parseInt(params.id, 10);
|
||||||
|
|
||||||
if (!courseId) {
|
if (!courseId) {
|
||||||
return url.includes('index.php');
|
return url.includes('index.php');
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,21 +30,12 @@ export class CoreUserProfileLinkHandlerService extends CoreContentLinksHandlerBa
|
||||||
pattern = /((\/user\/view\.php)|(\/user\/profile\.php)).*([?&]id=\d+)/;
|
pattern = /((\/user\/view\.php)|(\/user\/profile\.php)).*([?&]id=\d+)/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of actions for a link (url).
|
* @inheritdoc
|
||||||
*
|
|
||||||
* @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(
|
getActions(
|
||||||
siteIds: string[],
|
siteIds: string[],
|
||||||
url: string,
|
url: string,
|
||||||
params: Record<string, 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[]> {
|
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
||||||
return [{
|
return [{
|
||||||
action: (siteId): void => {
|
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.
|
* @inheritdoc
|
||||||
* 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
|
async isEnabled(siteId: string, url: string): Promise<boolean> {
|
||||||
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
|
|
||||||
return url.indexOf('/grade/report/') == -1;
|
return url.indexOf('/grade/report/') == -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ export class CoreUserProfileFieldDelegateService extends CoreDelegate<CoreUserPr
|
||||||
if (data) {
|
if (data) {
|
||||||
result.push(data);
|
result.push(data);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -43,7 +43,7 @@ export class CoreFormatDatePipe implements PipeTransform {
|
||||||
timestamp = timestamp || Date.now();
|
timestamp = timestamp || Date.now();
|
||||||
format = format || 'strftimedaydatetime';
|
format = format || 'strftimedaydatetime';
|
||||||
|
|
||||||
if (typeof timestamp == 'string') {
|
if (typeof timestamp === 'string') {
|
||||||
// Convert the value to a number.
|
// Convert the value to a number.
|
||||||
const numberTimestamp = parseInt(timestamp, 10);
|
const numberTimestamp = parseInt(timestamp, 10);
|
||||||
if (isNaN(numberTimestamp)) {
|
if (isNaN(numberTimestamp)) {
|
||||||
|
@ -55,7 +55,7 @@ export class CoreFormatDatePipe implements PipeTransform {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add "core." if needed.
|
// 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;
|
format = 'core.' + format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1205,7 +1205,7 @@ export class CoreFileProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors, maybe it doesn't exist.
|
// Ignore errors, maybe it doesn't exist.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1467,7 +1467,7 @@ export class CoreFilepoolProvider {
|
||||||
const fileSize = await CoreFile.getFileSize(file.path);
|
const fileSize = await CoreFile.getFileSize(file.path);
|
||||||
|
|
||||||
size += fileSize;
|
size += fileSize;
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore failures, maybe some file was deleted.
|
// Ignore failures, maybe some file was deleted.
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -200,10 +200,8 @@ export class CorePluginFileDelegateService extends CoreDelegate<CorePluginFileHa
|
||||||
|
|
||||||
if (handler && handler.getFileSize) {
|
if (handler && handler.getFileSize) {
|
||||||
try {
|
try {
|
||||||
const size = handler.getFileSize(downloadableFile, siteId);
|
return await handler.getFileSize(downloadableFile, siteId);
|
||||||
|
} catch {
|
||||||
return size;
|
|
||||||
} catch (error) {
|
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,14 +302,12 @@ export class CoreMimetypeUtilsProvider {
|
||||||
*/
|
*/
|
||||||
guessExtensionFromUrl(fileUrl: string): string | undefined {
|
guessExtensionFromUrl(fileUrl: string): string | undefined {
|
||||||
const split = fileUrl.split('.');
|
const split = fileUrl.split('.');
|
||||||
let candidate;
|
let extension: string | undefined;
|
||||||
let extension;
|
|
||||||
let position;
|
|
||||||
|
|
||||||
if (split.length > 1) {
|
if (split.length > 1) {
|
||||||
candidate = split[split.length - 1].toLowerCase();
|
let candidate = split[split.length - 1].toLowerCase();
|
||||||
// Remove params if any.
|
// Remove params if any.
|
||||||
position = candidate.indexOf('?');
|
let position = candidate.indexOf('?');
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
candidate = candidate.substring(0, position);
|
candidate = candidate.substring(0, position);
|
||||||
}
|
}
|
||||||
|
@ -343,7 +341,7 @@ export class CoreMimetypeUtilsProvider {
|
||||||
*/
|
*/
|
||||||
getFileExtension(filename: string): string | undefined {
|
getFileExtension(filename: string): string | undefined {
|
||||||
const dot = filename.lastIndexOf('.');
|
const dot = filename.lastIndexOf('.');
|
||||||
let ext;
|
let ext: string | undefined;
|
||||||
|
|
||||||
if (dot > -1) {
|
if (dot > -1) {
|
||||||
ext = filename.substring(dot + 1).toLowerCase();
|
ext = filename.substring(dot + 1).toLowerCase();
|
||||||
|
@ -582,11 +580,10 @@ export class CoreMimetypeUtilsProvider {
|
||||||
*/
|
*/
|
||||||
removeExtension(path: string): string {
|
removeExtension(path: string): string {
|
||||||
const position = path.lastIndexOf('.');
|
const position = path.lastIndexOf('.');
|
||||||
let extension;
|
|
||||||
|
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
// Check extension corresponds to a mimetype to know if it's valid.
|
// 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) {
|
if (this.getMimeType(extension) !== undefined) {
|
||||||
return path.substring(0, position); // Remove extension.
|
return path.substring(0, position); // Remove extension.
|
||||||
}
|
}
|
||||||
|
|
|
@ -741,7 +741,7 @@ export class CoreTextUtilsProvider {
|
||||||
* @returns Treated text.
|
* @returns Treated text.
|
||||||
*/
|
*/
|
||||||
replaceArguments(text: string, replacements: Record<string, string> = {}, encoding?: 'uri'): string {
|
replaceArguments(text: string, replacements: Record<string, string> = {}, encoding?: 'uri'): string {
|
||||||
let match;
|
let match: RegExpMatchArray | null = null;
|
||||||
|
|
||||||
while ((match = text.match(/\{\{([^}]+)\}\}/))) {
|
while ((match = text.match(/\{\{([^}]+)\}\}/))) {
|
||||||
const argument = match[1].trim();
|
const argument = match[1].trim();
|
||||||
|
@ -829,7 +829,7 @@ export class CoreTextUtilsProvider {
|
||||||
/**
|
/**
|
||||||
* Replace @@PLUGINFILE@@ wildcards with the real URL in a text.
|
* 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.
|
* @param files Files to extract the pluginfile URL from. They need to have the URL in a url or fileurl attribute.
|
||||||
* @return Treated text.
|
* @return Treated text.
|
||||||
*/
|
*/
|
||||||
|
@ -847,8 +847,10 @@ export class CoreTextUtilsProvider {
|
||||||
/**
|
/**
|
||||||
* Restore original draftfile URLs.
|
* Restore original draftfile URLs.
|
||||||
*
|
*
|
||||||
* @param text Text to treat, including pluginfile URLs.
|
* @param siteUrl Site URL.
|
||||||
* @param replaceMap Map of the replacements that were done.
|
* @param treatedText Treated text with replacements.
|
||||||
|
* @param originalText Original text.
|
||||||
|
* @param files List of files to search and replace.
|
||||||
* @return Treated text.
|
* @return Treated text.
|
||||||
*/
|
*/
|
||||||
restoreDraftfileUrls(siteUrl: string, treatedText: string, originalText: string, files: CoreWSFile[]): string {
|
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 title Title of the new state.
|
||||||
* @param content Content of the text to be expanded.
|
* @param content Content of the text to be expanded.
|
||||||
* @param component Component to link the embedded files to.
|
|
||||||
* @param options Options.
|
* @param options Options.
|
||||||
* @return Promise resolved when the modal is displayed.
|
* @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''.
|
* 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.
|
* @return Short human readable text.
|
||||||
* @deprecated since app 4.0. Use CoreTime.formatTimeShort instead.
|
* @deprecated since app 4.0. Use CoreTime.formatTimeShort instead.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -544,7 +544,7 @@ export class CoreUrlUtilsProvider {
|
||||||
url = url.replace(/\/webservice\/pluginfile\.php\//, '/pluginfile.php/');
|
url = url.replace(/\/webservice\/pluginfile\.php\//, '/pluginfile.php/');
|
||||||
|
|
||||||
// Make sure the URL doesn't contain the token.
|
// Make sure the URL doesn't contain the token.
|
||||||
url.replace(/([?&])token=[^&]*&?/, '$1');
|
url = url.replace(/([?&])token=[^&]*&?/, '$1');
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,7 +486,7 @@ export class CoreUtilsProvider {
|
||||||
* @param ...args All the params sent after checkAll will be passed to isEnabledFn.
|
* @param ...args All the params sent after checkAll will be passed to isEnabledFn.
|
||||||
* @return Promise resolved with the list of enabled sites.
|
* @return Promise resolved with the list of enabled sites.
|
||||||
*/
|
*/
|
||||||
filterEnabledSites<P extends unknown[]>(
|
async filterEnabledSites<P extends unknown[]>(
|
||||||
siteIds: string[],
|
siteIds: string[],
|
||||||
isEnabledFn: (siteId, ...args: P) => boolean | Promise<boolean>,
|
isEnabledFn: (siteId, ...args: P) => boolean | Promise<boolean>,
|
||||||
checkAll?: boolean,
|
checkAll?: boolean,
|
||||||
|
@ -507,16 +507,14 @@ export class CoreUtilsProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.allPromises(promises).catch(() => {
|
await CoreUtils.ignoreErrors(this.allPromises(promises));
|
||||||
// Ignore errors.
|
|
||||||
}).then(() => {
|
|
||||||
if (!checkAll) {
|
if (!checkAll) {
|
||||||
// Checking 1 was enough, so it will either return all the sites or none.
|
// Checking 1 was enough, so it will either return all the sites or none.
|
||||||
return enabledSites.length ? siteIds : [];
|
return enabledSites.length ? siteIds : [];
|
||||||
} else {
|
} else {
|
||||||
return enabledSites;
|
return enabledSites;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -639,11 +637,12 @@ export class CoreUtilsProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved with the list of countries.
|
* @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.
|
// Get the keys of the countries.
|
||||||
return this.getCountryKeysList().then((keys) => {
|
const keys = await this.getCountryKeysList();
|
||||||
|
|
||||||
// Now get the code and the translated name.
|
// Now get the code and the translated name.
|
||||||
const countries = {};
|
const countries: Record<string, string> = {};
|
||||||
|
|
||||||
keys.forEach((key) => {
|
keys.forEach((key) => {
|
||||||
if (key.indexOf('assets.countries.') === 0) {
|
if (key.indexOf('assets.countries.') === 0) {
|
||||||
|
@ -653,7 +652,6 @@ export class CoreUtilsProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
return countries;
|
return countries;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -661,18 +659,14 @@ export class CoreUtilsProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved with the list of countries.
|
* @return Promise resolved with the list of countries.
|
||||||
*/
|
*/
|
||||||
getCountryListSorted(): Promise<CoreCountry[]> {
|
async getCountryListSorted(): Promise<CoreCountry[]> {
|
||||||
// Get the keys of the countries.
|
// Get the keys of the countries.
|
||||||
return this.getCountryList().then((countries) => {
|
const countries = await this.getCountryList();
|
||||||
|
|
||||||
// Sort translations.
|
// Sort translations.
|
||||||
const sortedCountries: { code: string; name: string }[] = [];
|
return Object.keys(countries)
|
||||||
|
.sort((a, b) => countries[a].localeCompare(countries[b]))
|
||||||
Object.keys(countries).sort((a, b) => countries[a].localeCompare(countries[b])).forEach((key) => {
|
.map((code) => ({ code, name: countries[code] }));
|
||||||
sortedCountries.push({ code: key, name: countries[key] });
|
|
||||||
});
|
|
||||||
|
|
||||||
return sortedCountries;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -680,11 +674,13 @@ export class CoreUtilsProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved with the countries list. Rejected if not translated.
|
* @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.
|
// It's possible that the current language isn't translated, so try with default language first.
|
||||||
const defaultLang = CoreLang.getDefaultLanguage();
|
const defaultLang = CoreLang.getDefaultLanguage();
|
||||||
|
|
||||||
return this.getCountryKeysListForLanguage(defaultLang).catch(() => {
|
try {
|
||||||
|
return await this.getCountryKeysListForLanguage(defaultLang);
|
||||||
|
} catch {
|
||||||
// Not translated, try to use the fallback language.
|
// Not translated, try to use the fallback language.
|
||||||
const fallbackLang = CoreLang.getFallbackLanguage();
|
const fallbackLang = CoreLang.getFallbackLanguage();
|
||||||
|
|
||||||
|
@ -693,8 +689,8 @@ export class CoreUtilsProvider {
|
||||||
throw new Error('Countries not found.');
|
throw new Error('Countries not found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getCountryKeysListForLanguage(fallbackLang);
|
return await this.getCountryKeysListForLanguage(fallbackLang);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -732,17 +728,19 @@ export class CoreUtilsProvider {
|
||||||
* @param url The URL of the file.
|
* @param url The URL of the file.
|
||||||
* @return Promise resolved with the mimetype.
|
* @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.
|
// First check if it can be guessed from the URL.
|
||||||
const extension = CoreMimetypeUtils.guessExtensionFromUrl(url);
|
const extension = CoreMimetypeUtils.guessExtensionFromUrl(url);
|
||||||
const mimetype = extension && CoreMimetypeUtils.getMimeType(extension);
|
let mimetype = extension && CoreMimetypeUtils.getMimeType(extension);
|
||||||
|
|
||||||
if (mimetype) {
|
if (mimetype) {
|
||||||
return Promise.resolve(mimetype);
|
return mimetype;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't be guessed, get the remote mimetype.
|
// Can't be guessed, get the remote mimetype.
|
||||||
return CoreWS.getRemoteFileMimeType(url).then(mimetype => mimetype || '');
|
mimetype = await CoreWS.getRemoteFileMimeType(url);
|
||||||
|
|
||||||
|
return mimetype || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -772,7 +770,7 @@ export class CoreUtilsProvider {
|
||||||
/**
|
/**
|
||||||
* Check if an unknown value is a FileEntry.
|
* 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.
|
* @return Type guard indicating if the file is a FileEntry.
|
||||||
*/
|
*/
|
||||||
valueIsFileEntry(file: unknown): file is FileEntry {
|
valueIsFileEntry(file: unknown): file is FileEntry {
|
||||||
|
@ -1029,7 +1027,7 @@ export class CoreUtilsProvider {
|
||||||
this.iabInstance = InAppBrowser.create(url, '_blank', options);
|
this.iabInstance = InAppBrowser.create(url, '_blank', options);
|
||||||
|
|
||||||
if (CorePlatform.isMobile()) {
|
if (CorePlatform.isMobile()) {
|
||||||
let loadStopSubscription;
|
let loadStopSubscription: Subscription | undefined;
|
||||||
const loadStartUrls: string[] = [];
|
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.
|
// Trigger global events when a url is loaded or the window is closed. This is to make it work like in Ionic 1.
|
||||||
|
@ -1720,7 +1718,7 @@ export class CoreUtilsProvider {
|
||||||
* Ignore errors from a promise.
|
* Ignore errors from a promise.
|
||||||
*
|
*
|
||||||
* @param promise Promise to ignore errors.
|
* @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.
|
* @return Promise with ignored errors, resolving to the fallback result if provided.
|
||||||
*/
|
*/
|
||||||
async ignoreErrors<Result>(promise: Promise<Result>): Promise<Result | undefined>;
|
async ignoreErrors<Result>(promise: Promise<Result>): Promise<Result | undefined>;
|
||||||
|
|
Loading…
Reference in New Issue