@internetarchive/ia-book-actions 1.1.0-alpha1 → 1.1.0-alpha11

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/demo/index.html CHANGED
@@ -131,7 +131,7 @@
131
131
  iaBookActions.returnUrl = '';
132
132
  iaBookActions.localCache = localCache;
133
133
 
134
- let loanTotalTime2Min = { loanTotalTime: 65, loanRenewAtLast: 60, pageChangedInLast: 15 };
134
+ let loanTotalTime2Min = { loanTotalTime: 170, loanRenewAtLast: 80, pageChangedInLast: 15 };
135
135
  let loanTotalTime5Min = { loanTotalTime: 300, loanRenewAtLast: 180, pageChangedInLast: 15 };
136
136
  let loanTotalTime1Hour = { loanTotalTime: 3600, loanRenewAtLast: 660, pageChangedInLast: 900 };
137
137
 
@@ -390,7 +390,6 @@
390
390
  </div>
391
391
  <div>
392
392
  <button id="show_expired_modal">While Browsing (`user_has_browsed`), Expire book & show its modal</button>
393
- how_expired_modal
394
393
  </div>
395
394
  </td>
396
395
  <td class="availableToBorrow">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "1.1.0-alpha1",
3
+ "version": "1.1.0-alpha11",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -14,18 +14,16 @@
14
14
  "lint": "eslint --ext .js,.html . --ignore-path .gitignore && prettier \"**/*.js\" --check --ignore-path .gitignore",
15
15
  "format": "eslint --ext .js,.html . --fix --ignore-path .gitignore && prettier \"**/*.js\" --write --ignore-path .gitignore",
16
16
  "test": "yarn run lint && yarn test:fast",
17
- "test:fast": "web-test-runner --coverage --playwright --browsers chromium firefox webkit",
18
- "test:watch": "web-test-runner --watch --playwright --browsers chromium firefox webkit"
17
+ "test:fast": "web-test-runner --coverage",
18
+ "test:watch": "web-test-runner --watch"
19
19
  },
20
20
  "dependencies": {
21
21
  "@internetarchive/icon-info": "^1.2.6",
22
22
  "@internetarchive/local-cache": "^0.2.1",
23
- "@internetarchive/modal-manager": "^0.2.12",
23
+ "@internetarchive/modal-manager": "2.0.0",
24
24
  "@internetarchive/shared-resize-observer": "^0.2.0",
25
- "@internetarchive/toast-manager": "0.1.0",
26
25
  "install-deps": "^1.1.0",
27
- "lit": "^2.5.0",
28
- "playwright": "^1.43.1"
26
+ "lit": "^2.8.0"
29
27
  },
30
28
  "devDependencies": {
31
29
  "@open-wc/eslint-config": "^4.2.0",
@@ -118,7 +118,7 @@ export const canBrowseAndBorrow = {
118
118
  loanStartDate: '2021-07-30 09:57:40',
119
119
  loansUrl: '/details/@neeraj-archive?tab=loans#loans-on-loan',
120
120
  maxLoans: 10,
121
- secondsLeftOnLoan: 155,
121
+ secondsLeftOnLoan: 170,
122
122
  shouldProtectImages: true,
123
123
  totalWaitlistCount: 0,
124
124
  userHasBorrowed: false,
@@ -21,6 +21,7 @@ export default css`
21
21
  .action-buttons .ia-button {
22
22
  margin: 0;
23
23
  height: 3.5rem;
24
+ padding: 0 2rem;
24
25
  }
25
26
  .action-buttons .desktop {
26
27
  background-color: ${whiteColor};
@@ -36,7 +36,7 @@ export default css`
36
36
  align-items: center;
37
37
  transition: all 0.1s ease 0s;
38
38
  vertical-align: middle;
39
- padding: 0 3rem;
39
+ padding: 0 1rem;
40
40
  outline-color: ${whiteColor};
41
41
  outline-offset: -4px;
42
42
  user-select: none;
@@ -47,7 +47,7 @@ export default class TimerCountdown extends LitElement {
47
47
  }
48
48
 
49
49
  render() {
50
- const viewClass = this.displayTime ? 'view' : 'hide';
50
+ const viewClass = this.displayTime ? 'view' : 'hide1';
51
51
  return html`
52
52
  <button
53
53
  id="timer-counter"
@@ -4,7 +4,6 @@ import { html, css, LitElement, nothing } from 'lit';
4
4
 
5
5
  import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
6
6
  import { ModalConfig } from '@internetarchive/modal-manager';
7
- import { ToastConfig } from '@internetarchive/toast-manager';
8
7
  import { LocalCache } from '@internetarchive/local-cache';
9
8
 
10
9
  import './components/collapsible-action-group.js';
@@ -90,7 +89,7 @@ export default class IABookActions extends LitElement {
90
89
  this.lendingOptions = {};
91
90
  this.borrowType = null; // 'browsed'|'borrowed'
92
91
  this.browseTimer = undefined; // timeout
93
- this.timerExecutionSeconds = 30;
92
+ this.timerExecutionSeconds = 2;
94
93
 
95
94
  /** @deprecated */
96
95
  this.toast = undefined;
@@ -129,10 +128,14 @@ export default class IABookActions extends LitElement {
129
128
  // clear all intervals for lending system
130
129
  window?.IALendingIntervals?.clearAll();
131
130
 
132
- window?.Sentry?.captureMessage(sentryLogs.disconnectedCallback);
131
+ this.sentryCaptureMsg(sentryLogs.disconnectedCallback);
133
132
  this.disconnectResizeObserver();
134
133
  }
135
134
 
135
+ sentryCaptureMsg(msg) {
136
+ if (window?.Sentry) window?.Sentry?.captureMessage(msg ?? '');
137
+ }
138
+
136
139
  firstUpdated() {
137
140
  // bind auto loan renew events
138
141
  this.bindLoanRenewEvents();
@@ -224,7 +227,7 @@ export default class IABookActions extends LitElement {
224
227
  log('setupLendingToolbarActions > hasExpired --- ');
225
228
 
226
229
  if (!this.tokenPoller) {
227
- window?.Sentry?.captureMessage(sentryLogs.bookWasExpired);
230
+ this.sentryCaptureMsg(sentryLogs.bookWasExpired);
228
231
  }
229
232
  window?.IALendingIntervals?.clearAll();
230
233
 
@@ -283,6 +286,25 @@ export default class IABookActions extends LitElement {
283
286
  this.autoLoanRenewChecker(true);
284
287
  }
285
288
  });
289
+
290
+ /**
291
+ * auto-renew interval may stale when tab is in background,
292
+ * so [visibilitychange] event can trigger timer to show relavent messages
293
+ */
294
+ document.addEventListener("visibilitychange", async () => {
295
+ if (!document.hidden) {
296
+ log('visibilitychange is not hidden time: ------------------ ', new Date().getMinutes(), new Date().getSeconds());
297
+
298
+ const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
299
+ const secondsLeft = Math.round((loanTime - new Date()) / 1000); // different in seconds
300
+
301
+ if (secondsLeft >= this.timerExecutionSeconds) {
302
+ this.setIntervalExecutionBlock(Number(secondsLeft));
303
+ } else {
304
+ this.disconnectedCallback();
305
+ }
306
+ }
307
+ });
286
308
  }
287
309
 
288
310
  /**
@@ -403,7 +425,10 @@ export default class IABookActions extends LitElement {
403
425
  ></ia-activity-indicator>`
404
426
  : 'Keep reading'}
405
427
  </button>
406
- <span class="sr-only">Renewing loan, one moment please.</span>
428
+ <span
429
+ style="position: absolute; visibility: none; height: 1px; width: 1px; overflow: hidden;"
430
+ >Renewing loan, one moment please.</span
431
+ >
407
432
  <button
408
433
  disabled
409
434
  style="${modalButtonStyle.iaButton} ${modalButtonStyle.return}"
@@ -484,36 +509,6 @@ export default class IABookActions extends LitElement {
484
509
  this.toast?.remove();
485
510
  }
486
511
 
487
- /**
488
- * @deprecated
489
- * Show toast messages on some specific loan renew features. e.g.
490
- * - show message when book is auto renewed
491
- * - show message when book is expired
492
- * - show message having remaining time when book is about to auto returned
493
- */
494
- async showToastMessage() {
495
- await this.useToastManager();
496
-
497
- // if secondsLeft < 60, consider it 1 minute
498
- let { secondsLeft } = this.loanRenewResult;
499
- if (secondsLeft === undefined) {
500
- secondsLeft = this.lendingStatus.secondsLeftOnLoan;
501
- } else {
502
- secondsLeft = secondsLeft > 60 ? secondsLeft : 60;
503
- }
504
-
505
- const config = new ToastConfig();
506
- config.dismissOnClick = true;
507
- config.texts = this.loanRenewHelper?.getMessageTexts(
508
- this.loanRenewResult.texts,
509
- secondsLeft
510
- );
511
-
512
- this.toast?.showToast({
513
- config,
514
- });
515
- }
516
-
517
512
  /**
518
513
  * Execute when loan is expired
519
514
  */
@@ -539,7 +534,7 @@ export default class IABookActions extends LitElement {
539
534
 
540
535
  await this.showExpiredModal();
541
536
 
542
- window?.Sentry?.captureMessage(sentryLogs.browseHasExpired);
537
+ this.sentryCaptureMsg(sentryLogs.browseHasExpired);
543
538
  }
544
539
 
545
540
  async startBrowseTimer() {
@@ -662,7 +657,7 @@ export default class IABookActions extends LitElement {
662
657
  this.modal?.closeModal();
663
658
  this.modal.removeAttribute('id');
664
659
  this.modal.customModalContent = nothing;
665
- window?.Sentry?.captureMessage(sentryLogs.bookHasRenewed);
660
+ this.sentryCaptureMsg(sentryLogs.bookHasRenewed);
666
661
  }
667
662
  }
668
663
 
@@ -674,47 +669,61 @@ export default class IABookActions extends LitElement {
674
669
  startTimerCountdown() {
675
670
  window?.IALendingIntervals?.clearTimerCountdown();
676
671
 
677
- let secondsLeft = Number(this.lendingStatus.secondsLeftOnLoan);
672
+ const secondsLeft = Number(this.lendingStatus.secondsLeftOnLoan);
678
673
  this.timeWhenTimerStart = new Date();
679
674
 
680
675
  window.IALendingIntervals.timerCountdown = setInterval(async () => {
681
- secondsLeft -= this.timerExecutionSeconds;
682
- secondsLeft = Math.round(secondsLeft); // round number
683
-
684
- // re-sync timer if gone off because of background window
685
- // side effect: updates this.lendingStatus & kicks off lifecycle,
686
- // if really updated, escape from here
687
- const resync = await this.reSyncTimerIfGoneOff(secondsLeft);
688
-
689
- if (resync) {
690
- log('startTimerCountdown --- stale, timer has resyncd', {
691
- secondsLeft,
692
- });
693
- return;
694
- }
676
+ // interval execution block
677
+ await this.setIntervalExecutionBlock(secondsLeft);
678
+ }, this.timerExecutionSeconds * 1000);
679
+ }
695
680
 
696
- log('startTimerCountdown --- countdown still valid. continue...', {
697
- resync,
681
+ /**
682
+ * setInterval execution function do following things
683
+ * - if setInterval timer gone off, let's resync
684
+ * - loan-renew attempt to renew the loan OR show relavant message
685
+ * - if loan has expired, clear interval timers
686
+ *
687
+ * @param {Number} secondsLeftOnLoan
688
+ */
689
+ async setIntervalExecutionBlock(secondsLeftOnLoan) {
690
+ let secondsLeft = secondsLeftOnLoan;
691
+ secondsLeft -= this.timerExecutionSeconds;
692
+ secondsLeft = Math.round(secondsLeft); // round number
693
+
694
+ // re-sync timer if gone off because of background window
695
+ // side effect: updates this.lendingStatus & kicks off lifecycle,
696
+ // if really updated, escape from here
697
+ const resyncd = await this.reSyncTimerIfGoneOff(secondsLeft);
698
+
699
+ if (resyncd?.hasSynced) {
700
+ secondsLeft = resyncd.whatShouldLeft;
701
+ log('startTimerCountdown --- stale, timer has resyncd', {
698
702
  secondsLeft,
699
- loanRenewAtLast: this.loanRenewTimeConfig.loanRenewAtLast,
700
703
  });
704
+ }
701
705
 
702
- /**
703
- * execute from last 10th minute to 0th minute
704
- * - 10th - to check if user has viewed
705
- * - till 0th - to show warning msg with remaining time to auto expired
706
- * @see IABookActions::bindLoanRenewEvents
707
- */
708
- if (secondsLeft <= this.loanRenewTimeConfig.loanRenewAtLast) {
709
- await this.loanRenewAttempt(secondsLeft);
710
- }
706
+ log('startTimerCountdown --- countdown still valid. continue...', {
707
+ resyncd,
708
+ secondsLeft,
709
+ loanRenewAtLast: this.loanRenewTimeConfig.loanRenewAtLast,
710
+ }, 'time: ', new Date().getMinutes(), ':', new Date().getSeconds(), ', timerDelay: ', this.timerExecutionSeconds);
711
711
 
712
- // clear interval in secondsLeft if less
713
- if (secondsLeft <= this.timerExecutionSeconds) {
714
- this.disconnectedCallback();
715
- window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
716
- }
717
- }, this.timerExecutionSeconds * 1000);
712
+ /**
713
+ * execute from last 10th minute to 0th minute
714
+ * - 10th - to check if user has viewed
715
+ * - till 0th - to show warning msg with remaining time to auto expired
716
+ * @see IABookActions::bindLoanRenewEvents
717
+ */
718
+ if (secondsLeft <= this.loanRenewTimeConfig.loanRenewAtLast) {
719
+ await this.loanRenewAttempt(secondsLeft);
720
+ }
721
+
722
+ // clear interval in secondsLeft if less
723
+ if (secondsLeft <= this.timerExecutionSeconds) {
724
+ this.disconnectedCallback();
725
+ this.sentryCaptureMsg(sentryLogs.clearOneHourTimer);
726
+ }
718
727
  }
719
728
 
720
729
  /**
@@ -758,7 +767,7 @@ export default class IABookActions extends LitElement {
758
767
  if (whatIsleft !== whatShouldLeft) {
759
768
  log(`reSyncTimerIfGoneOff --- let's re-sync.`);
760
769
 
761
- return true;
770
+ return { hasSynced: true, whatShouldLeft };
762
771
  }
763
772
  return false;
764
773
  }
@@ -985,17 +994,6 @@ export default class IABookActions extends LitElement {
985
994
  --toastBGColor: #333;
986
995
  --toastFontColor: #fff;
987
996
  }
988
-
989
- .sr-only {
990
- position: absolute;
991
- left: -9999px;
992
- width: 1px;
993
- height: 1px;
994
- margin: 0;
995
- padding: 0;
996
- border: none;
997
- overflow: hidden;
998
- }
999
997
  `;
1000
998
  }
1001
999
  }