From d74c87d55419d7b493e7ee73446ed41c4f4cc262 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 2 Jun 2021 13:49:14 +0200 Subject: [PATCH 01/10] MOBILE-3320 tabs: Improve number of tabs calculation --- src/core/classes/tabs.ts | 9 +++++++-- src/core/components/tabs-outlet/core-tabs-outlet.html | 1 - 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/classes/tabs.ts b/src/core/classes/tabs.ts index 92f76b076..bafe71197 100644 --- a/src/core/classes/tabs.ts +++ b/src/core/classes/tabs.ts @@ -378,9 +378,14 @@ export class CoreTabsBaseComponent implements OnInit, Aft } this.maxSlides = 3; - const width = this.slidesSwiper.width; + let width = this.slidesSwiper.width; if (!width) { - return; + this.slidesSwiper.updateSize(); + width = this.slidesSwiper.width; + + if (!width) { + return; + } } const zoomLevel = await CoreSettingsHelper.getZoom(); diff --git a/src/core/components/tabs-outlet/core-tabs-outlet.html b/src/core/components/tabs-outlet/core-tabs-outlet.html index 0c5ce4ea6..74747fbe7 100644 --- a/src/core/components/tabs-outlet/core-tabs-outlet.html +++ b/src/core/components/tabs-outlet/core-tabs-outlet.html @@ -11,7 +11,6 @@ Date: Wed, 2 Jun 2021 15:18:40 +0200 Subject: [PATCH 02/10] MOBILE-3320 notes: Fix textarea size when adding a note --- src/addons/notes/components/add/add-modal.html | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/addons/notes/components/add/add-modal.html b/src/addons/notes/components/add/add-modal.html index c3fe269d6..843df9053 100644 --- a/src/addons/notes/components/add/add-modal.html +++ b/src/addons/notes/components/add/add-modal.html @@ -19,11 +19,10 @@ - - - - + + +
From dd2eb1fc97426a72f39712d4355ce80fbf8bc5ff Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 2 Jun 2021 16:16:22 +0200 Subject: [PATCH 03/10] MOBILE-3320 core: Fix bugs with concat(), like notes sync --- src/addons/calendar/services/calendar-helper.ts | 4 ++-- src/addons/mod/forum/services/handlers/prefetch.ts | 4 ++-- src/addons/mod/glossary/components/index/index.ts | 2 -- src/addons/notes/services/notes-sync.ts | 8 +++----- src/core/features/mainmenu/mainmenu-tab-routing.module.ts | 2 +- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/addons/calendar/services/calendar-helper.ts b/src/addons/calendar/services/calendar-helper.ts index 593637898..80d70451f 100644 --- a/src/addons/calendar/services/calendar-helper.ts +++ b/src/addons/calendar/services/calendar-helper.ts @@ -546,12 +546,12 @@ export class AddonCalendarHelperProvider { const site = await CoreSites.getSite(siteId); const fetchTimestarts: number[] = []; const invalidateTimestarts: number[] = []; - const promises: Promise[] = []; + let promises: Promise[] = []; // Always fetch upcoming events. promises.push(AddonCalendar.getUpcomingEvents(undefined, undefined, true, site.id)); - promises.concat(events.map(async (eventData) => { + promises = promises.concat(events.map(async (eventData) => { if (eventData.repeated <= 1) { // Not repeated. diff --git a/src/addons/mod/forum/services/handlers/prefetch.ts b/src/addons/mod/forum/services/handlers/prefetch.ts index a9c55d2e9..79e1bf33b 100644 --- a/src/addons/mod/forum/services/handlers/prefetch.ts +++ b/src/addons/mod/forum/services/handlers/prefetch.ts @@ -48,13 +48,13 @@ export class AddonModForumPrefetchHandlerService extends CoreCourseActivityPrefe try { const forum = await AddonModForum.getForum(courseId, module.id); - const files = this.getIntroFilesFromInstance(module, forum); + let files = this.getIntroFilesFromInstance(module, forum); // Get posts. const posts = await this.getPostsForPrefetch(forum, { cmId: module.id }); // Add posts attachments and embedded files. - files.concat(this.getPostsFiles(posts)); + files = files.concat(this.getPostsFiles(posts)); return files; } catch (error) { diff --git a/src/addons/mod/glossary/components/index/index.ts b/src/addons/mod/glossary/components/index/index.ts index 03be8f63b..d79b755ea 100644 --- a/src/addons/mod/glossary/components/index/index.ts +++ b/src/addons/mod/glossary/components/index/index.ts @@ -573,7 +573,6 @@ class AddonModGlossaryEntriesManager extends CorePageItemsListManager */ setOnlineEntries(onlineEntries: AddonModGlossaryEntry[], hasMoreItems: boolean = false): void { this.setItems(( this.offlineEntries).concat(onlineEntries), hasMoreItems); - this.onlineEntries.concat(onlineEntries); } /** @@ -583,7 +582,6 @@ class AddonModGlossaryEntriesManager extends CorePageItemsListManager */ setOfflineEntries(offlineEntries: AddonModGlossaryOfflineEntry[]): void { this.setItems(( offlineEntries).concat(this.onlineEntries), this.hasMoreItems); - this.offlineEntries = offlineEntries; } /** diff --git a/src/addons/notes/services/notes-sync.ts b/src/addons/notes/services/notes-sync.ts index 2df96b2ce..a9dfac04d 100644 --- a/src/addons/notes/services/notes-sync.ts +++ b/src/addons/notes/services/notes-sync.ts @@ -62,12 +62,10 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { - const courseIds = notes.map((note) => note.courseid); - - courseIds.concat(courseIds); - }, []); + courseIds = courseIds.concat(notes.map((note) => note.courseid)); + }); CoreUtils.uniqueArray(courseIds); diff --git a/src/core/features/mainmenu/mainmenu-tab-routing.module.ts b/src/core/features/mainmenu/mainmenu-tab-routing.module.ts index 3a4c0ddb0..ca9c0538c 100644 --- a/src/core/features/mainmenu/mainmenu-tab-routing.module.ts +++ b/src/core/features/mainmenu/mainmenu-tab-routing.module.ts @@ -24,7 +24,7 @@ export function buildTabMainRoutes(injector: Injector, mainRoute: Route): Routes mainRoute.path = mainRoute.path || ''; mainRoute.children = mainRoute.children || []; - mainRoute.children.concat(routes.children); + mainRoute.children = mainRoute.children.concat(routes.children); return [ mainRoute, From ac9e87727a9bee2e4af2da593ea2fadfcc7cf11a Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 3 Jun 2021 09:16:40 +0200 Subject: [PATCH 04/10] MOBILE-3320 tabs: Try to fix tabs width after orientation change --- src/core/classes/tabs.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/classes/tabs.ts b/src/core/classes/tabs.ts index bafe71197..7182606c4 100644 --- a/src/core/classes/tabs.ts +++ b/src/core/classes/tabs.ts @@ -247,7 +247,7 @@ export class CoreTabsBaseComponent implements OnInit, Aft await this.calculateMaxSlides(); - this.updateSlides(); + await this.updateSlides(); } /** @@ -624,7 +624,7 @@ export class CoreTabsBaseComponent implements OnInit, Aft protected windowResized(): void { setTimeout(() => { this.calculateSlides(); - }); + }, 200); } /** From af4703a358148443adb2578968bec4a140e880db Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 3 Jun 2021 10:32:08 +0200 Subject: [PATCH 05/10] MOBILE-3320 notifications: Fix badge not updated after mark read --- src/addons/notifications/notifications.module.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/addons/notifications/notifications.module.ts b/src/addons/notifications/notifications.module.ts index c81f9813b..86595e7c3 100644 --- a/src/addons/notifications/notifications.module.ts +++ b/src/addons/notifications/notifications.module.ts @@ -64,6 +64,8 @@ const preferencesRoutes: Routes = [ CoreCronDelegate.register(AddonNotificationsCronHandler.instance); CorePushNotificationsDelegate.registerClickHandler(AddonNotificationsPushClickHandler.instance); CoreSettingsDelegate.registerHandler(AddonNotificationsSettingsHandler.instance); + + AddonNotificationsMainMenuHandler.initialize(); }, }, ], From e417c63e611c3e75557975bbd3f37999ee787f13 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 3 Jun 2021 12:21:32 +0200 Subject: [PATCH 06/10] MOBILE-3320 user: Fix address not opened --- src/core/directives/format-text.ts | 4 +++- src/core/directives/link.ts | 14 +++++++++++--- src/core/features/user/pages/about/about.html | 8 ++++---- src/core/features/user/pages/about/about.page.ts | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/core/directives/format-text.ts b/src/core/directives/format-text.ts index f67985298..16ee00021 100644 --- a/src/core/directives/format-text.ts +++ b/src/core/directives/format-text.ts @@ -23,6 +23,7 @@ import { Optional, ViewContainerRef, } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; import { IonContent } from '@ionic/angular'; import { CoreEventLoadingChangedData, CoreEventObserver, CoreEvents } from '@singletons/events'; @@ -90,6 +91,7 @@ export class CoreFormatTextDirective implements OnChanges { element: ElementRef, @Optional() protected content: IonContent, protected viewContainerRef: ViewContainerRef, + protected sanitizer: DomSanitizer, ) { this.element = element.nativeElement; @@ -504,7 +506,7 @@ export class CoreFormatTextDirective implements OnChanges { // Important: We need to look for links first because in 'img' we add new links without core-link. anchors.forEach((anchor) => { // Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually. - const linkDir = new CoreLinkDirective(new ElementRef(anchor), this.content); + const linkDir = new CoreLinkDirective(new ElementRef(anchor), this.content, this.sanitizer); linkDir.capture = this.captureLinks ?? true; linkDir.inApp = this.openLinksInApp; linkDir.ngOnInit(); diff --git a/src/core/directives/link.ts b/src/core/directives/link.ts index 49d296352..94aae1bf7 100644 --- a/src/core/directives/link.ts +++ b/src/core/directives/link.ts @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core'; +import { Directive, Input, OnInit, ElementRef, Optional, SecurityContext } from '@angular/core'; +import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { IonContent } from '@ionic/angular'; import { CoreFileHelper } from '@services/file-helper'; @@ -33,7 +34,7 @@ import { CoreCustomURLSchemes } from '@services/urlschemes'; }) export class CoreLinkDirective implements OnInit { - @Input() href?: string; // Link URL. + @Input() href?: string | SafeUrl; // Link URL. @Input() capture?: boolean | string; // If the link needs to be captured by the app. @Input() inApp?: boolean | string; // True to open in embedded browser, false to open in system browser. /* Whether the link should be opened with auto-login. Accepts the following values: @@ -47,6 +48,7 @@ export class CoreLinkDirective implements OnInit { constructor( element: ElementRef, @Optional() protected content: IonContent, + protected sanitizer: DomSanitizer, ) { this.element = element.nativeElement; } @@ -91,7 +93,13 @@ export class CoreLinkDirective implements OnInit { return; // Link already treated, stop. } - let href = this.href || this.element.getAttribute('href') || this.element.getAttribute('xlink:href'); + let href: string | null = null; + if (this.href) { + // Convert the URL back to string if needed. + href = typeof this.href === 'string' ? this.href : this.sanitizer.sanitize(SecurityContext.URL, this.href); + } + + href = href || this.element.getAttribute('href') || this.element.getAttribute('xlink:href'); if (!href || CoreUrlUtils.getUrlScheme(href) == 'javascript') { return; diff --git a/src/core/features/user/pages/about/about.html b/src/core/features/user/pages/about/about.html index 463fc451d..41072034b 100644 --- a/src/core/features/user/pages/about/about.html +++ b/src/core/features/user/pages/about/about.html @@ -38,21 +38,21 @@

- +

{{ 'core.user.address' | translate}}

- {{ user.address }} + {{ formattedAddress }}

- +

{{ 'core.user.city' | translate}}

{{ user.city }}

- +

{{ 'core.user.country' | translate}}

{{ user.country }}

diff --git a/src/core/features/user/pages/about/about.page.ts b/src/core/features/user/pages/about/about.page.ts index 1999862e4..2c3e5808f 100644 --- a/src/core/features/user/pages/about/about.page.ts +++ b/src/core/features/user/pages/about/about.page.ts @@ -75,7 +75,7 @@ export class CoreUserAboutPage implements OnInit { if (user.address) { this.formattedAddress = CoreUserHelper.formatAddress(user.address, user.city, user.country); - this.encodedAddress = CoreTextUtils.buildAddressURL(user.address); + this.encodedAddress = CoreTextUtils.buildAddressURL(this.formattedAddress); } this.hasContact = !!(user.email || user.phone1 || user.phone2 || user.city || user.country || user.address); From 7243f48fc51691d821da074cef2fb13cb4f144b0 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 3 Jun 2021 13:04:14 +0200 Subject: [PATCH 07/10] MOBILE-3320 tags: Open a certain tag in current tab --- src/core/features/tag/components/list/list.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/features/tag/components/list/list.ts b/src/core/features/tag/components/list/list.ts index 286d8916c..561db82bf 100644 --- a/src/core/features/tag/components/list/list.ts +++ b/src/core/features/tag/components/list/list.ts @@ -40,7 +40,7 @@ export class CoreTagListComponent { fromContextId: tag.taginstancecontextid, }; - CoreNavigator.navigateToSitePath('/tag/index', { params, preferCurrentTab: false }); + CoreNavigator.navigateToSitePath('/tag/index', { params }); } } From 34b2a1f56591339065ccda0f50f2e9e2498dd14e Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 3 Jun 2021 13:56:34 +0200 Subject: [PATCH 08/10] MOBILE-3320 messages: Fix error handling when sending request --- src/addons/messages/services/messages.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/addons/messages/services/messages.ts b/src/addons/messages/services/messages.ts index 5fd53a9c6..dd2ae0076 100644 --- a/src/addons/messages/services/messages.ts +++ b/src/addons/messages/services/messages.ts @@ -31,6 +31,7 @@ import { CoreWSExternalWarning } from '@services/ws'; import { makeSingleton } from '@singletons'; import { CoreError } from '@classes/errors/error'; import { AddonMessagesSyncEvents, AddonMessagesSyncProvider } from './messages-sync'; +import { CoreWSError } from '@classes/errors/wserror'; const ROOT_CACHE_KEY = 'mmaMessages:'; @@ -191,7 +192,14 @@ export class AddonMessagesProvider { requesteduserid: userId, }; - await site.write('core_message_create_contact_request', params); + const result = await site.write( + 'core_message_create_contact_request', + params, + ); + + if (result.warnings?.length) { + throw new CoreWSError(result.warnings[0]); + } } await this.invalidateAllMemberInfo(userId, site).finally(() => { @@ -3483,6 +3491,19 @@ type AddonMessagesConfirmContactRequestWSParams = { */ type AddonMessagesCreateContactRequestWSParams = AddonMessagesConfirmContactRequestWSParams; +/** + * Data returned by core_message_create_contact_request WS. + */ +export type AddonMessagesCreateContactRequestWSResponse = { + request?: { + id: number; // Message id. + userid: number; // User from id. + requesteduserid: number; // User to id. + timecreated: number; // Time created. + }; // Request record. + warnings?: CoreWSExternalWarning[]; +}; + /** * Params of core_message_decline_contact_request WS. */ From aebedbd1508575498d9da84e99c10bab7f6b3b32 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 3 Jun 2021 15:47:01 +0200 Subject: [PATCH 09/10] MOBILE-3320 core: Fix cancel reconnect when app is resumed --- src/app/app.component.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index bc4d2881f..7457bda23 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -132,16 +132,21 @@ export class AppComponent implements OnInit, AfterViewInit { // Check InAppBrowser closed. CoreEvents.on(CoreEvents.IAB_EXIT, () => { - CoreLoginHelper.setWaitingForBrowser(false); this.lastInAppUrl = ''; - CoreLoginHelper.checkLogout(); + + if (CoreLoginHelper.isWaitingForBrowser()) { + CoreLoginHelper.setWaitingForBrowser(false); + CoreLoginHelper.checkLogout(); + } }); Platform.resume.subscribe(() => { // Wait a second before setting it to false since in iOS there could be some frozen WS calls. setTimeout(() => { - CoreLoginHelper.setWaitingForBrowser(false); - CoreLoginHelper.checkLogout(); + if (CoreLoginHelper.isWaitingForBrowser()) { + CoreLoginHelper.setWaitingForBrowser(false); + CoreLoginHelper.checkLogout(); + } }, 1000); }); From 0ca8bbfe244e7c6c32f3ab077b166c981838fa2a Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 3 Jun 2021 16:18:45 +0200 Subject: [PATCH 10/10] MOBILE-3320 sharedfiles: Fix site picker not displayed when pick file --- .../features/sharedfiles/components/list-modal/list-modal.html | 3 ++- .../features/sharedfiles/components/list-modal/list-modal.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/features/sharedfiles/components/list-modal/list-modal.html b/src/core/features/sharedfiles/components/list-modal/list-modal.html index f022309dd..602b672ac 100644 --- a/src/core/features/sharedfiles/components/list-modal/list-modal.html +++ b/src/core/features/sharedfiles/components/list-modal/list-modal.html @@ -14,6 +14,7 @@ + [path]="path" [showSitePicker]="!hideSitePicker" (onPathChanged)="calculateTitle($event)" + (onFilePicked)="filePicked($event)"> diff --git a/src/core/features/sharedfiles/components/list-modal/list-modal.ts b/src/core/features/sharedfiles/components/list-modal/list-modal.ts index f3ba2f873..9a38a9c75 100644 --- a/src/core/features/sharedfiles/components/list-modal/list-modal.ts +++ b/src/core/features/sharedfiles/components/list-modal/list-modal.ts @@ -32,7 +32,7 @@ export class CoreSharedFilesListModalComponent implements OnInit { @Input() manage?: boolean; @Input() pick?: boolean; // To pick a file you MUST use a modal. @Input() path?: string; - @Input() showSitePicker?: boolean; + @Input() hideSitePicker?: boolean; title?: string;