import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Inject, Input, OnDestroy, OnInit, PLATFORM_ID, ViewChild } from "@angular/core"; import {LayoutService, SidebarItem} from "../sidebar/layout.service"; declare var UIkit; declare var ResizeObserver; @Component({ selector: '[page-content]', template: `
`, }) export class PageContentComponent implements OnInit, AfterViewInit, OnDestroy { @Input() public headerSticky: boolean = false; @Input() public border: boolean = true; public offset: number; public shouldSticky: boolean = true; public isMobile: boolean = false; public isStickyActive: boolean = false; public footer_height: number = 0; @ViewChild('header') header: ElementRef; @ViewChild('actions') actions: ElementRef; @ViewChild("sticky_footer") sticky_footer: ElementRef; private sticky = { header: null, footer: null } subscriptions = []; constructor(private layoutService: LayoutService, private cdr: ChangeDetectorRef, @Inject(PLATFORM_ID) private platformId) { } ngOnInit() { this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => { this.isMobile = isMobile; if (typeof document !== "undefined") { this.offset = this.isMobile?0:Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height')); this.stickyBugWorkaround(); } this.cdr.detectChanges(); })); } get isBrowser() { return this.platformId === 'browser'; } ngAfterViewInit() { if (typeof document !== "undefined") { this.observeStickyFooter(); if (this.shouldSticky && typeof document !== 'undefined') { this.sticky.header = UIkit.sticky((this.headerSticky ? this.header.nativeElement : this.actions.nativeElement), { offset: this.offset }); this.subscriptions.push(UIkit.util.on(document, 'active', '#' + this.sticky.header.$el.id, () => { this.isStickyActive = true; this.cdr.detectChanges(); })); this.subscriptions.push(UIkit.util.on(document, 'inactive', '#' + this.sticky.header.$el.id, () => { this.isStickyActive = false; this.cdr.detectChanges(); })); } if (this.sticky_footer) { let footer_offset = this.calcStickyFooterOffset(this.sticky_footer.nativeElement); this.sticky.footer = UIkit.sticky(this.sticky_footer.nativeElement, {bottom: true, offset: footer_offset}); } } } ngOnDestroy() { this.subscriptions.forEach(subscription => { if (subscription instanceof (ResizeObserver || IntersectionObserver)) { subscription.disconnect(); } }); } /** * Workaround for sticky not update bug when sidebar is toggled. * TODO when UIKit will be updated => remove * * */ stickyBugWorkaround() { let sidebarOffset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--dashboard-sidebar-width')) - Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--dashboard-sidebar-mini-width')); let transitionDelay = Number.parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--dashboard-transition-delay')) * 1000; this.subscriptions.push(this.layoutService.isOpen.subscribe(isOpen => { if (this.sticky.header) { if (isOpen) { this.sticky.header.$el.style.width = Number.parseInt(this.sticky.header.$el.style.width) - sidebarOffset + 'px'; } else { this.sticky.header.$el.style.width = Number.parseInt(this.sticky.header.$el.style.width) + sidebarOffset + 'px'; } setTimeout(() => { this.sticky.header.$emit(); }, transitionDelay); } if (this.sticky.footer) { if (isOpen) { this.sticky.footer.$el.style.width = Number.parseInt(this.sticky.footer.$el.style.width) - sidebarOffset + 'px'; } else { this.sticky.footer.$el.style.width = Number.parseInt(this.sticky.footer.$el.style.width) + sidebarOffset + 'px'; } setTimeout(() => { this.sticky.footer.$emit(); }, transitionDelay); } this.cdr.detectChanges(); })); } /** * @deprecated * * Should be smooth * * */ private observeBottom() { let bottom = document.getElementById('bottom'); if (bottom) { let bottomObs = new IntersectionObserver(entries => { entries.forEach(entry => { this.shouldSticky = !entry.isIntersecting; }) }); this.subscriptions.push(bottomObs); bottomObs.observe(bottom); } } /** * @deprecated * */ private observeHeader() { if (this.header) { let headerObs = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.boundingClientRect.height > 0) { this.layoutService.setReplaceHeader(!entry.isIntersecting); } }) }); this.subscriptions.push(headerObs); headerObs.observe(this.header.nativeElement); } } private observeStickyFooter() { if (this.sticky_footer) { let resizeObs = new ResizeObserver(entries => { entries.forEach(entry => { setTimeout(() => { this.sticky.footer.offset = this.calcStickyFooterOffset(entry.target); this.cdr.detectChanges(); }); }) }); this.subscriptions.push(resizeObs); resizeObs.observe(this.sticky_footer.nativeElement); } } calcStickyFooterOffset(element) { this.footer_height = element.offsetHeight; return window.innerHeight - this.footer_height; } }