@@ -2,6 +2,7 @@ import mobilecss from '../assets/mobile-video-drawer.css';
22import dax from '../assets/dax.svg' ;
33import info from '../assets/info-solid.svg' ;
44import { createPolicy , html , trustedUnsafe } from '../../../dom-utils.js' ;
5+ import { DDGVideoThumbnailOverlay } from './ddg-video-thumbnail-overlay-mobile' ;
56
67/**
78 * @typedef {ReturnType<import("../text").overlayCopyVariants> } TextVariants
@@ -19,6 +20,7 @@ export class DDGVideoDrawerMobile extends HTMLElement {
1920 static OPT_OUT = 'opt-out' ;
2021 static DISMISS = 'dismiss' ;
2122 static THUMBNAIL_CLICK = 'thumbnail-click' ;
23+ static DID_EXIT = 'did-exit' ;
2224
2325 policy = createPolicy ( ) ;
2426 /** @type {boolean } */
@@ -29,8 +31,11 @@ export class DDGVideoDrawerMobile extends HTMLElement {
2931 container ;
3032 /** @type {HTMLElement | null } */
3133 drawer ;
32- /** @type {import('./ddg-video-thumbnail-overlay-mobile').DDGVideoThumbnailOverlay } */
33- thumbnailOverlay ;
34+ /** @type {HTMLElement | null } */
35+ overlay ;
36+
37+ /** @type {'idle'|'animating' } */
38+ animationState = 'idle' ;
3439
3540 connectedCallback ( ) {
3641 this . createMarkupAndStyles ( ) ;
@@ -44,17 +49,10 @@ export class DDGVideoDrawerMobile extends HTMLElement {
4449 const content = this . mobileHtml ( ) ;
4550 overlayElement . innerHTML = this . policy . createHTML ( content ) ;
4651 shadow . append ( style , overlayElement ) ;
47- this . setupElements ( overlayElement ) ;
48- this . setupEventHandlers ( ) ;
52+ this . setupEventHandlers ( overlayElement ) ;
4953 this . animateOverlay ( 'in' ) ;
5054 }
5155
52- /** @param {HTMLElement } container */
53- setupElements ( container ) {
54- this . container = container ;
55- this . drawer = container . querySelector ( '.ddg-mobile-drawer' ) ;
56- }
57-
5856 /**
5957 * @returns {string }
6058 */
@@ -102,47 +100,72 @@ export class DDGVideoDrawerMobile extends HTMLElement {
102100 * @param {'in'|'out' } direction
103101 */
104102 animateOverlay ( direction ) {
105- const overlay = this . container ?. querySelector ( '.ddg-mobile-drawer- overlay' ) ;
106- if ( ! overlay ) return ;
103+ if ( ! this . overlay ) return ;
104+ this . animationState = 'animating' ;
107105
108106 switch ( direction ) {
109107 case 'in' :
110- overlay . classList . remove ( 'animateOut' ) ;
111- overlay . classList . add ( 'animateIn' ) ;
108+ this . overlay . classList . remove ( 'animateOut' ) ;
109+ this . overlay . classList . add ( 'animateIn' ) ;
112110 break ;
113111 case 'out' :
114- overlay . classList . remove ( 'animateIn' ) ;
115- overlay . classList . add ( 'animateOut' ) ;
112+ this . overlay . classList . remove ( 'animateIn' ) ;
113+ this . overlay . classList . add ( 'animateOut' ) ;
116114 break ;
117115 }
118116 }
119117
120- setupEventHandlers ( ) {
121- if ( ! this . container ) {
118+ /**
119+ * @param {() => void } callback
120+ */
121+ onAnimationEnd ( callback ) {
122+ if ( this . animationState !== 'animating' ) callback ( ) ;
123+
124+ this . overlay ?. addEventListener (
125+ 'animationend' ,
126+ ( ) => {
127+ callback ( ) ;
128+ } ,
129+ { once : true } ,
130+ ) ;
131+ }
132+
133+ /**
134+ * @param {HTMLElement } [container]
135+ * @returns
136+ */
137+ setupEventHandlers ( container ) {
138+ if ( ! container ) {
122139 console . warn ( 'Error setting up drawer component' ) ;
123140 return ;
124141 }
125142
126- const switchElem = this . container . querySelector ( '[role=switch]' ) ;
127- const infoButton = this . container . querySelector ( '.info-button' ) ;
128- const remember = this . container . querySelector ( 'input[name="ddg-remember"]' ) ;
129- const cancelElement = this . container . querySelector ( '.ddg-vpo-cancel' ) ;
130- const watchInPlayer = this . container . querySelector ( '.ddg-vpo-open' ) ;
131- const overlay = this . container . querySelector ( '.ddg-mobile-drawer-overlay' ) ;
132- const background = this . container . querySelector ( '.ddg-mobile-drawer-background' ) ;
143+ const switchElem = container . querySelector ( '[role=switch]' ) ;
144+ const infoButton = container . querySelector ( '.info-button' ) ;
145+ const remember = container . querySelector ( 'input[name="ddg-remember"]' ) ;
146+ const cancelElement = container . querySelector ( '.ddg-vpo-cancel' ) ;
147+ const watchInPlayer = container . querySelector ( '.ddg-vpo-open' ) ;
148+ const background = container . querySelector ( '.ddg-mobile-drawer-background' ) ;
149+ const overlay = container . querySelector ( '.ddg-mobile-drawer-overlay' ) ;
150+ const drawer = container . querySelector ( '.ddg-mobile-drawer' ) ;
133151
134152 if (
135153 ! cancelElement ||
136154 ! watchInPlayer ||
137155 ! switchElem ||
138156 ! infoButton ||
139- ! overlay ||
140157 ! background ||
158+ ! overlay ||
159+ ! drawer ||
141160 ! ( remember instanceof HTMLInputElement )
142161 ) {
143162 return console . warn ( 'missing elements' ) ;
144163 }
145164
165+ this . container = container ;
166+ this . overlay = /** @type {HTMLElement } */ ( overlay ) ;
167+ this . drawer = /** @type {HTMLElement } */ ( drawer ) ;
168+
146169 infoButton . addEventListener ( 'click' , ( ) => {
147170 this . dispatchEvent ( new Event ( DDGVideoDrawerMobile . OPEN_INFO ) ) ;
148171 } ) ;
@@ -173,10 +196,15 @@ export class DDGVideoDrawerMobile extends HTMLElement {
173196 this . animateOverlay ( 'out' ) ;
174197
175198 const mouseEvent = /** @type {MouseEvent } */ ( e ) ;
176- const isClickOnOverlay = this . thumbnailOverlay ?. isMouseEventWithinBounds ( mouseEvent ) ;
177- const event = isClickOnOverlay ? DDGVideoDrawerMobile . THUMBNAIL_CLICK : DDGVideoDrawerMobile . DISMISS ;
199+ let eventName = DDGVideoDrawerMobile . DISMISS ;
200+ for ( const element of document . elementsFromPoint ( mouseEvent . clientX , mouseEvent . clientY ) ) {
201+ if ( element . tagName === DDGVideoThumbnailOverlay . CUSTOM_TAG_NAME . toUpperCase ( ) ) {
202+ eventName = DDGVideoDrawerMobile . THUMBNAIL_CLICK ;
203+ break ;
204+ }
205+ }
178206
179- this . dispatchEvent ( new CustomEvent ( event ) ) ;
207+ this . dispatchEvent ( new CustomEvent ( eventName ) ) ;
180208 } ) ;
181209
182210 watchInPlayer . addEventListener ( 'click' , ( e ) => {
@@ -185,5 +213,9 @@ export class DDGVideoDrawerMobile extends HTMLElement {
185213 e . stopImmediatePropagation ( ) ;
186214 this . dispatchEvent ( new CustomEvent ( DDGVideoDrawerMobile . OPT_IN , { detail : { remember : remember . checked } } ) ) ;
187215 } ) ;
216+
217+ overlay . addEventListener ( 'animationend' , ( ) => {
218+ this . animationState = 'idle' ;
219+ } ) ;
188220 }
189221}
0 commit comments