From 7c33680159964d4ed6125f8b8622f844d1915768 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 21 Dec 2021 16:22:31 +0100 Subject: [PATCH 1/3] MOBILE-3833 glossary: Fix item parameters mutation --- src/addons/mod/glossary/classes/glossary-entries-source.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/addons/mod/glossary/classes/glossary-entries-source.ts b/src/addons/mod/glossary/classes/glossary-entries-source.ts index d1dd67b5c..1bf6fdef7 100644 --- a/src/addons/mod/glossary/classes/glossary-entries-source.ts +++ b/src/addons/mod/glossary/classes/glossary-entries-source.ts @@ -131,6 +131,7 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource< */ startSearch(): void { this.isSearch = true; + this.setDirty(true); } /** @@ -148,6 +149,7 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource< this.hasSearched = false; this.onlineEntries = cachedOnlineEntries; this.hasMoreItems = hasMoreOnlineEntries; + this.setDirty(true); } /** @@ -177,6 +179,7 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource< 'ASC', ); this.hasSearched = true; + this.setDirty(true); } /** @@ -209,6 +212,7 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource< this.fetchMode = mode; this.isSearch = false; + this.setDirty(true); switch (mode) { case 'author_all': From 008453d5ab3d13bd2701b3a16756b025991b0647 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 21 Dec 2021 16:23:09 +0100 Subject: [PATCH 2/3] MOBILE-3833 core: Fix swipe race conditions --- .../forum-discussions-swipe-manager.ts | 25 ++---------------- .../classes/glossary-entries-swipe-manager.ts | 25 ++---------------- .../swipe-navigation-items-manager.ts | 26 ++++++++++++++++--- 3 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/addons/mod/forum/classes/forum-discussions-swipe-manager.ts b/src/addons/mod/forum/classes/forum-discussions-swipe-manager.ts index 2b1ca1e99..0586a718f 100644 --- a/src/addons/mod/forum/classes/forum-discussions-swipe-manager.ts +++ b/src/addons/mod/forum/classes/forum-discussions-swipe-manager.ts @@ -24,29 +24,8 @@ export class AddonModForumDiscussionsSwipeManager /** * @inheritdoc */ - async navigateToNextItem(): Promise { - let delta = -1; - const item = await this.getItemBy(-1); - - if (item && this.getSource().isNewDiscussionForm(item)) { - delta--; - } - - await this.navigateToItemBy(delta, 'back'); - } - - /** - * @inheritdoc - */ - async navigateToPreviousItem(): Promise { - let delta = 1; - const item = await this.getItemBy(1); - - if (item && this.getSource().isNewDiscussionForm(item)) { - delta++; - } - - await this.navigateToItemBy(delta, 'forward'); + protected skipItemInSwipe(item: AddonModForumDiscussionItem): boolean { + return this.getSource().isNewDiscussionForm(item); } } diff --git a/src/addons/mod/glossary/classes/glossary-entries-swipe-manager.ts b/src/addons/mod/glossary/classes/glossary-entries-swipe-manager.ts index c6fc2bb57..b1136068b 100644 --- a/src/addons/mod/glossary/classes/glossary-entries-swipe-manager.ts +++ b/src/addons/mod/glossary/classes/glossary-entries-swipe-manager.ts @@ -24,29 +24,8 @@ export abstract class AddonModGlossaryEntriesSwipeManager /** * @inheritdoc */ - async navigateToNextItem(): Promise { - let delta = -1; - const item = await this.getItemBy(-1); - - if (item && this.getSource().isNewEntryForm(item)) { - delta--; - } - - await this.navigateToItemBy(delta, 'back'); - } - - /** - * @inheritdoc - */ - async navigateToPreviousItem(): Promise { - let delta = 1; - const item = await this.getItemBy(1); - - if (item && this.getSource().isNewEntryForm(item)) { - delta++; - } - - await this.navigateToItemBy(delta, 'forward'); + protected skipItemInSwipe(item: AddonModGlossaryEntryItem): boolean { + return this.getSource().isNewEntryForm(item); } } diff --git a/src/core/classes/items-management/swipe-navigation-items-manager.ts b/src/core/classes/items-management/swipe-navigation-items-manager.ts index a156cedc9..57b1dd2c7 100644 --- a/src/core/classes/items-management/swipe-navigation-items-manager.ts +++ b/src/core/classes/items-management/swipe-navigation-items-manager.ts @@ -82,7 +82,13 @@ export class CoreSwipeNavigationItemsManager< * @param animationDirection Animation direction. */ protected async navigateToItemBy(delta: number, animationDirection: 'forward' | 'back'): Promise { - const item = await this.getItemBy(delta); + let item: Item | null; + + do { + item = await this.getItemBy(delta); + + delta += delta > 0 ? 1 : -1; + } while (item && this.skipItemInSwipe(item)); if (!item) { return; @@ -100,14 +106,15 @@ export class CoreSwipeNavigationItemsManager< const items = this.getSource().getItems(); // Get selected item. - const index = (this.selectedItem && items?.indexOf(this.selectedItem)) ?? -1; + const selectedIndex = (this.selectedItem && items?.indexOf(this.selectedItem)) ?? -1; + const nextIndex = selectedIndex + delta; - if (index === -1) { + if (selectedIndex === -1 || nextIndex < 0) { return null; } // Get item by delta. - const item = items?.[index + delta] ?? null; + const item = items?.[nextIndex] ?? null; if (!item && !this.getSource().isCompleted()) { await this.getSource().load(); @@ -118,4 +125,15 @@ export class CoreSwipeNavigationItemsManager< return item; } + /** + * Check if an item should be skipped during swipe navigation. + * + * @param item Item. + * @returns Whether to skip this item during swipe navigation. + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + protected skipItemInSwipe(item: Item): boolean { + return false; + } + } From 03f573b63f3a76642983459ee32947bd363a0ed7 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 21 Dec 2021 16:23:57 +0100 Subject: [PATCH 3/3] MOBILE-3833 core: Fix resolving prefetch handlers --- .../course/components/module/module.ts | 2 +- .../features/course/services/course-helper.ts | 4 +-- .../services/module-prefetch-delegate.ts | 36 +++++++++---------- .../components/module-index/module-index.ts | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/core/features/course/components/module/module.ts b/src/core/features/course/components/module/module.ts index 944eed73a..82df87061 100644 --- a/src/core/features/course/components/module/module.ts +++ b/src/core/features/course/components/module/module.ts @@ -106,7 +106,7 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy { if (this.module.handlerData.showDownloadButton) { // Listen for changes on this module status, even if download isn't enabled. - this.prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module.name); + this.prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module.modname); this.statusObserver = CoreEvents.on(CoreEvents.PACKAGE_STATUS_CHANGED, (data) => { if (!this.module || data.componentId != this.module.id || !this.prefetchHandler || diff --git a/src/core/features/course/services/course-helper.ts b/src/core/features/course/services/course-helper.ts index 4162eb2b4..071faa626 100644 --- a/src/core/features/course/services/course-helper.ts +++ b/src/core/features/course/services/course-helper.ts @@ -1013,7 +1013,7 @@ export class CoreCourseHelperProvider { ): Promise { siteId = siteId || CoreSites.getCurrentSiteId(); - const prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module.name); + const prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module.modname); if (prefetchHandler) { // Use the prefetch handler to download the module. @@ -2048,7 +2048,7 @@ export class CoreCourseHelperProvider { promises.push(CoreCourseModulePrefetchDelegate.removeModuleFiles(module, courseId)); - const handler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module.name); + const handler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module.modname); const site = CoreSites.getCurrentSite(); if (handler && site) { promises.push(site.deleteComponentFromCache(handler.component, module.id)); diff --git a/src/core/features/course/services/module-prefetch-delegate.ts b/src/core/features/course/services/module-prefetch-delegate.ts index a2998f6d7..31984758f 100644 --- a/src/core/features/course/services/module-prefetch-delegate.ts +++ b/src/core/features/course/services/module-prefetch-delegate.ts @@ -95,7 +95,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { // Module not supported, cannot use check updates. @@ -171,7 +171,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { // Check if the module has a prefetch handler. - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { return; @@ -381,7 +381,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { return { size: 0, total: false }; @@ -419,7 +419,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { return 0; } @@ -492,7 +492,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (handler?.getFiles) { // The handler defines a function to get files, use it. @@ -548,7 +548,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { // No handler found, module not downloadable. @@ -712,7 +712,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler || (onlyToDisplay && handler.skipListStatus)) { return; } @@ -758,7 +758,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); const siteId = CoreSites.getCurrentSiteId(); if (!handler) { @@ -895,7 +895,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { const promises = modules.map(async (module) => { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { return; } @@ -919,7 +919,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); const moduleUpdates = updates[module.id]; if (handler?.hasUpdates) { @@ -1033,7 +1033,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { return; } @@ -1067,7 +1067,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate(module: CoreCourseAnyModuleData, courseId: number): Promise { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler?.sync) { return; } @@ -1124,7 +1124,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { // Check if the module has a prefetch handler. - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); if (!handler) { return; } @@ -1170,7 +1170,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { - const handler = this.getPrefetchHandlerFor(module.name); + const handler = this.getPrefetchHandlerFor(module.modname); const siteId = CoreSites.getCurrentSiteId(); if (handler?.removeFiles) { diff --git a/src/core/features/siteplugins/components/module-index/module-index.ts b/src/core/features/siteplugins/components/module-index/module-index.ts index a4cab3943..7b8d9311e 100644 --- a/src/core/features/siteplugins/components/module-index/module-index.ts +++ b/src/core/features/siteplugins/components/module-index/module-index.ts @@ -145,7 +145,7 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C this.refreshIcon = CoreConstants.ICON_REFRESH; // Check if there is a prefetch handler for this type of module. - if (CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module.name)) { + if (CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module.modname)) { CoreCourseHelper.fillContextMenu(this, this.module, this.courseId, refresh, this.component); } }