From 4209dd139330f0f22df1a194137aff2ae2a2a48d Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 12 Dec 2019 12:15:44 +0100 Subject: [PATCH 1/7] MOBILE-3213 notes: Fix HTML not rendered in notes --- src/addon/notes/components/list/addon-notes-list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/notes/components/list/addon-notes-list.html b/src/addon/notes/components/list/addon-notes-list.html index 903727ec3..0409e6aae 100644 --- a/src/addon/notes/components/list/addon-notes-list.html +++ b/src/addon/notes/components/list/addon-notes-list.html @@ -53,7 +53,7 @@ - {{ note.content }} + From 268e45ef09c3052928e370e1a0457818d13d5e1d Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 12 Dec 2019 13:12:17 +0100 Subject: [PATCH 2/7] MOBILE-3213 badges: Don't show alignment if broken --- .../pages/issued-badge/issued-badge.html | 2 +- src/addon/badges/providers/badges.ts | 26 ++++++++++++------- .../entries/addon-blog-entries.html | 2 +- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/addon/badges/pages/issued-badge/issued-badge.html b/src/addon/badges/pages/issued-badge/issued-badge.html index 75ee12adf..ec4dc0e4f 100644 --- a/src/addon/badges/pages/issued-badge/issued-badge.html +++ b/src/addon/badges/pages/issued-badge/issued-badge.html @@ -156,7 +156,7 @@

{{ 'addon.badges.relatedbages' | translate}}

-

<{{ relatedBadge.name }}

+

{{ relatedBadge.name }}

{{ 'addon.badges.norelated' | translate}}

diff --git a/src/addon/badges/providers/badges.ts b/src/addon/badges/providers/badges.ts index bfb70431e..bce298dc4 100644 --- a/src/addon/badges/providers/badges.ts +++ b/src/addon/badges/providers/badges.ts @@ -91,6 +91,12 @@ export class AddonBadgesProvider { // In 3.7, competencies was renamed to alignment. Rename the property in 3.6 too. response.badges.forEach((badge) => { badge.alignment = badge.alignment || badge.competencies; + + // Check that the alignment is valid, they were broken in 3.7. + if (badge.alignment && badge.alignment[0] && typeof badge.alignment[0].targetname == 'undefined') { + // If any badge lacks targetname it means they are affected by the Moodle bug, don't display them. + delete badge.alignment; + } }); return response.badges; @@ -175,20 +181,20 @@ export type AddonBadgesUserBadge = { alignment?: { // @since 3.7. Calculated by the app for 3.6 sites. Badge alignments. id?: number; // Alignment id. badgeid?: number; // Badge id. - targetName?: string; // Target name. - targetUrl?: string; // Target URL. - targetDescription?: string; // Target description. - targetFramework?: string; // Target framework. - targetCode?: string; // Target code. + targetname?: string; // Target name. + targeturl?: string; // Target URL. + targetdescription?: string; // Target description. + targetframework?: string; // Target framework. + targetcode?: string; // Target code. }[]; competencies?: { // @deprecated from 3.7. @since 3.6. In 3.7 it was renamed to alignment. id?: number; // Alignment id. badgeid?: number; // Badge id. - targetName?: string; // Target name. - targetUrl?: string; // Target URL. - targetDescription?: string; // Target description. - targetFramework?: string; // Target framework. - targetCode?: string; // Target code. + targetname?: string; // Target name. + targeturl?: string; // Target URL. + targetdescription?: string; // Target description. + targetframework?: string; // Target framework. + targetcode?: string; // Target code. }[]; relatedbadges?: { // @since 3.6. Related badges. id: number; // Badge id. diff --git a/src/addon/blog/components/entries/addon-blog-entries.html b/src/addon/blog/components/entries/addon-blog-entries.html index 557bf3ed3..a77b45b2f 100644 --- a/src/addon/blog/components/entries/addon-blog-entries.html +++ b/src/addon/blog/components/entries/addon-blog-entries.html @@ -5,7 +5,7 @@ {{ 'addon.blog.showonlyyourentries' | translate }} - > + From 72a2b571cdc20dbf881b86b43df8138a45624ada Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 13 Dec 2019 08:30:54 +0100 Subject: [PATCH 3/7] MOBILE-3213 folder: Fix PTR in folder --- src/addon/mod/folder/components/index/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/mod/folder/components/index/index.ts b/src/addon/mod/folder/components/index/index.ts index 573b4dfb6..922ec3836 100644 --- a/src/addon/mod/folder/components/index/index.ts +++ b/src/addon/mod/folder/components/index/index.ts @@ -105,7 +105,7 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo if (this.canGetFolder) { promise = this.folderProvider.getFolder(this.courseId, this.module.id).then((folder) => { - return this.courseProvider.loadModuleContents(this.module, this.courseId).then(() => { + return this.courseProvider.loadModuleContents(this.module, this.courseId, undefined, false, refresh).then(() => { folderContents = this.module.contents; return folder; From 5053274a85964bf6781afae8c6023e52cc44c38a Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 13 Dec 2019 09:26:04 +0100 Subject: [PATCH 4/7] MOBILE-3213 resource: Fix PTR on mod resource --- src/core/course/providers/helper.ts | 85 ++++++++++++++++++----------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index ffbc281b5..1f393b487 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -661,7 +661,6 @@ export class CoreCourseHelperProvider { const mainFile = files[0], fileUrl = this.fileHelper.getFileUrl(mainFile), - timemodified = this.fileHelper.getFileTimemodified(mainFile), result = { fixedUrl: undefined, path: undefined, @@ -678,48 +677,23 @@ export class CoreCourseHelperProvider { return this.filepoolProvider.getPackageStatus(siteId, component, componentId).then((status) => { result.status = status; - const isWifi = this.appProvider.isWifi(), - isOnline = this.appProvider.isOnline(); - if (status === CoreConstants.DOWNLOADED) { // Get the local file URL. return this.filepoolProvider.getInternalUrlByUrl(siteId, fileUrl).catch((error) => { - // File not found, mark the module as not downloaded and reject. + // File not found, mark the module as not downloaded and try again. return this.filepoolProvider.storePackageStatus(siteId, CoreConstants.NOT_DOWNLOADED, component, componentId).then(() => { - return Promise.reject(error); + return this.downloadModuleWithMainFile(module, courseId, fixedUrl, files, status, component, + componentId, siteId); }); }); } else if (status === CoreConstants.DOWNLOADING && !this.appProvider.isDesktop()) { // Return the online URL. return fixedUrl; } else { - if (!isOnline && status === CoreConstants.NOT_DOWNLOADED) { - // Not downloaded and we're offline, reject. - return Promise.reject(this.translate.instant('core.networkerrormsg')); - } - - return this.filepoolProvider.shouldDownloadBeforeOpen(fixedUrl, mainFile.filesize).then(() => { - // Download and then return the local URL. - return this.downloadModule(module, courseId, component, componentId, files, siteId).then(() => { - return this.filepoolProvider.getInternalUrlByUrl(siteId, fileUrl); - }); - }, () => { - // Start the download if in wifi, but return the URL right away so the file is opened. - if (isWifi) { - this.downloadModule(module, courseId, component, componentId, files, siteId); - } - - if (!this.fileHelper.isStateDownloaded(status) || isOnline) { - // Not downloaded or online, return the online URL. - return fixedUrl; - } else { - // Outdated but offline, so we return the local URL. Use getUrlByUrl so it's added to the queue. - return this.filepoolProvider.getUrlByUrl(siteId, fileUrl, component, componentId, timemodified, - false, false, mainFile); - } - }); + return this.downloadModuleWithMainFile(module, courseId, fixedUrl, files, status, component, componentId, + siteId); } }).then((path) => { result.path = path; @@ -735,6 +709,55 @@ export class CoreCourseHelperProvider { }); } + /** + * Convenience function to download a module that has a main file and return the local file's path and other info. + * This is meant for modules like mod_resource. + * + * @param module The module to download. + * @param courseId The course ID of the module. + * @param fixedUrl Main file's fixed URL. + * @param files List of files of the module. + * @param status The package status. + * @param component The component to link the files to. + * @param componentId An ID to use in conjunction with the component. + * @param siteId The site ID. If not defined, current site. + * @return Promise resolved when done. + */ + protected downloadModuleWithMainFile(module: any, courseId: number, fixedUrl: string, files: any[], status: string, + component?: string, componentId?: string | number, siteId?: string): Promise { + + const isOnline = this.appProvider.isOnline(); + const mainFile = files[0]; + const fileUrl = this.fileHelper.getFileUrl(mainFile); + const timemodified = this.fileHelper.getFileTimemodified(mainFile); + + if (!isOnline && status === CoreConstants.NOT_DOWNLOADED) { + // Not downloaded and we're offline, reject. + return Promise.reject(this.translate.instant('core.networkerrormsg')); + } + + return this.filepoolProvider.shouldDownloadBeforeOpen(fixedUrl, mainFile.filesize).then(() => { + // Download and then return the local URL. + return this.downloadModule(module, courseId, component, componentId, files, siteId).then(() => { + return this.filepoolProvider.getInternalUrlByUrl(siteId, fileUrl); + }); + }, () => { + // Start the download if in wifi, but return the URL right away so the file is opened. + if (this.appProvider.isWifi()) { + this.downloadModule(module, courseId, component, componentId, files, siteId); + } + + if (!this.fileHelper.isStateDownloaded(status) || isOnline) { + // Not downloaded or online, return the online URL. + return fixedUrl; + } else { + // Outdated but offline, so we return the local URL. Use getUrlByUrl so it's added to the queue. + return this.filepoolProvider.getUrlByUrl(siteId, fileUrl, component, componentId, timemodified, + false, false, mainFile); + } + }); + } + /** * Convenience function to download a module. * From 4ecb148c192d39a2fc25ddf33b88c371059a7011 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 13 Dec 2019 12:30:07 +0100 Subject: [PATCH 5/7] MOBILE-3213 ios: Fix RTE toolbar in iOS 12+ --- src/components/rich-text-editor/rich-text-editor.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/rich-text-editor/rich-text-editor.ts b/src/components/rich-text-editor/rich-text-editor.ts index 83d4baaef..d4367e509 100644 --- a/src/components/rich-text-editor/rich-text-editor.ts +++ b/src/components/rich-text-editor/rich-text-editor.ts @@ -180,18 +180,19 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy if (this.platform.is('android')) { // In Android we ignore the keyboard height because it is not part of the web view. height = this.domUtils.getContentHeight(this.content) - this.getSurroundingHeight(this.element); - } else if (this.platform.is('ios') && this.kbHeight > 0) { - // Keyboard open in iOS. - // In this case, the header disappears or is scrollable, so we need to adjust the calculations. + } else if (this.platform.is('ios') && this.kbHeight > 0 && this.platform.version().major < 12) { + // Keyboard open in iOS 11 or previous. The window height changes when the keyboard is open. height = window.innerHeight - this.getSurroundingHeight(this.element); if (this.element.getBoundingClientRect().top < 40) { // In iOS sometimes the editor is placed below the status bar. Move the scroll a bit so it doesn't happen. window.scrollTo(window.scrollX, window.scrollY - 40); } + } else { // Header is fixed, use the content to calculate the editor height. height = this.domUtils.getContentHeight(this.content) - this.kbHeight - this.getSurroundingHeight(this.element); + } if (height > this.minHeight) { @@ -549,12 +550,14 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy } /** - * Hide the toolbar. + * Hide the toolbar in phone mode. */ hideToolbar($event: any): void { this.stopBubble($event); - this.toolbarHidden = true; + if (this.isPhone) { + this.toolbarHidden = true; + } } /** From f454ed291f9639d09313c20cf684dd6c09f2f7c5 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 13 Dec 2019 15:11:18 +0100 Subject: [PATCH 6/7] MOBILE-3213 feedback: Fix question name not filtered --- src/addon/mod/feedback/pages/form/form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/mod/feedback/pages/form/form.html b/src/addon/mod/feedback/pages/form/form.html index 189131ab6..adb569d88 100644 --- a/src/addon/mod/feedback/pages/form/form.html +++ b/src/addon/mod/feedback/pages/form/form.html @@ -17,7 +17,7 @@ {{item.itemnumber}}. - + {{item.postfix}}
From af38ef23831daf4db3baddf8b2853cf5e3b8d531 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 13 Dec 2019 18:42:23 +0100 Subject: [PATCH 7/7] MOBILE-3213 assign: Fix not refreshed after copy previous submission --- src/addon/mod/assign/providers/assign.ts | 42 ++++++++++++++++-------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/addon/mod/assign/providers/assign.ts b/src/addon/mod/assign/providers/assign.ts index 34c02701d..2ab77ae3a 100644 --- a/src/addon/mod/assign/providers/assign.ts +++ b/src/addon/mod/assign/providers/assign.ts @@ -119,6 +119,25 @@ export class AddonModAssignProvider { return assign.submissiondrafts; } + /** + * Fix some submission status params. + * + * @param site Site to use. + * @param userId User Id (empty for current user). + * @param groupId Group Id (empty for all participants). + * @param isBlind If blind marking is enabled or not. + * @return Object with fixed params. + */ + protected fixSubmissionStatusParams(site: CoreSite, userId?: number, groupId?: number, isBlind?: boolean) + : {userId: number, groupId: number, isBlind: boolean} { + + return { + isBlind: !userId ? false : !!isBlind, + groupId: site.isVersionGreaterEqualThan('3.5') ? groupId || 0 : 0, + userId: userId || site.getUserId(), + }; + } + /** * Get an assignment by course module ID. * @@ -502,24 +521,23 @@ export class AddonModAssignProvider { getSubmissionStatus(assignId: number, userId?: number, groupId?: number, isBlind?: boolean, filter: boolean = true, ignoreCache?: boolean, siteId?: string): Promise { - userId = userId || 0; - return this.sitesProvider.getSite(siteId).then((site) => { - groupId = site.isVersionGreaterEqualThan('3.5') ? groupId || 0 : 0; + const fixedParams = this.fixSubmissionStatusParams(site, userId, groupId, isBlind); const params = { assignid: assignId, - userid: userId + userid: fixedParams.userId }, preSets: CoreSiteWSPreSets = { - cacheKey: this.getSubmissionStatusCacheKey(assignId, userId, groupId, isBlind), + cacheKey: this.getSubmissionStatusCacheKey(assignId, fixedParams.userId, fixedParams.groupId, + fixedParams.isBlind), getCacheUsingCacheKey: true, // We use the cache key to take isBlind into account. filter: filter, rewriteurls: filter }; - if (groupId) { - params['groupid'] = groupId; + if (fixedParams.groupId) { + params['groupid'] = fixedParams.groupId; } if (ignoreCache) { @@ -578,11 +596,6 @@ export class AddonModAssignProvider { * @return Cache key. */ protected getSubmissionStatusCacheKey(assignId: number, userId: number, groupId?: number, isBlind?: boolean): string { - if (!userId) { - isBlind = false; - userId = this.sitesProvider.getCurrentSiteUserId(); - } - return this.getSubmissionsCacheKey(assignId) + ':' + userId + ':' + (isBlind ? 1 : 0) + ':' + groupId; } @@ -809,7 +822,10 @@ export class AddonModAssignProvider { invalidateSubmissionStatusData(assignId: number, userId?: number, groupId?: number, isBlind?: boolean, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { - return site.invalidateWsCacheForKey(this.getSubmissionStatusCacheKey(assignId, userId, groupId, isBlind)); + const fixedParams = this.fixSubmissionStatusParams(site, userId, groupId, isBlind); + + return site.invalidateWsCacheForKey(this.getSubmissionStatusCacheKey(assignId, fixedParams.userId, + fixedParams.groupId, fixedParams.isBlind)); }); }