@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 +1 -2
- package/package.json +5 -7
- package/src/assets/data/lending-get-status-service.js +1 -1
- package/src/assets/styles/collapsible-action-group.js +1 -0
- package/src/assets/styles/ia-button.js +1 -1
- package/src/components/timer-countdown.js +1 -1
- package/src/ia-book-actions.js +80 -82
package/demo/index.html
CHANGED
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
iaBookActions.returnUrl = '';
|
|
132
132
|
iaBookActions.localCache = localCache;
|
|
133
133
|
|
|
134
|
-
let loanTotalTime2Min = { loanTotalTime:
|
|
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-
|
|
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
|
|
18
|
-
"test:watch": "web-test-runner --watch
|
|
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": "
|
|
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.
|
|
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:
|
|
121
|
+
secondsLeftOnLoan: 170,
|
|
122
122
|
shouldProtectImages: true,
|
|
123
123
|
totalWaitlistCount: 0,
|
|
124
124
|
userHasBorrowed: false,
|
package/src/ia-book-actions.js
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
672
|
+
const secondsLeft = Number(this.lendingStatus.secondsLeftOnLoan);
|
|
678
673
|
this.timeWhenTimerStart = new Date();
|
|
679
674
|
|
|
680
675
|
window.IALendingIntervals.timerCountdown = setInterval(async () => {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
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
|
-
|
|
697
|
-
|
|
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
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
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
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
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
|
}
|