ng-prime-tools 1.1.12 → 1.1.14

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.
@@ -9794,6 +9794,7 @@ var PTNewsTickerTrend;
9794
9794
 
9795
9795
  class PTNewsTickerComponent {
9796
9796
  static { this.SCROLL_ANIMATION_NAME = 'pt-news-ticker-scroll'; }
9797
+ static { this.MINIMUM_CYCLE_TIMEOUT_MS = 50; }
9797
9798
  constructor(changeDetectorRef, zone) {
9798
9799
  this.changeDetectorRef = changeDetectorRef;
9799
9800
  this.zone = zone;
@@ -9843,6 +9844,7 @@ class PTNewsTickerComponent {
9843
9844
  this.hovered = false;
9844
9845
  this.pendingNews = null;
9845
9846
  this.animationFrameId = null;
9847
+ this.pendingNewsCycleTimeoutId = null;
9846
9848
  this.viewInitialized = false;
9847
9849
  this.applyingPendingNews = false;
9848
9850
  this.newBadgeTimeouts = new Map();
@@ -9851,11 +9853,15 @@ class PTNewsTickerComponent {
9851
9853
  ngOnChanges(changes) {
9852
9854
  if (changes['news']) {
9853
9855
  const normalizedNews = this.normalizeNews(changes['news'].currentValue ?? []);
9854
- this.queueOrApplyNews(normalizedNews);
9856
+ this.queueInputNewsWithoutRestart(normalizedNews);
9855
9857
  }
9856
9858
  if (changes['speed'] || changes['minSpeed'] || changes['maxSpeed']) {
9857
9859
  this.speed = this.normalizeSpeed(this.speed);
9860
+ this.clearPendingNewsCycleTimeout();
9858
9861
  this.scheduleAnimationRefresh(true);
9862
+ if (this.pendingNews) {
9863
+ this.schedulePendingNewsAtCurrentCycleEnd();
9864
+ }
9859
9865
  }
9860
9866
  if (changes['defaultSpeed']) {
9861
9867
  this.defaultSpeed = this.normalizeSpeed(this.defaultSpeed);
@@ -9869,12 +9875,19 @@ class PTNewsTickerComponent {
9869
9875
  if (!this.playing) {
9870
9876
  this.applyPendingNewsImmediately();
9871
9877
  }
9878
+ else if (this.pendingNews) {
9879
+ this.schedulePendingNewsAtCurrentCycleEnd();
9880
+ }
9872
9881
  }
9873
9882
  if (changes['gap'] ||
9874
9883
  changes['height'] ||
9875
9884
  changes['direction'] ||
9876
9885
  changes['loop']) {
9886
+ this.clearPendingNewsCycleTimeout();
9877
9887
  this.scheduleAnimationRefresh(true);
9888
+ if (this.pendingNews) {
9889
+ this.schedulePendingNewsAtCurrentCycleEnd();
9890
+ }
9878
9891
  }
9879
9892
  }
9880
9893
  ngAfterViewInit() {
@@ -9883,6 +9896,9 @@ class PTNewsTickerComponent {
9883
9896
  this.initializeResizeObserver();
9884
9897
  this.scheduleAnimationRefresh(true);
9885
9898
  this.changeDetectorRef.detectChanges();
9899
+ if (this.pendingNews) {
9900
+ this.schedulePendingNewsAtCurrentCycleEnd();
9901
+ }
9886
9902
  }
9887
9903
  ngOnDestroy() {
9888
9904
  this.resizeObserver?.disconnect();
@@ -9891,6 +9907,7 @@ class PTNewsTickerComponent {
9891
9907
  cancelAnimationFrame(this.animationFrameId);
9892
9908
  this.animationFrameId = null;
9893
9909
  }
9910
+ this.clearPendingNewsCycleTimeout();
9894
9911
  this.clearNewBadgeTimeouts();
9895
9912
  this.pendingNews = null;
9896
9913
  }
@@ -9927,6 +9944,7 @@ class PTNewsTickerComponent {
9927
9944
  });
9928
9945
  }
9929
9946
  clearNews() {
9947
+ this.clearPendingNewsCycleTimeout();
9930
9948
  this.pendingNews = null;
9931
9949
  this.internalNews = [];
9932
9950
  this.clearNewBadgeTimeouts();
@@ -9949,6 +9967,9 @@ class PTNewsTickerComponent {
9949
9967
  }
9950
9968
  this.playing = true;
9951
9969
  this.emitPlayStateChange();
9970
+ if (this.pendingNews) {
9971
+ this.schedulePendingNewsAtCurrentCycleEnd();
9972
+ }
9952
9973
  }
9953
9974
  pause() {
9954
9975
  if (!this.playing) {
@@ -9963,6 +9984,10 @@ class PTNewsTickerComponent {
9963
9984
  this.emitPlayStateChange();
9964
9985
  if (!this.playing) {
9965
9986
  this.applyPendingNewsImmediately();
9987
+ return;
9988
+ }
9989
+ if (this.pendingNews) {
9990
+ this.schedulePendingNewsAtCurrentCycleEnd();
9966
9991
  }
9967
9992
  }
9968
9993
  increaseSpeed() {
@@ -9986,16 +10011,24 @@ class PTNewsTickerComponent {
9986
10011
  speed: nextSpeed,
9987
10012
  });
9988
10013
  this.emitPlayStateChange();
10014
+ this.clearPendingNewsCycleTimeout();
9989
10015
  this.scheduleAnimationRefresh(true);
10016
+ if (this.pendingNews) {
10017
+ this.schedulePendingNewsAtCurrentCycleEnd();
10018
+ }
9990
10019
  }
9991
10020
  onMouseEnter() {
9992
10021
  if (!this.pauseOnHover) {
9993
10022
  return;
9994
10023
  }
9995
10024
  this.hovered = true;
10025
+ this.clearPendingNewsCycleTimeout();
9996
10026
  }
9997
10027
  onMouseLeave() {
9998
10028
  this.hovered = false;
10029
+ if (this.pendingNews && this.playing) {
10030
+ this.schedulePendingNewsAtCurrentCycleEnd();
10031
+ }
9999
10032
  }
10000
10033
  onTrackAnimationIteration(event) {
10001
10034
  if (!this.isTickerScrollEvent(event)) {
@@ -10179,16 +10212,38 @@ class PTNewsTickerComponent {
10179
10212
  ? 0
10180
10213
  : -1;
10181
10214
  }
10215
+ queueInputNewsWithoutRestart(news) {
10216
+ const clonedNews = this.cloneNews(news);
10217
+ this.scheduleNewBadges(clonedNews);
10218
+ if (!this.viewInitialized ||
10219
+ !this.loop ||
10220
+ !this.playing ||
10221
+ this.internalNews.length === 0 ||
10222
+ this.prefersReducedMotion()) {
10223
+ this.clearPendingNewsCycleTimeout();
10224
+ this.pendingNews = null;
10225
+ this.internalNews = clonedNews;
10226
+ if (this.viewInitialized) {
10227
+ this.changeDetectorRef.detectChanges();
10228
+ this.scheduleAnimationRefresh(true);
10229
+ }
10230
+ return;
10231
+ }
10232
+ this.pendingNews = clonedNews;
10233
+ this.schedulePendingNewsAtCurrentCycleEnd();
10234
+ }
10182
10235
  queueOrApplyNews(news) {
10183
10236
  const clonedNews = this.cloneNews(news);
10184
10237
  this.scheduleNewBadges(clonedNews);
10185
10238
  if (this.shouldApplyNewsImmediately()) {
10239
+ this.clearPendingNewsCycleTimeout();
10186
10240
  this.pendingNews = null;
10187
10241
  this.internalNews = clonedNews;
10188
10242
  this.scheduleAnimationRefresh(true);
10189
10243
  return;
10190
10244
  }
10191
10245
  this.pendingNews = clonedNews;
10246
+ this.schedulePendingNewsAtCurrentCycleEnd();
10192
10247
  }
10193
10248
  shouldApplyNewsImmediately() {
10194
10249
  return (!this.viewInitialized ||
@@ -10197,10 +10252,63 @@ class PTNewsTickerComponent {
10197
10252
  this.internalNews.length === 0 ||
10198
10253
  this.prefersReducedMotion());
10199
10254
  }
10255
+ schedulePendingNewsAtCurrentCycleEnd() {
10256
+ if (!this.pendingNews ||
10257
+ this.pendingNewsCycleTimeoutId !== null ||
10258
+ !this.viewInitialized ||
10259
+ !this.playing ||
10260
+ this.hovered) {
10261
+ return;
10262
+ }
10263
+ const remainingDuration = this.resolveCurrentCycleRemainingDuration();
10264
+ this.zone.runOutsideAngular(() => {
10265
+ this.pendingNewsCycleTimeoutId = setTimeout(() => {
10266
+ this.zone.run(() => {
10267
+ this.pendingNewsCycleTimeoutId = null;
10268
+ if (!this.playing || this.hovered) {
10269
+ return;
10270
+ }
10271
+ this.applyPendingNewsAtCycleBoundary();
10272
+ });
10273
+ }, remainingDuration);
10274
+ });
10275
+ }
10276
+ resolveCurrentCycleRemainingDuration() {
10277
+ const trackElement = this.tickerTrack?.nativeElement;
10278
+ const fallbackDuration = Math.max(PTNewsTickerComponent.MINIMUM_CYCLE_TIMEOUT_MS, this.animationDurationSeconds * 1000);
10279
+ if (!trackElement || typeof trackElement.getAnimations !== 'function') {
10280
+ return fallbackDuration;
10281
+ }
10282
+ const animation = trackElement
10283
+ .getAnimations()
10284
+ .find((candidate) => candidate.playState !== 'idle');
10285
+ if (!animation) {
10286
+ return fallbackDuration;
10287
+ }
10288
+ const computedTiming = animation.effect?.getComputedTiming();
10289
+ const animationDuration = typeof computedTiming?.duration === 'number'
10290
+ ? computedTiming.duration
10291
+ : fallbackDuration;
10292
+ const currentTime = typeof animation.currentTime === 'number' ? animation.currentTime : 0;
10293
+ if (!Number.isFinite(animationDuration) || animationDuration <= 0) {
10294
+ return fallbackDuration;
10295
+ }
10296
+ const elapsedInCurrentCycle = currentTime % animationDuration;
10297
+ const remainingDuration = animationDuration - elapsedInCurrentCycle;
10298
+ return Math.max(PTNewsTickerComponent.MINIMUM_CYCLE_TIMEOUT_MS, Math.ceil(remainingDuration));
10299
+ }
10300
+ clearPendingNewsCycleTimeout() {
10301
+ if (this.pendingNewsCycleTimeoutId === null) {
10302
+ return;
10303
+ }
10304
+ clearTimeout(this.pendingNewsCycleTimeoutId);
10305
+ this.pendingNewsCycleTimeoutId = null;
10306
+ }
10200
10307
  applyPendingNewsAtCycleBoundary() {
10201
10308
  if (!this.pendingNews || this.applyingPendingNews) {
10202
10309
  return;
10203
10310
  }
10311
+ this.clearPendingNewsCycleTimeout();
10204
10312
  this.applyingPendingNews = true;
10205
10313
  const nextNews = this.cloneNews(this.pendingNews);
10206
10314
  this.pendingNews = null;
@@ -10212,6 +10320,9 @@ class PTNewsTickerComponent {
10212
10320
  this.zone.run(() => {
10213
10321
  this.calculateAnimationDuration();
10214
10322
  this.applyingPendingNews = false;
10323
+ if (this.pendingNews) {
10324
+ this.schedulePendingNewsAtCurrentCycleEnd();
10325
+ }
10215
10326
  });
10216
10327
  });
10217
10328
  });
@@ -10221,6 +10332,7 @@ class PTNewsTickerComponent {
10221
10332
  if (!this.pendingNews) {
10222
10333
  return;
10223
10334
  }
10335
+ this.clearPendingNewsCycleTimeout();
10224
10336
  const nextNews = this.cloneNews(this.pendingNews);
10225
10337
  this.pendingNews = null;
10226
10338
  this.internalNews = nextNews;
@@ -10343,7 +10455,11 @@ class PTNewsTickerComponent {
10343
10455
  this.zone.runOutsideAngular(() => {
10344
10456
  this.resizeObserver = new ResizeObserver(() => {
10345
10457
  this.zone.run(() => {
10458
+ this.clearPendingNewsCycleTimeout();
10346
10459
  this.scheduleAnimationRefresh(true);
10460
+ if (this.pendingNews) {
10461
+ this.schedulePendingNewsAtCurrentCycleEnd();
10462
+ }
10347
10463
  });
10348
10464
  });
10349
10465
  this.resizeObserver.observe(viewportElement);