@internetarchive/ia-book-actions 0.1.10 → 0.1.11-b1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "0.1.10",
3
+ "version": "0.1.11-b1",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -1,12 +1,9 @@
1
1
  import { html, css, LitElement } from 'lit';
2
- import { sentryLogs } from '../core/config/sentry-events.js';
3
2
 
4
3
  export default class TimerCountdown extends LitElement {
5
4
  static get properties() {
6
5
  return {
7
6
  secondsLeftOnLoan: { type: Number }, // in seconds
8
- loanTotalTime: { type: Number }, // in seconds
9
- loanRenewAtLast: { type: Number }, // in seconds
10
7
  };
11
8
  }
12
9
 
@@ -18,139 +15,6 @@ export default class TimerCountdown extends LitElement {
18
15
  * @type {number}
19
16
  */
20
17
  this.secondsLeftOnLoan = 0;
21
-
22
- /**
23
- * total seconds a loan does have
24
- * @type {number}
25
- */
26
- this.loanTotalTime = 0;
27
-
28
- /**
29
- * at the remaining time, we attempt to renew current loan
30
- * @type {number}
31
- */
32
- this.loanRenewAtLast = 0;
33
-
34
- /**
35
- * store time when timer is started
36
- * @type {string}
37
- */
38
- this.timeWhenTimerStart = '';
39
-
40
- /**
41
- * delay seconds in setInterval function
42
- * @type {number}
43
- */
44
- this.timerExecutionSeconds = 30;
45
- }
46
-
47
- disconnectedCallback() {
48
- window?.IALendingIntervals?.clearTimerCountdown();
49
- }
50
-
51
- firstUpdated() {
52
- this.timerCountdown();
53
- }
54
-
55
- updated(changed) {
56
- if (changed.has('secondsLeftOnLoan') && this.secondsLeftOnLoan > 0) {
57
- this.timerCountdown();
58
- }
59
- }
60
-
61
- timerCountdown() {
62
- this.disconnectedCallback();
63
-
64
- let secondsLeft = this.secondsLeftOnLoan;
65
-
66
- // store current time
67
- this.timeWhenTimerStart = new Date();
68
-
69
- // this.dispatchLoanRenewEvent(secondsLeft);
70
- /**
71
- * set interval in window object
72
- * @see ia-lending-intervals.js
73
- */
74
- window.IALendingIntervals.timerCountdown = setInterval(async () => {
75
- secondsLeft -= this.timerExecutionSeconds;
76
- secondsLeft = Math.round(secondsLeft); // round number
77
-
78
- // re-sync timer if gone off because of background window
79
- await this.reSyncTimerIfGoneOff(secondsLeft);
80
-
81
- /**
82
- * execute from last 10th minute to 0th minute
83
- * - 10th - to check if user has viewed
84
- * - till 0th - to show warning msg with remaining time to auto expired
85
- * @see IABookActions::bindLoanRenewEvents
86
- */
87
- if (secondsLeft <= this.loanRenewAtLast) {
88
- this.dispatchLoanRenewEvent(secondsLeft);
89
- }
90
-
91
- // clear interval in secondsLeft if less
92
- if (secondsLeft <= this.timerExecutionSeconds) {
93
- this.disconnectedCallback();
94
- window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
95
- }
96
- }, this.timerExecutionSeconds * 1000);
97
- }
98
-
99
- /**
100
- * dispatch loan renew attempt event
101
- *
102
- * @param {number} secondsLeft
103
- * @memberof TimerCountdown
104
- */
105
- dispatchLoanRenewEvent(secondsLeft) {
106
- this.dispatchEvent(
107
- new CustomEvent('IABookActions:loanRenew', {
108
- detail: {
109
- hasPageChanged: false,
110
- secondsLeft,
111
- },
112
- bubbles: true,
113
- composed: true,
114
- })
115
- );
116
- }
117
-
118
- /**
119
- * helper function to determine if timer is not in sync properly
120
- *
121
- * @param {number} timerSecondsLeft - actual seconds left get from setInterval
122
- *
123
- * @memberof TimerCountdown
124
- */
125
- async reSyncTimerIfGoneOff(timerSecondsLeft) {
126
- // debug info
127
- console.log(
128
- new Date().toLocaleTimeString(),
129
- 'timeLeftInSec',
130
- timerSecondsLeft,
131
- ' ||| timeLeftInMin',
132
- Math.ceil(timerSecondsLeft / 60)
133
- );
134
-
135
- const currentTime = new Date();
136
-
137
- // current time - loan time
138
- const diffInSeconds =
139
- currentTime.getTime() / 1000 - this.timeWhenTimerStart.getTime() / 1000;
140
-
141
- const secondsShouldLeft = this.secondsLeftOnLoan - diffInSeconds;
142
-
143
- // convert in minutes
144
- const whatIsleft = Math.round(timerSecondsLeft);
145
- const whatShouldLeft = Math.round(secondsShouldLeft);
146
-
147
- if (whatIsleft !== whatShouldLeft) {
148
- // debug info
149
- console.log(
150
- `timer is gone off, let's re-sync, whatIsleft -> ${whatIsleft}, whatShouldLeft -> ${whatShouldLeft}`
151
- );
152
- this.secondsLeftOnLoan = secondsShouldLeft; // the seconds should left in timer again
153
- }
154
18
  }
155
19
 
156
20
  /**
@@ -142,6 +142,7 @@ export default class ActionsHandler extends LitElement {
142
142
  action,
143
143
  identifier: this.identifier,
144
144
  success: data => {
145
+ console.log("RENEW_LOAN --- ", data, action, data.loan, this.identifier);
145
146
  if (data?.success === true && data?.loan?.renewal === true) {
146
147
  this.setBrowseTimeSession();
147
148
  this.dispatchEvent(
@@ -86,15 +86,12 @@ export default class IABookActions extends LitElement {
86
86
  this.primaryColor = 'primary';
87
87
  this.secondaryActions = [];
88
88
  this.lendingOptions = {};
89
- this.borrowType = ''; // (browsed|borrowed)
89
+ this.borrowType = null; // (browsed|borrowed)
90
90
  this.browseTimer = undefined;
91
+ this.timerExecutionSeconds = 30;
91
92
 
92
93
  /** @deprecated */
93
94
  this.toast = undefined;
94
- /** @deprecated */
95
- this.suppressToast = false;
96
- /** @deprecated */
97
- this.suppressAutoRenew = false;
98
95
 
99
96
  /**
100
97
  * when user click on [return the book] button on warning modal
@@ -196,9 +193,6 @@ export default class IABookActions extends LitElement {
196
193
  /** End SharedObserver resize handler */
197
194
 
198
195
  async setupLendingToolbarActions() {
199
- this.suppressToast = false;
200
- this.suppressAutoRenew = false;
201
-
202
196
  this.lendingOptions = new GetLendingActions(
203
197
  this.userid,
204
198
  this.identifier,
@@ -218,7 +212,7 @@ export default class IABookActions extends LitElement {
218
212
  return action != null;
219
213
  });
220
214
 
221
- this.borrowType = actions.borrowType;
215
+ this.borrowType = actions.borrowType ? actions.borrowType : null;
222
216
 
223
217
  const hasExpired =
224
218
  'browsingExpired' in this.lendingStatus &&
@@ -243,7 +237,9 @@ export default class IABookActions extends LitElement {
243
237
  }
244
238
 
245
239
  if (this.borrowType === 'browsed') {
246
- console.log('this.borrowType', this.borrowType);
240
+ // start timer for loan-renew
241
+ await this.startTimerCountdown();
242
+
247
243
  // start timer for browsed.
248
244
  await this.startBrowseTimer();
249
245
  }
@@ -285,41 +281,6 @@ export default class IABookActions extends LitElement {
285
281
  this.autoLoanRenewChecker(true);
286
282
  }
287
283
  });
288
-
289
- /**
290
- * this event dispatched from timer-countdown component for:
291
- * 1. user turned book page after showing auto-returned warning modal
292
- * 2. show warning modal having remaining time
293
- * @see TimerCountdown::timerCountdown
294
- */
295
- this.addEventListener('IABookActions:loanRenew', async event => {
296
- await this.autoLoanRenewChecker(false);
297
-
298
- /**
299
- * auto-renew is not possible in last seconds (let say 50 second) because,
300
- * 1. less time to execute ajax call
301
- * 2. less time to write loan on datanodes
302
- * 3. less time to load images by create_token api
303
- * so if seconds left is < 50, just expire the loan
304
- */
305
- let secondsLeft = event?.detail?.secondsLeft;
306
- if (secondsLeft < 50) {
307
- this.suppressAutoRenew = true;
308
- this.browseHasExpired();
309
- }
310
-
311
- // show warning modal with remaining time to auto returned it.
312
- if (this.loanRenewResult.renewNow === false) {
313
- /**
314
- * so compensate for the 50 second buffer to handle above race conditions
315
- * let's reduce 1 min from warning texts and early return the book when 1 min left.
316
- */
317
- secondsLeft -= 60;
318
- this.loanRenewResult.secondsLeft = secondsLeft;
319
-
320
- this.showWarningModal();
321
- }
322
- });
323
284
  }
324
285
 
325
286
  /**
@@ -383,9 +344,9 @@ export default class IABookActions extends LitElement {
383
344
  <div id="custom-buttons" style="display:flex;justify-content:center;">
384
345
  <button
385
346
  style="${modalButtonStyle.iaButton} ${modalButtonStyle.renew}"
386
- @click=${event => {
387
- this.changeModalState(event);
388
- this.autoLoanRenewChecker(true);
347
+ @click=${async event => {
348
+ await this.changeModalState(event);
349
+ this.loanRenewResult = { texts: '', renewNow: true };
389
350
  }}
390
351
  >
391
352
  Keep reading
@@ -402,7 +363,7 @@ export default class IABookActions extends LitElement {
402
363
  </button>
403
364
  </div> `;
404
365
 
405
- this.modal.showModal({ config, customModalContent: customContent });
366
+ this.modal?.showModal({ config, customModalContent: customContent });
406
367
  }
407
368
 
408
369
  /**
@@ -430,6 +391,7 @@ export default class IABookActions extends LitElement {
430
391
  * Show modal when book is auto returned
431
392
  */
432
393
  async showExpiredModal() {
394
+ console.log('showExpiredModal()');
433
395
  await this.useModalManager();
434
396
 
435
397
  const config = new ModalConfig();
@@ -494,12 +456,6 @@ export default class IABookActions extends LitElement {
494
456
  * - show message having remaining time when book is about to auto returned
495
457
  */
496
458
  async showToastMessage() {
497
- console.log('** showToastMessage', {
498
- suppressToast: this.suppressToast,
499
- loanRenewResult: this.loanRenewResult,
500
- });
501
- if (this.suppressToast) return;
502
-
503
459
  await this.useToastManager();
504
460
 
505
461
  // if secondsLeft < 60, consider it 1 minute
@@ -523,7 +479,6 @@ export default class IABookActions extends LitElement {
523
479
  }
524
480
 
525
481
  async browseHasRenew() {
526
- console.log('****** browseHasRenew ******');
527
482
  window?.IALendingIntervals?.clearAll();
528
483
 
529
484
  const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
@@ -556,7 +511,7 @@ export default class IABookActions extends LitElement {
556
511
  this.loanRenewResult.texts =
557
512
  'This book has been returned due to inactivity.';
558
513
 
559
- this.showExpiredModal();
514
+ await this.showExpiredModal();
560
515
 
561
516
  window?.Sentry?.captureMessage(sentryLogs.browseHasExpired);
562
517
  }
@@ -574,8 +529,6 @@ export default class IABookActions extends LitElement {
574
529
  return;
575
530
  }
576
531
 
577
- console.log('user browsed', this.lendingStatus);
578
-
579
532
  this.browseTimer = setTimeout(() => {
580
533
  this.browseHasExpired();
581
534
  }, secondsLeftOnLoan * 1000);
@@ -631,8 +584,6 @@ export default class IABookActions extends LitElement {
631
584
  return this.borrowType === 'browsed'
632
585
  ? html`<timer-countdown
633
586
  .secondsLeftOnLoan=${Number(this.lendingStatus.secondsLeftOnLoan)}
634
- .loanTotalTime=${this.loanRenewTimeConfig.loanTotalTime}
635
- .loanRenewAtLast=${this.loanRenewTimeConfig.loanRenewAtLast}
636
587
  ></timer-countdown>`
637
588
  : nothing;
638
589
  }
@@ -683,7 +634,14 @@ export default class IABookActions extends LitElement {
683
634
  secondsLeftOnLoan: Math.round(this.lendingStatus.secondsLeftOnLoan),
684
635
  });
685
636
 
637
+ /**
638
+ * update the lendingStatus property
639
+ */
686
640
  await this.browseHasRenew();
641
+
642
+ /**
643
+ * reset timer countdown states
644
+ */
687
645
  await this.resetTimerCountState();
688
646
 
689
647
  // close the modal
@@ -694,6 +652,138 @@ export default class IABookActions extends LitElement {
694
652
  }
695
653
  }
696
654
 
655
+ /**
656
+ * start timer countdown interval after loan auto-renewed
657
+ *
658
+ * @memberof IABookActions
659
+ */
660
+ startTimerCountdown() {
661
+ console.log('startTimerCountdown()');
662
+ window?.IALendingIntervals?.clearTimerCountdown();
663
+
664
+ let secondsLeft = Number(this.lendingStatus.secondsLeftOnLoan);
665
+ this.timeWhenTimerStart = new Date();
666
+
667
+ window.IALendingIntervals.timerCountdown = setInterval(async () => {
668
+ secondsLeft -= this.timerExecutionSeconds;
669
+ secondsLeft = Math.round(secondsLeft); // round number
670
+
671
+ // re-sync timer if gone off because of background window
672
+ const resync = await this.reSyncTimerIfGoneOff(secondsLeft);
673
+
674
+ console.log("*** startTimerCountdown ***", secondsLeft, resync);
675
+
676
+ if (resync) {
677
+ console.log('have resyncd, will end startTimerCountdown here - ');
678
+ return;
679
+ }
680
+
681
+ console.log('startTimerCountdown - NO RESYNC');
682
+
683
+ /**
684
+ * execute from last 10th minute to 0th minute
685
+ * - 10th - to check if user has viewed
686
+ * - till 0th - to show warning msg with remaining time to auto expired
687
+ * @see IABookActions::bindLoanRenewEvents
688
+ */
689
+ if (secondsLeft <= this.loanRenewTimeConfig.loanRenewAtLast) {
690
+ await this.loanRenewAttempt(secondsLeft);
691
+ }
692
+
693
+ // clear interval in secondsLeft if less
694
+ if (secondsLeft <= this.timerExecutionSeconds) {
695
+ this.disconnectedCallback();
696
+ window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
697
+ }
698
+ }, this.timerExecutionSeconds * 1000);
699
+ }
700
+
701
+ /**
702
+ * helper function to determine if timer is not in sync properly
703
+ *
704
+ * @param {number} timerSecondsLeft - actual seconds left get from setInterval
705
+ *
706
+ * @memberof TimerCountdown
707
+ */
708
+ async reSyncTimerIfGoneOff(timerSecondsLeft) {
709
+ // debug info
710
+ console.log(
711
+ new Date().toLocaleTimeString(),
712
+ 'timeLeftInSec',
713
+ timerSecondsLeft,
714
+ ' ||| timeLeftInMin',
715
+ Math.ceil(timerSecondsLeft / 60)
716
+ );
717
+
718
+ const currentTime = new Date();
719
+
720
+ // current time - loan time
721
+ const diffInSeconds =
722
+ currentTime.getTime() / 1000 - this.timeWhenTimerStart.getTime() / 1000;
723
+
724
+ const secondsShouldLeft =
725
+ this.lendingStatus.secondsLeftOnLoan - diffInSeconds;
726
+
727
+ // convert in minutes
728
+ const whatIsleft = Math.round(timerSecondsLeft);
729
+ const whatShouldLeft = Math.round(secondsShouldLeft);
730
+
731
+ if (whatIsleft !== whatShouldLeft) {
732
+ // debug info
733
+ console.log(
734
+ `timer is gone off, let's re-sync, whatIsleft -> ${whatIsleft}, whatShouldLeft -> ${whatShouldLeft}`
735
+ );
736
+
737
+ // the seconds should left in timer again
738
+ const currStatus = {
739
+ ...this.lendingStatus,
740
+ secondsLeftOnLoan: secondsShouldLeft,
741
+ };
742
+ this.lendingStatus = currStatus;
743
+ return true;
744
+ }
745
+ return false;
746
+ }
747
+
748
+ /**
749
+ * attmept to loan renew from
750
+ * - timer countdown
751
+ * - onclick on [keep reading] button
752
+ *
753
+ * @param {*} secondsLeft
754
+ * @memberof IABookActions
755
+ */
756
+ async loanRenewAttempt(secondsLeft) {
757
+ console.log('loanRenewAttempt()', secondsLeft, this.loanRenewResult);
758
+ let loanSecondsLeft = secondsLeft;
759
+ /**
760
+ * auto-renew is not possible in last seconds (let say 50 second) because,
761
+ * 1. less time to execute ajax call
762
+ * 2. less time to write loan on datanodes
763
+ * 3. less time to load images by create_token api
764
+ * so if seconds left is < 50, just expire the loan
765
+ */
766
+ if (loanSecondsLeft < 50) {
767
+ console.log('if (loanSecondsLeft < 50) {');
768
+ await this.browseHasExpired();
769
+ return;
770
+ }
771
+
772
+ await this.autoLoanRenewChecker(false);
773
+
774
+ // show warning modal with remaining time to auto returned it.
775
+ if (this.loanRenewResult.renewNow === false) {
776
+ /**
777
+ * so compensate for the 50 second buffer to handle above race conditions
778
+ * let's reduce 1 min from warning texts and early return the book when 1 min left.
779
+ */
780
+ loanSecondsLeft -= 60;
781
+ this.loanRenewResult.secondsLeft = loanSecondsLeft;
782
+
783
+ this.showWarningModal();
784
+ }
785
+ }
786
+
697
787
  /**
698
788
  * enable access of borrowed/browsed books
699
789
  * @see LoanTokenPoller
@@ -817,7 +907,7 @@ export default class IABookActions extends LitElement {
817
907
  <code>errorLog: ${errorMsg}</code>`;
818
908
  }
819
909
 
820
- this.modal.showModal({
910
+ this.modal?.showModal({
821
911
  config: modalConfig,
822
912
  });
823
913
  }