forked from EVOgeek/Vmeda.Online
		
	MOBILE-3947 swipe: Fix Swipe slides update component
This commit is contained in:
		
							parent
							
								
									210b3a75a3
								
							
						
					
					
						commit
						522d1e2c79
					
				| @ -142,7 +142,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Component loaded. |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
|     ngOnInit(): void { |     ngOnInit(): void { | ||||||
|         this.canNavigate = typeof this.canNavigate == 'undefined' ? true : CoreUtils.isTrueOrOne(this.canNavigate); |         this.canNavigate = typeof this.canNavigate == 'undefined' ? true : CoreUtils.isTrueOrOne(this.canNavigate); | ||||||
| @ -164,7 +164,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Detect and act upon changes that Angular can’t or won’t detect on its own (objects and arrays). |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
|     ngDoCheck(): void { |     ngDoCheck(): void { | ||||||
|         const items = this.manager?.getSource().getItems(); |         const items = this.manager?.getSource().getItems(); | ||||||
| @ -368,7 +368,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Component destroyed. |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
|     ngOnDestroy(): void { |     ngOnDestroy(): void { | ||||||
|         this.undeleteEventObserver?.off(); |         this.undeleteEventObserver?.off(); | ||||||
|  | |||||||
| @ -15,7 +15,9 @@ | |||||||
| import { | import { | ||||||
|     Component, ContentChild, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChange, TemplateRef, ViewChild, |     Component, ContentChild, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChange, TemplateRef, ViewChild, | ||||||
| } from '@angular/core'; | } from '@angular/core'; | ||||||
|  | import { AsyncDirective } from '@classes/async-directive'; | ||||||
| import { CoreSwipeSlidesItemsManager } from '@classes/items-management/swipe-slides-items-manager'; | import { CoreSwipeSlidesItemsManager } from '@classes/items-management/swipe-slides-items-manager'; | ||||||
|  | import { CorePromisedValue } from '@classes/promised-value'; | ||||||
| import { IonContent } from '@ionic/angular'; | import { IonContent } from '@ionic/angular'; | ||||||
| import { CoreDomUtils, VerticalPoint } from '@services/utils/dom'; | import { CoreDomUtils, VerticalPoint } from '@services/utils/dom'; | ||||||
| import { CoreUtils } from '@services/utils/utils'; | import { CoreUtils } from '@services/utils/utils'; | ||||||
| @ -32,7 +34,7 @@ import { SwiperOptions } from 'swiper/types'; | |||||||
|     templateUrl: 'swipe-slides.html', |     templateUrl: 'swipe-slides.html', | ||||||
|     styleUrls: ['swipe-slides.scss'], |     styleUrls: ['swipe-slides.scss'], | ||||||
| }) | }) | ||||||
| export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDestroy { | export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDestroy, AsyncDirective { | ||||||
| 
 | 
 | ||||||
|     @Input() manager?: CoreSwipeSlidesItemsManager<Item>; |     @Input() manager?: CoreSwipeSlidesItemsManager<Item>; | ||||||
|     @Input() options: CoreSwipeSlidesOptions = {}; |     @Input() options: CoreSwipeSlidesOptions = {}; | ||||||
| @ -46,22 +48,21 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|          * This setTimeout waits for Ionic's async initialization to complete. |          * This setTimeout waits for Ionic's async initialization to complete. | ||||||
|          * Otherwise, an outdated swiper reference will be used. |          * Otherwise, an outdated swiper reference will be used. | ||||||
|          */ |          */ | ||||||
|         setTimeout(() => { |         setTimeout(async () => { | ||||||
|             if (swiperRef?.nativeElement?.swiper) { |             if (swiperRef?.nativeElement?.swiper) { | ||||||
|                 this.swiper = swiperRef.nativeElement.swiper as Swiper; |                 this.swiper = swiperRef.nativeElement.swiper as Swiper; | ||||||
| 
 | 
 | ||||||
|  |                 await this.initialize(); | ||||||
|  | 
 | ||||||
|                 if (this.options.initialSlide) { |                 if (this.options.initialSlide) { | ||||||
|                     this.swiper.slideTo(this.options.initialSlide, 0, this.options.runCallbacksOnInit); |                     this.swiper.slideTo(this.options.initialSlide, 0, this.options.runCallbacksOnInit); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 this.updateOptions(); | ||||||
|  | 
 | ||||||
|                 this.swiper.on('slideChangeTransitionStart', () => this.slideWillChange()); |                 this.swiper.on('slideChangeTransitionStart', () => this.slideWillChange()); | ||||||
|                 this.swiper.on('slideChangeTransitionEnd', () => this.slideDidChange()); |                 this.swiper.on('slideChangeTransitionEnd', () => this.slideDidChange()); | ||||||
| 
 | 
 | ||||||
|                 Object.keys(this.options).forEach((key) => { |  | ||||||
|                     if (this.swiper) { |  | ||||||
|                         this.swiper.params[key] = this.options[key]; |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
|             } |             } | ||||||
|         }, 0); |         }, 0); | ||||||
|     } |     } | ||||||
| @ -72,6 +73,7 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|     protected unsubscribe?: () => void; |     protected unsubscribe?: () => void; | ||||||
|     protected resizeListener: CoreEventObserver; |     protected resizeListener: CoreEventObserver; | ||||||
|     protected activeSlideIndexes: number[] = []; |     protected activeSlideIndexes: number[] = []; | ||||||
|  |     protected onReadyPromise = new CorePromisedValue<void>(); | ||||||
| 
 | 
 | ||||||
|     constructor( |     constructor( | ||||||
|         elementRef: ElementRef<HTMLElement>, |         elementRef: ElementRef<HTMLElement>, | ||||||
| @ -87,17 +89,11 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|     /** |     /** | ||||||
|      * @inheritdoc |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
|     ngOnChanges(changes: { [name: string]: SimpleChange }): void { |     async ngOnChanges(changes: { [name: string]: SimpleChange }): Promise<void> { | ||||||
|         if (!this.unsubscribe && this.manager) { |         await this.initialize(); | ||||||
|             this.initialize(this.manager); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (changes.options) { |         if (changes.options) { | ||||||
|             Object.keys(this.options).forEach((key) => { |             this.updateOptions(); | ||||||
|                 if (this.swiper) { |  | ||||||
|                     this.swiper.params[key] = this.options[key]; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -122,8 +118,12 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|     /** |     /** | ||||||
|      * Initialize some properties based on the manager. |      * Initialize some properties based on the manager. | ||||||
|      */ |      */ | ||||||
|     protected async initialize(manager: CoreSwipeSlidesItemsManager<Item>): Promise<void> { |     protected async initialize(): Promise<void> { | ||||||
|         this.unsubscribe = manager.getSource().addListener({ |         if (this.unsubscribe || !this.swiper || !this.manager) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.unsubscribe = this.manager.getSource().addListener({ | ||||||
|             onItemsUpdated: () => this.onItemsUpdated(), |             onItemsUpdated: () => this.onItemsUpdated(), | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
| @ -131,16 +131,16 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|         // This is because default callbacks aren't triggered for index 0, and to prevent auto scroll on init.
 |         // This is because default callbacks aren't triggered for index 0, and to prevent auto scroll on init.
 | ||||||
|         this.options.runCallbacksOnInit = false; |         this.options.runCallbacksOnInit = false; | ||||||
| 
 | 
 | ||||||
|         await manager.getSource().waitForLoaded(); |         await this.manager.getSource().waitForLoaded(); | ||||||
| 
 | 
 | ||||||
|         if (this.options.initialSlide === undefined) { |         if (this.options.initialSlide === undefined) { | ||||||
|             // Calculate the initial slide.
 |             // Calculate the initial slide.
 | ||||||
|             const index = manager.getSource().getInitialItemIndex(); |             const index = this.manager.getSource().getInitialItemIndex(); | ||||||
|             this.options.initialSlide = Math.max(index, 0); |             this.options.initialSlide = Math.max(index, 0); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Emit change events with the initial item.
 |         // Emit change events with the initial item.
 | ||||||
|         const items = manager.getSource().getItems(); |         const items = this.manager.getSource().getItems(); | ||||||
|         if (!items || !items.length) { |         if (!items || !items.length) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @ -155,9 +155,11 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
| 
 | 
 | ||||||
|         this.activeSlideIndexes = [initialIndex]; |         this.activeSlideIndexes = [initialIndex]; | ||||||
| 
 | 
 | ||||||
|         manager.setSelectedItem(items[initialIndex]); |         this.manager.setSelectedItem(items[initialIndex]); | ||||||
|         this.onWillChange.emit(initialItemData); |         this.onWillChange.emit(initialItemData); | ||||||
|         this.onDidChange.emit(initialItemData); |         this.onDidChange.emit(initialItemData); | ||||||
|  | 
 | ||||||
|  |         this.onReadyPromise.resolve(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -167,19 +169,20 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|      * @param speed Animation speed. |      * @param speed Animation speed. | ||||||
|      * @param runCallbacks Whether to run callbacks. |      * @param runCallbacks Whether to run callbacks. | ||||||
|      */ |      */ | ||||||
|     slideToIndex(index: number, speed?: number, runCallbacks?: boolean): void { |     async slideToIndex(index: number, speed?: number, runCallbacks?: boolean): Promise<void> { | ||||||
|         // If slides are being updated, wait for the update to finish.
 |         // If slides are being updated, wait for the update to finish.
 | ||||||
|         if (!this.swiper) { |         await this.ready(); | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         // Verify that the number of slides matches the number of items.
 |         // Verify that the number of slides matches the number of items.
 | ||||||
|         const slidesLength = this.swiper.slides.length; |         const slidesLength = this.swiper?.slides?.length || 0; | ||||||
|         if (slidesLength !== this.items.length) { |         if (slidesLength !== this.items.length) { | ||||||
|             // Number doesn't match, do a new update to try to match them.
 |             // Number doesn't match, do a new update to try to match them.
 | ||||||
|             this.updateSlidesComponent(); |             await this.updateSlidesComponent(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (!this.swiper?.slides) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         this.swiper?.slideTo(index, speed, runCallbacks); |         this.swiper?.slideTo(index, speed, runCallbacks); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -190,10 +193,10 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|      * @param speed Animation speed. |      * @param speed Animation speed. | ||||||
|      * @param runCallbacks Whether to run callbacks. |      * @param runCallbacks Whether to run callbacks. | ||||||
|      */ |      */ | ||||||
|     slideToItem(item: Item, speed?: number, runCallbacks?: boolean): void { |     async slideToItem(item: Item, speed?: number, runCallbacks?: boolean): Promise<void> { | ||||||
|         const index = this.manager?.getSource().getItemIndex(item) ?? -1; |         const index = this.manager?.getSource().getItemIndex(item) ?? -1; | ||||||
|         if (index != -1) { |         if (index != -1) { | ||||||
|             this.slideToIndex(index, speed, runCallbacks); |             await this.slideToIndex(index, speed, runCallbacks); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -225,7 +228,7 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|         await CoreUtils.nextTick(); |         await CoreUtils.nextTick(); | ||||||
| 
 | 
 | ||||||
|         // Update the slides component so the slides list reflects the new items.
 |         // Update the slides component so the slides list reflects the new items.
 | ||||||
|         this.updateSlidesComponent(); |         await this.updateSlidesComponent(); | ||||||
| 
 | 
 | ||||||
|         const currentItem = this.manager?.getSelectedItem(); |         const currentItem = this.manager?.getSelectedItem(); | ||||||
| 
 | 
 | ||||||
| @ -234,10 +237,26 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Keep the same slide in case the list has changed.
 |         // Keep the same slide in case the list has changed.
 | ||||||
|         const newIndex = this.manager.getSource().getItemIndex(currentItem) ?? -1; |         this.slideToItem(currentItem, 0, false); | ||||||
|         if (newIndex != -1) { |     } | ||||||
|             this.swiper?.slideTo(newIndex, 0, false); | 
 | ||||||
|  |     /** | ||||||
|  |      * Update Swiper params from options. | ||||||
|  |      */ | ||||||
|  |     protected updateOptions(): void { | ||||||
|  |         if (!this.swiper) { | ||||||
|  |             return; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (this.swiper.params === undefined) { | ||||||
|  |             this.swiper.params = {}; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Object.keys(this.options).forEach((key) => { | ||||||
|  |             if (this.swiper) { | ||||||
|  |                 this.swiper.params[key] = this.options[key]; | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -322,8 +341,24 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe | |||||||
|     /** |     /** | ||||||
|      * Update slides component. |      * Update slides component. | ||||||
|      */ |      */ | ||||||
|     updateSlidesComponent(): void { |     async updateSlidesComponent(): Promise<void> { | ||||||
|  |         await this.ready(); | ||||||
|  | 
 | ||||||
|  |         if (!this.swiper) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         this.swiper?.update(); |         this.swiper?.update(); | ||||||
|  | 
 | ||||||
|  |         // We need to ensure the slides are updated before continuing.
 | ||||||
|  |         await CoreUtils.nextTicks(2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @inheritdoc | ||||||
|  |      */ | ||||||
|  |     async ready(): Promise<void> { | ||||||
|  |         return this.onReadyPromise; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user