j1-template 2024.3.21 → 2024.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/assets/data/amplitude_app.html +60 -51
  3. data/assets/theme/j1/adapter/js/advertising.js +40 -38
  4. data/assets/theme/j1/adapter/js/algolia.js +13 -11
  5. data/assets/theme/j1/adapter/js/amplitude.js +504 -348
  6. data/assets/theme/j1/adapter/js/analytics.js +19 -17
  7. data/assets/theme/j1/adapter/js/asciidoctor.js +10 -8
  8. data/assets/theme/j1/adapter/js/attic.js +24 -22
  9. data/assets/theme/j1/adapter/js/bmd.js +10 -8
  10. data/assets/theme/j1/adapter/js/carousel.js +12 -9
  11. data/assets/theme/j1/adapter/js/chatbot.js +106 -104
  12. data/assets/theme/j1/adapter/js/clipboard.js +16 -14
  13. data/assets/theme/j1/adapter/js/comments.js +24 -22
  14. data/assets/theme/j1/adapter/js/cookieConsent.js +5 -1
  15. data/assets/theme/j1/adapter/js/customFunctions.js +12 -10
  16. data/assets/theme/j1/adapter/js/customModule.js +10 -8
  17. data/assets/theme/j1/adapter/js/docsearch.js +33 -31
  18. data/assets/theme/j1/adapter/js/dropdowns.js +16 -14
  19. data/assets/theme/j1/adapter/js/fab.js +34 -32
  20. data/assets/theme/j1/adapter/js/gallery.js +21 -19
  21. data/assets/theme/j1/adapter/js/gemini.js +66 -64
  22. data/assets/theme/j1/adapter/js/iconPicker.js +31 -29
  23. data/assets/theme/j1/adapter/js/iconPickerPage.js +11 -9
  24. data/assets/theme/j1/adapter/js/iframer.js +17 -15
  25. data/assets/theme/j1/adapter/js/j1.js +146 -143
  26. data/assets/theme/j1/adapter/js/lazyLoader.js +33 -31
  27. data/assets/theme/j1/adapter/js/lightbox.js +9 -7
  28. data/assets/theme/j1/adapter/js/logger.js +11 -9
  29. data/assets/theme/j1/adapter/js/lunr.js +37 -35
  30. data/assets/theme/j1/adapter/js/masonry.js +23 -21
  31. data/assets/theme/j1/adapter/js/masterslider.js +31 -29
  32. data/assets/theme/j1/adapter/js/mmenu.js +25 -23
  33. data/assets/theme/j1/adapter/js/navigator.js +43 -41
  34. data/assets/theme/j1/adapter/js/particles.js +12 -10
  35. data/assets/theme/j1/adapter/js/rangeSlider.js +21 -19
  36. data/assets/theme/j1/adapter/js/rouge.js +10 -8
  37. data/assets/theme/j1/adapter/js/rtable.js +14 -12
  38. data/assets/theme/j1/adapter/js/rtextResizer.js +10 -8
  39. data/assets/theme/j1/adapter/js/scroller.js +15 -13
  40. data/assets/theme/j1/adapter/js/slick.js +18 -16
  41. data/assets/theme/j1/adapter/js/slimSelect.js +30 -28
  42. data/assets/theme/j1/adapter/js/speak2me.js +25 -23
  43. data/assets/theme/j1/adapter/js/swiper.js +13 -11
  44. data/assets/theme/j1/adapter/js/themeToggler.js +11 -9
  45. data/assets/theme/j1/adapter/js/themes.js +25 -23
  46. data/assets/theme/j1/adapter/js/toccer.js +13 -11
  47. data/assets/theme/j1/adapter/js/translator.js +19 -16
  48. data/assets/theme/j1/adapter/js/videojs.js +9 -7
  49. data/assets/theme/j1/adapter/js/waves.js +18 -16
  50. data/assets/theme/j1/core/js/template.js +11180 -10968
  51. data/assets/theme/j1/core/js/template.min.js +13 -18
  52. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.css +10 -4
  53. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.min.css +1 -1
  54. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.css +15 -8
  55. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.min.css +2 -1
  56. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.css +35 -14
  57. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.min.css +1 -1
  58. data/assets/theme/j1/modules/amplitudejs/js/tech/ytp.js +475 -423
  59. data/assets/theme/j1/modules/backstretch/js/backstretch.js +2 -2
  60. data/assets/theme/j1/modules/backstretch/js/backstretch.min.js +1 -1
  61. data/assets/theme/j1/modules/cookieConsent/js/cookieConsent.js +11 -11
  62. data/assets/theme/j1/modules/cookieConsent/js/cookieConsent.min.js +2 -1
  63. data/assets/theme/j1/modules/dropdowns/js/dropdowns.js +2 -2
  64. data/assets/theme/j1/modules/dropdowns/js/dropdowns.min.js +1 -1
  65. data/assets/theme/j1/modules/fab/js/fab.js +2 -2
  66. data/assets/theme/j1/modules/fab/js/fab.min.js +1 -1
  67. data/assets/theme/j1/modules/lunr/js/j1.js +1 -1
  68. data/assets/theme/j1/modules/lunr/js/j1.min.js +2 -1
  69. data/assets/theme/j1/modules/rtable/js/rtable.js +2 -2
  70. data/assets/theme/j1/modules/rtable/js/rtable.min.js +2 -1
  71. data/assets/theme/j1/modules/scroller/js/scroller.js +31 -29
  72. data/assets/theme/j1/modules/scroller/js/scroller.min.js +2 -1
  73. data/assets/theme/j1/modules/themeSwitcher/js/switcher.js +26 -26
  74. data/assets/theme/j1/modules/themeSwitcher/js/switcher.min.js +2 -1
  75. data/assets/theme/j1/modules/translator/js/translator.js +17 -17
  76. data/assets/theme/j1/modules/translator/js/translator.min.js +1 -1
  77. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/dailymotion.js +10 -8
  78. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/dailymotion.min.js +1 -1
  79. data/assets/theme/j1/modules/videojs/js/plugins/players/vm/vimeo.js +9 -7
  80. data/assets/theme/j1/modules/videojs/js/plugins/players/vm/vimeo.min.js +1 -1
  81. data/assets/theme/j1/modules/videojs/js/plugins/players/wt/wistia.js +13 -11
  82. data/assets/theme/j1/modules/videojs/js/plugins/players/wt/wistia.min.js +1 -1
  83. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/youtube.js +10 -8
  84. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/youtube.min.js +1 -1
  85. data/lib/j1/version.rb +1 -1
  86. data/lib/starter_web/README.md +5 -5
  87. data/lib/starter_web/_config.yml +1 -1
  88. data/lib/starter_web/_data/modules/amplitude_playlists.yml +124 -79
  89. data/lib/starter_web/_data/modules/defaults/amplitude.yml +5 -3
  90. data/lib/starter_web/_data/templates/feed.xml +1 -1
  91. data/lib/starter_web/_plugins/asciidoctor/videojs-block.rb +8 -0
  92. data/lib/starter_web/_plugins/asciidoctor/youtube-block.rb +7 -0
  93. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  94. data/lib/starter_web/assets/audio/album/emancipator/Alligator.mp3 +0 -0
  95. data/lib/starter_web/assets/audio/album/emancipator/DabCity.mp3 +0 -0
  96. data/lib/starter_web/assets/audio/album/emancipator/SeaToSky.mp3 +0 -0
  97. data/lib/starter_web/assets/audio/album/emancipator/TimeForSpace.mp3 +0 -0
  98. data/lib/starter_web/assets/audio/cover/emancipator/alligator.jpg +0 -0
  99. data/lib/starter_web/assets/audio/cover/emancipator/anthem.jpg +0 -0
  100. data/lib/starter_web/assets/audio/cover/emancipator/dab-city.jpg +0 -0
  101. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn.jpg +0 -0
  102. data/lib/starter_web/assets/audio/cover/emancipator/safe-in-the-steep-cliffs.jpg +0 -0
  103. data/lib/starter_web/assets/audio/cover/emancipator/sea-to-sky.jpg +0 -0
  104. data/lib/starter_web/assets/audio/cover/emancipator/soon-it-will-be-cold-enough.jpg +0 -0
  105. data/lib/starter_web/assets/audio/cover/emancipator/tine-for-space.jpg +0 -0
  106. data/lib/starter_web/package.json +1 -1
  107. data/lib/starter_web/pages/public/tour/audio_data.adoc +11 -6
  108. metadata +19 -11
  109. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/anthem.jpg +0 -0
  110. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/from-dusk-to-dawn.jpg +0 -0
  111. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/safe-in-the-steep-cliffs.jpg +0 -0
  112. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/soon-it-will-be-cold-enough.jpg +0 -0
  113. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn → !info}/!sound.links.txt +0 -0
  114. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/Anthem.mp3 → Anthem.mp3} +0 -0
  115. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/DuskToDawn.mp3 → DuskToDawn.mp3} +0 -0
  116. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/FirstSnow.mp3 → FirstSnow.mp3} +0 -0
  117. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/SafeInTheSteepCliffs.mp3 → SafeInTheSteepCliffs.mp3} +0 -0
@@ -6,7 +6,7 @@ regenerate: true
6
6
 
7
7
  {% comment %}
8
8
  # -----------------------------------------------------------------------------
9
- # ~/assets/theme/j1/adapter/js/amplitude.40.js
9
+ # ~/assets/theme/j1/adapter/js/amplitude.41.js
10
10
  # Liquid template to adapt J1 AmplitudeJS Apps
11
11
  #
12
12
  # Product/Info:
@@ -63,7 +63,7 @@ regenerate: true
63
63
 
64
64
  /*
65
65
  # -----------------------------------------------------------------------------
66
- # ~/assets/theme/j1/adapter/js/amplitude.40.js
66
+ # ~/assets/theme/j1/adapter/js/amplitude.41.js
67
67
  # J1 Adapter for the amplitude module
68
68
  #
69
69
  # Product/Info:
@@ -87,34 +87,39 @@ regenerate: true
87
87
 
88
88
  j1.adapter.amplitude = ((j1, window) => {
89
89
 
90
- // global settings
90
+ const isDev = (j1.env === "development" || j1.env === "dev") ? true : false;
91
+
92
+ // Adapter GLOBAL settings
91
93
  // ---------------------------------------------------------------------------
92
94
  var environment = '{{environment}}';
93
95
  var cookie_names = j1.getCookieNames();
94
96
  var user_state = j1.readCookie(cookie_names.user_state);
95
97
  var state = 'not_started';
96
98
 
97
- // module settings
98
99
  // ---------------------------------------------------------------------------
99
-
100
100
  // control|logging
101
- // ---------------------------------------------------------------------------
101
+ // ------------------------------------
102
+ var consoleFilterSettings = {};
102
103
  var _this;
103
104
  var logger;
104
105
  var logText;
105
106
  var toJSON;
106
107
  var toText;
107
108
 
109
+ // --------------------------------------------------------------------------
108
110
  // date|time monitoring
109
- //----------------------------------------------------------------------------
111
+ // ------------------------------------
110
112
  var startTime;
111
113
  var endTime;
112
114
  var startTimeModule;
113
115
  var endTimeModule;
114
116
  var timeSeconds;
115
117
 
116
- // AmplitudeJS API settings
117
- // ---------------------------------------------------------------------------
118
+ // --------------------------------------------------------------------------
119
+ // AmplitudeJS GLOBAL settings
120
+ // ----------------------------------
121
+ const requiredForATP = false;
122
+
118
123
  const AT_PLAYER_STATE = {
119
124
  ENDED: 0,
120
125
  PLAYING: 1,
@@ -135,12 +140,16 @@ j1.adapter.amplitude = ((j1, window) => {
135
140
  6: "changed",
136
141
  };
137
142
 
138
- var playLists = {};
139
- var playersUILoaded = { state: false };
140
- var apiInitialized = { state: false };
141
-
142
- var isFadingIn = false;
143
- var isFadingOut = false;
143
+ var playLists = {};
144
+ var playersUILoaded = { state: false };
145
+ var apiInitialized = { state: false };
146
+ var playerCounter = 0;
147
+ var load_dependencies = {};
148
+ var playersProcessed = [];
149
+ var playersHtmlLoaded = false;
150
+ var processingPlayersFinished = false;
151
+ var isFadingIn = false;
152
+ var isFadingOut = false;
144
153
 
145
154
  var amplitudePlayerState;
146
155
  var amplitudeDefaults;
@@ -156,42 +165,49 @@ j1.adapter.amplitude = ((j1, window) => {
156
165
  var pluginManagerEnabled;
157
166
  var playerExistsInPage;
158
167
 
159
- // AmplitudeJS Player DEFAULT settings
168
+
169
+ // AmplitudeJS DEFAULT settings
160
170
  // ---------------------------------------------------------------------------
161
- var playerCounter = 0;
162
- var load_dependencies = {};
163
- var playersProcessed = [];
164
- var playersHtmlLoaded = false;
165
- var processingPlayersFinished = false;
166
171
 
167
- var playerAudioInfo = ('{{amplitude_defaults.playlist.audio_info}}' === 'true') ? true : false;
168
- var playerDefaultPluginManager = ('{{amplitude_defaults.player.plugin_manager.enabled}}' === 'true') ? true : false;
172
+ // PLAYER settings
173
+ // ------------------------------------
174
+ var playerDefaultPluginManager = {{amplitude_defaults.player.plugin_manager.enabled}};
169
175
  var playerDefaultType = '{{amplitude_defaults.player.type}}';
170
176
  var playerDefaultVolume = {{amplitude_defaults.player.volume_slider.preset_value}};
171
177
  var playerVolumeSliderStep = {{amplitude_defaults.player.volume_slider.slider_step}};
172
- var playerRepeat = ('{{amplitude_defaults.player.player_repeat}}' === 'true') ? true : false;
173
- var playerShuffle = ('{{amplitude_defaults.player.player_shuffle}}' === 'true') ? true : false;
174
- var playerPlayNextTitle = ('{{amplitude_defaults.player.play_next_title}}' === 'true') ? true : false;
175
- var playerPauseNextTitle = ('{{amplitude_defaults.player.pause_next_title}}' === 'true') ? true : false;
178
+ var playerRepeat = {{amplitude_defaults.player.player_repeat}};
179
+ var playerShuffle = {{amplitude_defaults.player.player_shuffle}};
180
+ var playerPlayNextTitle = {{amplitude_defaults.player.play_next_title}};
181
+ var playerPauseNextTitle = {{amplitude_defaults.player.pause_next_title}};
176
182
  var playerDelayNextTitle = {{amplitude_defaults.player.delay_next_title}};
177
183
  var playerForwardBackwardSkipSeconds = {{amplitude_defaults.player.forward_backward_skip_seconds}};
184
+ var playerHoverPageScrollDisabled = {{amplitude_defaults.player.player_hover_page_scroll_disabled}};
178
185
 
179
- var playerSongElementHeigthMobile = {{amplitude_defaults.player.song_element_heigth_mobile}};
180
- var playerSongElementHeigthDesktop = {{amplitude_defaults.player.song_element_heigt_desktop}};
186
+ var playerSongElementHeigthMobile = {{amplitude_defaults.player.player_song_element_heigth_mobile}};
187
+ var playerSongElementHeigthDesktop = {{amplitude_defaults.player.player_song_element_heigt_desktop}};
181
188
  var playerScrollerSongElementMin = {{amplitude_defaults.player.player_scroller_song_element_min}};
182
189
  var playerScrollControl = {{amplitude_defaults.player.player_scroll_control}};
183
190
  var playerAutoScrollSongElement = {{amplitude_defaults.player.player_auto_scroll_song_element}};
184
191
 
185
- // AmplitudeJS settings curently NOT used
186
192
  // ---------------------------------------------------------------------------
187
- var playerWaveformsEnabled = {{amplitude_defaults.player.waveforms.enabled}};
188
- var playerWaveformsSampleRate = {{amplitude_defaults.player.waveforms.sample_rate}};
189
- var playerVisualizationEnabled = {{amplitude_defaults.player.visualization.enabled}};
190
- var playerVisualizationName = '{{amplitude_defaults.player.visualization.name}}';
193
+ // PLAYLIST settings
194
+ // ------------------------------------
195
+ var playlistAudioInfo = {{amplitude_defaults.playlist.audio_info}};
196
+
197
+ // ---------------------------------------------------------------------------
198
+ // UNUSED settings
199
+ // ------------------------------------
200
+ var playerWaveformsEnabled = {{amplitude_defaults.player.waveforms.enabled}};
201
+ var playerWaveformsSampleRate = {{amplitude_defaults.player.waveforms.sample_rate}};
202
+ var playerVisualizationEnabled = {{amplitude_defaults.player.visualization.enabled}};
203
+ var playerVisualizationName = '{{amplitude_defaults.player.visualization.name}}';
191
204
 
192
205
  // ---------------------------------------------------------------------------
193
206
  // helper functions
194
207
  // ---------------------------------------------------------------------------
208
+ function forceJsError() {
209
+ throw new Error("GENERATED JavaScript error!");
210
+ }
195
211
 
196
212
  // ---------------------------------------------------------------------------
197
213
  // main
@@ -203,6 +219,20 @@ j1.adapter.amplitude = ((j1, window) => {
203
219
  // -------------------------------------------------------------------------
204
220
  init: (options) => {
205
221
 
222
+ // -----------------------------------------------------------------------
223
+ // set console log filters (early)
224
+ // -----------------------------------------------------------------------
225
+ // consoleFilterSettings = {
226
+ // debug: false,
227
+ // };
228
+ // j1.api.consoleFilters.filter(consoleFilterSettings);
229
+ j1.api.consoleFilters.filter();
230
+
231
+ // -----------------------------------------------------------------------
232
+ // set error log filters (JS early)
233
+ // -----------------------------------------------------------------------
234
+ // j1.api.errorFilters.filter();
235
+
206
236
  // -----------------------------------------------------------------------
207
237
  // default module settings
208
238
  // -----------------------------------------------------------------------
@@ -256,13 +286,19 @@ j1.adapter.amplitude = ((j1, window) => {
256
286
  startTimeModule = Date.now();
257
287
 
258
288
  _this.setState('started');
259
- logger.debug('\n' + 'module state: ' + _this.getState());
260
- logger.info('\n' + 'module is being initialized');
289
+ logger.debug('module state: ' + _this.getState());
290
+ logger.info('module is being initialized');
261
291
 
262
- // window.addEventListener('resize',(e)=>{
263
- // console.log( `resize: width: ${e.target.visualViewport.width}px`);
264
- // console.log( `resize: height: ${e.target.visualViewport.height}px`);
265
- // });
292
+ // test data for console filters
293
+ // -------------------------------------------------------------------
294
+ // console.warn("consoleFilters: Diese WARNUNG wird gefiltert.");
295
+ // isDev && logger.warn("consoleFilters: Diese WARNUNG wird gefiltert.");
296
+ // console.warn("consoleFilters: Diese Meldung wird nicht gefiltert.");
297
+ // isDev && logger.warn("consoleFilters: Diese Meldung wird nicht gefiltert.");
298
+
299
+ // test data for error filters
300
+ // -------------------------------------------------------------------
301
+ // forceJsError();
266
302
 
267
303
  // -------------------------------------------------------------------
268
304
  // create global playlist (songs)
@@ -327,7 +363,7 @@ j1.adapter.amplitude = ((j1, window) => {
327
363
  // -------------------------------------------------------------------------
328
364
  songLoader: (songs) => {
329
365
 
330
- logger.info('\n' + 'creating global playlist (API): started');
366
+ logger.info('creating global playlist (API): started');
331
367
 
332
368
  // -----------------------------------------------------------------------
333
369
  // initialize amplitude songs
@@ -363,12 +399,21 @@ j1.adapter.amplitude = ((j1, window) => {
363
399
  continue;
364
400
  } else if (key === 'rating') {
365
401
  song.rating = item[key];
366
- continue;
367
- } else if (key === 'audio_single') {
368
- song.audio_single = item[key];
369
- continue;
402
+ continue;
403
+ } else if (key === 'playlist') {
404
+ song.playlist = item[key];
405
+ continue;
370
406
  } else if (key === 'shuffle') {
371
- song.shuffle = item[key];
407
+ song.shuffle = ((!!item[key]) === false) ? playerShuffle : item[key];
408
+ continue;
409
+ } else if (key === 'repeat') {
410
+ song.repeat = ((!!item[key]) === false) ? playerRepeat : item[key];
411
+ continue;
412
+ } else if (key === 'start') {
413
+ song.start = ((!!item[key]) === false) ? '00:00:00' : item[key];
414
+ continue;
415
+ } else if (key === 'end') {
416
+ song.end = ((!!item[key]) === false) ? '00:00:00' : item[key];
372
417
  continue;
373
418
  } else {
374
419
  song[key] = item[key];
@@ -381,7 +426,7 @@ j1.adapter.amplitude = ((j1, window) => {
381
426
 
382
427
  {% endif %} {% endfor %}
383
428
 
384
- logger.info('\n' + 'creating global playlist (API): finished');
429
+ logger.info('creating global playlist (API): finished');
385
430
  }, // END songLoader
386
431
 
387
432
  // -------------------------------------------------------------------------
@@ -393,7 +438,7 @@ j1.adapter.amplitude = ((j1, window) => {
393
438
  // -----------------------------------------------------------------------
394
439
  // initialize HTML portion (UI) for all players configured|enabled
395
440
  // -----------------------------------------------------------------------
396
- logger.info('\n' + 'loading player HTML components (UI): started');
441
+ logger.info('loading player HTML components (UI): started');
397
442
 
398
443
  {% for player in amplitude_options.players %} {% if player.enabled %}
399
444
  {% assign xhr_data_path = amplitude_options.xhr_data_path %}
@@ -404,7 +449,7 @@ j1.adapter.amplitude = ((j1, window) => {
404
449
  playerExistsInPage = ($('#' + '{{xhr_container_id}}')[0] !== undefined) ? true : false;
405
450
  if (playerExistsInPage) {
406
451
  playerCounter++;
407
- logger.debug('\n' + 'load player UI on ID #{{player.id}}: started');
452
+ logger.debug('load player UI on ID #{{player.id}}: started');
408
453
 
409
454
  j1.loadHTML({
410
455
  xhr_container_id: '{{xhr_container_id}}',
@@ -428,7 +473,7 @@ j1.adapter.amplitude = ((j1, window) => {
428
473
 
429
474
  if (xhrLoadState === 'success') {
430
475
  playersProcessed.push('{{xhr_container_id}}');
431
- logger.debug('\n' + 'load player UI on ID #{{player.id}}: finished');
476
+ logger.debug('load player UI on ID #{{player.id}}: finished');
432
477
 
433
478
  clearInterval(load_dependencies['dependencies_met_html_loaded_{{player.id}}']);
434
479
  }
@@ -444,7 +489,7 @@ j1.adapter.amplitude = ((j1, window) => {
444
489
  }
445
490
 
446
491
  if (processingPlayersFinished) {
447
- logger.info('\n' + 'loading player HTML components (UI): finished');
492
+ logger.info('loading player HTML components (UI): finished');
448
493
 
449
494
  clearInterval(load_dependencies['dependencies_met_players_loaded']);
450
495
  playersLoaded.state = true;
@@ -458,7 +503,7 @@ j1.adapter.amplitude = ((j1, window) => {
458
503
  // -------------------------------------------------------------------------
459
504
  initApi: (songlist) => {
460
505
 
461
- logger.info('\n' + 'initialze API: started');
506
+ logger.info('initialze API: started');
462
507
 
463
508
  {% comment %} collect playlists
464
509
  -------------------------------------------------------------------------- {% endcomment %}
@@ -480,7 +525,6 @@ j1.adapter.amplitude = ((j1, window) => {
480
525
  {% capture song_item %}
481
526
  {
482
527
  "name": "{{item.title}}",
483
- // "track": "{{item.track}}",
484
528
  "artist": "{{item.artist}}",
485
529
  "playlist": "{{item.playlist}}",
486
530
  "album": "{{item.name}}",
@@ -490,8 +534,8 @@ j1.adapter.amplitude = ((j1, window) => {
490
534
  "start": "{{item.start}}",
491
535
  "end": "{{item.end}}",
492
536
  "shuffle": "{{item.shuffle}}",
537
+ "repeat": "{{item.repeat}}",
493
538
  "duration": "{{item.duration}}",
494
- "audio_single": "{{item.audio_single}}",
495
539
  // "audio_fade_in": "{{item.audio_fade_in}}",
496
540
  // "audio_fade_out": "{{item.audio_fade_out}}",
497
541
  "cover_art_url": "{{item.cover_image}}"
@@ -542,14 +586,14 @@ j1.adapter.amplitude = ((j1, window) => {
542
586
  callbacks: {
543
587
  initialized: function() {
544
588
  var amplitudeConfig = Amplitude.getConfig();
545
- logger.info('\n' + 'initialze API: finished');
589
+ logger.info('initialze API: finished');
546
590
  // indicate api successfully initialized
547
591
  apiInitialized.state = true;
548
592
  },
549
593
  onInitError: function() {
550
594
  // indicate api failed on initialization
551
595
  apiInitialized.state = false;
552
- console.error('\n' + 'Amplitude API failed on initialization');
596
+ console.error('Amplitude API failed on initialization');
553
597
  },
554
598
  play: function() {
555
599
  // make sure the player is playing
@@ -585,7 +629,7 @@ j1.adapter.amplitude = ((j1, window) => {
585
629
  var currentState = Amplitude.getPlayerState();
586
630
  onPlayerStateChange(4);
587
631
  if (playerDelayNextTitle) {
588
- logger.debug('\n' + 'delay on previous title: ' + songMetaData.name + ' with titleIndex ' + songMetaData.index);
632
+ logger.debug('delay on previous title: ' + songMetaData.name + ' with titleIndex ' + songMetaData.index);
589
633
  }
590
634
 
591
635
  if (playerPauseNextTitle) {
@@ -593,7 +637,7 @@ j1.adapter.amplitude = ((j1, window) => {
593
637
  if (amplitudePlayerState === 'playing' || amplitudePlayerState === 'stopped' ) {
594
638
  setTimeout(() => {
595
639
  // pause playback of next title
596
- logger.debug('\n' + 'paused on next title: ' + songMetaData.name);
640
+ logger.debug('paused on next title: ' + songMetaData.name);
597
641
  Amplitude.pause();
598
642
  }, 150);
599
643
  } // END if playing
@@ -604,7 +648,7 @@ j1.adapter.amplitude = ((j1, window) => {
604
648
  next: function() {
605
649
  onPlayerStateChange(5);
606
650
  if (playerDelayNextTitle) {
607
- logger.debug('\n' + 'delay on next title: ' + songMetaData.name + ' with titleIndex ' + songMetaData.index);
651
+ logger.debug('delay on next title: ' + songMetaData.name + ' with titleIndex ' + songMetaData.index);
608
652
  }
609
653
 
610
654
  if (playerPauseNextTitle) {
@@ -612,7 +656,7 @@ j1.adapter.amplitude = ((j1, window) => {
612
656
  if (amplitudePlayerState === 'playing' || amplitudePlayerState === 'stopped' ) {
613
657
  setTimeout(() => {
614
658
  // pause playback of next title
615
- logger.debug('\n' + 'paused on next title: ' + songMetaData.name);
659
+ logger.debug('paused on next title: ' + songMetaData.name);
616
660
  Amplitude.pause();
617
661
  }, 150);
618
662
  } // END if playing
@@ -637,58 +681,6 @@ j1.adapter.amplitude = ((j1, window) => {
637
681
 
638
682
  }); // END Amplitude init
639
683
 
640
- // -----------------------------------------------------------------------
641
- // timestamp2seconds
642
- //
643
- // TODO: Add support for timestamp w/o hours like mm:ss
644
- // -----------------------------------------------------------------------
645
- function timestamp2seconds(timestamp) {
646
- // split timestamp
647
- const parts = timestamp.split(':');
648
-
649
- // check timestamp format
650
- if (parts.length !== 3) {
651
- // return "invalid timestamp";
652
- return false;
653
- }
654
-
655
- // convert parts to integers
656
- const hours = parseInt(parts[0], 10);
657
- const minutes = parseInt(parts[1], 10);
658
- const seconds = parseInt(parts[2], 10);
659
-
660
- // check valid timestamp values
661
- if (isNaN(hours) || isNaN(minutes) || isNaN(seconds) ||
662
- hours < 0 || hours > 23 ||
663
- minutes < 0 || minutes > 59 ||
664
- seconds < 0 || seconds > 59) {
665
- return "invalid timestamp";
666
- }
667
-
668
- const totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
669
-
670
- return totalSeconds;
671
- } // END timestamp2seconds
672
-
673
- // -----------------------------------------------------------------------
674
- // seconds2timestamp
675
- // -----------------------------------------------------------------------
676
- function seconds2timestamp(seconds) {
677
-
678
- if (isNaN(seconds)) {
679
- return false;
680
- }
681
-
682
- const hours = Math.floor(seconds / 3600);
683
- const minutes = Math.floor((seconds % 3600) / 60);
684
- const remainSeconds = seconds % 60;
685
- const tsHours = hours.toString().padStart(2, '0');
686
- const tsMinutes = minutes.toString().padStart(2, '0');
687
- const tsSeconds = remainSeconds.toString().padStart(2, '0');
688
-
689
- return `${tsHours}:${tsMinutes}:${tsSeconds}`;
690
- } // END seconds2timestamp
691
-
692
684
  // -----------------------------------------------------------------------
693
685
  // atpFadeInAudio
694
686
  // -----------------------------------------------------------------------
@@ -721,7 +713,7 @@ j1.adapter.amplitude = ((j1, window) => {
721
713
  currentStep = 1;
722
714
 
723
715
  if (volumeSlider === undefined || volumeSlider === null) {
724
- logger.warn('\n' + 'no volume slider found at playerID: ' + settings.playerID);
716
+ isDev && logger.warn('no volume slider found at playerID: ' + settings.playerID);
725
717
  return;
726
718
  }
727
719
 
@@ -798,7 +790,7 @@ j1.adapter.amplitude = ((j1, window) => {
798
790
  songs = Amplitude.getSongsInPlaylist(playlist);
799
791
 
800
792
  if (songIndex === songs.length-1) {
801
- logger.debug('\n' + 'restore player volume on last trackID|volume at: ' + trackID + '|' + defaultVolume);
793
+ logger.debug('restore player volume on last trackID|volume at: ' + trackID + '|' + defaultVolume);
802
794
  volumeSlider.value = defaultVolume;
803
795
  }
804
796
 
@@ -816,131 +808,60 @@ j1.adapter.amplitude = ((j1, window) => {
816
808
  // wrraper for states that are not processed
817
809
  // -----------------------------------------------------------------------
818
810
  function doNothingOnStateChange(state) {
819
- var playlist, songMetaData, songIndex, trackID;
811
+ var playlist, playerID, songMetaData,
812
+ songIndex, trackID;
820
813
 
821
814
  playlist = Amplitude.getActivePlaylist();
815
+ playerID = playlist + '_large';
822
816
  songMetaData = Amplitude.getActiveSongMetadata();
823
817
  songIndex = songMetaData.index;
824
818
  trackID = songIndex + 1;
825
819
 
826
- logger.warn('\n' + `DO NOTHING on StateChange for playlist: ${playlist} at trackID|state: ${trackID}|${AT_PLAYER_STATE_NAMES[state]}`);
820
+ isDev && logger.warn(`DO NOTHING on StateChange for playlist: ${playlist} at trackID|state: ${trackID}|${AT_PLAYER_STATE_NAMES[state]}`);
827
821
 
828
822
  } // END doNothingOnStateChange
829
823
 
830
824
  // -----------------------------------------------------------------------
831
825
  // processOnStateChangePlaying()
832
826
  //
833
- // wrraper to update the ACTIVE player on state PLAYING
827
+ // wrraper to process the ACTIVE player on state PLAYING
834
828
  // -----------------------------------------------------------------------
835
829
  function processOnStateChangePlaying(state) {
836
- var playList, activePlayist, playerID, playerType,
837
- activePlayerType, startVolume, songIndex, trackID,
838
- ratingIndex, rating, ratingElement, songMetaData,
839
- songStartTS, songEndTS, songStartSec, songEndSec,
840
- screenControlRatingElements, screenControlRating;
830
+ var songMetaData, songIndex, playList, trackID;
841
831
 
842
832
  songMetaData = Amplitude.getActiveSongMetadata();
843
833
  songIndex = songMetaData.index;
844
834
  playList = Amplitude.getActivePlaylist();
845
835
  trackID = songIndex + 1;
846
- songStartTS = songMetaData.start;
847
- songEndTS = songMetaData.end;
848
- songStartSec = timestamp2seconds(songStartTS);
849
- songEndSec = timestamp2seconds(songEndTS);
850
- startVolume = Amplitude.getVolume();
851
836
 
852
- logger.debug('\n' + `PLAY audio on processOnStateChangePlaying for playlist \'${playList}\' at trackID|state: ${trackID}|${AT_PLAYER_STATE_NAMES[state]}`);
837
+ logger.debug(`PLAY audio on ATP at playlist|trackID: ${playList}|${trackID}`);
838
+ // logger.debug(`PLAY audio on processOnStateChangePlaying for playlist \'${playList}\' at trackID|state: ${trackID}|${AT_PLAYER_STATE_NAMES[state]}`);
853
839
 
854
- // update song rating in playlist-screen|meta-container
855
- // -------------------------------------------------------------------
856
- j1.adapter.amplitude.atUpdateSongRating(Amplitude.getActiveSongMetadata());
840
+ // save player GLOBAL data for later use (e.g. events)
841
+ j1.adapter.amplitude.data.activePlayer = 'atp';
857
842
 
858
- // scroll active song in players playlist
859
- // ---------------------------------------------------------------------
860
- j1.adapter.amplitude.atPlayerScrollToActiveElement(Amplitude.getActiveSongMetadata());
843
+ // set song (manually) active at index in playlist
844
+ _this.setSongActive(playList, songIndex);
861
845
 
862
846
  // stop active YT players
863
- // -----------------------------------------------
864
- const ytPlayers = Object.keys(j1.adapter.amplitude.data.ytPlayers);
865
- for (let i=0; i<ytPlayers.length; i++) {
866
- const playerID = ytPlayers[i];
867
- const playerProperties = j1.adapter.amplitude.data.ytPlayers[playerID];
868
- logger.debug('\n' + 'process player id: ' + playerID);
869
- var ytpPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
870
- var playerState = ytpPlayer.getPlayerState();
871
- var ytpPlayerState = YT_PLAYER_STATE_NAMES[playerState];
872
-
873
- if (ytpPlayerState === 'playing' || ytpPlayerState === 'paused' || ytpPlayerState === 'buffering') {
874
- logger.debug('\n' + 'process player id: ' + playerID + ' stopped');
875
- ytpPlayer.stopVideo();
876
- }
877
- }
847
+ // ---------------------------------------------------------------------
848
+ _this.atpStopParallelActivePlayers(j1.adapter.amplitude.data.ytPlayers);
878
849
 
879
- // process audio for configured START position
880
- // -------------------------------------------------------------------
881
- var checkIsFading = setInterval (() => {
882
- if (!isFadingIn) {
883
- var currentAudioTime = Amplitude.getSongPlayedSeconds();
884
- if (songStartSec && currentAudioTime <= songStartSec) {
885
- var songDurationSec = timestamp2seconds(songMetaData.duration);
886
-
887
- // seek audio to configured START position
888
- // NOTE: use setSongPlayedPercentage for seeking to NOT
889
- // generation any addition state changes like stopped
890
- // or playing
891
- logger.debug('\n' + 'seek audio in on playlist: ' + playList + ' at|to trackID|timestamp: ' + trackID + '|' + songStartTS);
892
- Amplitude.setSongPlayedPercentage((songStartSec / songDurationSec) * 100);
893
-
894
- // fade-in audio (if enabled)
895
- var fadeAudioIn = (songMetaData.audio_fade_in === 'true') ? true : false;
896
- if (fadeAudioIn) {
897
- logger.debug('\n' + 'faden audio in on playlist: ' + playList + ' at|to trackID|timestamp: ' + trackID + '|' + songStartTS);
898
- atpFadeInAudio({ playerID: playerID });
899
- } // END if fadeAudio
850
+ // update song rating in playlist-screen|meta-container
851
+ // ---------------------------------------------------------------------
852
+ _this.atpUpdatMetaContainers(songMetaData);
900
853
 
901
- } // END if songStartSec
854
+ // scroll active song in players playlist
855
+ // ---------------------------------------------------------------------
856
+ _this.atPlayerScrollToActiveElement(songMetaData);
902
857
 
903
- clearInterval(checkIsFading);
904
- }
905
- }, 100); // END checkIsFading
906
-
907
- // check|process audio for configured END position
908
- // -------------------------------------------------------------------
909
- if (songEndSec > songStartSec) {
910
- var checkIsOnVideoEnd = setInterval(() => {
911
-
912
- if (!isFadingOut) {
913
- var currentAudioTime = Amplitude.getSongPlayedSeconds();
914
- var songMetaData = Amplitude.getActiveSongMetadata();
915
- var songEndTS = songMetaData.end;
916
- var songEndSec = timestamp2seconds(songEndTS);
917
-
918
- if (currentAudioTime > songEndSec) {
919
- songMetaData = Amplitude.getActiveSongMetadata();
920
- songIndex = songMetaData.index;
921
- trackID = songIndex + 1;
922
-
923
- // seek audio out to total end END position
924
- // NOTE: use setSongPlayedPercentage for seeking to NOT
925
- // generation any addition state changes like stopped
926
- // or playing
927
- logger.debug('\n' + 'seek audio out to end on playlist: ' + playList + ' at trackID|timestamp: ' + trackID + '|' + songEndTS);
928
- Amplitude.setSongPlayedPercentage(99.99);
929
-
930
- // fade-out audio (if enabled)
931
- var fadeAudioOut = (songMetaData.audio_fade_out === 'true') ? true : false;
932
- if (fadeAudioOut) {
933
- logger.debug('\n' + 'fade audio out on playlist: ' + playList + ' at|to trackID|timestamp: ' + trackID + '|' + songEndTS);
934
- atpFadeAudioOut({ playerID: playerID });
935
- } // END if fadeAudio
936
-
937
- clearInterval(checkIsOnVideoEnd);
938
- } // END if currentAudioTime
939
-
940
- } // END if !isFading
941
-
942
- }, 100); // END checkIsOnVideoEnd
943
- } // END if songEndSec
858
+ // process audio for AT players at configured START position
859
+ // ---------------------------------------------------------------------
860
+ _this.atpProcessAudioStartPosition();
861
+
862
+ // process audio for AT players at configured END position
863
+ // ---------------------------------------------------------------------
864
+ _this.atpProcessAudioEndPosition();
944
865
 
945
866
  // save YT player data for later use (e.g. events)
946
867
  // ---------------------------------------------------------------------
@@ -989,7 +910,7 @@ j1.adapter.amplitude = ((j1, window) => {
989
910
  doNothingOnStateChange(AT_PLAYER_STATE.ENDED);
990
911
  break;
991
912
  default:
992
- logger.error('\n' + `UNKNOWN state on StateChange fired: ${state}`);
913
+ logger.error(`UNKNOWN state on StateChange fired: ${state}`);
993
914
  } // END switch state
994
915
  } // END onPlayerStateChange
995
916
 
@@ -1034,7 +955,7 @@ j1.adapter.amplitude = ((j1, window) => {
1034
955
  var parentContainer = (document.getElementById('{{xhr_container_id}}') !== null) ? true : false;
1035
956
  var parentContainerExist = ($('#' + '{{xhr_container_id}}')[0] !== undefined) ? true : false;
1036
957
 
1037
- logger.info('\n' + 'initialize player specific UI events: started');
958
+ logger.info('initialize player specific UI events: started');
1038
959
 
1039
960
  {% for player in amplitude_options.players %} {% if player.enabled %}
1040
961
  {% assign xhr_data_path = amplitude_options.xhr_data_path %}
@@ -1059,18 +980,18 @@ j1.adapter.amplitude = ((j1, window) => {
1059
980
  var playListName = '{{player.playlist.name}}';
1060
981
  var playListTitle = '{{player.playlist.title}}';
1061
982
 
1062
- logger.debug('\n' + 'initialize audio player instance on id: {{player.id}}');
983
+ logger.debug('initialize audio player instance on id: {{player.id}}');
1063
984
 
1064
985
  // set song (title) specific audio info links
1065
986
  // -------------------------------------------------------------
1066
- if (playerAudioInfo) {
987
+ if (playlistAudioInfo) {
1067
988
  var infoLinks = document.getElementsByClassName('audio-info-link');
1068
989
  _this.setAudioInfo(infoLinks);
1069
990
  }
1070
991
 
1071
992
  // set player specific UI events
1072
993
  // -------------------------------------------------------------
1073
- logger.debug('\n' + 'setup audio player specific UI events on ID #{{player.id}}: started');
994
+ logger.debug('setup audio player specific UI events on ID #{{player.id}}: started');
1074
995
 
1075
996
  var dependencies_met_api_initialized = setInterval (() => {
1076
997
  if (apiInitialized.state) {
@@ -1280,13 +1201,13 @@ j1.adapter.amplitude = ((j1, window) => {
1280
1201
  for (let i=0; i<ytPlayers.length; i++) {
1281
1202
  const playerID = ytPlayers[i];
1282
1203
  const playerProperties = j1.adapter.amplitude.data.ytPlayers[playerID];
1283
- logger.debug('\n' + 'process player id: ' + playerID);
1204
+ logger.debug('process player id: ' + playerID);
1284
1205
  ytpPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
1285
1206
  playerState = ytpPlayer.getPlayerState();
1286
1207
  ytpPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1287
1208
 
1288
1209
  if (ytpPlayerState === 'playing' || ytpPlayerState === 'paused' || ytpPlayerState === 'buffering') {
1289
- logger.debug('\n' + 'process player id: ' + playerID + ' stopped');
1210
+ logger.debug('process player id: ' + playerID + ' stopped');
1290
1211
  ytpPlayer.stopVideo();
1291
1212
  }
1292
1213
  }
@@ -1393,8 +1314,10 @@ j1.adapter.amplitude = ((j1, window) => {
1393
1314
  var playlistInfo = {{player.playlist | replace: 'nil', 'null' | replace: '=>', ':'}};
1394
1315
  var playList = playlistInfo.name;
1395
1316
 
1317
+ {% comment %} PREPARED event listener for LATER use
1318
+ ----------------------------------------------------------
1396
1319
  // add listeners to all SongContainers found (LARGE player)
1397
- // -------------------------------------------------------
1320
+ // -------------------------------------------------------
1398
1321
  var largePlayerSongContainer = document.getElementsByClassName("amplitude-song-container");
1399
1322
  for (var i=0; i<largePlayerSongContainer.length; i++) {
1400
1323
  if (largePlayerSongContainer[i].dataset.amplitudeSource === 'youtube') {
@@ -1415,55 +1338,19 @@ j1.adapter.amplitude = ((j1, window) => {
1415
1338
  metaData = Amplitude.getActiveSongMetadata();
1416
1339
  atpPlayerState = Amplitude.getPlayerState();
1417
1340
 
1418
- // update song rating in screen controls
1419
- // -----------------------------------------------
1420
- // updateSongRating(playlist, metaData.index, metaData.rating);
1421
-
1422
- // var largePlayerSongAudioRating = document.getElementsByClassName("audio-rating-screen-controls");
1423
- // if (largePlayerSongAudioRating.length) {
1424
- // for (var i=0; i<largePlayerSongAudioRating.length; i++) {
1425
- // var currentPlaylist = largePlayerSongAudioRating[i].dataset.amplitudePlaylist;
1426
- // if (currentPlaylist === playlist) {
1427
- // if (metaData.rating) {
1428
- // var trackID = metaData.index + 1;
1429
- // logger.debug('\n' + `UPDATE song rating on updatMetaContainers for trackID|playlist at: ${trackID}|${playlist} with a value of: ${metaData.rating}`);
1430
- // largePlayerSongAudioRating[i].innerHTML = '<img src="/assets/image/pattern/rating/scalable/' + metaData.rating + '-star.svg"' + 'alt="song rating">';
1431
- // } else {
1432
- // largePlayerSongAudioRating[i].innerHTML = '';
1433
- // }
1434
- // }
1435
- // }
1436
- // } // END if largePlayerSongAudioRating
1437
-
1438
- // scroll song active at index in player
1439
- // -----------------------------------------------
1440
- // if (playerAutoScrollSongElement) {
1441
- // j1.adapter.amplitude.atPlayerScrollToActiveElement(playlist);
1442
- // }
1443
-
1444
- // toggle active AT players
1445
- // -----------------------------------------------
1446
- // if (atpPlayerState === 'playing') {
1447
- // // start|pause active player
1448
- // // logger.debug('\n' + 'process player id: ' + atpPlayerActive[0] + ' stopped');
1449
- // Amplitude.pause();
1450
- // } else {
1451
- // Amplitude.playPlaylistSongAtIndex(playlistIndex, playlist);
1452
- // }
1453
-
1454
1341
  // stop active YT players
1455
1342
  // -----------------------------------------------
1456
1343
  const ytPlayers = Object.keys(j1.adapter.amplitude.data.ytPlayers);
1457
1344
  for (let i=0; i<ytPlayers.length; i++) {
1458
1345
  const playerID = ytPlayers[i];
1459
1346
  const playerProperties = j1.adapter.amplitude.data.ytPlayers[playerID];
1460
- logger.debug('\n' + 'process player id: ' + playerID);
1347
+ logger.debug('process player id: ' + playerID);
1461
1348
  ytpPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
1462
1349
  playerState = ytpPlayer.getPlayerState();
1463
1350
  ytpPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1464
1351
 
1465
1352
  if (ytpPlayerState === 'playing' || ytpPlayerState === 'paused' || ytpPlayerState === 'buffering') {
1466
- logger.debug('\n' + 'process player id: ' + playerID + ' stopped');
1353
+ logger.debug('process player id: ' + playerID + ' stopped');
1467
1354
  ytpPlayer.stopVideo();
1468
1355
  }
1469
1356
  }
@@ -1477,6 +1364,8 @@ j1.adapter.amplitude = ((j1, window) => {
1477
1364
  } // END if currentPlaylist
1478
1365
  } // ENF if largePlayerSongContainer
1479
1366
  } // END for largePlayerSongContainer
1367
+ ----------------------------------------------------------
1368
+ {% endcomment %}
1480
1369
 
1481
1370
  // click on prev button
1482
1371
  var largePlayerPreviousButton = document.getElementById('large_player_previous');
@@ -1484,11 +1373,10 @@ j1.adapter.amplitude = ((j1, window) => {
1484
1373
  // do nothing for YTP (managed by plugin)
1485
1374
  }
1486
1375
 
1487
- // add listeners to all PlayPause Buttons found (LARGE player)
1488
- // -------------------------------------------------------
1489
-
1490
1376
  {% comment %} PREPARED event listener for LATER use
1491
- ----------------------------------------------------------
1377
+ ----------------------------------------------------------
1378
+ // add listeners to all PlayPause Buttons found (LARGE player)
1379
+ // -------------------------------------------------------
1492
1380
  var largePlayerPlayPauseButton = document.getElementsByClassName('large-player-play-pause');
1493
1381
  for (var i=0; i<largePlayerPlayPauseButton.length; i++) {
1494
1382
  if (largePlayerPlayPauseButton[i].dataset.amplitudeSource === 'youtube') {
@@ -1528,8 +1416,10 @@ j1.adapter.amplitude = ((j1, window) => {
1528
1416
  }
1529
1417
  } // END for
1530
1418
 
1419
+ {% comment %} PREPARED event listener for LATER use
1420
+ ----------------------------------------------------------
1531
1421
  // add listeners to all Next Buttons found (LARGE player)
1532
- // -------------------------------------------------------
1422
+ // -------------------------------------------------------
1533
1423
  var largeNextButtons = document.getElementsByClassName("large-player-next");
1534
1424
  for (var i=0; i<largeNextButtons.length; i++) {
1535
1425
  if (largeNextButtons[i].dataset.amplitudeSource === 'youtube') {
@@ -1544,39 +1434,15 @@ j1.adapter.amplitude = ((j1, window) => {
1544
1434
  playlist = this.getAttribute("data-amplitude-playlist");
1545
1435
  metaData = Amplitude.getActiveSongMetadata();
1546
1436
 
1547
- // update song rating in screen controls
1548
- var largePlayerSongAudioRating = document.getElementsByClassName("audio-rating-screen-controls");
1549
- if (largePlayerSongAudioRating.length) {
1550
- for (var i=0; i<largePlayerSongAudioRating.length; i++) {
1551
- var currentPlaylist = largePlayerSongAudioRating[i].dataset.amplitudePlaylist;
1552
- if (currentPlaylist === playlist) {
1553
- if (metaData.rating) {
1554
- var trackID = metaData.index + 1;
1555
- logger.debug('\n' + `UPDATE song rating on updatMetaContainers for trackID|playlist at: ${trackID}|${playlist} with a value of: ${metaData.rating}`);
1556
- largePlayerSongAudioRating[i].innerHTML = '<img src="/assets/image/pattern/rating/scalable/' + metaData.rating + '-star.svg"' + 'alt="song rating">';
1557
- } else {
1558
- largePlayerSongAudioRating[i].innerHTML = '';
1559
- }
1560
- }
1561
- }
1562
- } // END if largePlayerSongAudioRating
1563
-
1564
- // scroll song active at index in player
1565
- // -----------------------------------------------
1566
- if (playerAutoScrollSongElement) {
1567
- j1.adapter.amplitude.atPlayerScrollToActiveElement(playlist);
1568
- }
1569
-
1570
- // save YT player data for later use (e.g. events)
1571
- // -----------------------------------------------
1572
- j1.adapter.amplitude.data.activePlayer = 'atp';
1573
- j1.adapter.amplitude.data.atpGlobals.activePlayerType = atpPlayerActive[0];
1574
-
1575
1437
  }); // END EventListener 'click'
1576
1438
  } // END addEventListener
1577
1439
  } // END if largeNextButtons
1578
1440
  } // END for Next Buttons
1441
+ ----------------------------------------------------------
1442
+ {% endcomment %}
1579
1443
 
1444
+ {% comment %} PREPARED event listener for LATER use
1445
+ ----------------------------------------------------------
1580
1446
  // add listeners to all Previous Buttons found
1581
1447
  // -------------------------------------------------------
1582
1448
  var largePreviousButtons = document.getElementsByClassName("large-player-previous");
@@ -1601,7 +1467,7 @@ j1.adapter.amplitude = ((j1, window) => {
1601
1467
  if (currentPlaylist === playlist) {
1602
1468
  if (metaData.rating) {
1603
1469
  var trackID = metaData.index + 1;
1604
- logger.debug('\n' + `UPDATE song rating on updatMetaContainers for trackID|playlist at: ${trackID}|${playlist} with a value of: ${metaData.rating}`);
1470
+ logger.debug(`UPDATE song rating on updatMetaContainers for trackID|playlist at: ${trackID}|${playlist} with a value of: ${metaData.rating}`);
1605
1471
  largePlayerSongAudioRating[i].innerHTML = '<img src="/assets/image/pattern/rating/scalable/' + metaData.rating + '-star.svg"' + 'alt="song rating">';
1606
1472
  } else {
1607
1473
  largePlayerSongAudioRating[i].innerHTML = '';
@@ -1612,12 +1478,12 @@ j1.adapter.amplitude = ((j1, window) => {
1612
1478
 
1613
1479
  // scroll song active at index in player
1614
1480
  if (playerAutoScrollSongElement) {
1615
- j1.adapter.amplitude.atPlayerScrollToActiveElement(playlist);
1481
+ j1.adapter.amplitude.atPlayerScrollToActiveElement(Amplitude.getActiveSongMetadata());
1616
1482
  }
1617
1483
 
1618
1484
  // scroll song active at index in player
1619
1485
  if (playerAutoScrollSongElement) {
1620
- j1.adapter.amplitude.atPlayerScrollToActiveElement(playlist);
1486
+ j1.adapter.amplitude.atPlayerScrollToActiveElement(Amplitude.getActiveSongMetadata());
1621
1487
  }
1622
1488
 
1623
1489
  // save YT player data for later use (e.g. events)
@@ -1628,6 +1494,8 @@ j1.adapter.amplitude = ((j1, window) => {
1628
1494
  } // END if largePreviousButtons
1629
1495
  } // END if largePreviousButtons
1630
1496
  } // END for Previous Buttons
1497
+ ----------------------------------------------------------
1498
+ {% endcomment %}
1631
1499
 
1632
1500
  // add listeners to all SkipForward Buttons found
1633
1501
  // See: https://github.com/serversideup/amplitudejs/issues/384
@@ -1645,7 +1513,7 @@ j1.adapter.amplitude = ((j1, window) => {
1645
1513
  const targetTime = parseFloat(currentTime + skipOffset);
1646
1514
 
1647
1515
  if (currentTime > 0) {
1648
- logger.debug('\n' + `SKIP forward on Button skipForward for ${skipOffset} seconds`);
1516
+ logger.debug(`SKIP forward on Button skipForward for ${skipOffset} seconds`);
1649
1517
  Amplitude.setSongPlayedPercentage((targetTime / duration) * 100);
1650
1518
  }
1651
1519
  }); // END addEventListener
@@ -1668,7 +1536,7 @@ j1.adapter.amplitude = ((j1, window) => {
1668
1536
  const targetTime = parseFloat(currentTime - skipOffset);
1669
1537
 
1670
1538
  if (currentTime > 0) {
1671
- logger.debug('\n' + `SKIP backward on Button skipForward for ${skipOffset} seconds`);
1539
+ logger.debug(`SKIP backward on Button skipForward for ${skipOffset} seconds`);
1672
1540
  Amplitude.setSongPlayedPercentage((targetTime / duration) * 100);
1673
1541
  }
1674
1542
  }); // END addEventListener
@@ -1681,7 +1549,7 @@ j1.adapter.amplitude = ((j1, window) => {
1681
1549
  if (largePlayerShuffleButton) {
1682
1550
  largePlayerShuffleButton.addEventListener('click', function(event) {
1683
1551
  var shuffleState = (document.getElementById('large_player_shuffle').className.includes('amplitude-shuffle-on')) ? true : false;
1684
- logger.debug('\n' + `Set shuffle state to: ${shuffleState}`);
1552
+ logger.debug(`Set shuffle state to: ${shuffleState}`);
1685
1553
  Amplitude.setShuffle(shuffleState)
1686
1554
  }); // END addEventListener
1687
1555
  } // END if largePlayerShuffleButton
@@ -1691,18 +1559,19 @@ j1.adapter.amplitude = ((j1, window) => {
1691
1559
  if (largePlayerRepeatButton) {
1692
1560
  largePlayerRepeatButton.addEventListener('click', function(event) {
1693
1561
  var repeatState = (document.getElementById('large_player_repeat').className.includes('amplitude-repeat-on')) ? true : false;
1694
- logger.debug('\n' + `Set repeat state to: ${repeatState}`);
1562
+ logger.debug(`Set repeat state to: ${repeatState}`);
1695
1563
  Amplitude.setRepeat(repeatState)
1696
1564
  }); // END addEventListener
1697
1565
  } // END if largePlayerRepeatButton
1698
1566
 
1699
- // enable|disable scrolling on playlist (LARGE player)
1567
+ // enable|disable PAGE scrolling on players playlist (LARGE player)
1700
1568
  // -------------------------------------------------------
1701
- if (document.getElementById('large_player_right') !== null) {
1569
+ // if (playerHoverPageScrollDisabled && document.getElementById('large_player_right') !== null) {
1570
+ if (playerHoverPageScrollDisabled) {
1702
1571
 
1703
1572
  // show|hide scrollbar in playlist
1704
1573
  // -----------------------------------------------------
1705
- var songsInPlaylist = Amplitude.getSongsInPlaylist(playListName);
1574
+ const songsInPlaylist = Amplitude.getSongsInPlaylist(playListName);
1706
1575
  if (songsInPlaylist.length <= playerScrollerSongElementMin) {
1707
1576
  const titleListLargePlayer = document.getElementById('large_player_title_list_' + playListName);
1708
1577
  if (titleListLargePlayer !== null) {
@@ -1783,7 +1652,7 @@ j1.adapter.amplitude = ((j1, window) => {
1783
1652
  }
1784
1653
  }); // END addEventListener
1785
1654
 
1786
- } // END enable|disable scrolling on playlist
1655
+ } // END enable|disable PAGE scrolling on players playlist
1787
1656
 
1788
1657
  // set volume slider presets (for the player when exists|enabled)
1789
1658
  //
@@ -1804,14 +1673,16 @@ j1.adapter.amplitude = ((j1, window) => {
1804
1673
 
1805
1674
  } // END large player UI events
1806
1675
  {% endif %}
1676
+ {% comment %} END process UI events for all LARGE Players
1677
+ ============================================================ {% endcomment %}
1807
1678
 
1808
1679
  // ---------------------------------------------------------
1809
1680
  // START configured player features
1810
1681
 
1811
- logger.debug('\n' + 'set play next title: ' + playerPlayNextTitle);
1812
- logger.debug('\n' + 'set delay between titles: ' + playerDelayNextTitle + 'ms');
1813
- logger.debug('\n' + 'set repeat (album): ' + playerRepeat);
1814
- logger.debug('\n' + 'set shuffle (album): ' + playerShuffle);
1682
+ logger.debug('set play next title: ' + playerPlayNextTitle);
1683
+ logger.debug('set delay between titles: ' + playerDelayNextTitle + 'ms');
1684
+ logger.debug('set repeat (album): ' + playerRepeat);
1685
+ logger.debug('set shuffle (album): ' + playerShuffle);
1815
1686
 
1816
1687
  // set delay between titles (songs)
1817
1688
  Amplitude.setDelay(playerDelayNextTitle);
@@ -1825,8 +1696,8 @@ j1.adapter.amplitude = ((j1, window) => {
1825
1696
 
1826
1697
  // finished messages
1827
1698
  // ---------------------------------------------------------
1828
- logger.debug('\n' + 'current player state: ' + amplitudePlayerState);
1829
- logger.debug('\n' + 'setup player specific UI events on ID #{{player.id}}: finished');
1699
+ logger.debug('current player state: ' + amplitudePlayerState);
1700
+ logger.debug('setup player specific UI events on ID #{{player.id}}: finished');
1830
1701
 
1831
1702
  clearInterval(dependencies_met_api_initialized);
1832
1703
  } // END if apiInitialized
@@ -1846,14 +1717,14 @@ j1.adapter.amplitude = ((j1, window) => {
1846
1717
 
1847
1718
  {% endif %} {% endfor %}
1848
1719
 
1849
- logger.info('\n' + 'initialize player specific UI events: finished');
1720
+ logger.info('initialize player specific UI events: finished');
1850
1721
 
1851
1722
  _this.setState('finished');
1852
- logger.debug('\n' + 'module state: ' + _this.getState());
1853
- logger.info('\n' + 'module initialized successfully');
1723
+ logger.debug('module state: ' + _this.getState());
1724
+ logger.info('module initialized successfully');
1854
1725
 
1855
1726
  endTimeModule = Date.now();
1856
- logger.info('\n' + 'module initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
1727
+ logger.info('module initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
1857
1728
 
1858
1729
  clearInterval(dependencies_met_player_instances_initialized);
1859
1730
  } // END if apiInitialized
@@ -1877,7 +1748,7 @@ j1.adapter.amplitude = ((j1, window) => {
1877
1748
  // songEvents
1878
1749
  // -------------------------------------------------------------------------
1879
1750
  songEvents: (songs) => {
1880
- logger.debug('\n' + 'initializing title events for player on ID ' + '#' + playerID + ': started');
1751
+ logger.debug('initializing title events for player on ID ' + '#' + playerID + ': started');
1881
1752
 
1882
1753
  for (var i = 0; i < songs.length; i++) {
1883
1754
  // ensure that on mouseover, CSS styles don't get messed up for active songs
@@ -1905,7 +1776,7 @@ j1.adapter.amplitude = ((j1, window) => {
1905
1776
  }); // END EventListener 'click' (songlist)
1906
1777
  }
1907
1778
 
1908
- logger.debug('\n' + 'initializing title events for player on ID ' + '#' + playerID + ': finished');
1779
+ logger.debug('initializing title events for player on ID ' + '#' + playerID + ': finished');
1909
1780
  }, // END songEvents
1910
1781
 
1911
1782
  // -------------------------------------------------------------------------
@@ -1939,7 +1810,7 @@ j1.adapter.amplitude = ((j1, window) => {
1939
1810
  }
1940
1811
 
1941
1812
  if (plugin !== '' && isPluginLoaded(plugin)) {
1942
- logger.debug('\n' + 'plugin loaded: ' + plugin);
1813
+ logger.debug('plugin loaded: ' + plugin);
1943
1814
 
1944
1815
  // make sure the plugin installed only ONCE
1945
1816
  j1.adapter.amplitude.data.atpGlobals.ytpInstalled = true;
@@ -1950,9 +1821,9 @@ j1.adapter.amplitude = ((j1, window) => {
1950
1821
  // atPlayerScrollToActiveElement(metaData)
1951
1822
  // -------------------------------------------------------------------------
1952
1823
  atPlayerScrollToActiveElement: (metaData) => {
1953
- var scrollableList, songIndex,
1954
- activeElement, activeElementOffsetTop,
1955
- songElementMin, numSongs;
1824
+ var scrollableList, songIndex, playlist,
1825
+ activeElement, activeElementOffsetTop, numSongs,
1826
+ songElementMin, playerSongElementHeigthCompact;
1956
1827
 
1957
1828
  if (!playerAutoScrollSongElement) {
1958
1829
  // do nothing if playerAutoScrollSongElement is false
@@ -1961,18 +1832,19 @@ j1.adapter.amplitude = ((j1, window) => {
1961
1832
 
1962
1833
  songIndex = metaData.index;
1963
1834
  songElementMin = playerScrollerSongElementMin;
1964
- numSongs = Amplitude.getSongsInPlaylist(metaData.playlist).length;
1965
- scrollableList = document.getElementById('large_player_title_list_' + metaData.playlist);
1835
+ playlist = metaData.playlist;
1836
+ scrollableList = document.getElementById('large_player_title_list_' + playlist);
1966
1837
  activeElement = scrollableList.querySelector('.amplitude-active-song-container');
1838
+ numSongs = Amplitude.getSongsInPlaylist(playlist).length;
1967
1839
 
1968
1840
  if (activeElement === null || scrollableList === null) {
1969
1841
  // do nothing if NO scrollableList or ACTIVE element found (failsafe)
1970
1842
  return;
1971
1843
  }
1972
1844
 
1845
+ // LARGE players
1846
+ // -----------------------------------------------------------------------
1973
1847
  if (songIndex > 0 && numSongs >= songElementMin) {
1974
- scrollableList = document.getElementById('large_player_title_list_' + metaData.playlist);
1975
- activeElement = scrollableList.querySelector('.amplitude-active-song-container');
1976
1848
  activeElementOffsetTop = songIndex * j1.adapter.amplitude.data.playerSongElementHeigth;
1977
1849
  scrollableList.scrollTop = activeElementOffsetTop;
1978
1850
  } else {
@@ -1980,44 +1852,328 @@ j1.adapter.amplitude = ((j1, window) => {
1980
1852
  return;
1981
1853
  }
1982
1854
 
1855
+ // COMPACT players (WIP)
1856
+ // -----------------------------------------------------------------------
1857
+ // playerSongElementHeigthCompact = 74.00;
1858
+ // if (songIndex > 0 && numSongs >= songElementMin) {
1859
+ // // scrollableList = document.getElementById('compact_player_title_list_' + metaData.playlist);
1860
+ // // activeElement = scrollableList.querySelector('.amplitude-active-song-container');
1861
+ // activeElementOffsetTop = (songIndex * playerSongElementHeigthCompact);
1862
+ // scrollableList.scrollTop = activeElementOffsetTop;
1863
+ // } else {
1864
+ // // do nothing if songIndex is 0 or less than songElementMin
1865
+ // return;
1866
+ // }
1867
+
1983
1868
  }, // END atPlayerScrollToActiveElement
1984
1869
 
1985
1870
  // -------------------------------------------------------------------------
1986
- // atUpdateSongRating(playlist, rating)
1871
+ // atpUpdatMetaContainers(playlist, rating)
1987
1872
  //
1988
1873
  // update song rating in playlist-screen|meta-container
1874
+ // for all (compact|large) players
1989
1875
  // -------------------------------------------------------------------------
1990
- atUpdateSongRating: (metaData) => {
1991
- var screenControlRating = null;
1876
+ atpUpdatMetaContainers: (metaData) => {
1877
+ var activePlayist = metaData.playlist;
1878
+ var rating = parseInt(metaData.rating);
1879
+ var trackID = metaData.index + 1;
1880
+ const notRequiredForATP = true
1881
+
1882
+ logger.debug(`UPDATE metadata on atpUpdatMetaContainers for trackID|playlist at: ${trackID}|${activePlayist}`);
1883
+
1884
+ // properties automatically set by AT API
1885
+ if (requiredForATP) {
1886
+ // update SONG NAME in meta-containers
1887
+ var songName = document.getElementsByClassName("song-name");
1888
+ if (songName.length) {
1889
+ for (var i=0; i<songName.length; i++) {
1890
+ var currentPlaylist = songName[i].dataset.amplitudePlaylist;
1891
+ if (currentPlaylist === activePlayist) {
1892
+ songName[i].innerHTML = metaData.name;
1893
+ }
1894
+ }
1895
+ }
1896
+ }
1897
+
1898
+ // properties automatically set by AT API
1899
+ if (requiredForATP) {
1900
+ // update SONG ARTIST name in meta-containers
1901
+ var artistName = document.getElementsByClassName("artist");
1902
+ if (artistName.length) {
1903
+ for (var i=0; i<artistName.length; i++) {
1904
+ var currentPlaylist = songName[i].dataset.amplitudePlaylist;
1905
+ if (currentPlaylist === activePlayist) {
1906
+ artistName[i].innerHTML = metaData.artist;
1907
+ }
1908
+ }
1909
+ }
1910
+ }
1911
+
1912
+ // properties automatically set by AT API
1913
+ if (requiredForATP) {
1914
+ // update SONG ALBUM name in meta-containers
1915
+ var albumName = document.getElementsByClassName("album");
1916
+ if (albumName.length) {
1917
+ for (var i=0; i<albumName.length; i++) {
1918
+ var currentPlaylist = albumName[i].dataset.amplitudePlaylist;
1919
+ if (currentPlaylist === activePlayist) {
1920
+ albumName[i].innerHTML = metaData.album;
1921
+ }
1922
+ }
1923
+ }
1924
+ }
1925
+
1926
+ // update SONG RATING in screen controls
1992
1927
  var screenControlRatingElements = document.getElementsByClassName('audio-rating-screen-controls');
1993
- var ratingIndex;
1994
-
1995
- for (let i=0; i<screenControlRatingElements.length; i++) {
1996
- var ratingElement = screenControlRatingElements[i];
1997
- var rating = parseInt(metaData.rating);
1998
- var playerType = ratingElement.dataset.playerType;
1999
- var activePlayerType = j1.adapter.amplitude.data.atpGlobals.activePlayerType;
2000
- var activePlayist = metaData.playlist;
2001
-
2002
- if (ratingElement.dataset.amplitudePlaylist === activePlayist && playerType === activePlayerType) {
2003
- ratingIndex = i;
2004
- screenControlRating = ratingElement;
2005
- break;
1928
+ if (rating) {
1929
+ for (let i=0; i<screenControlRatingElements.length; i++) {
1930
+ var ratingElement = screenControlRatingElements[i];
1931
+ if (ratingElement.dataset.amplitudePlaylist === activePlayist && ratingElement.classList.contains('audio-rating-screen-controls')) {
1932
+ ratingElement.innerHTML = '<img src="/assets/image/pattern/rating/scalable/' + rating + '-star.svg"' + 'alt="song rating">';
1933
+ }
1934
+ }
1935
+ }
1936
+
1937
+ // update SONG INFO in screen controls
1938
+ var songAudioInfo = document.getElementsByClassName("audio-info-link-screen-controls");
1939
+ if (songAudioInfo.length) {
1940
+ for (var i=0; i<songAudioInfo.length; i++) {
1941
+ var currentPlaylist = songAudioInfo[i].dataset.amplitudePlaylist;
1942
+ if (currentPlaylist === activePlayist) {
1943
+ if (metaData.audio_info) {
1944
+ songAudioInfo[i].setAttribute("href", metaData.audio_info);
1945
+ }
1946
+ }
2006
1947
  }
1948
+ } // END if songAudioInfo
1949
+
1950
+ }, // END atpUpdatMetaContainers
2007
1951
 
1952
+ // -------------------------------------------------------------------------
1953
+ // atpStopParallelActivePlayers(players)
1954
+ //
1955
+ // stop active YT players (running in parallel to AT players)
1956
+ // -------------------------------------------------------------------------
1957
+ atpStopParallelActivePlayers: (players) => {
1958
+ var ytPlayer, playerState, ytPlayerState;
1959
+
1960
+ const ytPlayers = Object.keys(players);
1961
+ for (var i=0; i<ytPlayers.length; i++) {
1962
+ const ytPlayerID = ytPlayers[i];
1963
+
1964
+ ytPlayer = players[ytPlayerID].player;
1965
+ playerState = ytPlayer.getPlayerState();
1966
+ ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1967
+
1968
+ // stop YT players running in parallel
1969
+ // ---------------------------------------------------------------------
1970
+ if (ytPlayerState === 'playing' || ytPlayerState === 'paused' || ytPlayerState === 'buffering') {
1971
+ logger.debug(`STOP YT player on id: ${playerID}`);
1972
+ ytPlayer.stopVideo();
1973
+ }
1974
+
1975
+ // toggle PlayPause buttons playing => puased
1976
+ // ---------------------------------------------------------------------
1977
+ var ytpButtonPlayerPlayPause = document.getElementsByClassName("large-player-play-pause-" + ytPlayerID);
1978
+ for (var j=0; j<ytpButtonPlayerPlayPause.length; j++) {
1979
+
1980
+ var htmlElement = ytpButtonPlayerPlayPause[j];
1981
+ if (htmlElement.dataset.amplitudeSource === 'youtube') {
1982
+ if (htmlElement.classList.contains('amplitude-playing')) {
1983
+ htmlElement.classList.remove('amplitude-playing');
1984
+ htmlElement.classList.add('amplitude-paused');
1985
+ }
1986
+ }
1987
+ } // END for ytpButtonPlayerPlayPause
1988
+
1989
+ } // END for ytPlayers
1990
+ }, // END atpStopParallelActivePlayers
1991
+
1992
+ // -------------------------------------------------------------------------
1993
+ // atpProcessAudioStartPosition()
1994
+ //
1995
+ // process audio for configured START position
1996
+ // -------------------------------------------------------------------------
1997
+ atpProcessAudioStartPosition: () => {
1998
+ var songMetaData, songIndex, playList,
1999
+ songStartSec, songStartTS, trackID;
2000
+
2001
+ songMetaData = Amplitude.getActiveSongMetadata();
2002
+ songIndex = songMetaData.index;
2003
+ songStartTS = songMetaData.start;
2004
+ songStartSec = _this.timestamp2seconds(songStartTS);
2005
+ playList = Amplitude.getActivePlaylist();
2006
+ trackID = songIndex + 1;
2007
+
2008
+ if (!songStartSec) {
2009
+ return;
2008
2010
  }
2009
2011
 
2010
- // set the rating for ACTIVE screenControlRatingElement
2011
- // -----------------------------------------------------------------------
2012
- if (screenControlRating) {
2013
- if (rating) {
2014
- ratingElement.innerHTML = '<img src="/assets/image/pattern/rating/scalable/' + rating + '-star.svg"' + 'alt="song rating">';
2015
- } else {
2016
- ratingElement.innerHTML = '';
2012
+ var checkIsFading = setInterval (() => {
2013
+ if (!isFadingIn) {
2014
+ var currentAudioTime = Amplitude.getSongPlayedSeconds();
2015
+ if (songStartSec && currentAudioTime <= songStartSec) {
2016
+ var songDurationSec = _this.timestamp2seconds(songMetaData.duration);
2017
+
2018
+ // seek audio to configured START position
2019
+ // NOTE: use setSongPlayedPercentage for seeking to NOT
2020
+ // generation any addition state changes like stopped
2021
+ // or playing
2022
+ logger.debug('seek audio in on playlist: ' + playList + ' at|to trackID|timestamp: ' + trackID + '|' + songStartTS);
2023
+ Amplitude.setSongPlayedPercentage((songStartSec / songDurationSec) * 100);
2024
+
2025
+ // fade-in audio (if enabled)
2026
+ var fadeAudioIn = (songMetaData.audio_fade_in === 'true') ? true : false;
2027
+ if (fadeAudioIn) {
2028
+ logger.debug('faden audio in on playlist: ' + playList + ' at|to trackID|timestamp: ' + trackID + '|' + songStartTS);
2029
+ atpFadeInAudio({ playerID: playerID });
2030
+ } // END if fadeAudio
2031
+
2032
+ } // END if songStartSec
2033
+
2034
+ clearInterval(checkIsFading);
2035
+ }
2036
+ }, 100); // END checkIsFading
2037
+ }, // END atpProcessAudioStartPosition
2038
+
2039
+ // -------------------------------------------------------------------------
2040
+ // atpProcessAudioEndPosition()
2041
+ //
2042
+ // process audio for configured END position
2043
+ // -------------------------------------------------------------------------
2044
+ atpProcessAudioEndPosition: () => {
2045
+ var songMetaData, songIndex, playList,
2046
+ songStartSec, songStartTS, songEndSec, songEndTS,
2047
+ trackID;
2048
+
2049
+ songMetaData = Amplitude.getActiveSongMetadata();
2050
+ songIndex = songMetaData.index;
2051
+ songStartTS = songMetaData.start;
2052
+ songStartSec = _this.timestamp2seconds(songStartTS);
2053
+ songEndTS = songMetaData.end;
2054
+ songEndSec = _this.timestamp2seconds(songEndTS);
2055
+ playList = Amplitude.getActivePlaylist();
2056
+ trackID = songIndex + 1;
2057
+
2058
+ if (songEndSec > songStartSec) {
2059
+ var checkIsOnVideoEnd = setInterval(() => {
2060
+ if (!isFadingOut) {
2061
+ var currentAudioTime = Amplitude.getSongPlayedSeconds();
2062
+ if (currentAudioTime >= songEndSec) {
2063
+ songMetaData = Amplitude.getActiveSongMetadata();
2064
+ songIndex = songMetaData.index;
2065
+ trackID = songIndex + 1;
2066
+
2067
+ // seek audio out to END position
2068
+ // NOTE:
2069
+ // ---------------------------------------------------------------
2070
+ // use setSongPlayedPercentage for seeking to NOT
2071
+ // generation any addition state changes like stopped
2072
+ // or playing
2073
+ logger.debug('seek audio to end on playlist: ' + playList + ' at trackID|timestamp: ' + trackID + '|' + songEndTS);
2074
+ Amplitude.setSongPlayedPercentage(99.99);
2075
+
2076
+ // fade-out audio (if enabled)
2077
+ var fadeAudioOut = (songMetaData.audio_fade_out === 'true') ? true : false;
2078
+ if (fadeAudioOut) {
2079
+ logger.debug('fade audio out on playlist: ' + playList + ' at|to trackID|timestamp: ' + trackID + '|' + songEndTS);
2080
+ atpFadeAudioOut({ playerID: playerID });
2081
+ } // END if fadeAudio
2082
+
2083
+ clearInterval(checkIsOnVideoEnd);
2084
+ } // END if currentAudioTime
2085
+ } // END if !isFading
2086
+ }, 100); // END checkIsOnVideoEnd
2087
+ } // END if songEndSec
2088
+
2089
+ }, // END atpProcessAudioEndPosition
2090
+
2091
+ // -------------------------------------------------------------------------
2092
+ // setSongActive(currentPlayList, currentIndex)
2093
+ //
2094
+ // set song active at index in playlist
2095
+ // -------------------------------------------------------------------------
2096
+ setSongActive: (currentPlayList, currentIndex) => {
2097
+ var playlist, songContainers, songIndex;
2098
+
2099
+ songIndex = currentIndex;
2100
+
2101
+ // clear ALL active song containers
2102
+ // -------------------------------------------------------------------------
2103
+ songContainers = document.getElementsByClassName("amplitude-song-container");
2104
+ for (var i=0; i<songContainers.length; i++) {
2105
+ songContainers[i].classList.remove("amplitude-active-song-container");
2106
+ }
2107
+
2108
+ // find current song container and activate the element
2109
+ // -------------------------------------------------------------------------
2110
+ songContainers = document.querySelectorAll('.amplitude-song-container[data-amplitude-song-index="' + songIndex + '"]');
2111
+ for (var i=0; i<songContainers.length; i++) {
2112
+ if (songContainers[i].hasAttribute("data-amplitude-playlist")) {
2113
+ playlist = songContainers[i].getAttribute("data-amplitude-playlist");
2114
+ if (playlist === currentPlayList) {
2115
+ songContainers[i].classList.add("amplitude-active-song-container");
2116
+ }
2017
2117
  }
2018
2118
  }
2019
2119
 
2020
- }, // END atUpdateSongRating
2120
+ }, // END setSongActive
2121
+
2122
+ // -------------------------------------------------------------------------
2123
+ // timestamp2seconds(timestamp)
2124
+ //
2125
+ // converts a timestamp of hh:mm:ss into seconds
2126
+ // -------------------------------------------------------------------------
2127
+ // TODO:
2128
+ // Add support for timestamp w/o hours like mm:ss
2129
+ // -------------------------------------------------------------------------
2130
+ timestamp2seconds: (timestamp) => {
2131
+ // split timestamp
2132
+ const parts = timestamp.split(':');
2133
+
2134
+ // check timestamp format
2135
+ if (parts.length !== 3) {
2136
+ // return "invalid timestamp";
2137
+ return false;
2138
+ }
2139
+
2140
+ // convert parts to integers
2141
+ const hours = parseInt(parts[0], 10);
2142
+ const minutes = parseInt(parts[1], 10);
2143
+ const seconds = parseInt(parts[2], 10);
2144
+
2145
+ // check valid timestamp values
2146
+ if (isNaN(hours) || isNaN(minutes) || isNaN(seconds) ||
2147
+ hours < 0 || hours > 23 ||
2148
+ minutes < 0 || minutes > 59 ||
2149
+ seconds < 0 || seconds > 59) {
2150
+ return "invalid timestamp";
2151
+ }
2152
+
2153
+ const totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
2154
+
2155
+ return totalSeconds;
2156
+ }, // END timestamp2seconds
2157
+
2158
+ // -------------------------------------------------------------------------
2159
+ // seconds2timestamp(seconds)
2160
+ //
2161
+ // converts seconds into a timestamp of hh:mm:ss
2162
+ // -------------------------------------------------------------------------
2163
+ seconds2timestamp: (seconds) => {
2164
+ if (isNaN(seconds)) {
2165
+ return false;
2166
+ }
2167
+
2168
+ const hours = Math.floor(seconds / 3600);
2169
+ const minutes = Math.floor((seconds % 3600) / 60);
2170
+ const remainSeconds = seconds % 60;
2171
+ const tsHours = hours.toString().padStart(2, '0');
2172
+ const tsMinutes = minutes.toString().padStart(2, '0');
2173
+ const tsSeconds = remainSeconds.toString().padStart(2, '0');
2174
+
2175
+ return `${tsHours}:${tsMinutes}:${tsSeconds}`;
2176
+ }, // END seconds2timestamp
2021
2177
 
2022
2178
  // -------------------------------------------------------------------------
2023
2179
  // messageHandler()
@@ -2026,7 +2182,7 @@ j1.adapter.amplitude = ((j1, window) => {
2026
2182
  messageHandler: (sender, message) => {
2027
2183
  var json_message = JSON.stringify(message, undefined, 2);
2028
2184
 
2029
- logText = '\n' + 'received message from ' + sender + ': ' + json_message;
2185
+ logText = 'received message from ' + sender + ': ' + json_message;
2030
2186
  logger.debug(logText);
2031
2187
 
2032
2188
  // -----------------------------------------------------------------------
@@ -2038,7 +2194,7 @@ j1.adapter.amplitude = ((j1, window) => {
2038
2194
  // place handling of command|action here
2039
2195
  //
2040
2196
 
2041
- logger.info('\n' + message.text);
2197
+ logger.info(message.text);
2042
2198
  }
2043
2199
 
2044
2200
  //