1
1
/* global gtag, URI, getSearchResults, getAutocompleteSuggestions, parseYoutubeVideoID, getYouTubeVideoDescription */
2
2
3
3
var keyCodes = {
4
- SPACEBAR : 32
4
+ SPACEBAR : 32 ,
5
+ ENTER : 13
5
6
} ;
6
7
7
8
var timeIntervals = {
@@ -15,6 +16,12 @@ var plyrPlayer;
15
16
var youTubeDataApiKey = "AIzaSyCxVxsC5k46b8I-CLXlF3cZHjpiqP_myVk" ;
16
17
var currentVideoID ;
17
18
19
+ // global playlist, this is populated with an ajax call
20
+ var tags = [ ] ;
21
+ var playList = new Set ( ) ;
22
+ var autoplayState = false ;
23
+ const MAX_TAGS = 10 ;
24
+
18
25
var errorMessage = {
19
26
init : function ( ) {
20
27
// nothing for now
@@ -137,6 +144,7 @@ var ZenPlayer = {
137
144
that . setupTitle ( ) ;
138
145
that . setupVideoDescription ( videoID ) ;
139
146
that . setupPlyrToggle ( ) ;
147
+ that . setupAutoplayToggle ( ) ;
140
148
} ) ;
141
149
142
150
plyrPlayer . addEventListener ( "playing" , function ( ) {
@@ -165,6 +173,17 @@ var ZenPlayer = {
165
173
updateTweetMessage ( ) ;
166
174
} ) ;
167
175
176
+ // when player has finished playing
177
+ plyrPlayer . addEventListener ( "ended" , function ( ) {
178
+ if ( autoplayState ) {
179
+ if ( playList . length === 0 || playList . size === 0 ) {
180
+ fetchSuggestedVideoIds ( ) ;
181
+ }
182
+ var newId = getNewVideoID ( ) ;
183
+ that . playNext ( newId ) ;
184
+ }
185
+ } ) ;
186
+
168
187
plyrPlayer . addEventListener ( "timeupdate" , function ( ) {
169
188
// Nothing is playing
170
189
if ( ! plyrPlayer . plyr || ! plyrPlayer . plyr . embed ) {
@@ -223,6 +242,11 @@ var ZenPlayer = {
223
242
} ) ;
224
243
}
225
244
} ,
245
+ // play next song from autoplay
246
+ playNext : function ( videoID ) {
247
+ $ ( "#v" ) . val ( videoID ) ;
248
+ $ ( "#form" ) . submit ( ) ;
249
+ } ,
226
250
show : function ( ) {
227
251
$ ( "#audioplayer" ) . show ( ) ;
228
252
// Hide the demo link as some video is playing
@@ -258,6 +282,24 @@ var ZenPlayer = {
258
282
toggleElement ( event , ".plyr__video-wrapper" , "Player" ) ;
259
283
} ) ;
260
284
} ,
285
+ setupAutoplayToggle : function ( ) {
286
+ // toggle auto next song playing
287
+ $ ( "#toggleAutoplay" ) . click ( function ( event ) {
288
+ var toggleTextElement = $ ( "#" + event . currentTarget . id ) ;
289
+ if ( autoplayState ) {
290
+ toggleTextElement . text ( "Start autoplay" ) ;
291
+ autoplayState = false ;
292
+ window . sessionStorage . removeItem ( "autoPlay" ) ;
293
+ window . sessionStorage . removeItem ( "playList" ) ;
294
+ }
295
+ else {
296
+ toggleTextElement . text ( "Stop autoplay" ) ;
297
+ autoplayState = true ;
298
+ window . sessionStorage . setItem ( "autoPlay" , true ) ;
299
+ }
300
+ } ) ;
301
+ } ,
302
+
261
303
getVideoDescription : function ( videoID ) {
262
304
var description = "" ;
263
305
@@ -275,6 +317,7 @@ var ZenPlayer = {
275
317
}
276
318
else {
277
319
description = data . items [ 0 ] . snippet . description ;
320
+ tags = data . items [ 0 ] . snippet . tags ;
278
321
}
279
322
} ,
280
323
function ( jqXHR , textStatus , errorThrown ) {
@@ -524,6 +567,81 @@ function pickDemo() {
524
567
return demos [ Math . floor ( Math . random ( ) * demos . length ) ] ;
525
568
}
526
569
570
+ function updateAutoplayToggle ( state ) {
571
+ if ( state ) {
572
+ $ ( "#toggleAutoplay" ) . text ( "Stop autoplay" ) ;
573
+ }
574
+ else {
575
+ $ ( "#toggleAutoplay" ) . text ( "Start autoplay" ) ;
576
+ }
577
+ }
578
+
579
+ function getNewVideoID ( ) {
580
+ var nextID = null ;
581
+ nextID = playList . pop ( ) ;
582
+ while ( currentVideoID === nextID ) {
583
+ nextID = playList . pop ( ) ;
584
+ }
585
+ window . sessionStorage . setItem ( "playList" , JSON . stringify ( playList ) ) ;
586
+ return nextID ;
587
+ }
588
+
589
+ function fetchSuggestedVideoIds ( ) {
590
+ if ( playList . length === 0 || playList . size === 0 ) {
591
+ if ( tags . length ) {
592
+ // get similar videos, populate playList
593
+ if ( ! isFileProtocol ( ) ) {
594
+ for ( let index = 0 ; index < tags . length && index < MAX_TAGS ; index ++ ) {
595
+ $ . ajax ( {
596
+ url : "https://www.googleapis.com/youtube/v3/search" ,
597
+ dataType : "json" ,
598
+ async : false ,
599
+ data : {
600
+ key : youTubeDataApiKey ,
601
+ part : "snippet" ,
602
+ type : "video" ,
603
+ order : "relevance" ,
604
+ q : tags [ index ] ,
605
+ maxResults : 2
606
+ } ,
607
+ success : onRelatedVideoFetchSuccess
608
+ } ) . fail ( function ( jqXHR , textStatus , errorThrown ) {
609
+ logError ( jqXHR , textStatus , errorThrown , "Related video lookup error" ) ;
610
+ } ) ;
611
+ }
612
+ playList = Array . from ( playList ) ;
613
+ window . sessionStorage . setItem ( "playList" , JSON . stringify ( playList ) ) ;
614
+ }
615
+ }
616
+ }
617
+ }
618
+
619
+ function onRelatedVideoFetchSuccess ( data ) {
620
+ // push items into playlist
621
+ for ( var i = 0 ; i < data . items . length ; i ++ ) {
622
+ playList . add ( data . items [ i ] . id . videoId ) ;
623
+ }
624
+ }
625
+
626
+ function loadAutoPlayDetails ( ) {
627
+ // load playList from session storage on reload
628
+ if ( window . sessionStorage . getItem ( "playList" ) ) {
629
+ playList = JSON . parse ( window . sessionStorage . getItem ( "playList" ) ) ;
630
+ }
631
+
632
+ // fetch autoPlay from session storage on reload
633
+ if ( window . sessionStorage . getItem ( "autoPlay" ) ) {
634
+ autoplayState = window . sessionStorage . getItem ( "autoPlay" ) ;
635
+ updateAutoplayToggle ( autoplayState ) ;
636
+ }
637
+ }
638
+
639
+ function resetAutoPlayList ( ) {
640
+ playList = new Set ( ) ;
641
+ tags = [ ] ;
642
+ window . sessionStorage . removeItem ( "playList" ) ;
643
+ }
644
+
527
645
$ ( function ( ) {
528
646
if ( / A n d r o i d | w e b O S | i P h o n e | i P a d | i P o d | B l a c k B e r r y | I E M o b i l e | O p e r a M i n i / i. test ( navigator . userAgent ) ) {
529
647
$ ( "#container" ) . hide ( ) ;
@@ -534,6 +652,8 @@ $(function() {
534
652
535
653
errorMessage . init ( ) ;
536
654
655
+ loadAutoPlayDetails ( ) ;
656
+
537
657
// How do we know if the value is truly invalid?
538
658
// Preload the form from the URL
539
659
var currentVideoID = getCurrentVideoID ( ) ;
@@ -608,20 +728,22 @@ $(function() {
608
728
data : {
609
729
key : youTubeDataApiKey ,
610
730
part : "snippet" ,
611
- fields : "items/snippet/description" ,
612
731
id : videoID
613
732
} ,
614
733
success : function ( data ) {
615
734
if ( data . items . length === 0 ) {
616
735
window . location . href = makeSearchURL ( formValue ) ;
617
736
}
618
737
else {
738
+ tags = data . items [ 0 ] . snippet . tags ;
619
739
window . location . href = makeListenURL ( videoID , formValueTime ) ;
620
740
}
621
741
}
622
742
} ) . fail ( function ( jqXHR , textStatus , errorThrown ) {
623
743
logError ( jqXHR , textStatus , errorThrown , "Lookup error" ) ;
624
744
} ) ;
745
+ // fetching next videoIds for auto play
746
+ fetchSuggestedVideoIds ( ) ;
625
747
}
626
748
}
627
749
else {
@@ -654,6 +776,8 @@ $(function() {
654
776
// Handle demo link click
655
777
$ ( "#demo" ) . click ( function ( event ) {
656
778
event . preventDefault ( ) ;
779
+ resetAutoPlayList ( ) ;
780
+
657
781
gtag ( "send" , "event" , "demo" , "clicked" ) ;
658
782
659
783
// Don't continue appending to the URL if it appears "good enough".
@@ -670,13 +794,22 @@ $(function() {
670
794
// Handle focus link click
671
795
$ ( "#focus-btn" ) . click ( function ( event ) {
672
796
event . preventDefault ( ) ;
797
+ resetAutoPlayList ( ) ;
798
+
673
799
gtag ( "send" , "event" , "focus" , "clicked" ) ;
674
800
// Redirect to the favorite "focus" URL
675
801
window . location . href = makeListenURL ( focusId ) ;
676
802
} ) ;
677
803
804
+ // handle click on search icon
805
+ $ ( "#submit" ) . click ( function ( ) {
806
+ resetAutoPlayList ( ) ;
807
+ } ) ;
808
+
678
809
// Check if the current ID is the focus ID
679
810
$ ( window ) . on ( "load" , function ( ) {
811
+ loadAutoPlayDetails ( ) ;
812
+
680
813
// Show Focus Button
681
814
if ( window . location . href . indexOf ( focusId ) === - 1 ) {
682
815
$ ( "#focus-btn" ) . show ( ) ;
@@ -709,5 +842,9 @@ $(function() {
709
842
if ( evt . keyCode === keyCodes . SPACEBAR && ! $ ( "#v" ) . is ( ":focus" ) ) {
710
843
evt . preventDefault ( ) ;
711
844
}
845
+
846
+ if ( evt . keyCode === keyCodes . ENTER && $ ( "#v" ) . is ( ":focus" ) ) {
847
+ resetAutoPlayList ( ) ;
848
+ }
712
849
} ) ;
713
850
} ) ;
0 commit comments