forked from CIT/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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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.
 | 
			
		||||
        // 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.scrollElement?.clientHeight || 0)) < 5;
 | 
			
		||||
        this.scrollBottom = CoreDom.scrollIsBottom(this.scrollElement, 5);
 | 
			
		||||
 | 
			
		||||
        if (this.messagesBeingSent > 0) {
 | 
			
		||||
            // 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.
 | 
			
		||||
     */
 | 
			
		||||
    scrollFunction(): void {
 | 
			
		||||
        if (this.newMessages > 0) {
 | 
			
		||||
            const scrollBottom = (this.scrollElement?.scrollTop || 0) + (this.scrollElement?.clientHeight || 0);
 | 
			
		||||
            const scrollHeight = (this.scrollElement?.scrollHeight || 0);
 | 
			
		||||
            if (scrollBottom > scrollHeight - 40) {
 | 
			
		||||
                // At the bottom, reset.
 | 
			
		||||
                this.setNewMessagesBadge(0);
 | 
			
		||||
        if (this.newMessages == 0) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                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();
 | 
			
		||||
            const scrollBottomPos = (scrollElRect && scrollElRect.bottom) || 0;
 | 
			
		||||
            return elementRect.bottom <= scrollBottomPos;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return elementRect.bottom <= scrollBottomPos;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (newMessagesUnread > 0 && newMessagesUnread < this.newMessages) {
 | 
			
		||||
                this.setNewMessagesBadge(newMessagesUnread);
 | 
			
		||||
            }
 | 
			
		||||
        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 { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreDom } from '@singletons/dom';
 | 
			
		||||
 | 
			
		||||
const MOODLE_VERSION_PREFIX = 'version-';
 | 
			
		||||
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.
 | 
			
		||||
        win.addEventListener('ionScroll', ({ detail, target }: CustomEvent<ScrollDetail>) => {
 | 
			
		||||
            const header = (target as HTMLElement).closest('.ion-page')?.querySelector('ion-header');
 | 
			
		||||
            header?.classList.toggle('core-header-shadow', detail.scrollTop > 0);
 | 
			
		||||
        win.addEventListener('ionScroll', async ({ detail, target }: CustomEvent<ScrollDetail>) => {
 | 
			
		||||
            if ((target as HTMLElement).tagName != 'ION-CONTENT') {
 | 
			
		||||
                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.
 | 
			
		||||
 | 
			
		||||
@ -126,6 +126,9 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
 | 
			
		||||
        const scroll = await this.content.getScrollElement();
 | 
			
		||||
        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 => {
 | 
			
		||||
            if (!this.content) {
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
@ -232,6 +232,21 @@ export class CoreDom {
 | 
			
		||||
        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.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -1434,8 +1434,11 @@ ion-grid.core-no-grid > ion-row {
 | 
			
		||||
    right: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[collapsible-footer] {
 | 
			
		||||
.core-footer-shadow [collapsible-footer] {
 | 
			
		||||
    box-shadow: var(--drop-shadow-top, none);
 | 
			
		||||
}
 | 
			
		||||
[collapsible-footer] {
 | 
			
		||||
    transition: box-shadow 0.5s;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    z-index: 3;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user