@internetarchive/ia-book-actions 0.0.29-alpha37 → 0.0.29-alpha38
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 +2 -2
- package/package.json +1 -1
- package/src/ia-book-actions.js +28 -15
- package/test/ia-book-actions.test.js +97 -3
package/demo/index.html
CHANGED
|
@@ -133,8 +133,8 @@
|
|
|
133
133
|
|
|
134
134
|
let isDevBox = true;
|
|
135
135
|
iaBookActions.loanRenewConfig = {
|
|
136
|
-
totalTime: isDevBox ?
|
|
137
|
-
autoCheckAt: isDevBox ?
|
|
136
|
+
totalTime: isDevBox ? 10 : 3600, // 60 second = 1 min
|
|
137
|
+
autoCheckAt: isDevBox ? 5 : 3540, // at last 10th minute
|
|
138
138
|
pageChangedInLast: isDevBox ? 5 : 900, // within last 15 second/minute
|
|
139
139
|
isDevBox: isDevBox,
|
|
140
140
|
};
|
package/package.json
CHANGED
package/src/ia-book-actions.js
CHANGED
|
@@ -72,15 +72,22 @@ export default class IABookActions extends LitElement {
|
|
|
72
72
|
this.borrowType = ''; // (browsed|borrowed)
|
|
73
73
|
this.consecutiveLoanCounts = 1; // consecutive loan count
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
/**
|
|
76
|
+
* contains loan renew time config
|
|
77
|
+
* - totalTime:- number of seconds a loan should last
|
|
78
|
+
* - autoCheckAt:- check for loan renew at last
|
|
79
|
+
* - pageChangedInLast: consider loan renew eligible in last
|
|
80
|
+
* - isDevBox:- it just for testing purpose
|
|
81
|
+
*/
|
|
77
82
|
this.loanRenewConfig = {};
|
|
78
83
|
this.suppressToast = false;
|
|
84
|
+
this.browseTimer = undefined;
|
|
79
85
|
|
|
80
86
|
/**
|
|
81
87
|
* contains loan auto-renew response
|
|
82
88
|
* - texts:- texts messages need to show in toast message
|
|
83
89
|
* - renewNow:- key to determine if need to renew now
|
|
90
|
+
* - timeLeft:- number of seconds left in active loan
|
|
84
91
|
*/
|
|
85
92
|
this.loanRenewResult = {
|
|
86
93
|
texts: null,
|
|
@@ -92,7 +99,7 @@ export default class IABookActions extends LitElement {
|
|
|
92
99
|
}
|
|
93
100
|
|
|
94
101
|
disconnectedCallback() {
|
|
95
|
-
this.tokenPoller
|
|
102
|
+
this.tokenPoller?.disconnectedInterval();
|
|
96
103
|
window?.Sentry?.captureMessage(sentryLogs.disconnectedCallback);
|
|
97
104
|
this.disconnectResizeObserver();
|
|
98
105
|
}
|
|
@@ -252,17 +259,17 @@ export default class IABookActions extends LitElement {
|
|
|
252
259
|
/**
|
|
253
260
|
* Detech click-event on document to close toast-template
|
|
254
261
|
*/
|
|
255
|
-
document.addEventListener('click',
|
|
262
|
+
document.addEventListener('click', e => {
|
|
256
263
|
if (this.loanRenewHelper && this.loanRenewResult.timeLeft > 0) {
|
|
257
264
|
console.log('clicked-outside');
|
|
258
265
|
this.suppressToast = true;
|
|
259
266
|
}
|
|
260
267
|
|
|
261
|
-
// reload when user click on page
|
|
268
|
+
// reload when user click on book-page and book is EXPIRED
|
|
262
269
|
const hasExpired =
|
|
263
270
|
'browsingExpired' in this.lendingStatus &&
|
|
264
271
|
this.lendingStatus?.browsingExpired;
|
|
265
|
-
if (hasExpired) {
|
|
272
|
+
if (hasExpired && e.target.nodeName !== 'IA-BOOK-ACTIONS') {
|
|
266
273
|
window.location?.reload();
|
|
267
274
|
}
|
|
268
275
|
});
|
|
@@ -283,6 +290,11 @@ export default class IABookActions extends LitElement {
|
|
|
283
290
|
});
|
|
284
291
|
}
|
|
285
292
|
|
|
293
|
+
/**
|
|
294
|
+
* To determine if need to be renewed browsed book
|
|
295
|
+
*
|
|
296
|
+
* @param {Boolean} hasPageChanged
|
|
297
|
+
*/
|
|
286
298
|
async autoLoanRenewChecker(hasPageChanged = false) {
|
|
287
299
|
this.loanRenewHelper = new LoanRenewHelper(
|
|
288
300
|
hasPageChanged,
|
|
@@ -304,7 +316,9 @@ export default class IABookActions extends LitElement {
|
|
|
304
316
|
async showToastMessage() {
|
|
305
317
|
if (this.suppressToast) return;
|
|
306
318
|
|
|
307
|
-
const iaBookActions = document.querySelector('ia-book-actions')
|
|
319
|
+
const iaBookActions = document.querySelector('ia-book-actions')?.shadowRoot;
|
|
320
|
+
if (!iaBookActions) return;
|
|
321
|
+
|
|
308
322
|
let toastTemplate = iaBookActions.querySelector('toast-template');
|
|
309
323
|
if (!toastTemplate) {
|
|
310
324
|
toastTemplate = document.createElement('toast-template');
|
|
@@ -338,8 +352,7 @@ export default class IABookActions extends LitElement {
|
|
|
338
352
|
}
|
|
339
353
|
|
|
340
354
|
startBrowseTimer() {
|
|
341
|
-
clearTimeout(this.
|
|
342
|
-
|
|
355
|
+
clearTimeout(this.browseTimer);
|
|
343
356
|
const {
|
|
344
357
|
browsingExpired,
|
|
345
358
|
user_has_browsed,
|
|
@@ -349,7 +362,7 @@ export default class IABookActions extends LitElement {
|
|
|
349
362
|
return;
|
|
350
363
|
}
|
|
351
364
|
|
|
352
|
-
this.
|
|
365
|
+
this.browseTimer = setTimeout(() => {
|
|
353
366
|
this.browseHasExpired();
|
|
354
367
|
}, secondsLeftOnLoan * 1000);
|
|
355
368
|
}
|
|
@@ -358,11 +371,11 @@ export default class IABookActions extends LitElement {
|
|
|
358
371
|
* Execute when loan is expired
|
|
359
372
|
*/
|
|
360
373
|
async browseHasExpired() {
|
|
361
|
-
clearTimeout(this.browserTimer);
|
|
362
|
-
|
|
363
374
|
const currStatus = { ...this.lendingStatus, browsingExpired: true };
|
|
364
375
|
this.lendingStatus = currStatus;
|
|
365
376
|
|
|
377
|
+
this.tokenPoller?.disconnectedInterval();
|
|
378
|
+
|
|
366
379
|
// remove respected key:value for loan-renew
|
|
367
380
|
await this.localCache.delete(`${this.identifier}-loanTime`);
|
|
368
381
|
await this.localCache.delete(`${this.identifier}-pageChangedTime`);
|
|
@@ -468,7 +481,7 @@ export default class IABookActions extends LitElement {
|
|
|
468
481
|
*/
|
|
469
482
|
async handleLoanAutoRenewed() {
|
|
470
483
|
if (this.loanRenewResult.renewNow) {
|
|
471
|
-
this.tokenPoller
|
|
484
|
+
this.tokenPoller?.disconnectedInterval();
|
|
472
485
|
|
|
473
486
|
this.suppressToast = false;
|
|
474
487
|
await this.showToastMessage();
|
|
@@ -491,7 +504,7 @@ export default class IABookActions extends LitElement {
|
|
|
491
504
|
startLoanTokenPoller() {
|
|
492
505
|
if (this.tokenPoller) {
|
|
493
506
|
window?.Sentry?.captureMessage(sentryLogs.clearTokenPoller);
|
|
494
|
-
this.tokenPoller
|
|
507
|
+
this.tokenPoller?.disconnectedInterval();
|
|
495
508
|
}
|
|
496
509
|
const successCallback = () => {
|
|
497
510
|
this.lendingBarPostInit();
|
|
@@ -551,7 +564,7 @@ export default class IABookActions extends LitElement {
|
|
|
551
564
|
// - clear tokenPoller interval
|
|
552
565
|
// - set user_has_browsed to `false`
|
|
553
566
|
if (action === 'create_token') {
|
|
554
|
-
this.tokenPoller
|
|
567
|
+
this.tokenPoller?.disconnectedInterval();
|
|
555
568
|
|
|
556
569
|
const currStatus = {
|
|
557
570
|
...this.lendingStatus,
|
|
@@ -230,9 +230,14 @@ describe('Browsing expired status', () => {
|
|
|
230
230
|
},
|
|
231
231
|
})
|
|
232
232
|
);
|
|
233
|
-
expect(el.primaryTitle).contains('
|
|
233
|
+
expect(el.primaryTitle).contains('');
|
|
234
234
|
expect(el.primaryActions[0].text).to.equal('Return now');
|
|
235
235
|
expect(el.primaryActions[1].text).to.equal('Print Disability Access');
|
|
236
|
+
|
|
237
|
+
// default params of one-hour loan renew
|
|
238
|
+
expect(el.loanRenewResult.texts).to.equal(null);
|
|
239
|
+
expect(el.loanRenewResult.renewNow).to.equal(false);
|
|
240
|
+
expect(el.loanRenewResult.timeLeft).to.equal(0);
|
|
236
241
|
});
|
|
237
242
|
|
|
238
243
|
it('Book is browsing and going to expire after 1 second', async () => {
|
|
@@ -248,10 +253,63 @@ describe('Browsing expired status', () => {
|
|
|
248
253
|
})
|
|
249
254
|
);
|
|
250
255
|
|
|
256
|
+
// timer-countdown is still active
|
|
257
|
+
expect(el.shadowRoot.querySelector('timer-countdown')).to.not.be.null;
|
|
258
|
+
|
|
251
259
|
await aTimeout(1500); // wait for 1.5 second
|
|
252
260
|
await el.updateComplete;
|
|
253
261
|
|
|
254
262
|
expect(el.primaryActions[0].text).to.equal('Borrow');
|
|
263
|
+
|
|
264
|
+
// timer-countdown is gone now
|
|
265
|
+
expect(el.shadowRoot.querySelector('timer-countdown')).to.be.null;
|
|
266
|
+
|
|
267
|
+
// book has been expired
|
|
268
|
+
expect(el.loanRenewResult.timeLeft).to.equal(0);
|
|
269
|
+
expect(el.loanRenewResult.texts).to.equal(
|
|
270
|
+
'This book has been automatically returned due to inactivity.'
|
|
271
|
+
);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('Book is browsing and eligible to renew it', async () => {
|
|
275
|
+
const el = await fixture(
|
|
276
|
+
container({
|
|
277
|
+
userid: '@userid',
|
|
278
|
+
lendingStatus: {
|
|
279
|
+
is_lendable: true,
|
|
280
|
+
user_has_browsed: true,
|
|
281
|
+
browseHasExpired: false,
|
|
282
|
+
secondsLeftOnLoan: 1,
|
|
283
|
+
},
|
|
284
|
+
})
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
// timer-countdown is still active
|
|
288
|
+
// expect(el.shadowRoot.querySelector('timer-countdown')).to.not.be.null
|
|
289
|
+
|
|
290
|
+
// let eventReceived = false;
|
|
291
|
+
// const listener = () => {
|
|
292
|
+
// eventReceived = true;
|
|
293
|
+
// };
|
|
294
|
+
// el.addEventListener('IABookReader:userAction', listener);
|
|
295
|
+
|
|
296
|
+
el.loanRenewResult = {
|
|
297
|
+
texts: 'book has been renewed',
|
|
298
|
+
renewNow: true,
|
|
299
|
+
timeLeft: 10,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
await aTimeout(1500); // wait for 1.5 second
|
|
303
|
+
await el.updateComplete;
|
|
304
|
+
|
|
305
|
+
// // timer-countdown is gone now
|
|
306
|
+
// expect(el.shadowRoot.querySelector('timer-countdown')).to.not.be.null
|
|
307
|
+
// expect(el.shadowRoot.querySelector('toast-template')).to.not.be.null
|
|
308
|
+
|
|
309
|
+
expect(el.loanRenewResult.timeLeft).to.equal(10);
|
|
310
|
+
// // book has been expired
|
|
311
|
+
// expect(el.loanRenewResult.timeLeft).to.equal(0);
|
|
312
|
+
// expect(el.loanRenewResult.texts).to.equal('This book has been automatically returned due to inactivity.');
|
|
255
313
|
});
|
|
256
314
|
|
|
257
315
|
it('Expiring book cancels interval & emits event', async () => {
|
|
@@ -276,9 +334,8 @@ describe('Browsing expired status', () => {
|
|
|
276
334
|
el.lendingStatus = browsingStatus;
|
|
277
335
|
await el.updateComplete;
|
|
278
336
|
|
|
279
|
-
expect(el.primaryTitle).contains('
|
|
337
|
+
expect(el.primaryTitle).contains('');
|
|
280
338
|
expect(el.primaryActions[0].text).to.equal('Return now');
|
|
281
|
-
expect(el.tokenPoller.loanTokenInterval).to.not.equal(undefined);
|
|
282
339
|
|
|
283
340
|
const expiredStatus = { ...browsingStatus, browsingExpired: true };
|
|
284
341
|
el.lendingStatus = expiredStatus;
|
|
@@ -327,3 +384,40 @@ describe('Shared Resize Observer', () => {
|
|
|
327
384
|
expect(component.sharedObserver).to.not.be.undefined;
|
|
328
385
|
});
|
|
329
386
|
});
|
|
387
|
+
|
|
388
|
+
describe('Shared Resize Observer', () => {
|
|
389
|
+
it('can receive a Shared Resize Observer', async () => {
|
|
390
|
+
const sharedObserverStub = new SharedResizeObserver();
|
|
391
|
+
const addObserverSpy = Sinon.spy(sharedObserverStub, 'addObserver');
|
|
392
|
+
const component = await fixture(html` <ia-book-actions
|
|
393
|
+
.userid=${'@userid'}
|
|
394
|
+
.identifier=${'foo'}
|
|
395
|
+
.lendingStatus=${{
|
|
396
|
+
is_lendable: true,
|
|
397
|
+
user_has_browsed: true,
|
|
398
|
+
available_to_browse: true,
|
|
399
|
+
available_to_borrow: true,
|
|
400
|
+
}}
|
|
401
|
+
.sharedObserver=${sharedObserverStub}
|
|
402
|
+
></ia-book-actions>`);
|
|
403
|
+
await component.updateComplete;
|
|
404
|
+
|
|
405
|
+
expect(addObserverSpy.callCount).to.equal(1);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('loads its own resize observer if it is not received', async () => {
|
|
409
|
+
const component = await fixture(html` <ia-book-actions
|
|
410
|
+
.userid=${'@userid'}
|
|
411
|
+
.identifier=${'foo'}
|
|
412
|
+
.lendingStatus=${{
|
|
413
|
+
is_lendable: true,
|
|
414
|
+
user_has_browsed: true,
|
|
415
|
+
available_to_browse: true,
|
|
416
|
+
available_to_borrow: true,
|
|
417
|
+
}}
|
|
418
|
+
></ia-book-actions>`);
|
|
419
|
+
|
|
420
|
+
await component.updateComplete;
|
|
421
|
+
expect(component.sharedObserver).to.not.be.undefined;
|
|
422
|
+
});
|
|
423
|
+
});
|