1- import { GleapTranslationManager } from "./Gleap" ;
2- import { loadIcon } from "./UI" ;
1+ import { GleapConfigManager , GleapTranslationManager } from "./Gleap" ;
2+ import { calculateContrast , loadIcon } from "./UI" ;
33
44const localStorageKey = "gleap-tour-data" ;
55const pointerContainerId = "copilot-pointer-container" ;
@@ -352,9 +352,22 @@ export default class GleapCopilotTours {
352352 this . removeScrollListeners ( ) ;
353353 }
354354
355+ toggleAudio ( muted = false ) {
356+ this . audioMuted = muted ;
357+ if ( this . currentAudio ) {
358+ this . currentAudio . muted = this . audioMuted ;
359+ }
360+ document . querySelector ( `.${ copilotJoinedContainerId } -mute` ) . innerHTML =
361+ loadIcon ( this . audioMuted ? "unmute" : "mute" ) ;
362+ }
363+
355364 setupCopilotTour ( ) {
356365 if ( typeof window === "undefined" ) return ;
357366
367+ const primaryColor =
368+ GleapConfigManager . getInstance ( ) . flowConfig ?. color ?? "#485BFF" ;
369+ const contrastColor = calculateContrast ( primaryColor ) ;
370+
358371 let styleNode = document . getElementById ( styleId ) ;
359372 if ( ! styleNode ) {
360373 styleNode = document . createElement ( "style" ) ;
@@ -550,6 +563,70 @@ export default class GleapCopilotTours {
550563 opacity: 0;
551564 }
552565 }
566+
567+ .gleap-audio-unmute-modal-overlay {
568+ position: fixed;
569+ top: 0;
570+ left: 0;
571+ width: 100vw;
572+ height: 100vh;
573+ background-color: rgba(0, 0, 0, 0.5);
574+ display: flex;
575+ justify-content: center;
576+ align-items: center;
577+ z-index: 2147483620;
578+ }
579+
580+ .gleap-audio-unmute-modal {
581+ background-color: #fff;
582+ padding: 20px;
583+ border-radius: 8px;
584+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
585+ text-align: center;
586+ max-width: 90%;
587+ width: 400px;
588+ }
589+
590+ .gleap-audio-unmute-modal p {
591+ margin-bottom: 20px;
592+ font-size: 16px;
593+ line-height: 22px;
594+ font-weight: normal;
595+ }
596+
597+ .gleap-audio-unmute-button {
598+ background: ${ primaryColor } ;
599+ color: ${ contrastColor } ;
600+ outline: none;
601+ border: none;
602+ padding: 10px 14px;
603+ border-radius: 12px;
604+ font-size: 14px;
605+ font-weight: bold;
606+ cursor: pointer;
607+ }
608+
609+ .gleap-audio-unmute-button:hover {
610+ opacity: 0.8;
611+ }
612+
613+ .gleap-tour-continue-button {
614+ color: ${ primaryColor } ;
615+ text-decoration: none;
616+ cursor: pointer;
617+ font-size: 14px;
618+ font-weight: bold;
619+ border: none;
620+ background: none;
621+ padding: 0;
622+ margin: 0;
623+ margin-left: 20px;
624+ }
625+
626+ .gleap-tour-continue-button:hover {
627+ opacity: 0.8;
628+ }
629+
553630 body.gl-copilot-fade-out::before,
554631 body.gl-copilot-fade-out::after,
555632 body.gl-copilot-fade-out #${ copilotJoinedContainerId } {
@@ -659,12 +736,7 @@ export default class GleapCopilotTours {
659736 document
660737 . querySelector ( `.${ copilotJoinedContainerId } -mute` )
661738 . addEventListener ( "click" , ( ) => {
662- self . audioMuted = ! self . audioMuted ;
663- if ( self . currentAudio ) {
664- self . currentAudio . muted = self . audioMuted ;
665- }
666- document . querySelector ( `.${ copilotJoinedContainerId } -mute` ) . innerHTML =
667- loadIcon ( self . audioMuted ? "unmute" : "mute" ) ;
739+ this . toggleAudio ( ! this . audioMuted ) ;
668740 } ) ;
669741
670742 if ( this . productTourData ?. allowClose ) {
@@ -687,10 +759,65 @@ export default class GleapCopilotTours {
687759 canPlayAudio ( ) . then ( ( supported ) => {
688760 this . audioMuted = ! supported ;
689761 this . setupCopilotTour ( ) ;
762+
763+ console . log ( this . audioMuted , config ) ;
764+
765+ if ( this . audioMuted && config ?. showUnmuteModal ) {
766+ this . showAudioUnmuteModal ( ) ;
767+ } else {
768+ setTimeout ( ( ) => {
769+ this . renderNextStep ( ) ;
770+ } , 1500 ) ;
771+ }
772+ } ) ;
773+ }
774+
775+ showAudioUnmuteModal ( ) {
776+ // Create the overlay element
777+ const modalOverlay = document . createElement ( "div" ) ;
778+ modalOverlay . classList . add ( "gleap-audio-unmute-modal-overlay" ) ;
779+
780+ // Create the modal container element
781+ const modal = document . createElement ( "div" ) ;
782+ modal . classList . add ( "gleap-audio-unmute-modal" ) ;
783+
784+ // Create and add the modal message
785+ const message = document . createElement ( "p" ) ;
786+ message . textContent = this . productTourData ?. unmuteModalTitle ;
787+ modal . appendChild ( message ) ;
788+
789+ // Create the "Unmute Audio" button
790+ const unmuteButton = document . createElement ( "button" ) ;
791+ unmuteButton . classList . add ( "gleap-audio-unmute-button" ) ;
792+ unmuteButton . textContent = this . productTourData ?. unmuteModalButton ;
793+ unmuteButton . addEventListener ( "click" , ( ) => {
794+ this . toggleAudio ( false ) ;
795+ if ( modalOverlay . parentNode ) {
796+ modalOverlay . parentNode . removeChild ( modalOverlay ) ;
797+ }
798+ setTimeout ( ( ) => {
799+ this . renderNextStep ( ) ;
800+ } , 1000 ) ;
801+ } ) ;
802+ modal . appendChild ( unmuteButton ) ;
803+
804+ // Create the "Start Anyway" button
805+ const startAnywayButton = document . createElement ( "button" ) ;
806+ startAnywayButton . classList . add ( "gleap-tour-continue-button" ) ;
807+ startAnywayButton . textContent = this . productTourData ?. unmuteModalContinue ;
808+ startAnywayButton . addEventListener ( "click" , ( ) => {
809+ if ( modalOverlay . parentNode ) {
810+ modalOverlay . parentNode . removeChild ( modalOverlay ) ;
811+ }
690812 setTimeout ( ( ) => {
691813 this . renderNextStep ( ) ;
692- } , 1500 ) ;
814+ } , 1000 ) ;
693815 } ) ;
816+ modal . appendChild ( startAnywayButton ) ;
817+
818+ // Build the modal and attach it to the DOM
819+ modalOverlay . appendChild ( modal ) ;
820+ document . body . appendChild ( modalOverlay ) ;
694821 }
695822
696823 completeTour ( success = true ) {
0 commit comments