@internetarchive/ia-book-actions 1.0.0 → 1.1.0-alpha10
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 +22 -3
- package/package.json +6 -6
- 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/collapsible-action-group.js +1 -1
- package/src/components/timer-countdown.js +1 -1
- package/src/core/services/actions-config.js +0 -2
- package/src/core/services/actions-handler/actions-handler.js +5 -0
- package/src/ia-book-actions.js +68 -65
- package/test/ia-book-actions.test.js +2 -2
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
|
|
|
@@ -150,6 +150,25 @@
|
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
+
document.querySelectorAll('.searchParam input[type=checkbox]').forEach((item) => {
|
|
154
|
+
item.addEventListener('click', (e) => {
|
|
155
|
+
var searchParams = new URLSearchParams(window.location.search);
|
|
156
|
+
var separate = '';
|
|
157
|
+
if (e.target.checked) {
|
|
158
|
+
separate = '?';
|
|
159
|
+
searchParams.set('q', 'test');
|
|
160
|
+
} else {
|
|
161
|
+
separate = '';
|
|
162
|
+
searchParams.delete('q');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (history.pushState) {
|
|
166
|
+
var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + separate + searchParams;
|
|
167
|
+
window.history.pushState({path:newurl},'',newurl);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
153
172
|
document.querySelectorAll('.errorEnable input[type=checkbox]').forEach((item) => {
|
|
154
173
|
if (window.location.href.indexOf('?error=true') !== -1) {
|
|
155
174
|
item.checked = true;
|
|
@@ -327,7 +346,6 @@
|
|
|
327
346
|
// listen for IABookReader:BrowsingHasExpired
|
|
328
347
|
window.addEventListener('IABookReader:BrowsingHasExpired', () => {
|
|
329
348
|
console.log('IABookReader:BrowsingHasExpired EVENT FIRED');
|
|
330
|
-
alert('IABookReader:BrowsingHasExpired EVENT FIRED');
|
|
331
349
|
});
|
|
332
350
|
</script>
|
|
333
351
|
|
|
@@ -339,6 +357,8 @@
|
|
|
339
357
|
<td class="titleBar">
|
|
340
358
|
<label><input type="checkbox" name="title" value="title" />Title Bar</label>
|
|
341
359
|
</td>
|
|
360
|
+
<td class="searchParam">
|
|
361
|
+
<label><input type="checkbox" name="search" value="Search Param" />Search Param</label>
|
|
342
362
|
<td>
|
|
343
363
|
<button class="pageChangedEvent">Page Change Event</button>
|
|
344
364
|
</td>
|
|
@@ -370,7 +390,6 @@
|
|
|
370
390
|
</div>
|
|
371
391
|
<div>
|
|
372
392
|
<button id="show_expired_modal">While Browsing (`user_has_browsed`), Expire book & show its modal</button>
|
|
373
|
-
how_expired_modal
|
|
374
393
|
</div>
|
|
375
394
|
</td>
|
|
376
395
|
<td class="availableToBorrow">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/ia-book-actions",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0-alpha10",
|
|
4
4
|
"description": "Bookreader actions for borrowable book",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -14,16 +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
|
-
"
|
|
26
|
-
"lit": "^2.
|
|
25
|
+
"install-deps": "^1.1.0",
|
|
26
|
+
"lit": "^2.8.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
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,
|
|
@@ -178,7 +178,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
178
178
|
get renderSecondaryActions() {
|
|
179
179
|
if (!this.secondaryActions.length) return nothing;
|
|
180
180
|
|
|
181
|
-
return this.secondaryActions.map(action => this.
|
|
181
|
+
return this.secondaryActions.map(action => this.renderActionButton(action));
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
/**
|
|
@@ -207,8 +207,6 @@ export default class ActionsConfig {
|
|
|
207
207
|
id: 'adminAccess',
|
|
208
208
|
text: 'Admin Access',
|
|
209
209
|
title: 'You have administrative privileges to read this book',
|
|
210
|
-
url: '?admin=1',
|
|
211
|
-
target: '_self',
|
|
212
210
|
className: 'danger',
|
|
213
211
|
analyticsEvent: {
|
|
214
212
|
category: this.analyticsCategories.adminAccess,
|
|
@@ -115,6 +115,11 @@ export default class ActionsHandler extends LitElement {
|
|
|
115
115
|
this.addEventListener('adminAccess', ({ detail }) => {
|
|
116
116
|
const { category, action } = detail.event;
|
|
117
117
|
this.loanAnanlytics?.sendEvent(category, action, this.identifier);
|
|
118
|
+
|
|
119
|
+
// keep existing params and add new one
|
|
120
|
+
const url = new URL(window.location.href);
|
|
121
|
+
url.searchParams.append('admin', 1);
|
|
122
|
+
window.location.search = url.search;
|
|
118
123
|
});
|
|
119
124
|
|
|
120
125
|
this.addEventListener('exitAdminAccess', ({ detail }) => {
|
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';
|
|
@@ -283,6 +282,25 @@ export default class IABookActions extends LitElement {
|
|
|
283
282
|
this.autoLoanRenewChecker(true);
|
|
284
283
|
}
|
|
285
284
|
});
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* auto-renew interval may stale when tab is in background,
|
|
288
|
+
* so [visibilitychange] event can trigger timer to show relavent messages
|
|
289
|
+
*/
|
|
290
|
+
document.addEventListener("visibilitychange", async () => {
|
|
291
|
+
if (!document.hidden) {
|
|
292
|
+
log('visibilitychange', new Date().getMinutes, new Date().getSeconds());
|
|
293
|
+
|
|
294
|
+
const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
|
|
295
|
+
const secondsLeft = Math.round((loanTime - new Date()) / 1000); // different in seconds
|
|
296
|
+
|
|
297
|
+
if (secondsLeft >= this.timerExecutionSeconds) {
|
|
298
|
+
this.setIntervalExecutionBlock(Number(secondsLeft));
|
|
299
|
+
} else {
|
|
300
|
+
this.disconnectedCallback();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
286
304
|
}
|
|
287
305
|
|
|
288
306
|
/**
|
|
@@ -487,36 +505,6 @@ export default class IABookActions extends LitElement {
|
|
|
487
505
|
this.toast?.remove();
|
|
488
506
|
}
|
|
489
507
|
|
|
490
|
-
/**
|
|
491
|
-
* @deprecated
|
|
492
|
-
* Show toast messages on some specific loan renew features. e.g.
|
|
493
|
-
* - show message when book is auto renewed
|
|
494
|
-
* - show message when book is expired
|
|
495
|
-
* - show message having remaining time when book is about to auto returned
|
|
496
|
-
*/
|
|
497
|
-
async showToastMessage() {
|
|
498
|
-
await this.useToastManager();
|
|
499
|
-
|
|
500
|
-
// if secondsLeft < 60, consider it 1 minute
|
|
501
|
-
let { secondsLeft } = this.loanRenewResult;
|
|
502
|
-
if (secondsLeft === undefined) {
|
|
503
|
-
secondsLeft = this.lendingStatus.secondsLeftOnLoan;
|
|
504
|
-
} else {
|
|
505
|
-
secondsLeft = secondsLeft > 60 ? secondsLeft : 60;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
const config = new ToastConfig();
|
|
509
|
-
config.dismisOnClick = true;
|
|
510
|
-
config.texts = this.loanRenewHelper?.getMessageTexts(
|
|
511
|
-
this.loanRenewResult.texts,
|
|
512
|
-
secondsLeft
|
|
513
|
-
);
|
|
514
|
-
|
|
515
|
-
this.toast?.showToast({
|
|
516
|
-
config,
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
|
|
520
508
|
/**
|
|
521
509
|
* Execute when loan is expired
|
|
522
510
|
*/
|
|
@@ -677,47 +665,62 @@ export default class IABookActions extends LitElement {
|
|
|
677
665
|
startTimerCountdown() {
|
|
678
666
|
window?.IALendingIntervals?.clearTimerCountdown();
|
|
679
667
|
|
|
680
|
-
|
|
668
|
+
const secondsLeft = Number(this.lendingStatus.secondsLeftOnLoan);
|
|
681
669
|
this.timeWhenTimerStart = new Date();
|
|
682
670
|
|
|
683
671
|
window.IALendingIntervals.timerCountdown = setInterval(async () => {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
// side effect: updates this.lendingStatus & kicks off lifecycle,
|
|
689
|
-
// if really updated, escape from here
|
|
690
|
-
const resync = await this.reSyncTimerIfGoneOff(secondsLeft);
|
|
691
|
-
|
|
692
|
-
if (resync) {
|
|
693
|
-
log('startTimerCountdown --- stale, timer has resyncd', {
|
|
694
|
-
secondsLeft,
|
|
695
|
-
});
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
672
|
+
// interval execution block
|
|
673
|
+
await this.setIntervalExecutionBlock(secondsLeft);
|
|
674
|
+
}, this.timerExecutionSeconds * 1000);
|
|
675
|
+
}
|
|
698
676
|
|
|
699
|
-
|
|
700
|
-
|
|
677
|
+
/**
|
|
678
|
+
* setInterval execution function do following things
|
|
679
|
+
* - if setInterval timer gone off, let's resync
|
|
680
|
+
* - loan-renew attempt to renew the loan OR show relavant message
|
|
681
|
+
* - if loan has expired, clear interval timers
|
|
682
|
+
*
|
|
683
|
+
* @param {Number} secondsLeftOnLoan
|
|
684
|
+
*/
|
|
685
|
+
async setIntervalExecutionBlock(secondsLeftOnLoan) {
|
|
686
|
+
let secondsLeft = secondsLeftOnLoan;
|
|
687
|
+
secondsLeft -= this.timerExecutionSeconds;
|
|
688
|
+
secondsLeft = Math.round(secondsLeft); // round number
|
|
689
|
+
|
|
690
|
+
// re-sync timer if gone off because of background window
|
|
691
|
+
// side effect: updates this.lendingStatus & kicks off lifecycle,
|
|
692
|
+
// if really updated, escape from here
|
|
693
|
+
const resyncd = await this.reSyncTimerIfGoneOff(secondsLeft);
|
|
694
|
+
|
|
695
|
+
if (resyncd?.hasSynced) {
|
|
696
|
+
secondsLeft = resyncd.whatShouldLeft;
|
|
697
|
+
|
|
698
|
+
log('startTimerCountdown --- stale, timer has resyncd', {
|
|
701
699
|
secondsLeft,
|
|
702
|
-
loanRenewAtLast: this.loanRenewTimeConfig.loanRenewAtLast,
|
|
703
700
|
});
|
|
701
|
+
}
|
|
704
702
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
*/
|
|
711
|
-
if (secondsLeft <= this.loanRenewTimeConfig.loanRenewAtLast) {
|
|
712
|
-
await this.loanRenewAttempt(secondsLeft);
|
|
713
|
-
}
|
|
703
|
+
log('startTimerCountdown --- countdown still valid. continue...', {
|
|
704
|
+
resyncd,
|
|
705
|
+
secondsLeft,
|
|
706
|
+
loanRenewAtLast: this.loanRenewTimeConfig.loanRenewAtLast,
|
|
707
|
+
}, new Date().getMinutes(), new Date().getSeconds());
|
|
714
708
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
709
|
+
/**
|
|
710
|
+
* execute from last 10th minute to 0th minute
|
|
711
|
+
* - 10th - to check if user has viewed
|
|
712
|
+
* - till 0th - to show warning msg with remaining time to auto expired
|
|
713
|
+
* @see IABookActions::bindLoanRenewEvents
|
|
714
|
+
*/
|
|
715
|
+
if (secondsLeft <= this.loanRenewTimeConfig.loanRenewAtLast) {
|
|
716
|
+
await this.loanRenewAttempt(secondsLeft);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// clear interval in secondsLeft if less
|
|
720
|
+
if (secondsLeft <= this.timerExecutionSeconds) {
|
|
721
|
+
this.disconnectedCallback();
|
|
722
|
+
window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
|
|
723
|
+
}
|
|
721
724
|
}
|
|
722
725
|
|
|
723
726
|
/**
|
|
@@ -761,7 +764,7 @@ export default class IABookActions extends LitElement {
|
|
|
761
764
|
if (whatIsleft !== whatShouldLeft) {
|
|
762
765
|
log(`reSyncTimerIfGoneOff --- let's re-sync.`);
|
|
763
766
|
|
|
764
|
-
return true;
|
|
767
|
+
return { hasSynced: true, whatShouldLeft };
|
|
765
768
|
}
|
|
766
769
|
return false;
|
|
767
770
|
}
|
|
@@ -421,7 +421,7 @@ describe('Auto renew one hour loan', () => {
|
|
|
421
421
|
// timer-countdown reflects decreased loan time
|
|
422
422
|
expect(el.timerCountdownEl.secondsLeftOnLoan).to.equal(8);
|
|
423
423
|
|
|
424
|
-
expect(el.postInitComplete).to.equal(
|
|
424
|
+
expect(el.postInitComplete).to.equal(false);
|
|
425
425
|
|
|
426
426
|
// dispatch loanAutoRenewed event - test 200 callback
|
|
427
427
|
const collapsibleActionGroupEl = el.shadowRoot.querySelector(
|
|
@@ -445,7 +445,7 @@ describe('Auto renew one hour loan', () => {
|
|
|
445
445
|
expect(el.loanRenewResult.renewNow).to.equal(true);
|
|
446
446
|
expect(el.loanRenewResult.secondsLeft).to.equal(10);
|
|
447
447
|
expect(el.timerCountdownEl).to.exist;
|
|
448
|
-
expect(el.timerCountdownEl.secondsLeftOnLoan).to.equal(
|
|
448
|
+
expect(el.timerCountdownEl.secondsLeftOnLoan).to.equal(8);
|
|
449
449
|
});
|
|
450
450
|
});
|
|
451
451
|
|