// browser tab visibility state detection import Events from '../_events' import Consts from '../_consts' import Page from './models/page.jsx' import { getParents } from '../main/funcs' import { Collapse } from 'bootstrap' import SpinnerUI from '../main/loading-spinner' const MainUILinks = ((W) => { const NAME = 'main.links' const D = document const BODY = D.body class MainUILinks { window static init () { const ui = this ui.GraphPage = null console.log(`${NAME}: init`) ui.loaded() // history state switch W.addEventListener('popstate', (e) => { ui.popState(e) }) } static loaded () { const ui = this D.querySelectorAll('.graphql-page').forEach((el, i) => { const el_id = el.getAttribute('href') el.setAttribute(`data-${ui.name}-id`, el_id) el.addEventListener('click', ui.loadClick) }) } static setActiveLinks (link) { const ui = this D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach((el) => { el.classList.add('active') }) } static reset () { // reset focus D.activeElement.blur() // remove active and loading classes D.querySelectorAll('.graphql-page,.nav-item').forEach((el2) => { el2.classList.remove('active', 'loading') }) } static popState (e) { const ui = this SpinnerUI.show() if (e.state && e.state.page) { console.log(`${NAME}: [popstate] load`) const state = JSON.parse(e.state.page) state.current = null state.popstate = true ui.reset() ui.setActiveLinks(e.state.link) if (!ui.GraphPage) { console.log( `${NAME}: [popstate] GraphPage is missing. Have to render it first` ) ui.GraphPage = ReactDOM.render( , document.getElementById('MainContent') ) } ui.GraphPage.setState(state) SpinnerUI.hide() window.dispatchEvent(new Event(Events.AJAX)) } else if (e.state && e.state.landing) { console.log(`${NAME}: [popstate] go to landing`) W.location.href = e.state.landing } else { console.warn(`${NAME}: [popstate] state is missing`) console.log(e) SpinnerUI.hide() } } // link specific event {this} = current event, not MainUILinks static loadClick (e) { console.groupCollapsed(`${NAME}: load on click`) e.preventDefault() const ui = MainUILinks const el = e.currentTarget SpinnerUI.show() ui.reset() el.classList.add('loading') el.classList.remove('response-404', 'response-500', 'response-523') BODY.classList.add('ajax-loading') // hide parent mobile nav const navs = getParents(el, '.collapse') if (navs.length) { navs.forEach((nav) => { const collapseInst = Collapse.getInstance(nav) if (collapseInst) { collapseInst.hide() } }) } // hide parent dropdown /* const dropdowns = getParents(el, '.dropdown-menu'); if (dropdowns.length) { const DropdownInst = Dropdown.getInstance(dropdowns[0]); DropdownInst.hide(); } */ if (!ui.GraphPage) { ui.GraphPage = ReactDOM.render( , document.getElementById('MainContent') ) } const link = el.getAttribute('href') || el.getAttribute('data-href') ui.GraphPage.state.current = el ui.GraphPage.load(link) .then((response) => { BODY.classList.remove('ajax-loading') el.classList.remove('loading') el.classList.add('active') D.loading_apollo_link = null if (ui.GraphPage.state.Link) { window.history.pushState( { page: JSON.stringify(ui.GraphPage.state), link: el.getAttribute(`data-${ui.name}-id`), }, ui.GraphPage.state.Title, ui.GraphPage.state.Link ) ui.setActiveLinks(ui.GraphPage.state.Link) } SpinnerUI.hide() window.dispatchEvent(new Event(Events.AJAX)) console.groupEnd(`${NAME}: load on click`) }) .catch((e) => { console.error(`${NAME}: loading error`) console.log(e) /* BODY.classList.remove('ajax-loading'); el.classList.remove('loading'); */ el.classList.add('error', `response-${e.status}`) /* switch (e.status) { case 500: break; case 404: el.classList.add('not-found'); break; case 523: el.classList.add('unreachable'); break; } */ // SpinnerUI.hide(); // window.dispatchEvent(new Event(Events.AJAX)); console.groupEnd(`${NAME}: load on click`) console.log(`${NAME}: reloading page ${link}`) // fallback loading W.location.href = link }) } } W.addEventListener(`${Events.LOADED}`, () => { MainUILinks.init() }) W.addEventListener(`${Events.AJAX}`, () => { MainUILinks.loaded() }) // fallback /* W.addEventListener(`${Events.APOLLO_ERROR}`, (e) => { console.error(`${NAME}: [APOLLO_ERROR] loading failure, reloading the page`); //W.dispatchEvent(new Event(Events.OFFLINE)); if (D.loading_apollo_link) { W.location.href = D.loading_apollo_link; } }); */ })(window) export default MainUILinks