@@ -62,6 +62,10 @@ class YoutubePlatformBridge extends PlatformBridgeBase {
6262 return false
6363 }
6464
65+ get isClipboardSupported ( ) {
66+ return false
67+ }
68+
6569 // leaderboards
6670 get leaderboardsType ( ) {
6771 return LEADERBOARD_TYPE . NATIVE
@@ -71,6 +75,8 @@ class YoutubePlatformBridge extends PlatformBridgeBase {
7175
7276 #subscribeNotification = null
7377
78+ #videoPreview = null
79+
7480 initialize ( ) {
7581 if ( this . _isInitialized ) {
7682 return Promise . resolve ( )
@@ -81,6 +87,7 @@ class YoutubePlatformBridge extends PlatformBridgeBase {
8187
8288 if ( this . deviceType === DEVICE_TYPE . DESKTOP ) {
8389 this . #subscribeNotification = this . #createSubscribeNotification( )
90+ this . #videoPreview = this . #createVideoPreview( )
8491 }
8592
8693 waitFor ( 'ytgame' ) . then ( ( ) => {
@@ -280,6 +287,10 @@ class YoutubePlatformBridge extends PlatformBridgeBase {
280287 this . #subscribeNotification. remove ( )
281288 this . #subscribeNotification = null
282289 }
290+ if ( this . #videoPreview) {
291+ this . #videoPreview. remove ( )
292+ this . #videoPreview = null
293+ }
283294 return Promise . resolve ( )
284295 }
285296 default : {
@@ -506,6 +517,93 @@ class YoutubePlatformBridge extends PlatformBridgeBase {
506517 document . body . appendChild ( container )
507518 return container
508519 }
520+
521+ #createVideoPreview( ) {
522+ const previews = ( this . _options . videoPreviews ?? [ ] )
523+ . filter ( ( preview ) => Boolean ( preview ?. image && preview ?. videoId ) )
524+ if ( previews . length === 0 ) {
525+ return null
526+ }
527+
528+ const { image, videoId } = previews [ Math . floor ( Math . random ( ) * previews . length ) ]
529+
530+ if ( ! document . getElementById ( 'bridge-youtube-video-preview-styles' ) ) {
531+ const style = document . createElement ( 'style' )
532+ style . id = 'bridge-youtube-video-preview-styles'
533+ style . textContent = `
534+ #bridge-youtube-video-preview {
535+ position: fixed;
536+ bottom: -24px;
537+ right: 24px;
538+ width: min(256px, 40vw);
539+ border-radius: 16px;
540+ overflow: hidden;
541+ background-color: #000;
542+ box-shadow: 0 8px 24px 0 rgba(0, 0, 0, 0.4);
543+ cursor: pointer;
544+ opacity: 0;
545+ z-index: 9999999;
546+ animation: bridge-yt-preview-rise 285ms ease-out 590ms forwards;
547+ }
548+
549+ #bridge-youtube-video-preview .bridge-yt-preview-image {
550+ display: block;
551+ width: 100%;
552+ aspect-ratio: 16 / 9;
553+ object-fit: cover;
554+ user-select: none;
555+ -webkit-user-drag: none;
556+ }
557+
558+ #bridge-youtube-video-preview .bridge-yt-preview-play {
559+ position: absolute;
560+ top: 50%;
561+ left: 50%;
562+ width: 48px;
563+ height: 34px;
564+ transform: translate(-50%, -50%);
565+ pointer-events: none;
566+ }
567+
568+ @keyframes bridge-yt-preview-rise {
569+ 0% { bottom: -24px; opacity: 0; }
570+ 40% { bottom: 25.6px; opacity: 1; }
571+ 48% { bottom: 33.6px; }
572+ 60% { bottom: 32px; }
573+ 70% { bottom: 30.4px; }
574+ 79% { bottom: 28.8px; }
575+ 88% { bottom: 27.2px; }
576+ 95% { bottom: 25.6px; }
577+ 100% { bottom: 24px; opacity: 1; }
578+ }
579+ `
580+ document . head . appendChild ( style )
581+ }
582+
583+ const container = document . createElement ( 'div' )
584+ container . id = 'bridge-youtube-video-preview'
585+
586+ const img = document . createElement ( 'img' )
587+ img . className = 'bridge-yt-preview-image'
588+ img . src = image
589+ img . alt = ''
590+ img . draggable = false
591+ container . appendChild ( img )
592+
593+ container . insertAdjacentHTML ( 'beforeend' , `
594+ <svg class="bridge-yt-preview-play" viewBox="0 0 68 48" fill="none" xmlns="http://www.w3.org/2000/svg">
595+ <path d="M66.52 7.74C65.74 4.81 64.03 2.33 61.1 1.55C55.79 0.13 34 0 34 0C34 0 12.21 0.13 6.9 1.55C3.97 2.33 2.27 4.81 1.48 7.74C0.06 13.05 0 24 0 24C0 24 0.06 34.95 1.48 40.26C2.27 43.19 3.97 45.67 6.9 46.45C12.21 47.87 34 48 34 48C34 48 55.79 47.87 61.1 46.45C64.03 45.67 65.74 43.19 66.52 40.26C67.94 34.95 68 24 68 24C68 24 67.94 13.05 66.52 7.74Z" fill="#FF0033"/>
596+ <path d="M45 24L27 14V34L45 24Z" fill="white"/>
597+ </svg>
598+ ` )
599+
600+ container . addEventListener ( 'click' , ( ) => {
601+ window . ytgame ?. engagement . openYTContent ( { id : videoId } ) . catch ( ( ) => { } )
602+ } )
603+
604+ document . body . appendChild ( container )
605+ return container
606+ }
509607}
510608
511609export default YoutubePlatformBridge
0 commit comments