forked from EVOgeek/Vmeda.Online
		
	MOBILE-3833 style: Shadow on collapsible footer only if not at bottom
This commit is contained in:
		
							parent
							
								
									042619dd61
								
							
						
					
					
						commit
						602331d2c6
					
				| @ -445,13 +445,9 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Don't use domUtils.getScrollHeight because it gives an outdated value after receiving a new message.
 |  | ||||||
|         const scrollHeight = this.scrollElement ? this.scrollElement.scrollHeight : 0; |  | ||||||
| 
 |  | ||||||
|         // Check if we are at the bottom to scroll it after render.
 |         // Check if we are at the bottom to scroll it after render.
 | ||||||
|         // Use a 5px error margin because in iOS there is 1px difference for some reason.
 |         // Use a 5px error margin because in iOS there is 1px difference for some reason.
 | ||||||
|         this.scrollBottom = Math.abs(scrollHeight - (this.scrollElement?.scrollTop || 0) - |         this.scrollBottom = CoreDom.scrollIsBottom(this.scrollElement, 5); | ||||||
|             (this.scrollElement?.clientHeight || 0)) < 5; |  | ||||||
| 
 | 
 | ||||||
|         if (this.messagesBeingSent > 0) { |         if (this.messagesBeingSent > 0) { | ||||||
|             // Ignore polling due to a race condition.
 |             // Ignore polling due to a race condition.
 | ||||||
| @ -510,39 +506,39 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView | |||||||
|      * The scroll was moved. Update new messages count. |      * The scroll was moved. Update new messages count. | ||||||
|      */ |      */ | ||||||
|     scrollFunction(): void { |     scrollFunction(): void { | ||||||
|         if (this.newMessages > 0) { |         if (this.newMessages == 0) { | ||||||
|             const scrollBottom = (this.scrollElement?.scrollTop || 0) + (this.scrollElement?.clientHeight || 0); |             return; | ||||||
|             const scrollHeight = (this.scrollElement?.scrollHeight || 0); |         } | ||||||
|             if (scrollBottom > scrollHeight - 40) { |  | ||||||
|                 // At the bottom, reset.
 |  | ||||||
|                 this.setNewMessagesBadge(0); |  | ||||||
| 
 | 
 | ||||||
|                 return; |         if (CoreDom.scrollIsBottom(this.scrollElement, 40)) { | ||||||
|  |             // At the bottom, reset.
 | ||||||
|  |             this.setNewMessagesBadge(0); | ||||||
|  | 
 | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const scrollElRect = this.scrollElement?.getBoundingClientRect(); | ||||||
|  |         const scrollBottomPos = (scrollElRect && scrollElRect.bottom) || 0; | ||||||
|  | 
 | ||||||
|  |         if (scrollBottomPos == 0) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const messages = Array.from(this.hostElement.querySelectorAll('.addon-message-not-mine')) | ||||||
|  |             .slice(-this.newMessages) | ||||||
|  |             .reverse(); | ||||||
|  | 
 | ||||||
|  |         const newMessagesUnread = messages.findIndex((message) => { | ||||||
|  |             const elementRect = message.getBoundingClientRect(); | ||||||
|  |             if (!elementRect) { | ||||||
|  |                 return false; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             const scrollElRect = this.scrollElement?.getBoundingClientRect(); |             return elementRect.bottom <= scrollBottomPos; | ||||||
|             const scrollBottomPos = (scrollElRect && scrollElRect.bottom) || 0; |         }); | ||||||
| 
 | 
 | ||||||
|             if (scrollBottomPos == 0) { |         if (newMessagesUnread > 0 && newMessagesUnread < this.newMessages) { | ||||||
|                 return; |             this.setNewMessagesBadge(newMessagesUnread); | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             const messages = Array.from(this.hostElement.querySelectorAll('.addon-message-not-mine')) |  | ||||||
|                 .slice(-this.newMessages) |  | ||||||
|                 .reverse(); |  | ||||||
| 
 |  | ||||||
|             const newMessagesUnread = messages.findIndex((message) => { |  | ||||||
|                 const elementRect = message.getBoundingClientRect(); |  | ||||||
|                 if (!elementRect) { |  | ||||||
|                     return false; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 return elementRect.bottom <= scrollBottomPos; |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             if (newMessagesUnread > 0 && newMessagesUnread < this.newMessages) { |  | ||||||
|                 this.setNewMessagesBadge(newMessagesUnread); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -31,6 +31,7 @@ import { CoreUrlUtils } from '@services/utils/url'; | |||||||
| import { CoreConstants } from '@/core/constants'; | import { CoreConstants } from '@/core/constants'; | ||||||
| import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins'; | import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins'; | ||||||
| import { CoreDomUtils } from '@services/utils/dom'; | import { CoreDomUtils } from '@services/utils/dom'; | ||||||
|  | import { CoreDom } from '@singletons/dom'; | ||||||
| 
 | 
 | ||||||
| const MOODLE_VERSION_PREFIX = 'version-'; | const MOODLE_VERSION_PREFIX = 'version-'; | ||||||
| const MOODLEAPP_VERSION_PREFIX = 'moodleapp-'; | const MOODLEAPP_VERSION_PREFIX = 'moodleapp-'; | ||||||
| @ -90,9 +91,21 @@ export class AppComponent implements OnInit, AfterViewInit { | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         // Listen to scroll to add style when scroll is not 0.
 |         // Listen to scroll to add style when scroll is not 0.
 | ||||||
|         win.addEventListener('ionScroll', ({ detail, target }: CustomEvent<ScrollDetail>) => { |         win.addEventListener('ionScroll', async ({ detail, target }: CustomEvent<ScrollDetail>) => { | ||||||
|             const header = (target as HTMLElement).closest('.ion-page')?.querySelector('ion-header'); |             if ((target as HTMLElement).tagName != 'ION-CONTENT') { | ||||||
|             header?.classList.toggle('core-header-shadow', detail.scrollTop > 0); |                 return; | ||||||
|  |             } | ||||||
|  |             const content = (target as HTMLIonContentElement); | ||||||
|  | 
 | ||||||
|  |             const page = content.closest('.ion-page'); | ||||||
|  |             if (!page) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             page.querySelector<HTMLIonHeaderElement>('ion-header')?.classList.toggle('core-header-shadow', detail.scrollTop > 0); | ||||||
|  | 
 | ||||||
|  |             const scrollElement = await content.getScrollElement(); | ||||||
|  |             content.classList.toggle('core-footer-shadow', !CoreDom.scrollIsBottom(scrollElement)); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         // Listen for session expired events.
 |         // Listen for session expired events.
 | ||||||
|  | |||||||
| @ -126,6 +126,9 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy { | |||||||
|         const scroll = await this.content.getScrollElement(); |         const scroll = await this.content.getScrollElement(); | ||||||
|         this.content.scrollEvents = true; |         this.content.scrollEvents = true; | ||||||
| 
 | 
 | ||||||
|  |         // Init shadow.
 | ||||||
|  |         this.content.classList.toggle('core-footer-shadow', !CoreDom.scrollIsBottom(scroll)); | ||||||
|  | 
 | ||||||
|         this.content.addEventListener('ionScroll', this.contentScrollListener = (e: CustomEvent<ScrollDetail>): void => { |         this.content.addEventListener('ionScroll', this.contentScrollListener = (e: CustomEvent<ScrollDetail>): void => { | ||||||
|             if (!this.content) { |             if (!this.content) { | ||||||
|                 return; |                 return; | ||||||
|  | |||||||
| @ -232,6 +232,21 @@ export class CoreDom { | |||||||
|         return CoreDom.scrollToElement(container, '.core-input-error'); |         return CoreDom.scrollToElement(container, '.core-input-error'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Has the scroll reached bottom? | ||||||
|  |      * | ||||||
|  |      * @param scrollElement Scroll Element. | ||||||
|  |      * @param marginError Error margin when calculating. | ||||||
|  |      * @return Wether the scroll reached the bottom. | ||||||
|  |      */ | ||||||
|  |     static scrollIsBottom(scrollElement?: HTMLElement, marginError = 0): boolean { | ||||||
|  |         if (!scrollElement) { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return scrollElement.scrollTop + scrollElement.clientHeight >= scrollElement.scrollHeight - marginError; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Move element to content so it can be slotted. |      * Move element to content so it can be slotted. | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -1434,8 +1434,11 @@ ion-grid.core-no-grid > ion-row { | |||||||
|     right: 0; |     right: 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| [collapsible-footer] { | .core-footer-shadow [collapsible-footer] { | ||||||
|     box-shadow: var(--drop-shadow-top, none); |     box-shadow: var(--drop-shadow-top, none); | ||||||
|  | } | ||||||
|  | [collapsible-footer] { | ||||||
|  |     transition: box-shadow 0.5s; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     bottom: 0; |     bottom: 0; | ||||||
|     z-index: 3; |     z-index: 3; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user