Source: ui/skip_ad_button.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ui.SkipAdButton');
  7. goog.require('goog.asserts');
  8. goog.require('shaka.ads.Utils');
  9. goog.require('shaka.ui.Element');
  10. goog.require('shaka.ui.Locales');
  11. goog.require('shaka.ui.Localization');
  12. goog.require('shaka.ui.Utils');
  13. goog.require('shaka.util.Dom');
  14. goog.require('shaka.util.Timer');
  15. goog.requireType('shaka.ui.Controls');
  16. /**
  17. * @extends {shaka.ui.Element}
  18. * @final
  19. * @export
  20. */
  21. shaka.ui.SkipAdButton = class extends shaka.ui.Element {
  22. /**
  23. * @param {!HTMLElement} parent
  24. * @param {!shaka.ui.Controls} controls
  25. */
  26. constructor(parent, controls) {
  27. super(parent, controls);
  28. /** @private {!HTMLElement} */
  29. this.container_ = shaka.util.Dom.createHTMLElement('div');
  30. this.container_.classList.add('shaka-skip-ad-container');
  31. this.parent.appendChild(this.container_);
  32. /** @private {!HTMLElement} */
  33. this.counter_ = shaka.util.Dom.createHTMLElement('div');
  34. this.counter_.classList.add('shaka-skip-ad-counter');
  35. shaka.ui.Utils.setDisplay(this.counter_, false);
  36. this.container_.appendChild(this.counter_);
  37. /** @private {!HTMLButtonElement} */
  38. this.button_ = shaka.util.Dom.createButton();
  39. this.button_.classList.add('shaka-skip-ad-button');
  40. this.button_.disabled = true;
  41. shaka.ui.Utils.setDisplay(this.button_, false);
  42. this.button_.classList.add('shaka-no-propagation');
  43. this.container_.appendChild(this.button_);
  44. this.updateAriaLabel_();
  45. this.updateLocalizedStrings_();
  46. /**
  47. * The timer that tracks down the ad progress until it can be skipped.
  48. *
  49. * @private {shaka.util.Timer}
  50. */
  51. this.timer_ = new shaka.util.Timer(() => {
  52. this.onTimerTick_();
  53. });
  54. this.eventManager.listen(
  55. this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
  56. this.updateAriaLabel_();
  57. this.updateLocalizedStrings_();
  58. });
  59. this.eventManager.listen(
  60. this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
  61. this.updateAriaLabel_();
  62. this.updateLocalizedStrings_();
  63. });
  64. this.eventManager.listen(
  65. this.adManager, shaka.ads.Utils.AD_STARTED, () => {
  66. this.onAdStarted_();
  67. });
  68. this.eventManager.listen(
  69. this.adManager, shaka.ads.Utils.AD_SKIP_STATE_CHANGED, () => {
  70. this.onSkipStateChanged_();
  71. });
  72. this.eventManager.listen(
  73. this.adManager, shaka.ads.Utils.AD_STOPPED, () => {
  74. this.reset_();
  75. });
  76. this.eventManager.listen(
  77. this.button_, 'click', () => {
  78. this.ad.skip();
  79. });
  80. if (this.ad) {
  81. // There was already an ad.
  82. this.onAdStarted_();
  83. }
  84. }
  85. /**
  86. * @override
  87. */
  88. release() {
  89. this.timer_.stop();
  90. this.timer_ = null;
  91. super.release();
  92. }
  93. /**
  94. * @private
  95. */
  96. updateLocalizedStrings_() {
  97. const LocIds = shaka.ui.Locales.Ids;
  98. this.button_.textContent = this.localization.resolve(LocIds.SKIP_AD);
  99. }
  100. /**
  101. * @private
  102. */
  103. updateAriaLabel_() {
  104. // TODO
  105. }
  106. /**
  107. * @private
  108. */
  109. onAdStarted_() {
  110. if (this.ad.isSkippable() && this.ad.needsSkipUI()) {
  111. shaka.ui.Utils.setDisplay(this.button_, true);
  112. shaka.ui.Utils.setDisplay(this.counter_, true);
  113. this.counter_.textContent = '';
  114. this.timer_.tickNow();
  115. this.timer_.tickEvery(0.5);
  116. }
  117. }
  118. /**
  119. * @private
  120. */
  121. onTimerTick_() {
  122. goog.asserts.assert(this.ad != null,
  123. 'this.ad should exist at this point');
  124. if (this.ad.isSkippable()) {
  125. const secondsLeft = Math.round(this.ad.getTimeUntilSkippable());
  126. if (secondsLeft > 0) {
  127. this.counter_.textContent = secondsLeft;
  128. } else {
  129. // The ad should now be skippable. OnSkipStateChanged() is
  130. // listening for a SKIP_STATE_CHANGED event and will take care
  131. // of the button. Here we just stop the timer and hide the counter.
  132. // NOTE: onSkipStateChanged_() also hides the counter.
  133. this.timer_.stop();
  134. shaka.ui.Utils.setDisplay(this.counter_, false);
  135. }
  136. } else {
  137. this.reset_();
  138. }
  139. }
  140. /**
  141. * @private
  142. */
  143. onSkipStateChanged_() {
  144. // Double-check that the ad is now skippable
  145. if (!this.ad.isSkippable()) {
  146. this.reset_();
  147. } else if (this.ad.canSkipNow()) {
  148. this.button_.disabled = false;
  149. this.timer_.stop();
  150. shaka.ui.Utils.setDisplay(this.counter_, false);
  151. }
  152. }
  153. /**
  154. * @private
  155. */
  156. reset_() {
  157. this.timer_.stop();
  158. this.button_.disabled = true;
  159. shaka.ui.Utils.setDisplay(this.button_, false);
  160. shaka.ui.Utils.setDisplay(this.counter_, false);
  161. }
  162. };