export interface Ad { img: string, text: string href: string seconds: number } export default class CarouselAd { private currentAdNumber: number | null = null private ad: Ad | null = null private timeoutNumber: number | null = null private getCarousel(): HTMLElement { const carousel = document.querySelector('.carousel'); if (carousel === null || !(carousel instanceof HTMLElement)) { this.noMoreAds() CarouselAd.fail('No carousel.') } return carousel } static fail(error: string): never { throw new Error(error) } public async run(): Promise { this.loadOneAd() try { let start = 0 let end = 0 this.getCarousel().addEventListener('pointerdown', (event: MouseEvent) => { start = event.pageX console.log(start) }) this.getCarousel().addEventListener('pointerup', (event: MouseEvent) => { end = event.pageX console.log(end) if (start - end > 100) { if (this.timeoutNumber !== null) { window.clearTimeout(this.timeoutNumber) } this.loadOneAd() } else { const a = this.retrieveLinkCarousel() window.location.href = a.href } }) } catch (e) { console.log(e) return } } private noMoreAds() { const carousel = this.getCarousel() if (carousel !== null) { carousel.remove(); } this.expandPageContents(); if (this.timeoutNumber === null) { return } window.clearTimeout(this.timeoutNumber) } private expandPageContents() { const pageContents = document.querySelector('div.page-contents'); if (pageContents === null) { return; } pageContents.classList.add('no-carousel'); } private retrieveLinkCarousel(): HTMLAnchorElement { const carousel = this.getCarousel() const maybeA = carousel.querySelector('a') if (maybeA !== null) { return maybeA } const a = document.createElement('a') a.addEventListener('click', (event: MouseEvent) => { event.preventDefault() }) a.addEventListener('pointerdown', (event: MouseEvent) => { event.preventDefault() }) a.addEventListener('pointerup', (event: MouseEvent) => { event.preventDefault() }) carousel.innerHTML = "" carousel.append(a) return a } private async loadOneAd() { try { const params = new URLSearchParams(); if (this.currentAdNumber !== null) { params.append('n', ""+this.currentAdNumber); } const response = await fetch('/next-ad.json?' + params) const responseJson = await response.json() this.currentAdNumber = responseJson.current_ad_number this.ad = responseJson.ad if (this.ad === null) { this.noMoreAds() return } const must_continue = responseJson.continue const carousel = this.getCarousel() if (must_continue === 0 || carousel.offsetWidth === 0) { this.noMoreAds(); return; } const a = this.retrieveLinkCarousel() a.innerHTML = "" const image = document.createElement('img') const text_container = document.createElement('div') const text = document.createElement('h4') const promoted = document.createElement('p') promoted.classList.add('promoted-tag') promoted.innerText = "Promocionado" image.src = this.ad.img image.alt = "" text.innerText = this.ad.text a.href = this.ad.href a.append(image) text_container.append(promoted) text_container.append(text) a.append(text_container) this.timeoutNumber = window.setTimeout(() => { this.loadOneAd() }, this.ad.seconds * 1000) } catch (e) { this.timeoutNumber = window.setTimeout(() => { this.loadOneAd() }, 1000) } } }