j1-template 2024.3.15 → 2024.3.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/assets/data/amplitude.html +139 -68
  3. data/assets/data/banner.html +1 -1
  4. data/assets/data/cookieconsent.html +1 -1
  5. data/assets/data/docsearch.html +1 -1
  6. data/assets/data/fab.html +1 -1
  7. data/assets/data/footer.html +1 -1
  8. data/assets/data/galeries.html +1 -1
  9. data/assets/data/gallery_customizer.html +1 -1
  10. data/assets/data/gemini-ui.html +1 -1
  11. data/assets/data/iframes.html +1 -1
  12. data/assets/data/masonry.html +1 -1
  13. data/assets/data/masterslider.html +1 -1
  14. data/assets/data/menu.html +1 -1
  15. data/assets/data/mmenu.html +1 -1
  16. data/assets/data/mmenu_sidebar.html +1 -1
  17. data/assets/data/mmenu_toc.html +1 -1
  18. data/assets/data/panel.html +5 -4
  19. data/assets/data/quicklinks.html +1 -1
  20. data/assets/data/rtext_resizer.html +1 -1
  21. data/assets/data/slick.html +1 -1
  22. data/assets/data/speak2me.html +1 -1
  23. data/assets/data/swiper.html +313 -0
  24. data/assets/theme/j1/adapter/js/amplitude.30.js +1177 -0
  25. data/assets/theme/j1/adapter/js/amplitude.js +241 -191
  26. data/assets/theme/j1/adapter/js/j1.js +3 -3
  27. data/assets/theme/j1/adapter/js/masonry.js +2 -2
  28. data/assets/theme/j1/adapter/js/masterslider.js +2 -1
  29. data/assets/theme/j1/adapter/js/swiper.js +231 -0
  30. data/assets/theme/j1/adapter/js/videojs.js +212 -0
  31. data/assets/theme/j1/core/css/themes/unolight/bootstrap.css +7 -4
  32. data/assets/theme/j1/core/css/themes/unolight/bootstrap.css.map +1 -1
  33. data/assets/theme/j1/core/css/themes/unolight/bootstrap.min.css +1 -1
  34. data/assets/theme/j1/core/css/themes/unolight/bootstrap.min.css.map +1 -1
  35. data/assets/theme/j1/core/js/template.js +4 -0
  36. data/assets/theme/j1/core/js/template.min.js +2 -2
  37. data/assets/theme/j1/core/js/template.min.js.map +1 -1
  38. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.css +94 -4
  39. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.min.css +1 -1
  40. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.css +3 -2
  41. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.min.css +1 -1
  42. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.css +72 -10
  43. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.min.css +2 -1
  44. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/artist.svg +78 -0
  45. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/mute.svg +52 -20
  46. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/next.svg +20 -39
  47. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/now-playing.svg +24 -38
  48. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/playlist-hide.svg +85 -0
  49. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/playlist-music.svg +85 -0
  50. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/playlist-show.svg +85 -0
  51. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/playlist.svg +85 -0
  52. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/previous.svg +18 -37
  53. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/skip-backward.svg +33 -30
  54. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/skip-forward.svg +33 -29
  55. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/small/next.svg +55 -14
  56. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/small/previous.svg +56 -14
  57. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/volume.svg +38 -21
  58. data/assets/theme/j1/modules/amplitudejs/js/amplitude.map +20 -20
  59. data/assets/theme/j1/modules/amplitudejs/js/tech/ytp.15.js +1594 -0
  60. data/assets/theme/j1/modules/amplitudejs/js/tech/ytp.js +1617 -89
  61. data/assets/theme/j1/modules/amplitudejs/js/visualizations/bar.js +1 -1
  62. data/assets/theme/j1/modules/amplitudejs/js/visualizations/circular-equalizer.js +31 -1
  63. data/assets/theme/j1/modules/amplitudejs/js/visualizations/frequency-analyzer.js +1 -1
  64. data/assets/theme/j1/modules/amplitudejs/js/visualizations/michael-bromley.js +1 -1
  65. data/assets/theme/j1/modules/amplitudejs/js/visualizations/template.js +1 -1
  66. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.js +206 -122
  67. data/assets/theme/j1/modules/photoswipe/.version_5.4.4 +6 -0
  68. data/assets/theme/j1/modules/photoswipe/LICENSE +21 -0
  69. data/assets/theme/j1/modules/photoswipe/README.md +32 -0
  70. data/assets/theme/j1/modules/photoswipe/css/org/photoswipe-dynamic-caption-plugin.umd.min.js +5 -0
  71. data/assets/theme/j1/modules/photoswipe/css/org/photoswipe.css +420 -0
  72. data/assets/theme/j1/modules/photoswipe/css/photoswipe-caption-plugin.css +67 -0
  73. data/assets/theme/j1/modules/photoswipe/css/photoswipe-caption-plugin.min.css +16 -0
  74. data/assets/theme/j1/modules/photoswipe/css/photoswipe.css +376 -0
  75. data/assets/theme/j1/modules/photoswipe/css/photoswipe.min.css +17 -0
  76. data/assets/theme/j1/modules/photoswipe/css/scss/photoswipe.scss +427 -0
  77. data/assets/theme/j1/modules/photoswipe/example/photoswipe-caption-plugin.html +237 -0
  78. data/assets/theme/j1/modules/photoswipe/example/test-gallery.html +36 -0
  79. data/assets/theme/j1/modules/photoswipe/js/README.md +43 -0
  80. data/assets/theme/j1/modules/photoswipe/js/photoswipe-caption-plugin.min.js +5 -0
  81. data/assets/theme/j1/modules/photoswipe/js/photoswipe-core.min.js +18 -0
  82. data/assets/theme/j1/modules/photoswipe/js/photoswipe-lightbox.min.js +18 -0
  83. data/assets/theme/j1/modules/swiper/.version_1.2.0 +15 -0
  84. data/assets/theme/j1/modules/swiper/LICENSE +20 -0
  85. data/assets/theme/j1/modules/swiper/README.md +95 -0
  86. data/assets/theme/j1/modules/swiper/css/swiper-bundle.css +740 -0
  87. data/assets/theme/j1/modules/swiper/css/swiper-bundle.min..css +17 -0
  88. data/assets/theme/j1/modules/swiper/css/theme/uno.css +249 -0
  89. data/assets/theme/j1/modules/swiper/css/theme/uno.min.css +154 -0
  90. data/assets/theme/j1/modules/swiper/js/swiper-bundle.js +9785 -0
  91. data/assets/theme/j1/modules/swiper/js/swiper-bundle.min.js +17 -0
  92. data/assets/theme/j1/modules/swiper/swiperjs.com-demos.url +2 -0
  93. data/assets/theme/j1/modules/videojs/assets/icons/custom-icons/next.svg +82 -0
  94. data/assets/theme/j1/modules/videojs/css/font/README.md +151 -0
  95. data/assets/theme/j1/modules/videojs/css/font/VideoJS.svg +150 -0
  96. data/assets/theme/j1/modules/videojs/css/font/video-js-cdn.css +2012 -0
  97. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.0.css +32 -0
  98. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.1.css +31 -0
  99. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.css +31 -0
  100. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.min.css +21 -0
  101. data/assets/theme/j1/modules/videojs/css/themes/uno.css +14 -3
  102. data/assets/theme/j1/modules/videojs/css/themes/uno.min.css +1 -1
  103. data/assets/theme/j1/modules/videojs/css/videojs.css +1 -0
  104. data/assets/theme/j1/modules/videojs/js/plugins/controls/autocaption/LICENSE +13 -0
  105. data/assets/theme/j1/modules/videojs/js/plugins/controls/autocaption/README.md +75 -0
  106. data/assets/theme/j1/modules/videojs/js/plugins/controls/autocaption/autocaption.js +149 -0
  107. data/assets/theme/j1/modules/videojs/js/plugins/controls/autocaption/autocaption.min.js +21 -0
  108. data/assets/theme/j1/modules/videojs/js/plugins/controls/hotkeys/README.md +76 -30
  109. data/assets/theme/j1/modules/videojs/js/plugins/controls/hotkeys/hotkeys.js +64 -53
  110. data/assets/theme/j1/modules/videojs/js/plugins/controls/hotkeys/hotkeys.min.js +1 -1
  111. data/assets/theme/j1/modules/videojs/js/plugins/controls/skipbuttons/README.md +133 -0
  112. data/assets/theme/j1/modules/videojs/js/plugins/controls/skipbuttons/skipbuttons.js +137 -0
  113. data/assets/theme/j1/modules/videojs/js/plugins/controls/skipbuttons/skipbuttons.min.js +21 -0
  114. data/assets/theme/j1/modules/videojs/js/plugins/controls/zoom/zoom.js +15 -12
  115. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/youtube.js +43 -16
  116. data/lib/j1/patches/rubygems/eventmachine-1.2.7-x64-mingw32/lib/3.3/fastfilereaderext.so +0 -0
  117. data/lib/j1/patches/rubygems/eventmachine-1.2.7-x64-mingw32/lib/3.3/rubyeventmachine.so +0 -0
  118. data/lib/j1/patches/rubygems/eventmachine-1.2.7-x64-mingw32/lib/3.4/fastfilereaderext.so +0 -0
  119. data/lib/j1/patches/rubygems/eventmachine-1.2.7-x64-mingw32/lib/3.4/rubyeventmachine.so +0 -0
  120. data/lib/j1/version.rb +1 -1
  121. data/lib/j1_app/j1_auth_manager/config.rb +0 -4
  122. data/lib/starter_web/Gemfile +45 -22
  123. data/lib/starter_web/README.md +5 -5
  124. data/lib/starter_web/_config.yml +4 -6
  125. data/lib/starter_web/_data/modules/amplitude.yml +308 -363
  126. data/lib/starter_web/_data/modules/defaults/amplitude.yml +60 -35
  127. data/lib/starter_web/_data/modules/defaults/gallery.yml +42 -0
  128. data/lib/starter_web/_data/modules/defaults/slick.yml +1 -1
  129. data/lib/starter_web/_data/modules/defaults/swiper.yml +515 -0
  130. data/lib/starter_web/_data/modules/defaults/videojs.yml +107 -0
  131. data/lib/starter_web/_data/modules/gallery.yml +30 -14
  132. data/lib/starter_web/_data/modules/masonry.yml +15 -0
  133. data/lib/starter_web/_data/modules/swiper.yml +227 -0
  134. data/lib/starter_web/_data/modules/videojs.yml +57 -0
  135. data/lib/starter_web/_data/resources.yml +50 -16
  136. data/lib/starter_web/_data/templates/feed.xml +1 -1
  137. data/lib/starter_web/_includes/tables/jekyll_variables.asciidoc +1 -0
  138. data/lib/starter_web/_plugins/asciidoctor/amplitude-block.rb +1 -0
  139. data/lib/starter_web/_plugins/asciidoctor/dailymotion-block.rb +4 -1
  140. data/lib/starter_web/_plugins/asciidoctor/videojs-block.rb +141 -24
  141. data/lib/starter_web/_plugins/asciidoctor/vimeo-block.rb +4 -1
  142. data/lib/starter_web/_plugins/asciidoctor/wistia-block.rb +313 -0
  143. data/lib/starter_web/_plugins/asciidoctor/youtube-block.rb +192 -17
  144. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  145. data/lib/starter_web/assets/video/poster/youtube/faelle_des_bnd/der_unverzichtbare_feind.jpg +0 -0
  146. data/lib/starter_web/assets/video/poster/youtube/faelle_des_bnd/ein_diener_vieler_herren.jpg +0 -0
  147. data/lib/starter_web/assets/video/poster/youtube/the_piano/the-piano.jpg +0 -0
  148. data/lib/starter_web/package.json +1 -1
  149. data/lib/starter_web/pages/public/_includes/attributes.asciidoc +45 -0
  150. data/lib/starter_web/pages/public/_includes/documents/photoswipe/200_photoswipe_parameters.asciidoc +510 -0
  151. data/lib/starter_web/pages/public/_includes/documents/photoswipe/210_photoswipe_lightbox_parameters.asciidoc +98 -0
  152. data/lib/starter_web/pages/public/_includes/documents/photoswipe/300_caption_plugin_for_photoSwipe.asciidoc +327 -0
  153. data/lib/starter_web/pages/public/_includes/documents/swiper/100_swiper_features.asciidoc +50 -0
  154. data/lib/starter_web/pages/public/_includes/documents/swiper/100_swiper_html_layout.asciidoc +122 -0
  155. data/lib/starter_web/pages/public/_includes/documents/swiper/100_swiper_initialization.asciidoc +53 -0
  156. data/lib/starter_web/pages/public/_includes/documents/swiper/110_swiper_common_options.asciidoc +43 -0
  157. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_a_k.asciidoc +994 -0
  158. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_l_o.asciidoc +473 -0
  159. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_p_s.asciidoc +700 -0
  160. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_t_z.asciidoc +413 -0
  161. data/lib/starter_web/pages/public/_includes/documents/swiper/300_swiper_instance_properties.asciidoc +873 -0
  162. data/lib/starter_web/pages/public/_includes/documents/swiper/400_swiper_modules.asciidoc +2514 -0
  163. data/lib/starter_web/pages/public/_includes/documents/swiper/500_swiper_methods.asciidoc +989 -0
  164. data/lib/starter_web/pages/public/_includes/documents/swiper/600_swiper_events.asciidoc +1534 -0
  165. data/lib/starter_web/pages/public/amplitude_yt_tester.adoc +89 -62
  166. data/lib/starter_web/pages/public/manuals/integrations/amplitudejs/amplitudejs-api.adoc +1 -1
  167. data/lib/starter_web/pages/public/manuals/integrations/videojs/youtube-api.adoc +1638 -0
  168. data/lib/starter_web/pages/public/photoswipe_api.adoc +150 -0
  169. data/lib/starter_web/pages/public/swiper_api.adoc +128 -0
  170. data/lib/starter_web/pages/public/swiper_tester.adoc +973 -0
  171. data/lib/starter_web/pages/public/tools/previewer/preview_bootstrap_theme.adoc +5 -6
  172. data/lib/starter_web/pages/public/tools/previewer/preview_videojs.adoc +203 -0
  173. data/lib/starter_web/pages/{tour → public/tour}/modal_extentions.adoc +12 -5
  174. data/lib/starter_web/pages/{tour → public/tour}/play_audio.adoc +63 -15
  175. data/lib/starter_web/pages/{tour → public/tour}/play_video.adoc +79 -40
  176. data/lib/starter_web/pages/{tour → public/tour}/present_images.adoc +5 -5
  177. metadata +114 -41
  178. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/_pause.svg +0 -19
  179. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/_play.svg +0 -18
  180. data/assets/theme/j1/modules/amplitudejs/icons/player/dark/show-playlist.svg +0 -15
  181. data/assets/theme/j1/modules/jqueryScrollbar/LICENSE +0 -20
  182. data/assets/theme/j1/modules/jqueryScrollbar/README.md +0 -28
  183. data/assets/theme/j1/modules/jqueryScrollbar/css/scrollbar.css +0 -939
  184. data/assets/theme/j1/modules/jqueryScrollbar/css/scrollbar.min.css +0 -20
  185. data/assets/theme/j1/modules/jqueryScrollbar/js/scrollbar.js +0 -851
  186. data/assets/theme/j1/modules/jqueryScrollbar/js/scrollbar.min.js +0 -36
  187. data/assets/theme/j1/modules/jqueryScrollbar/sass/scrollbar.scss +0 -806
  188. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.0.js +0 -794
  189. /data/lib/starter_web/pages/{tour → public/tour}/_includes/attributes.asciidoc +0 -0
  190. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/100_gistblock.asciidoc +0 -0
  191. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_bottom_info.asciidoc +0 -0
  192. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_bottom_left_warning.asciidoc +0 -0
  193. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_bottom_right_danger.asciidoc +0 -0
  194. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_central_success.asciidoc +0 -0
  195. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_full_height_left_info.asciidoc +0 -0
  196. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_full_height_right_success.asciidoc +0 -0
  197. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_table_bs_modal_examples.asciidoc +0 -0
  198. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_top_info.asciidoc +0 -0
  199. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_top_left_info.asciidoc +0 -0
  200. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/410_top_right_success.asciidoc +0 -0
  201. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/419_advanced_modals_demo.asciidoc +0 -0
  202. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/tables/bs_modal_examples.asciidoc +0 -0
  203. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/themes_bootstrap.asciidoc +0 -0
  204. /data/lib/starter_web/pages/{tour → public/tour}/_includes/documents/themes_rouge.asciidoc +0 -0
  205. /data/lib/starter_web/pages/{tour → public/tour}/asciidoc_extensions.adoc +0 -0
  206. /data/lib/starter_web/pages/{tour → public/tour}/bootstrap_themes.adoc +0 -0
  207. /data/lib/starter_web/pages/{tour → public/tour}/highlghter_rouge.adoc +0 -0
  208. /data/lib/starter_web/pages/{tour → public/tour}/icon_fonts.adoc +0 -0
  209. /data/lib/starter_web/pages/{tour → public/tour}/quicksearch.adoc +0 -0
  210. /data/lib/starter_web/pages/{tour → public/tour}/responsive_tables.adoc +0 -0
  211. /data/lib/starter_web/pages/{tour → public/tour}/typography.adoc +0 -0
@@ -0,0 +1,1594 @@
1
+ ---
2
+ regenerate: true
3
+ ---
4
+
5
+ {%- capture cache -%}
6
+
7
+ {% comment %}
8
+ # -----------------------------------------------------------------------------
9
+ # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.js
10
+ # AmplitudeJS V5 Plugin|Tech for J1 Template
11
+ #
12
+ # Product/Info:
13
+ # https://jekyll.one
14
+ #
15
+ # Copyright (C) 2023, 2024 Juergen Adams
16
+ #
17
+ # J1 Template is licensed under the MIT License.
18
+ # See: https://github.com/jekyll-one-org/j1-template/blob/main/LICENSE
19
+ # -----------------------------------------------------------------------------
20
+ # Test data:
21
+ # {{ liquid_var | debug }}
22
+ # amplitude_options: {{ amplitude_options | debug }}
23
+ # -----------------------------------------------------------------------------
24
+ {% endcomment %}
25
+
26
+ {% comment %} Liquid procedures
27
+ -------------------------------------------------------------------------------- {% endcomment %}
28
+
29
+ {% comment %} Set global settings
30
+ -------------------------------------------------------------------------------- {% endcomment %}
31
+ {% assign environment = site.environment %}
32
+ {% assign asset_path = "/assets/theme/j1" %}
33
+
34
+ {% comment %} Process YML config data
35
+ ================================================================================ {% endcomment %}
36
+
37
+ {% comment %} Set config files
38
+ -------------------------------------------------------------------------------- {% endcomment %}
39
+ {% assign template_config = site.data.j1_config %}
40
+ {% assign blocks = site.data.blocks %}
41
+ {% assign modules = site.data.modules %}
42
+
43
+ {% comment %} Set config data (settings only)
44
+ -------------------------------------------------------------------------------- {% endcomment %}
45
+ {% assign amplitude_defaults = modules.defaults.amplitude.defaults %}
46
+ {% assign amplitude_settings = modules.amplitude.settings %}
47
+
48
+ {% comment %} Set config options (settings only)
49
+ -------------------------------------------------------------------------------- {% endcomment %}
50
+ {% assign amplitude_options = amplitude_defaults | merge: amplitude_settings %}
51
+
52
+ {% comment %} Detect prod mode
53
+ -------------------------------------------------------------------------------- {% endcomment %}
54
+ {% assign production = false %}
55
+ {% if environment == 'prod' or environment == 'production' %}
56
+ {% assign production = true %}
57
+ {% endif %}
58
+
59
+ /*
60
+ # -----------------------------------------------------------------------------
61
+ # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.js
62
+ # AmplitudeJS V5 Plugin|Tech for J1 Template
63
+ #
64
+ # Product/Info:
65
+ # https://jekyll.one
66
+ #
67
+ # Copyright (C) 2023, 2024 Juergen Adams
68
+ #
69
+ # J1 Template is licensed under the MIT License.
70
+ # See: https://github.com/jekyll-one-org/j1-template/blob/main/LICENSE
71
+ # -----------------------------------------------------------------------------
72
+ */
73
+ "use strict";
74
+
75
+ // date|time monitoring
76
+ //------------------------------------------------------------------------------
77
+ var startTime;
78
+ var endTime;
79
+ var startTimeModule;
80
+ var endTimeModule;
81
+ var timeSeconds;
82
+
83
+ // YT API settings
84
+ // -----------------------------------------------------------------------------
85
+ // const YT_PLAYER_STATE = {
86
+ var YT_PLAYER_STATE = {
87
+ UNSTARTED: -1,
88
+ ENDED: 0,
89
+ PLAYING: 1,
90
+ PAUSED: 2,
91
+ BUFFERING: 3,
92
+ CUED: 5
93
+ };
94
+
95
+ var firstScriptTag;
96
+ var ytPlayer;
97
+ var ytPlayerReady = false;
98
+ var ytApiReady = false;
99
+ var logger = log4javascript.getLogger('j1.adapter.amplitude.tech');
100
+
101
+ // YT Player settings data (created dynamically)
102
+ // -----------------------------------------------------------------------------
103
+ // var ytPlayers = {};
104
+ // var ytPlayersMap = new Map();
105
+
106
+ // AmplitudeJS API settings
107
+ // -----------------------------------------------------------------------------
108
+
109
+ var dependency;
110
+ var playerCounter = 0;
111
+ var load_dependencies = {};
112
+
113
+ var ytpSongIndex = "0";
114
+ var ytpAutoPlay = false;
115
+ var ytpLoop = true;
116
+ var playLists = {};
117
+ var playersUILoaded = { state: false };
118
+ var apiInitialized = { state: false };
119
+ var amplitudeDefaults = $.extend({}, {{amplitude_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
120
+ var amplitudeSettings = $.extend({}, {{amplitude_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
121
+ var amplitudeOptions = $.extend(true, {}, amplitudeDefaults, amplitudeSettings);
122
+
123
+ var playerExistsInPage = false;
124
+ var ytpContainer = null;
125
+ var playerProperties = {};
126
+ var playList;
127
+ var playerProperties;
128
+ var playerID;
129
+ var playerType;
130
+ var playListTitle;
131
+ var playListName;
132
+ var amplitudePlayerState;
133
+ var ytPlayer;
134
+ var ytpPlaybackRate
135
+
136
+ var songs;
137
+ var songMetaData;
138
+ var songURL;
139
+ var songIndex = 0; // set default song index to FIRST item
140
+ var progress;
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // Base YT functions and events
144
+ // ---------------------------------------------------------------------------
145
+
146
+ // Recursive function to MERGE objects
147
+ var mergeObject = function() {
148
+ mergeObject = Object.assign || function mergeObject(t) {
149
+ for (var s, i=1, n=arguments.length; i<n; i++) {
150
+ s = arguments[i];
151
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
152
+ }
153
+ return t;
154
+ };
155
+ return mergeObject.apply(this, arguments);
156
+ };
157
+
158
+ // Add property path dynamically to an existing object
159
+ // Example: addNestedProperty(j1.adapter.amplitude.data, 'playlist.profile.name', 'Max Mustermann')
160
+ function addNestedProperty(obj, path, value) {
161
+ let current = obj;
162
+ const properties = path.split('.');
163
+
164
+ properties.forEach((property, index) => {
165
+ if (index === properties.length - 1) {
166
+ current[property] = value;
167
+ } else {
168
+ if (!current[property]) {
169
+ current[property] = {};
170
+ }
171
+ current = current[property];
172
+ }
173
+ });
174
+ }
175
+
176
+ function setNestedProperty(obj, path, value) {
177
+ const keys = path.split('.');
178
+
179
+ // Basisfall: Wenn nur noch ein Schlüssel übrig ist, setzen wir den Wert direkt
180
+ if (keys.length === 1) {
181
+ obj[keys[0]] = value;
182
+ return;
183
+ }
184
+
185
+ // Rekursiver Fall: Wir erstellen das Objekt für den nächsten Schlüssel, falls es noch nicht existiert
186
+ let current = obj[keys[0]];
187
+ if (typeof current !== 'object') {
188
+ current = obj[keys[0]] = {};
189
+ }
190
+
191
+ // Rekursiver Aufruf für den Rest des Pfades
192
+ setNestedProperty(current, keys.slice(1).join('.'), value);
193
+ }
194
+
195
+ // Add (nested) object dynamically to an existing object
196
+ // Example: createNestedObject(myObject, ['level1', 'arrayProperty', 0], 'element1');
197
+ function addNestedObject(obj, path, value) {
198
+ const lastKey = path[path.length - 1];
199
+ let current = obj;
200
+
201
+ path.slice(0, -1).forEach(key => {
202
+ current[key] = current[key] || {};
203
+ current = current[key];
204
+ });
205
+
206
+ current[lastKey] = value;
207
+ }
208
+
209
+ // load YT Iframe player API
210
+ function initYtAPI() {
211
+ startTimeModule = Date.now();
212
+
213
+ logger.info('\n' + 'Initialize plugin|tech (ytp) : started');
214
+
215
+ // Load YT IFrame Player API asynchronously
216
+ // -------------------------------------------------------------------------
217
+ var tag = document.createElement('script');
218
+ tag.src = "//youtube.com/iframe_api";
219
+ firstScriptTag = document.getElementsByTagName('script')[0];
220
+
221
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
222
+ }
223
+
224
+ // setup YTPlayerUiEvents for AJS players
225
+ function initUiEventsForAJS() {
226
+
227
+ var dependencies_ytp_ready = setInterval (() => {
228
+ var ytApiReady = (j1.adapter.amplitude.data.ytpGlobals['ytApiReady'] !== undefined) ? j1.adapter.amplitude.data.ytpGlobals['ytApiReady'] : false;
229
+ var ytPlayerReady = (j1.adapter.amplitude.data.ytpGlobals['ytPlayerReady'] !== undefined) ? j1.adapter.amplitude.data.ytpGlobals['ytPlayerReady'] : false;
230
+
231
+ if (ytApiReady && ytPlayerReady) {
232
+
233
+ {% for player in amplitude_settings.players %}{% if player.enabled %}
234
+
235
+ {% if player.source == empty %}
236
+ {% assign player_source = amplitude_defaults.player.source %}
237
+ {% else %}
238
+ {% assign player_source = player.source %}
239
+ {% endif %}
240
+
241
+ {% if player_source == 'video' %}
242
+ var playerID = '{{player.id}}';
243
+ mimikYTPlayerUiEventsForAJS(playerID);
244
+ {% endif %}
245
+
246
+ {% endif %}{% endfor %}
247
+
248
+ clearInterval(dependencies_ytp_ready);
249
+ logger.info('\n' + 'Initialize APIPlayers : ready');
250
+ } // END if ready
251
+
252
+ }, 10); // END dependencies_ytp_ready
253
+ } // END initUiEventsForAJS()
254
+
255
+ // Create a player after Iframe player API is ready to use
256
+ // ---------------------------------------------------------------------------
257
+ function onYouTubeIframeAPIReady() {
258
+ // var currentOptions;
259
+ var playerSource;
260
+
261
+ ytApiReady = true;
262
+ // currentOptions = $.extend({}, {{amplitude_options | replace: 'nil', 'null' | replace: '=>', ':' }});
263
+
264
+ {% for player in amplitude_options.players %}{% if player.enabled %}
265
+ {% capture xhr_container_id %}{{player.id}}_parent{% endcapture %}
266
+
267
+ playerSource = '{{player.source}}';
268
+
269
+ {% if player.source == empty %}
270
+ {% assign player_source = amplitude_defaults.player.source %}
271
+ {% else %}
272
+ {% assign player_source = player.source %}
273
+ {% endif %}
274
+
275
+ {% if player_source != 'video' %}
276
+ {% continue %}
277
+ {% else %}
278
+ // load players of type 'video' configured in current page
279
+ //
280
+ playerExistsInPage = ($('#' + '{{xhr_container_id}}')[0] !== undefined) ? true : false;
281
+ if (playerExistsInPage) {
282
+ var playerSettings = $.extend({}, {{player | replace: 'nil', 'null' | replace: '=>', ':' }});
283
+ var songs = Amplitude.getSongsStatePlaylist(playerSettings.playlist.name);
284
+ var activeSongMetadata = songs[0];
285
+ var playerType = playerSettings.type
286
+
287
+ // increase number of found players in page by one
288
+ playerCounter++;
289
+
290
+ // load individual player settings (to manage multiple players in page)
291
+ //
292
+ var ytpVideoID = activeSongMetadata.url.split('=')[1];
293
+ var ytpAutoPlay = ('{{player.yt_player.autoplay}}'.length > 0) ? '{{player.yt_player.autoplay}}' : '{{amplitude_defaults.player.yt_player.autoplay}}';
294
+ var ytpLoop = ('{{player.yt_player.loop}}'.length > 0) ? '{{player.yt_player.loop}}' : '{{amplitude_defaults.player.yt_player.loop}}';
295
+ var ytpHeight = ('{{player.yt_player.height}}'.length > 0) ? '{{player.yt_player.height}}' : '{{amplitude_defaults.player.yt_player.height}}';
296
+ var ytpWidth = ('{{player.yt_player.width}}'.length > 0) ? '{{player.yt_player.width}}' : '{{amplitude_defaults.player.yt_player.width}}';
297
+
298
+ logger.info('\n' + 'AJS YouTube iFrame API: ready');
299
+ logger.info('\n' + 'configure player on ID: #{{player.id}}');
300
+
301
+ // create a hidden YT Player iFrame container
302
+ //
303
+ ytpContainer = document.getElementById('{{player.id}}_video');
304
+ ytpContainer.innerHTML = '<div id="iframe_{{player.id}}"></div>';
305
+ ytpContainer.style.cssText = 'display:none';
306
+
307
+ ytPlayer = new YT.Player('iframe_{{player.id}}', {
308
+ height: ytpHeight,
309
+ width: ytpWidth,
310
+ videoId: ytpVideoID,
311
+ playerVars: {
312
+ autoplay: ytpAutoPlay,
313
+ loop: ytpLoop
314
+ },
315
+ events: {
316
+ 'onReady': {{player.id}}OnPlayerReady,
317
+ 'onStateChange': {{player.id}}OnPlayerStateChange
318
+ }
319
+ });
320
+
321
+ // remove EMPTY properties
322
+ delete playerSettings.player;
323
+
324
+ // save YT player properties for later use
325
+ playerProperties = {
326
+ "playerDefaults": amplitudeDefaults.player,
327
+ "playerSettings": playerSettings,
328
+ "player": ytPlayer,
329
+ "playerReady": false,
330
+ "playerType": playerType,
331
+ "playerID": "{{player.id}}",
332
+ "videoID": ytpVideoID,
333
+ "songs": songs,
334
+ "activeIndex": 0,
335
+ };
336
+
337
+ // store player properties for later use
338
+ addNestedProperty(j1.adapter.amplitude.data.ytPlayers, '{{player.id}}', playerProperties);
339
+
340
+ // save YT player data for later use (e.g. events)
341
+ // j1.adapter.amplitude.data.ytpGlobals['ytVideoID'] = ytpVideoID;
342
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerDefaults'] = amplitudeDefaults.player;
343
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerSettings'] = playerSettings;
344
+ j1.adapter.amplitude.data.ytpGlobals['ytApiReady'] = ytApiReady;
345
+
346
+
347
+ // reset current player
348
+ playerExistsInPage = false;
349
+
350
+ } // END if playerExistsInPage()
351
+
352
+ // run AJS YouTube Player initialization
353
+ // -----------------------------------------------------------------------
354
+ function {{player.id}}OnPlayerReady(event) {
355
+ var hours, minutes, seconds;
356
+ var ytPlayer = event.target;
357
+ var ytPlayerReady = true;
358
+
359
+ logger.info('\n' + 'AJS YouTube Player on ID {{player.id}}: ready');
360
+
361
+ // save YT player data for later use (e.g. events)
362
+ j1.adapter.amplitude.data.ytpGlobals['ytPlayerReady'] = ytPlayerReady;
363
+ j1.adapter.amplitude.data.ytPlayers.{{player.id}}.playerReady = ytPlayerReady;
364
+
365
+ setInterval(updateCurrentTimeContainerYTP, 1000);
366
+ setInterval(updateProgressBarsYTP, 1000)
367
+
368
+ // get duration hours (if configured)
369
+ if ({{player.display_hours}} ) {
370
+ hours = ytpGetDurationHours (ytPlayer);
371
+ }
372
+
373
+ // get duration minutes|seconds
374
+ minutes = ytpGetDurationMinutes (ytPlayer);
375
+ seconds = ytpGetDurationSeconds (ytPlayer);
376
+
377
+ // set duration time values for current video
378
+ // ---------------------------------------------------------------------
379
+
380
+ // set duration|hours
381
+ if ({{player.display_hours}} ) {
382
+ var durationHours = document.getElementsByClassName("amplitude-duration-hours");
383
+ // do update
384
+ }
385
+
386
+ // set duration|minutes
387
+ var durationMinutes = document.getElementsByClassName("amplitude-duration-minutes");
388
+ durationMinutes[0].innerHTML = minutes;
389
+
390
+ // set duration|seconds
391
+ var durationSeconds = document.getElementsByClassName("amplitude-duration-seconds");
392
+ durationSeconds[0].innerHTML = seconds;
393
+
394
+ // final message
395
+ // ---------------------------------------------------------------------
396
+ endTimeModule = Date.now();
397
+
398
+ logger.info('\n' + 'Initialize plugin|tech (ytp) : finished');
399
+
400
+ if (playerCounter > 0) {
401
+ logger.info('\n' + 'Found players of type video (YTP) in page: ' + playerCounter);
402
+ } else {
403
+ logger.warn('\n' + 'Found NO players of type video (YTP) in page');
404
+ }
405
+
406
+ logger.info('\n' + 'plugin|tech initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
407
+
408
+ } // END onPlayerReady()
409
+
410
+ // update YT player elements on state change (playing)
411
+ // -----------------------------------------------------------------------
412
+ function {{player.id}}OnPlayerStateChange(event) {
413
+ var ytPlayer = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.player;
414
+ var songs = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.songs;
415
+ var activeIndex = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.activeIndex;
416
+
417
+ // set active ytPlayer
418
+ j1.adapter.amplitude.data.ytpGlobals['activePlayer'] = ytPlayer;
419
+
420
+ // save YT player data for later use (e.g. events)
421
+ // j1.adapter.amplitude.data.ytPlayers.{{player.id}}.player = ytPlayer;
422
+
423
+ resetCurrentTimeContainerYTP();
424
+ updateDurationTimeContainerYTP(ytPlayer);
425
+
426
+ // setInterval(updateCurrentTimeContainerYTP, 1000);
427
+ // setInterval(updateProgressBarsYTP('{{player.id}}'), 1000)
428
+
429
+ // Set the index of the active song (index starts by 0)
430
+ // ytpSetActiveIndex({{player.id}}, activeIndex);
431
+
432
+ if (event.data === YT_PLAYER_STATE.PLAYING || event.data === YT_PLAYER_STATE.BUFFERING) {
433
+ var bla = 1;
434
+ // j1.adapter.amplitude.data.ytpGlobals['activePlayer'] = ytPlayer;
435
+ // setInterval(updateCurrentTimeContainerYTP, 1000);
436
+ // setInterval(updateProgressBarsYTP, 1000)
437
+ }
438
+
439
+ // play next video
440
+ if (event.data === YT_PLAYER_STATE.ENDED) {
441
+
442
+ // var ytPlayer = j1.adapter.amplitude.data.ytpGlobals['ytPlayer'];
443
+ // var ytPlayer = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.player;
444
+ // var songs = j1.adapter.amplitude.data.ytpGlobals['ytPlayerSongs'];
445
+ // var songIndex = parseInt(j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex']) +1;
446
+
447
+ var songIndex = ytpSongIndex++;
448
+
449
+ if (songIndex < songs.length) {
450
+ var songMetaData = songs[songIndex];
451
+ var songURL = songMetaData.url;
452
+ var ytpVideoID = songURL.split('=')[1];
453
+
454
+ // continue on next video
455
+ ytPlayer.loadVideoById(ytpVideoID);
456
+
457
+ // reset|update time settings
458
+ resetCurrentTimeContainerYTP();
459
+ updateDurationTimeContainerYTP(ytPlayer);
460
+
461
+ // update global song index for next video
462
+ ytpSongIndex = songIndex;
463
+ ytpSetActiveIndex({{player.id}}, songIndex);
464
+
465
+ // save YT player data for later use (e.g. events)
466
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
467
+
468
+ // replace cover image for next video
469
+ var coverImage = document.querySelector(".cover-image");
470
+ coverImage.src = songMetaData.cover_art_url;
471
+
472
+ // replace song name in meta-containers for next video
473
+ var songName = document.getElementsByClassName("song-name");
474
+ songName[0].innerHTML = songMetaData.name; // player-bottom
475
+ songName[1].innerHTML = songMetaData.name; // playlist-screen-controls
476
+
477
+ // replace song rating (playlist-screen|meta-container)
478
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
479
+ if (largetPlayerSongAudioRating.length) {
480
+ if (songMetaData.rating) {
481
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
482
+ } else {
483
+ largetPlayerSongAudioRating[0].innerHTML = '';
484
+ }
485
+ } // END if largetPlayerSongAudioRating
486
+
487
+ // replace artist name in meta-containers for next video
488
+ var artistName = document.getElementsByClassName("artist");
489
+ artistName[0].innerHTML = songMetaData.artist;
490
+
491
+ // replace album name in meta-containers for next video
492
+ var albumName = document.getElementsByClassName("album");
493
+ albumName[0].innerHTML = songMetaData.album;
494
+
495
+ // set song active in playlist
496
+ setSongPlayed(songIndex);
497
+ } else {
498
+ // select FIRST video
499
+ songIndex = 0;
500
+ var songMetaData = songs[songIndex];
501
+ var songURL = songMetaData.url;
502
+ var ytpVideoID = songURL.split('=')[1];
503
+
504
+ ytpSetActiveIndex({{player.id}}, songIndex);
505
+
506
+ // continue (paused) on FIRST video
507
+ ytPlayer.loadVideoById(ytpVideoID);
508
+ // wait some time to make sure video is loaded|active
509
+ setTimeout(() => {
510
+ ytPlayer.pauseVideo();
511
+ // reset|update time settings
512
+ resetCurrentTimeContainerYTP();
513
+ updateDurationTimeContainerYTP(ytPlayer);
514
+
515
+ // update AJS play_pause button
516
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
517
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
518
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
519
+ }, 300);
520
+
521
+ // update global song index for first video
522
+ ytpSongIndex = songIndex;
523
+
524
+ // save YT player data for later use (e.g. events)
525
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
526
+
527
+ // load cover image for first video
528
+ var coverImage = document.querySelector(".cover-image");
529
+ coverImage.src = songMetaData.cover_art_url;
530
+
531
+ // replace name in meta-containers for first video
532
+ var songName = document.getElementsByClassName("song-name");
533
+ songName[0].innerHTML = songMetaData.name; // player-bottom
534
+ songName[1].innerHTML = songMetaData.name; // playlist-screen-controls
535
+
536
+ // replace song rating (playlist-screen|meta-container)
537
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
538
+ if (largetPlayerSongAudioRating.length) {
539
+ if (songMetaData.rating) {
540
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
541
+ } else {
542
+ largetPlayerSongAudioRating[0].innerHTML = '';
543
+ }
544
+ } // END if largetPlayerSongAudioRating
545
+
546
+ // replace artist name in meta-containers for next video
547
+ var artistName = document.getElementsByClassName("artist");
548
+ artistName.innerHTML = songMetaData.artist;
549
+
550
+ // replace album name in meta-containers for next video
551
+ var albumName = document.getElementsByClassName("album");
552
+ albumName.innerHTML = songMetaData.album;
553
+
554
+ // update AJS play_pause button
555
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
556
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
557
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
558
+
559
+ // set song (video) active in playlist
560
+ setSongPlayed(songIndex);
561
+ }
562
+ } // END if YT_PLAYER_STATE.ENDED
563
+
564
+ } // END {{player.id}}OnPlayerStateChange
565
+
566
+ {% endif %}
567
+ {% endif %}{% endfor %}
568
+
569
+ } // END onYouTubeIframeAPIReady ()
570
+
571
+
572
+ // ---------------------------------------------------------------------------
573
+ // main (plugin)
574
+ // ---------------------------------------------------------------------------
575
+ // load|initialize YT Iframe player API
576
+ //
577
+ initYtAPI();
578
+
579
+ // setup YTPlayerUiEvents for AJS players
580
+ //
581
+ initUiEventsForAJS();
582
+
583
+
584
+ // ---------------------------------------------------------------------------
585
+ // Base AJS Player functions
586
+ // ---------------------------------------------------------------------------
587
+
588
+ // ---------------------------------------------------------------------------
589
+ // Returns the index of the current video (song) in the songs array
590
+ // that is currently playing (starts by 0)
591
+ // ---------------------------------------------------------------------------
592
+ //
593
+ function getSongPlayed() {
594
+ var index = -1;
595
+ var songContainers = document.getElementsByClassName("amplitude-active-song-container");
596
+
597
+ if (songContainers.length) {
598
+ for (var i=0; i<songContainers.length; i++) {
599
+ index = parseInt(songContainers[i].getAttribute('data-amplitude-song-index'));
600
+ if (index >= 0) {
601
+ break;
602
+ }
603
+ }
604
+ }
605
+
606
+ return index;
607
+ } // END getSongPlayed
608
+
609
+ // ---------------------------------------------------------------------------
610
+ // Add class 'amplitude-active-song-container' to the element containing
611
+ // visual information for the active song.
612
+ //
613
+ // NOTE: We then don't care if shuffle is on or not.
614
+ // ---------------------------------------------------------------------------
615
+ //
616
+ function setSongPlayed(index) {
617
+ var direct;
618
+
619
+ // Specify if it was a (direct) click on the song container
620
+ direct = true;
621
+
622
+ // Gets all of the song container elements.
623
+ var songContainers = document.getElementsByClassName("amplitude-song-container");
624
+
625
+ // Clear all active song containrs.
626
+ for (var i = 0; i < songContainers.length; i++) {
627
+ songContainers[i].classList.remove("amplitude-active-song-container");
628
+ }
629
+
630
+ // Find the active index and add the active song container to the element
631
+ // that represents the song at the index.
632
+ //
633
+ if (Amplitude.getActivePlaylist() == "" || Amplitude.getActivePlaylist() == null) {
634
+ var activeIndex = "";
635
+
636
+ // If we click directly on the song element, we ignore
637
+ // whether it's in shuffle or not.
638
+ //
639
+ if (direct) {
640
+ // activeIndex = Amplitude.getActiveIndex();
641
+ activeIndex = index;
642
+ } else {
643
+ if (Amplitude.getConfig().shuffle_on) {
644
+ // activeIndex = Amplitude.getConfig().shuffle_list[Amplitude.getActiveIndex()];
645
+ } else {
646
+ // activeIndex = Amplitude.getActiveIndex();
647
+ activeIndex = index;
648
+ }
649
+ }
650
+
651
+ if (document.querySelectorAll('.amplitude-song-container[data-amplitude-song-index="' + activeIndex + '"]')) {
652
+ var _songContainers = document.querySelectorAll('.amplitude-song-container[data-amplitude-song-index="' + activeIndex + '"]');
653
+
654
+ for (var _i = 0; _i < _songContainers.length; _i++) {
655
+ // if (!_songContainers[_i].hasAttribute("data-amplitude-playlist")) {
656
+ if (_songContainers[_i].hasAttribute("data-amplitude-playlist")) {
657
+ _songContainers[_i].classList.add("amplitude-active-song-container");
658
+ }
659
+ }
660
+ }
661
+ } else {
662
+ // If we have an active playlist or the action took place directly on the
663
+ // song element, we ignore the shuffle.
664
+ //
665
+ if (Amplitude.getActivePlaylist() != null && Amplitude.getActivePlaylist() != "" || direct) {
666
+ var activePlaylistIndex = Amplitude.getActiveIndex();
667
+ } else {
668
+ var activePlaylistIndex = "";
669
+
670
+ if (Amplitude.getActivePlaylist().shuffle) {
671
+ activePlaylistIndex = Amplitude.getActiveIndex();
672
+ } else {
673
+ activePlaylistIndex = Amplitude.getActiveIndex();
674
+ }
675
+ } // END if
676
+ } // END if
677
+ } // END setSongPlayed
678
+
679
+ // Returns the position as a percentage the user clicked in player progressbar
680
+ // NOTE: The percentage is out of [0.00 .. 1.00]
681
+ // ---------------------------------------------------------------------------
682
+ function getProgressBarSelectedPositionPercentage (event, progessBar) {
683
+ var offset = progessBar.getBoundingClientRect();
684
+ var xpos = event.pageX - offset.left;
685
+ var percentage = (parseFloat(xpos) / parseFloat(progessBar.offsetWidth)).toFixed(2);
686
+
687
+ return percentage;
688
+ }
689
+
690
+ // Returns the time in seconds calculated from a percentage value
691
+ // NOTE: The percentage is out of [0.00 .. 1.00]
692
+ // ---------------------------------------------------------------------------
693
+ function getTimeFromPercentage (player, percentage) {
694
+ var videoDuration = ytpGetDuration(player);
695
+ var time = parseFloat((videoDuration * percentage).toFixed(2));
696
+
697
+ return time;
698
+ }
699
+
700
+ // Update YTP specific progress data
701
+ // ---------------------------------------------------------------------------
702
+ function updateProgressBarsYTP() {
703
+ var progress;
704
+ var activePlayer = j1.adapter.amplitude.data.ytpGlobals['activePlayer'];
705
+ var progressBars = document.getElementsByClassName("large-player-progress");
706
+
707
+ for (var i=0; i<progressBars.length; i++) {
708
+ if (activePlayer !== undefined) {
709
+ // calc procent value (float, 2 decimals [0.00 .. 1.00])
710
+ progress = parseFloat((activePlayer.getCurrentTime() / activePlayer.getDuration()).toFixed(2));
711
+
712
+ // set current progess value if valid
713
+ if (isFinite(progress)) {
714
+ progressBars[i].value = progress;
715
+ }
716
+ }
717
+ } // END for
718
+
719
+ // calc procent value (float, 2 decimals [0.00 .. 1.00])
720
+ // progress = parseFloat((ytPlayer.getCurrentTime() / ytPlayer.getDuration()).toFixed(2));
721
+
722
+ // // jadams, 2024-12-07: added check on finite value
723
+ // if (!isFinite(progress)) {
724
+ // // TODO: check why progress value may NOT finite
725
+ // progressBar.value = 0;
726
+ // } else if (progress === 1) {
727
+ // // reset progress value for next video
728
+ // progressBar.value = 0;
729
+ // } else {
730
+ // // calculate current progress
731
+ // progress = parseFloat((ytPlayer.getCurrentTime() / ytPlayer.getDuration()).toFixed(2));
732
+ // progressBar.value = progress;
733
+
734
+ // save YT player progress data for later use (e.g. events)
735
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerProgress'] = progress;
736
+ //}
737
+ }
738
+
739
+ // Update YTP specific DURATION time data
740
+ // ---------------------------------------------------------------------------
741
+ function updateDurationTimeContainerYTP(player) {
742
+ var hours, minutes, seconds;
743
+ var durationHours, durationMinutes, durationSeconds;
744
+
745
+ // get current hours|minutes|seconds
746
+ hours = ytpGetDurationHours(player);
747
+ minutes = ytpGetDurationMinutes(player);
748
+ seconds = ytpGetDurationSeconds(player);
749
+
750
+ // update time container values for current video
751
+ // -------------------------------------------------------------------------
752
+
753
+ // update current duration|hours
754
+ if (!isNaN(hours) && hours !== '00') {
755
+ durationHours = document.getElementsByClassName("amplitude-duration-hours");
756
+ // do update
757
+ }
758
+
759
+ // update current duration|minutes
760
+ durationMinutes = document.getElementsByClassName("amplitude-duration-minutes");
761
+ if (!isNaN(minutes)) {
762
+ durationMinutes[0].innerHTML = minutes;
763
+ }
764
+
765
+ // update duration|seconds
766
+ durationSeconds = document.getElementsByClassName("amplitude-duration-seconds");
767
+ if (!isNaN(seconds)) {
768
+ durationSeconds[0].innerHTML = seconds;
769
+ }
770
+ }
771
+
772
+ // Update YTP specific CURRENT time data
773
+ // ---------------------------------------------------------------------------
774
+ function updateCurrentTimeContainerYTP() {
775
+ var hours, minutes, seconds;
776
+ var currentHours, currentMinutes, currentSeconds;
777
+
778
+ // get current hours|minutes|seconds
779
+ hours = ytpGetCurrentHours(ytPlayer);
780
+ minutes = ytpGetCurrentMinutes(ytPlayer);
781
+ seconds = ytpGetCurrentSeconds(ytPlayer);
782
+
783
+ // update time container values for current video
784
+ // -------------------------------------------------------------------------
785
+
786
+ // update current duration|hours
787
+ if (hours !== '00') {
788
+ currentHours = document.getElementsByClassName("amplitude-current-hours");
789
+ currentHours[0].innerHTML = hours;
790
+ }
791
+
792
+ // update current duration|minutes
793
+ currentMinutes = document.getElementsByClassName("amplitude-current-minutes");
794
+ currentMinutes[0].innerHTML = minutes;
795
+
796
+ // update duration|seconds
797
+ currentSeconds = document.getElementsByClassName("amplitude-current-seconds");
798
+ currentSeconds[0].innerHTML = seconds;
799
+ }
800
+
801
+ // Reset YTP specific progress data
802
+ // ---------------------------------------------------------------------------
803
+ function resetProgressBarYTP(playerID) {
804
+ if (playerID !== undefined) {
805
+ var progressBar = j1.adapter.amplitude.data.ytPlayers[playerID].progressBar;
806
+ progressBar.value = 0;
807
+ }
808
+ }
809
+
810
+ // Reset YTP specific CURRENT time data
811
+ // ---------------------------------------------------------------------------
812
+ function resetCurrentTimeContainerYTP() {
813
+
814
+ // reset duration|hours
815
+ var currentHours = document.getElementsByClassName("amplitude-current-hours");
816
+ if (currentHours.length) {
817
+ currentHours[0].innerHTML = '00';
818
+ }
819
+
820
+ // reset duration|minutes
821
+ var currentMinutes = document.getElementsByClassName("amplitude-current-minutes");
822
+ currentMinutes[0].innerHTML = '00';
823
+
824
+ // reset duration|seconds
825
+ var currentSeconds = document.getElementsByClassName("amplitude-current-seconds");
826
+ currentSeconds[0].innerHTML = '00';
827
+ }
828
+
829
+
830
+ // ---------------------------------------------------------------------------
831
+ // Mimik Base AJS API functions
832
+ // ---------------------------------------------------------------------------
833
+
834
+ // Skip video to a time specified by time
835
+ // ---------------------------------------------------------------------------
836
+ function ytpSeekTo(player, time) {
837
+ player.seekTo(time, true);
838
+ }
839
+
840
+ // Returns the buffered percentage of the playing video
841
+ // ---------------------------------------------------------------------------
842
+ function ytpGetBuffered(player) {
843
+ // to be defined
844
+ }
845
+
846
+ // Returns the active song index (in the songs array, starts by 0)
847
+ function ytpGetActiveIndex(playerID) {
848
+ var activeIndex = -1;
849
+
850
+ if (j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex !== undefined) {
851
+ activeIndex = parseInt(j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex);
852
+ }
853
+
854
+ return activeIndex;
855
+ }
856
+
857
+ // Set the index of the active song (index starts by 0)
858
+ function ytpSetActiveIndex(playerID, idx) {
859
+ var success = false;
860
+ var index = parseInt(idx);
861
+
862
+ if (j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex !== undefined) {
863
+ j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = index;
864
+ success = true;
865
+ }
866
+
867
+ return success;
868
+ }
869
+
870
+ // Returns the percentage of the video played
871
+ // ---------------------------------------------------------------------------
872
+ function ytpGetPlayedPercentage(player) {
873
+ // to be defined
874
+ }
875
+
876
+ // Returns the actual video element
877
+ // ---------------------------------------------------------------------------
878
+ function ytpGetAudio(player) {
879
+ // to be defined
880
+ }
881
+
882
+ // Returns available playback speeds for the player
883
+ // ---------------------------------------------------------------------------
884
+ function ytpGetPlaybackSpeeds(player) {
885
+ // to be defined
886
+ }
887
+
888
+ // Returns the current playback speed for the player
889
+ // ---------------------------------------------------------------------------
890
+ function ytpGetPlaybackSpeed(player) {
891
+ }
892
+
893
+ // Returns the current state of the player
894
+ // ---------------------------------------------------------------------------
895
+ function ytpGetPlayerState(player) {
896
+ // to be defined
897
+ }
898
+
899
+ // Returns the duration of the video
900
+ // ---------------------------------------------------------------------------
901
+ function ytpGetDuration(player) {
902
+ var playerState, duration;
903
+
904
+ playerState = player.getPlayerState();
905
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.BUFFERING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
906
+ duration = player.getDuration();
907
+
908
+ return duration;
909
+ } else {
910
+ return 0;
911
+ }
912
+ }
913
+
914
+ // Returns the current time of the video played
915
+ // --------------------------------------------------------------------------
916
+ function ytpGetCurrentTime(player) {
917
+ var playerState;
918
+
919
+ if (player !== undefined && player.getPlayerState !== undefined) {
920
+ playerState = player.getPlayerState();
921
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
922
+ var currentTime = player.getCurrentTime();
923
+
924
+ return currentTime;
925
+ } else {
926
+ return 0;
927
+ }
928
+ }
929
+ }
930
+
931
+ // Returns the duration hours of the video
932
+ // ---------------------------------------------------------------------------
933
+ function ytpGetDurationHours(player) {
934
+ var playerState, duration, hours, d, h;
935
+
936
+ if (player !== undefined && player.getPlayerState !== undefined) {
937
+ playerState = player.getPlayerState();
938
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
939
+ duration = ytpGetDuration(player);
940
+ d = Number(duration);
941
+ h = Math.floor(d / 3600);
942
+ hours = h.toString().padStart(2, '0');
943
+
944
+ return hours;
945
+ } else {
946
+ return '00';
947
+ }
948
+ }
949
+ }
950
+
951
+ // Returns the duration minutes of the video
952
+ // ---------------------------------------------------------------------------
953
+ function ytpGetDurationMinutes(player) {
954
+ var playerState, duration, minutes, d, m;
955
+
956
+ if (player !== undefined && player.getPlayerState !== undefined) {
957
+ playerState = player.getPlayerState();
958
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
959
+ duration = ytpGetDuration(player);
960
+ d = Number(duration);
961
+ m = Math.floor(d % 3600 / 60);
962
+ minutes = m.toString().padStart(2, '0');
963
+
964
+ return minutes;
965
+ } else {
966
+ return '00';
967
+ }
968
+ }
969
+ }
970
+
971
+ // Returns the duration seconds of the video
972
+ //
973
+ function ytpGetDurationSeconds(player) {
974
+ var playerState, duration, seconds, d, s;
975
+
976
+ if (player !== undefined && player.getPlayerState !== undefined) {
977
+ playerState = player.getPlayerState();
978
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
979
+ duration = ytpGetDuration(player);
980
+ d = Number(duration);
981
+ s = Math.floor(d % 60);
982
+ seconds = s.toString().padStart(2, '0');
983
+
984
+ return seconds;
985
+ } else {
986
+ return '00';
987
+ }
988
+ }
989
+ }
990
+
991
+ // Returns the current hours the user is into the video
992
+ // ---------------------------------------------------------------------------
993
+ function ytpGetCurrentHours(player) {
994
+ var playerState, currentTime, hours, d, h;
995
+
996
+ if (player !== undefined && player.getPlayerState !== undefined) {
997
+ playerState = player.getPlayerState();
998
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
999
+ currentTime = ytpGetCurrentTime(player);
1000
+ d = Number(currentTime);
1001
+ h = Math.floor(d / 3600);
1002
+ hours = h.toString().padStart(2, '0');
1003
+
1004
+ return hours;
1005
+ } else {
1006
+ return '00';
1007
+ }
1008
+ }
1009
+ }
1010
+
1011
+ // Returns the current minutes the user is into the video
1012
+ // ---------------------------------------------------------------------------
1013
+ function ytpGetCurrentMinutes (player) {
1014
+ var playerState, currentTime, minutes, d, m;
1015
+
1016
+ if (player !== undefined && player.getPlayerState !== undefined) {
1017
+ playerState = player.getPlayerState();
1018
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1019
+ currentTime = ytpGetCurrentTime(player);
1020
+ d = Number(currentTime);
1021
+ m = Math.floor(d % 3600 / 60);
1022
+ minutes = m.toString().padStart(2, '0');
1023
+
1024
+ return minutes;
1025
+ } else {
1026
+ return '00';
1027
+ }
1028
+ }
1029
+ }
1030
+
1031
+ // Returns the current seconds the user is into the video
1032
+ //
1033
+ function ytpGetCurrentSeconds(player) {
1034
+ var playerState, currentTime, seconds, d, s;
1035
+
1036
+ if (player !== undefined && player.getPlayerState !== undefined) {
1037
+ playerState = player.getPlayerState();
1038
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
1039
+ currentTime = ytpGetCurrentTime(player);
1040
+ d = Number(currentTime);
1041
+ s = Math.floor(d % 60);
1042
+ seconds = s.toString().padStart(2, '0');
1043
+
1044
+ return seconds;
1045
+ } else {
1046
+ return '00';
1047
+ }
1048
+ }
1049
+ }
1050
+
1051
+ // ---------------------------------------------------------------------------
1052
+ // mimikYTPlayerUiEventsForAJS()
1053
+ // Mimik AJS button events for YT video
1054
+ // ---------------------------------------------------------------------------
1055
+ function mimikYTPlayerUiEventsForAJS(ytPlayerID) {
1056
+ if (j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID] !== undefined) {
1057
+ var playerDefaults = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].playerDefaults;
1058
+ var playerSettings = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].playerSettings;
1059
+ var playerButton = `large-player-play-pause-${ytPlayerID}`;
1060
+
1061
+ // -----------------------------------------------------------------------
1062
+ // Large AJS players
1063
+ //
1064
+ if (j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].playerSettings.type === 'large') {
1065
+
1066
+ // Overload AJS play_pause button for YT
1067
+ //
1068
+ var largePlayerPlayPauseButton = document.getElementsByClassName(playerButton);
1069
+ for (var i=0; i<largePlayerPlayPauseButton.length; i++) {
1070
+ var classArray = [].slice.call(largePlayerPlayPauseButton[i].classList, 0);
1071
+ var classString = classArray.toString();
1072
+
1073
+ if (classString.includes(ytPlayerID)) {
1074
+ largePlayerPlayPauseButton[i].addEventListener('click', function(event) {
1075
+ var playlist = this.getAttribute("data-amplitude-playlist");
1076
+ var playerID = playlist + '_large';
1077
+ var ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][playerID]['player'];
1078
+ var songs = j1.adapter.amplitude['data']['ytPlayers'][playerID]['songs'];
1079
+ var activeIndex = parseInt(j1.adapter.amplitude['data']['ytPlayers'][playerID]['activeIndex']);
1080
+ var songMetaData = songs[songIndex];
1081
+ var playPauseButton = `large-player-play-pause-${ytPlayerID}`;
1082
+
1083
+ // toggle YT play|pause video
1084
+ if (ytPlayer.getPlayerState() === YT_PLAYER_STATE.PLAYING || ytPlayer.getPlayerState() === YT_PLAYER_STATE.BUFFERING) {
1085
+ ytPlayer.pauseVideo();
1086
+ } else {
1087
+ ytPlayer.playVideo();
1088
+ }
1089
+
1090
+ // toggle AJS PlayPauseButton
1091
+ var largePlayerPlayPauseButton = document.getElementsByClassName(playPauseButton);
1092
+ if (largePlayerPlayPauseButton[0].classList.contains('amplitude-paused')) {
1093
+ largePlayerPlayPauseButton[0].classList.remove('amplitude-paused');
1094
+ largePlayerPlayPauseButton[0].classList.add('amplitude-playing');
1095
+ } else {
1096
+ largePlayerPlayPauseButton[0].classList.remove('amplitude-playing');
1097
+ largePlayerPlayPauseButton[0].classList.add('amplitude-paused');
1098
+ }
1099
+
1100
+ // don't activate playlist item on FIRST || LAST song
1101
+ // if (songIndex !== 0 && songIndex !== songs.length - 1) {
1102
+ if (songIndex !== songs.length - 1) {
1103
+ // set song active in playlist
1104
+ setSongPlayed(songIndex);
1105
+ }
1106
+
1107
+ // event.preventDefault();
1108
+ event.stopImmediatePropagation(); // deactivate AJS events
1109
+ }); // END EventListener largePlayerPlayPauseButton 'click'
1110
+ } // END if largePlayerPlayPauseButton
1111
+ } // END for largePlayerPlayPauseButton
1112
+
1113
+ // Overload AJS largePlayerSkipBackward button for YT
1114
+ //
1115
+ var largePlayerSkipForwardButtons = document.getElementsByClassName("large-player-skip-forward");
1116
+ for (var i=0; i<largePlayerSkipForwardButtons.length; i++) {
1117
+ var classArray = [].slice.call(largePlayerSkipForwardButtons[i].classList, 0);
1118
+ var classString = classArray.toString();
1119
+
1120
+ // load player settings
1121
+ var playerForwardBackwardSkipSeconds = (playerSettings.forward_backward_skip_seconds === undefined) ? playerDefaults.forward_backward_skip_seconds : playerSettings.forward_backward_skip_seconds;
1122
+
1123
+ // if (largePlayerSkipForwardButtons[i].id === 'skip-forward_' + ytPlayerID) {
1124
+ // if (classString.includes(ytPlayerID)) && largePlayerSkipForwardButtons[i].id === 'skip-forkward_' + ytPlayerID) {
1125
+ if (classString.includes(ytPlayerID)) {
1126
+ largePlayerSkipForwardButtons[i].addEventListener('click', function(event) {
1127
+ var currentTime, playerState, skipOffset, ytPlayer;
1128
+
1129
+ skipOffset = parseFloat(playerForwardBackwardSkipSeconds);
1130
+ ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].player;
1131
+ playerState = ytPlayer.getPlayerState();
1132
+ currentTime = ytPlayer.getCurrentTime();
1133
+
1134
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) {
1135
+ ytPlayer.seekTo(currentTime + skipOffset, true);
1136
+ }
1137
+
1138
+ // deactivate AJS events (if any)
1139
+ event.stopImmediatePropagation();
1140
+ }); // END Listener 'click'
1141
+ } // END if skip-forward button
1142
+ } // END for
1143
+
1144
+ // Overload AJS largePlayerSkipBackward button for YT
1145
+ //
1146
+ var largePlayerSkipBackwardButtons = document.getElementsByClassName("large-player-skip-backward");
1147
+ for (var i=0; i<largePlayerSkipBackwardButtons.length; i++) {
1148
+ var classArray = [].slice.call(largePlayerSkipBackwardButtons[i].classList, 0);
1149
+ var classString = classArray.toString();
1150
+
1151
+ // load player settings
1152
+ var playerForwardBackwardSkipSeconds = (playerSettings.forward_backward_skip_seconds === undefined) ? playerDefaults.forward_backward_skip_seconds : playerSettings.forward_backward_skip_seconds;
1153
+
1154
+ if (classString.includes(ytPlayerID)) {
1155
+ largePlayerSkipBackwardButtons[i].addEventListener('click', function(event) {
1156
+ var ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].player;
1157
+
1158
+ if (ytPlayer.getPlayerState() === YT_PLAYER_STATE.PLAYING) {
1159
+ var currentTime = ytPlayer.getCurrentTime();
1160
+ const skipOffset = parseFloat(playerForwardBackwardSkipSeconds);
1161
+
1162
+ ytPlayer.seekTo(currentTime - skipOffset, true);
1163
+ }
1164
+
1165
+ // deactivate AJS events (if any)
1166
+ event.stopImmediatePropagation();
1167
+ }); // END Listener 'click'
1168
+ } // END if skip-backward button
1169
+ } // END for
1170
+
1171
+ // click on (player) next button
1172
+ // TODO: Fix for multiple players in page
1173
+ // --------------------------------------------------------------------
1174
+
1175
+ // Overload AJS largePlayerNext button for YT
1176
+ //
1177
+ var largePlayerNextButton = document.getElementsByClassName("large-player-next");
1178
+ for (var i=0; i<largePlayerNextButton.length; i++) {
1179
+ var classArray = [].slice.call(largePlayerNextButton[i].classList, 0);
1180
+ var classString = classArray.toString();
1181
+
1182
+ if (classString.includes(ytPlayerID)) {
1183
+ largePlayerNextButton[i].addEventListener('click', function(event) {
1184
+ var ytpVideoID;
1185
+ var playlist = this.getAttribute("data-amplitude-playlist");
1186
+ var playerID = playlist + '_large';
1187
+ var songIndex = parseInt(j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex);
1188
+ var songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
1189
+ var ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
1190
+
1191
+ // var songs = j1.adapter.amplitude['data']['ytPlayers'][playerID].songs
1192
+ // var ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][playerID].player;
1193
+
1194
+ if (songIndex < songs.length) {
1195
+ // set song on next item
1196
+ songIndex++;
1197
+ j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1198
+ }
1199
+ // else {
1200
+ // songIndex--;
1201
+ // }
1202
+
1203
+ // set song on next item
1204
+ // songIndex++;
1205
+
1206
+ // save YT player data for later use (e.g. events)
1207
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerSongs'] = songs;
1208
+
1209
+ // collect (next) song data
1210
+ if (songIndex < songs.length) {
1211
+ songMetaData = songs[songIndex];
1212
+ //songIndex = songMetaData.index;
1213
+ songURL = songMetaData.url;
1214
+ //ytpSongIndex = songMetaData.index;
1215
+ ytpVideoID = songURL.split('=')[1];
1216
+ } else {
1217
+ songIndex = 0;
1218
+ j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1219
+ songMetaData = songs[songIndex];
1220
+ songURL = songMetaData.url;
1221
+ // ytpSongIndex = songIndex;
1222
+ ytpVideoID = songURL.split('=')[1];
1223
+ }
1224
+
1225
+ // save YT player data for later use (e.g. events)
1226
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
1227
+
1228
+ // pause song (video) if FIRST item reached
1229
+ // TODO: handle on player|shuffle different (do play)
1230
+ if (songMetaData.index === 0) {
1231
+ ytpSongIndex = 0;
1232
+
1233
+ // continue (paused) on FIRST video
1234
+ if (ytPlayer !== undefined) {
1235
+ ytPlayer.loadVideoById(ytpVideoID);
1236
+
1237
+ // wait some time to make sure video is loaded|active
1238
+ setTimeout(() => {
1239
+ ytPlayer.pauseVideo();
1240
+ // reset|update time settings
1241
+ resetCurrentTimeContainerYTP();
1242
+ updateDurationTimeContainerYTP(ytPlayer);
1243
+ resetProgressBarYTP(playerID);
1244
+
1245
+ // update AJS play_pause button
1246
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1247
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1248
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1249
+ }, 300);
1250
+ }
1251
+ } else {
1252
+ // load NEXT video if available
1253
+ if (ytPlayer !== undefined) {
1254
+ ytPlayer.loadVideoById(ytpVideoID);
1255
+
1256
+ // update AJS play_pause button (set playing)
1257
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1258
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1259
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1260
+ } else {
1261
+ // update AJS play_pause button (set paused)
1262
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1263
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1264
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1265
+ }
1266
+ }
1267
+
1268
+ // reset|update current time settings
1269
+ resetCurrentTimeContainerYTP();
1270
+ updateDurationTimeContainerYTP(ytPlayer);
1271
+
1272
+ // load new cover image
1273
+ var coverImage = document.querySelector(".cover-image");
1274
+ coverImage.src = songMetaData.cover_art_url;
1275
+
1276
+ // replace new song name (meta-container)
1277
+ var songName = document.getElementsByClassName("song-name");
1278
+ songName[0].innerHTML = songMetaData.name; // player-bottom
1279
+ songName[1].innerHTML = songMetaData.name; // playlist-screen
1280
+
1281
+ // replace song rating (playlist-screen|meta-container)
1282
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
1283
+ if (largetPlayerSongAudioRating.length) {
1284
+ if (songMetaData.rating) {
1285
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
1286
+ } else {
1287
+ largetPlayerSongAudioRating[0].innerHTML = '';
1288
+ }
1289
+ } // END if largetPlayerSongAudioRating
1290
+
1291
+ // replace artist name in meta-containers for next video
1292
+ var artistName = document.getElementsByClassName("artist");
1293
+ artistName[0].innerHTML = songMetaData.artist;
1294
+
1295
+ // replace album name in meta-containers for next video
1296
+ var albumName = document.getElementsByClassName("album");
1297
+ albumName[0].innerHTML = songMetaData.album;
1298
+
1299
+ // update AJS play_pause button
1300
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1301
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1302
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1303
+
1304
+ if (songIndex < songs.length) {
1305
+ // set song active in playlist
1306
+ setSongPlayed(songIndex);
1307
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1308
+ }
1309
+
1310
+ // deactivate AJS events (if any)
1311
+ event.stopImmediatePropagation();
1312
+ }); // END EventListener 'click' next button
1313
+ } // END if
1314
+ } // END for largePlayerNextButton
1315
+
1316
+ // click on (player) previous button
1317
+ // TODO: Fix for multiple players in page
1318
+ // -----------------------------------------------------------------------
1319
+
1320
+ // Overload AJS largePlayerPrevious button for YT
1321
+ //
1322
+ var largePlayePreviousButton = document.getElementsByClassName("large-player-previous");
1323
+ for (var i=0; i<largePlayePreviousButton.length; i++) {
1324
+ var classArray = [].slice.call(largePlayerNextButton[i].classList, 0);
1325
+ var classString = classArray.toString();
1326
+
1327
+ if (classString.includes(ytPlayerID)) {
1328
+ largePlayePreviousButton[i].addEventListener('click', function(event) {
1329
+ var ytpVideoID;
1330
+ var playlist = this.getAttribute("data-amplitude-playlist");
1331
+ var songIndex = parseInt(ytpSongIndex);
1332
+ var songs = j1.adapter.amplitude.data.ytPlayers.ytPlayerID.songs;
1333
+ var ytPlayer = j1.adapter.amplitude.data.ytPlayers.ytPlayerID.player;
1334
+
1335
+ // var songs = Amplitude.getSongsInPlaylist(playlist);
1336
+ // var ytPlayer = j1.adapter.amplitude.data.ytpGlobals['ytPlayer'];
1337
+
1338
+ // set song on previous item
1339
+ songIndex--;
1340
+
1341
+ // save YT player data for later use (e.g. events)
1342
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerSongs'] = songs;
1343
+
1344
+ // collect (next) song data
1345
+ if (songIndex > 0 && songIndex < songs.length) {
1346
+ songMetaData = songs[songIndex];
1347
+ songIndex = songMetaData.index;
1348
+ songURL = songMetaData.url;
1349
+ ytpSongIndex = songMetaData.index;
1350
+ ytpVideoID = songURL.split('=')[1];
1351
+ } else {
1352
+ songIndex = 0;
1353
+ songMetaData = songs[songIndex];
1354
+ songURL = songMetaData.url;
1355
+ ytpSongIndex = songIndex;
1356
+ ytpVideoID = songURL.split('=')[1];
1357
+ }
1358
+
1359
+ // save YT player data for later use (e.g. events)
1360
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
1361
+
1362
+ // pause song (video) if FIRST item reached
1363
+ // TODO: handle on player|shuffle different (do play)
1364
+ if (songMetaData.index === 0) {
1365
+ ytpSongIndex = 0;
1366
+
1367
+ // continue (paused) on FIRST video
1368
+ if (ytPlayer !== undefined) {
1369
+ ytPlayer.loadVideoById(ytpVideoID);
1370
+
1371
+ // wait some time to make sure video is loaded|active
1372
+ setTimeout(() => {
1373
+ ytPlayer.pauseVideo();
1374
+ // reset|update time settings
1375
+ resetCurrentTimeContainerYTP();
1376
+ updateDurationTimeContainerYTP(ytPlayer);
1377
+ resetProgressBarYTP(playerID);
1378
+
1379
+ // update AJS play_pause button
1380
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1381
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1382
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1383
+ }, 300);
1384
+ }
1385
+ } else {
1386
+ // load NEXT video if available
1387
+ if (ytPlayer !== undefined) {
1388
+ ytPlayer.loadVideoById(ytpVideoID);
1389
+
1390
+ // update AJS play_pause button (set playing)
1391
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1392
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1393
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1394
+ } else {
1395
+ // update AJS play_pause button (set paused)
1396
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1397
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1398
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1399
+ }
1400
+ }
1401
+
1402
+ // reset|update current time settings
1403
+ resetCurrentTimeContainerYTP();
1404
+ updateDurationTimeContainerYTP(ytPlayer);
1405
+
1406
+ // replace new song name (meta-container)
1407
+ var songName = document.getElementsByClassName("song-name");
1408
+ songName[0].innerHTML = songMetaData.name; // player-bottom
1409
+ songName[1].innerHTML = songMetaData.name; // playlist-screen
1410
+
1411
+ // load new cover image
1412
+ var coverImage = document.querySelector(".cover-image");
1413
+ coverImage.src = songMetaData.cover_art_url;
1414
+
1415
+ // replace song rating (playlist-screen|meta-container)
1416
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
1417
+ if (largetPlayerSongAudioRating.length) {
1418
+ if (songMetaData.rating) {
1419
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
1420
+ } else {
1421
+ largetPlayerSongAudioRating[0].innerHTML = '';
1422
+ }
1423
+ } // END if largetPlayerSongAudioRating
1424
+
1425
+ // replace artist name in meta-containers for next video
1426
+ var artistName = document.getElementsByClassName("artist");
1427
+ artistName[0].innerHTML = songMetaData.artist;
1428
+
1429
+ // replace album name in meta-containers for next video
1430
+ var albumName = document.getElementsByClassName("album");
1431
+ albumName[0].innerHTML = songMetaData.album;
1432
+
1433
+ // update AJS play_pause button
1434
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1435
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1436
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1437
+
1438
+ // on LAST item, don't activate item in playlist
1439
+ if (songIndex !== songs.length - 1) {
1440
+ // set song active in playlist
1441
+ setSongPlayed(songIndex);
1442
+ }
1443
+
1444
+ // set song active in playlist
1445
+ // setSongPlayed(songIndex);
1446
+
1447
+ // deactivate AJS events (if any)
1448
+ event.stopImmediatePropagation();
1449
+ }); // END EventListener 'click' previous button
1450
+ } // END if
1451
+ } // END for
1452
+
1453
+ // click on song container
1454
+ // TODO: Fix for multiple players in page
1455
+ // ---------------------------------------------------------------------
1456
+ var largetPlayerSongContainer = document.getElementsByClassName("amplitude-song-container");
1457
+ for (var i=0; i<largetPlayerSongContainer.length; i++) {
1458
+ largetPlayerSongContainer[i].addEventListener('click', function(event) {
1459
+ var ytpVideoID;
1460
+ var activeSongIndex;
1461
+ var success;
1462
+
1463
+ var playlist = this.getAttribute("data-amplitude-playlist");
1464
+ var playerID = playlist + '_large';
1465
+ var ytpSongIndex = parseInt(this.getAttribute("data-amplitude-song-index"));
1466
+ var songs = j1.adapter.amplitude.data.ytPlayers[ytPlayerID].songs;
1467
+
1468
+ // get active song index if video (song) is playing
1469
+ activeSongIndex = getSongPlayed();
1470
+
1471
+ if (activeSongIndex >= 0) {
1472
+ success = ytpSetActiveIndex(playerID, activeSongIndex);
1473
+ } else {
1474
+ success = ytpSetActiveIndex(playerID, ytpSongIndex);
1475
+ }
1476
+
1477
+ // save YT player data for later use (e.g. events)
1478
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerSongs'] = songs;
1479
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
1480
+
1481
+ var playerState = ytPlayer.getPlayerState();
1482
+ if (playerState === YT_PLAYER_STATE.PLAYING && ytpSongIndex === activeSongIndex) {
1483
+ // do NOT interupt current video (song) is playing
1484
+ return;
1485
+ } else {
1486
+ // set (current) song data
1487
+ songMetaData = songs[ytpSongIndex];
1488
+ songIndex = songMetaData.index;
1489
+ songURL = songMetaData.url;
1490
+ ytpSongIndex = songIndex;
1491
+ ytpVideoID = songURL.split('=')[1];
1492
+ // load new video
1493
+ ytPlayer.loadVideoById(ytpVideoID);
1494
+ }
1495
+
1496
+ // reset|update current time settings
1497
+ resetCurrentTimeContainerYTP();
1498
+ updateDurationTimeContainerYTP(ytPlayer);
1499
+
1500
+ // load new cover image
1501
+ var coverImage = document.querySelector(".cover-image");
1502
+ coverImage.src = songMetaData.cover_art_url;
1503
+
1504
+ // replace new song name (meta-container)
1505
+ var songName = document.getElementsByClassName("song-name");
1506
+ songName[0].innerHTML = songMetaData.name; // player-bottom
1507
+ songName[1].innerHTML = songMetaData.name; // playlist-screen
1508
+
1509
+ // replace song info URL (playlist-screen|meta-container)
1510
+ var largetPlayerSongInfoLink = document.getElementsByClassName("audio-info-link");
1511
+ if (largetPlayerSongInfoLink.length) {
1512
+ if (songMetaData.audio_info) {
1513
+ largetPlayerSongInfoLink[0].href = songMetaData.audio_info;
1514
+ } else {
1515
+ largetPlayerSongInfoLink[0].href = songURL;
1516
+ }
1517
+ } // END if largetPlayerSongInfoLink
1518
+
1519
+ // replace song rating (playlist-screen|meta-container)
1520
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
1521
+ if (largetPlayerSongAudioRating.length) {
1522
+ if (songMetaData.rating) {
1523
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
1524
+ } else {
1525
+ largetPlayerSongAudioRating[0].innerHTML = '';
1526
+ }
1527
+ } // END if largetPlayerSongAudioRating
1528
+
1529
+ // update AJS play_pause button
1530
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1531
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1532
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1533
+
1534
+ // set song active in playlist
1535
+ setSongPlayed(songIndex);
1536
+
1537
+ // deactivate AJS events (if any)
1538
+ event.stopImmediatePropagation();
1539
+ }); // END EventListener 'click' SongContainer
1540
+ } // END for
1541
+
1542
+ // add listeners to all progress bars found
1543
+ // TODO: Fix for multiple players in page
1544
+ // ---------------------------------------------------------------------
1545
+ var progressBars = document.getElementsByClassName("large-player-progress");
1546
+ if (progressBars.length) {
1547
+ for (var i=0; i<progressBars.length; i++) {
1548
+ var progressBar = progressBars[i];
1549
+ // var id = bar.id.split('large-player-progress_')[0];
1550
+ // var progressId = progressBars[i].id.split('large-player-progress_')[0];
1551
+ var progressId = progressBars[i].id;
1552
+ var playerId = progressId.split('large_player_progress_')[1];
1553
+
1554
+ // save YT player data for later use (e.g. events)
1555
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerProgressBar'] = progressBars[i];
1556
+ // j1.adapter.amplitude.data.ytPlayers[playerId].progressBar = progressId;
1557
+ j1.adapter.amplitude.data.ytPlayers[playerId].progressBar = progressBar;
1558
+
1559
+ progressBars[i].addEventListener('click', function(event) {
1560
+ // if (ytPlayer.getPlayerState() === YT_PLAYER_STATE.PLAYING) {
1561
+ if (ytPlayer !== undefined) {
1562
+ var progressBar, percentage, time;
1563
+ progressBar = this;
1564
+ percentage = getProgressBarSelectedPositionPercentage(event, progressBar);
1565
+ time = getTimeFromPercentage(ytPlayer, percentage);
1566
+
1567
+ // seek video to current time
1568
+ ytpSeekTo(ytPlayer, time);
1569
+
1570
+ // set current progess value if valid
1571
+ if (isFinite(percentage)) {
1572
+ progressBar.value = percentage;
1573
+ }
1574
+ } // END if ytPlayer
1575
+
1576
+ // deactivate AJS events (if any)
1577
+ event.stopImmediatePropagation();
1578
+ }); // END EventListener 'click'
1579
+ } // END for
1580
+ } // END if progressBars
1581
+
1582
+ } // END if playerType large'
1583
+ }
1584
+ } // END mimikYTPlayerUiEventsForAJS
1585
+
1586
+ {%- endcapture -%}
1587
+
1588
+ {%- if production -%}
1589
+ {{ cache|minifyJS }}
1590
+ {%- else -%}
1591
+ {{ cache|strip_empty_lines }}
1592
+ {%- endif -%}
1593
+
1594
+ {%- assign cache = false -%}