@internetarchive/ia-book-actions 0.1.11-b2 → 0.1.11-b20
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
package/package.json
CHANGED
|
@@ -21,7 +21,7 @@ export default async function ActionsHandlerService(options) {
|
|
|
21
21
|
const tokenError = 'loan token not found. please try again later.';
|
|
22
22
|
const borrowError =
|
|
23
23
|
'This book is not available to borrow at this time. Please try again later.';
|
|
24
|
-
const erroneousActions = ['browse_book', 'borrow_book', 'create_token'];
|
|
24
|
+
const erroneousActions = ['browse_book', 'borrow_book', 'create_token', 'renew_loan'];
|
|
25
25
|
const shouldReturnError =
|
|
26
26
|
location?.href?.indexOf('?error=true') !== -1 &&
|
|
27
27
|
location?.hostname !== 'archive.org';
|
|
@@ -142,7 +142,13 @@ export default class ActionsHandler extends LitElement {
|
|
|
142
142
|
action,
|
|
143
143
|
identifier: this.identifier,
|
|
144
144
|
success: data => {
|
|
145
|
-
console.log(
|
|
145
|
+
console.log(
|
|
146
|
+
'RENEW_LOAN --- ',
|
|
147
|
+
data,
|
|
148
|
+
action,
|
|
149
|
+
data.loan,
|
|
150
|
+
this.identifier
|
|
151
|
+
);
|
|
146
152
|
if (data?.success === true && data?.loan?.renewal === true) {
|
|
147
153
|
this.setBrowseTimeSession();
|
|
148
154
|
this.dispatchEvent(
|
|
@@ -300,6 +306,7 @@ export default class ActionsHandler extends LitElement {
|
|
|
300
306
|
* set browse time in indexedDB
|
|
301
307
|
*/
|
|
302
308
|
async setBrowseTimeSession() {
|
|
309
|
+
// TODO: USE loan info to determine what we have left
|
|
303
310
|
try {
|
|
304
311
|
const expireDate = new Date(
|
|
305
312
|
new Date().getTime() + this.loanTotalTime * 1000
|
package/src/ia-book-actions.js
CHANGED
|
@@ -77,7 +77,6 @@ export default class IABookActions extends LitElement {
|
|
|
77
77
|
this.barType = 'action'; // 'title'|'action'
|
|
78
78
|
this.sharedObserver = undefined;
|
|
79
79
|
this.disableActionGroup = false;
|
|
80
|
-
this.modal = undefined;
|
|
81
80
|
this.tokenDelay = 120; // in seconds
|
|
82
81
|
|
|
83
82
|
// private props
|
|
@@ -100,13 +99,17 @@ export default class IABookActions extends LitElement {
|
|
|
100
99
|
|
|
101
100
|
/**
|
|
102
101
|
* contains one hour auto-loan-renew time configuration
|
|
103
|
-
*
|
|
104
|
-
* @type {
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
102
|
+
* defaults to 1 hour config
|
|
103
|
+
* @type {{
|
|
104
|
+
* loanTotalTime: number, - total seconds a loan does have
|
|
105
|
+
* loanRenewAtLast: number, - check for loan renew at last
|
|
106
|
+
* pageChangedInLast: number, - consider loan renew eligible if viewed new page
|
|
108
107
|
*/
|
|
109
|
-
this.loanRenewTimeConfig = {
|
|
108
|
+
this.loanRenewTimeConfig = {
|
|
109
|
+
loanTotalTime: 3600, // 1 hour
|
|
110
|
+
loanRenewAtLast: 660, // 11 minutes
|
|
111
|
+
pageChangedInLast: 900, // 15 minutes
|
|
112
|
+
};
|
|
110
113
|
|
|
111
114
|
/**
|
|
112
115
|
* contains one hour auto-loan-renew response
|
|
@@ -253,6 +256,9 @@ export default class IABookActions extends LitElement {
|
|
|
253
256
|
// initial timer state for 1-hour loan
|
|
254
257
|
if (this.borrowType === 'browsed' && !this.loanRenewResult.renewNow) {
|
|
255
258
|
setTimeout(() => {
|
|
259
|
+
console.log(
|
|
260
|
+
'IN TIMEOUT OF --- setupLendingToolbarActions, firing resetTimerCountState'
|
|
261
|
+
);
|
|
256
262
|
this.resetTimerCountState();
|
|
257
263
|
}, 100);
|
|
258
264
|
}
|
|
@@ -301,19 +307,12 @@ export default class IABookActions extends LitElement {
|
|
|
301
307
|
this.loanRenewResult = this.loanRenewHelper.result;
|
|
302
308
|
}
|
|
303
309
|
|
|
304
|
-
/**
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
*/
|
|
308
|
-
async useModalManager() {
|
|
309
|
-
if (!this.modal) {
|
|
310
|
-
this.modal = document.querySelector('modal-manager');
|
|
311
|
-
|
|
312
|
-
if (!this.modal) this.modal = document.createElement('modal-manager');
|
|
313
|
-
}
|
|
310
|
+
/** @returns HTMLElement */
|
|
311
|
+
get modal() {
|
|
312
|
+
const modalOnDom = document.querySelector('modal-manager');
|
|
314
313
|
|
|
315
|
-
|
|
316
|
-
|
|
314
|
+
modalOnDom.id = 'action-bar-modal';
|
|
315
|
+
return modalOnDom;
|
|
317
316
|
}
|
|
318
317
|
|
|
319
318
|
/**
|
|
@@ -321,7 +320,9 @@ export default class IABookActions extends LitElement {
|
|
|
321
320
|
*/
|
|
322
321
|
async showWarningModal() {
|
|
323
322
|
console.log('****** showWarningModal ******');
|
|
324
|
-
|
|
323
|
+
// clear modal
|
|
324
|
+
this.modal?.showModal(new ModalConfig({ customModalContent: nothing }));
|
|
325
|
+
this.modal?.closeModal();
|
|
325
326
|
|
|
326
327
|
// if secondsLeft < 60, consider it 1 minute
|
|
327
328
|
let { secondsLeft } = this.loanRenewResult;
|
|
@@ -331,23 +332,21 @@ export default class IABookActions extends LitElement {
|
|
|
331
332
|
secondsLeft = secondsLeft > 60 ? secondsLeft : 60;
|
|
332
333
|
}
|
|
333
334
|
|
|
334
|
-
const config = new ModalConfig(
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
335
|
+
const config = new ModalConfig({
|
|
336
|
+
headline: 'Are you still here?',
|
|
337
|
+
showCloseButton: false,
|
|
338
|
+
closeOnBackdropClick: false,
|
|
339
|
+
message: this.loanRenewHelper?.getMessageTexts(
|
|
340
|
+
this.loanRenewResult.texts,
|
|
341
|
+
secondsLeft
|
|
342
|
+
)
|
|
343
|
+
});
|
|
342
344
|
|
|
343
|
-
const
|
|
344
|
-
<div id="custom-buttons" style="display:flex;justify-content:center;">
|
|
345
|
+
const customModalContent = html`<br />
|
|
346
|
+
<div id="book-action-bar-custom-buttons" style="display:flex;justify-content:center;">
|
|
345
347
|
<button
|
|
346
348
|
style="${modalButtonStyle.iaButton} ${modalButtonStyle.renew}"
|
|
347
|
-
@click=${
|
|
348
|
-
await this.changeModalState(event);
|
|
349
|
-
this.loanRenewResult = { texts: '', renewNow: true };
|
|
350
|
-
}}
|
|
349
|
+
@click=${event => this.patronWantsToRenewBook(event)}
|
|
351
350
|
>
|
|
352
351
|
Keep reading
|
|
353
352
|
</button>
|
|
@@ -363,7 +362,12 @@ export default class IABookActions extends LitElement {
|
|
|
363
362
|
</button>
|
|
364
363
|
</div> `;
|
|
365
364
|
|
|
366
|
-
this.modal?.showModal({ config, customModalContent
|
|
365
|
+
this.modal?.showModal({ config, customModalContent });
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
async patronWantsToRenewBook(event) {
|
|
369
|
+
this.changeModalState(event);
|
|
370
|
+
this.loanRenewResult = { texts: '', renewNow: true };
|
|
367
371
|
}
|
|
368
372
|
|
|
369
373
|
/**
|
|
@@ -374,9 +378,11 @@ export default class IABookActions extends LitElement {
|
|
|
374
378
|
* @param {Event} event
|
|
375
379
|
*/
|
|
376
380
|
changeModalState(event) {
|
|
381
|
+
// this doesn't really work? shows empty button
|
|
377
382
|
if (event.target === undefined) return;
|
|
378
383
|
|
|
379
384
|
const button = event.target;
|
|
385
|
+
button.disabled = true;
|
|
380
386
|
button.innerHTML = `<ia-activity-indicator
|
|
381
387
|
mode="processing"
|
|
382
388
|
style=${modalButtonStyle.loaderIcon}
|
|
@@ -392,15 +398,15 @@ export default class IABookActions extends LitElement {
|
|
|
392
398
|
*/
|
|
393
399
|
async showExpiredModal() {
|
|
394
400
|
console.log('showExpiredModal()');
|
|
395
|
-
await this.useModalManager();
|
|
396
401
|
|
|
397
|
-
const config = new ModalConfig(
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
+
const config = new ModalConfig({
|
|
403
|
+
headline: '',
|
|
404
|
+
showCloseButton: false,
|
|
405
|
+
closeOnBackdropClick: false,
|
|
406
|
+
message: 'This book has been returned due to inactivity.'
|
|
407
|
+
});
|
|
402
408
|
|
|
403
|
-
const
|
|
409
|
+
const customModalContent = html`<br />
|
|
404
410
|
<div style="text-align: center">
|
|
405
411
|
<button
|
|
406
412
|
style="${modalButtonStyle.iaButton} ${modalButtonStyle.renew}"
|
|
@@ -412,15 +418,7 @@ export default class IABookActions extends LitElement {
|
|
|
412
418
|
</button>
|
|
413
419
|
</div> `;
|
|
414
420
|
|
|
415
|
-
this.modal?.showModal({ config, customModalContent
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* close/hide modal-manager
|
|
420
|
-
*/
|
|
421
|
-
async closeModalManager() {
|
|
422
|
-
this.modal = document.querySelector('modal-manager');
|
|
423
|
-
this.modal?.closeModal();
|
|
421
|
+
this.modal?.showModal({ config, customModalContent });
|
|
424
422
|
}
|
|
425
423
|
|
|
426
424
|
/**
|
|
@@ -478,21 +476,6 @@ export default class IABookActions extends LitElement {
|
|
|
478
476
|
});
|
|
479
477
|
}
|
|
480
478
|
|
|
481
|
-
async browseHasRenew() {
|
|
482
|
-
window?.IALendingIntervals?.clearAll();
|
|
483
|
-
|
|
484
|
-
const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
|
|
485
|
-
const secondsLeft = (loanTime - new Date()) / 1000; // different in seconds
|
|
486
|
-
|
|
487
|
-
const currStatus = {
|
|
488
|
-
...this.lendingStatus,
|
|
489
|
-
user_has_browsed: true,
|
|
490
|
-
browsingExpired: false,
|
|
491
|
-
secondsLeftOnLoan: secondsLeft,
|
|
492
|
-
};
|
|
493
|
-
this.lendingStatus = currStatus;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
479
|
/**
|
|
497
480
|
* Execute when loan is expired
|
|
498
481
|
*/
|
|
@@ -518,7 +501,11 @@ export default class IABookActions extends LitElement {
|
|
|
518
501
|
|
|
519
502
|
async startBrowseTimer() {
|
|
520
503
|
clearTimeout(this.browseTimer);
|
|
521
|
-
console.log(
|
|
504
|
+
console.log(
|
|
505
|
+
'startBrowseTimerstartBrowseTimer just cleared timer',
|
|
506
|
+
this.browseTimer,
|
|
507
|
+
this.lendingStatus
|
|
508
|
+
);
|
|
522
509
|
|
|
523
510
|
const {
|
|
524
511
|
browsingExpired,
|
|
@@ -531,7 +518,10 @@ export default class IABookActions extends LitElement {
|
|
|
531
518
|
}
|
|
532
519
|
|
|
533
520
|
this.browseTimer = setTimeout(() => {
|
|
534
|
-
console.log(
|
|
521
|
+
console.log(
|
|
522
|
+
'start `this.browseTimer will fire his.browseHasExpired() - secondsLeftOnLoan',
|
|
523
|
+
secondsLeftOnLoan
|
|
524
|
+
);
|
|
535
525
|
this.browseHasExpired();
|
|
536
526
|
}, secondsLeftOnLoan * 1000);
|
|
537
527
|
}
|
|
@@ -543,11 +533,22 @@ export default class IABookActions extends LitElement {
|
|
|
543
533
|
const timerCountdown = this._shadowRoot.querySelector('timer-countdown');
|
|
544
534
|
if (!timerCountdown) return;
|
|
545
535
|
|
|
546
|
-
const secondsLeft = Number(
|
|
547
|
-
|
|
548
|
-
|
|
536
|
+
const secondsLeft = Number.parseInt(
|
|
537
|
+
Number(this.lendingStatus.secondsLeftOnLoan),
|
|
538
|
+
10
|
|
539
|
+
);
|
|
540
|
+
const firstStrokeDashOffset = Number.parseInt(
|
|
541
|
+
(secondsLeft / this.loanRenewTimeConfig.loanTotalTime) * 315 * 1.5,
|
|
542
|
+
10
|
|
543
|
+
);
|
|
544
|
+
const actualStrokeDashOffset =
|
|
545
|
+
firstStrokeDashOffset > 315 ? 315 : firstStrokeDashOffset;
|
|
549
546
|
|
|
550
|
-
|
|
547
|
+
console.log('resetTimerCountState === ', {
|
|
548
|
+
secondsLeft,
|
|
549
|
+
firstStrokeDashOffset,
|
|
550
|
+
actualStrokeDashOffset,
|
|
551
|
+
});
|
|
551
552
|
|
|
552
553
|
// set seconds left in loan expire
|
|
553
554
|
timerCountdown.style?.setProperty('--secondsLeftOnLoan', `${secondsLeft}s`);
|
|
@@ -555,7 +556,7 @@ export default class IABookActions extends LitElement {
|
|
|
555
556
|
// set circle stroke offset left in loan expire
|
|
556
557
|
timerCountdown.style?.setProperty(
|
|
557
558
|
'--strokeLeftOnLoan',
|
|
558
|
-
`${
|
|
559
|
+
`${actualStrokeDashOffset}` // the perimeter of the circle = (π * 2 * radius)
|
|
559
560
|
);
|
|
560
561
|
|
|
561
562
|
const animationCircle = timerCountdown.shadowRoot.querySelector('.circle');
|
|
@@ -584,14 +585,6 @@ export default class IABookActions extends LitElement {
|
|
|
584
585
|
></book-title-bar>`;
|
|
585
586
|
}
|
|
586
587
|
|
|
587
|
-
get timerCountdownTemplate() {
|
|
588
|
-
return this.borrowType === 'browsed'
|
|
589
|
-
? html`<timer-countdown
|
|
590
|
-
.secondsLeftOnLoan=${Number(this.lendingStatus.secondsLeftOnLoan)}
|
|
591
|
-
></timer-countdown>`
|
|
592
|
-
: nothing;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
588
|
get bookActionBar() {
|
|
596
589
|
return html`
|
|
597
590
|
<collapsible-action-group
|
|
@@ -616,7 +609,10 @@ export default class IABookActions extends LitElement {
|
|
|
616
609
|
>
|
|
617
610
|
</collapsible-action-group>
|
|
618
611
|
${this.textGroupTemplate} ${this.infoIconTemplate}
|
|
619
|
-
|
|
612
|
+
<timer-countdown
|
|
613
|
+
.secondsLeftOnLoan=${Number(this.lendingStatus.secondsLeftOnLoan)}
|
|
614
|
+
class=${this.borrowType === 'browsed' ? '' : 'hide'}
|
|
615
|
+
></timer-countdown>
|
|
620
616
|
`;
|
|
621
617
|
}
|
|
622
618
|
|
|
@@ -635,13 +631,24 @@ export default class IABookActions extends LitElement {
|
|
|
635
631
|
console.log('IABookActions: AutoRenewed:- ', {
|
|
636
632
|
ajaxResponse: event?.detail?.data,
|
|
637
633
|
loanRenewResult: this.loanRenewResult,
|
|
638
|
-
secondsLeftOnLoan: Math.round(this.lendingStatus.secondsLeftOnLoan),
|
|
634
|
+
secondsLeftOnLoan: Math.round(this.lendingStatus.secondsLeftOnLoan), // stale? how to fix
|
|
639
635
|
});
|
|
640
636
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
637
|
+
// Now, let's reset loan duration & this.lendingStatus
|
|
638
|
+
const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
|
|
639
|
+
const secondsLeft = (loanTime - new Date()) / 1000; // different in seconds
|
|
640
|
+
|
|
641
|
+
const currStatus = {
|
|
642
|
+
...this.lendingStatus,
|
|
643
|
+
user_has_browsed: true,
|
|
644
|
+
browsingExpired: false,
|
|
645
|
+
secondsLeftOnLoan: secondsLeft,
|
|
646
|
+
};
|
|
647
|
+
this.lendingStatus = currStatus;
|
|
648
|
+
|
|
649
|
+
console.log('~~~ handleLoanAutoRenewed - new this.lendingStatus', {
|
|
650
|
+
secondsLeftOnLoan: this.lendingStatus.secondsLeftOnLoan,
|
|
651
|
+
});
|
|
645
652
|
|
|
646
653
|
/**
|
|
647
654
|
* reset timer countdown states
|
|
@@ -649,8 +656,12 @@ export default class IABookActions extends LitElement {
|
|
|
649
656
|
await this.resetTimerCountState();
|
|
650
657
|
|
|
651
658
|
// close the modal
|
|
652
|
-
this.modal
|
|
653
|
-
this.modal
|
|
659
|
+
this.modal.removeAttribute('id');
|
|
660
|
+
const editedActionButtons = this.modal.shadowRoot.querySelector('#book-action-bar-custom-buttons');
|
|
661
|
+
if (editedActionButtons) {
|
|
662
|
+
editedActionButtons.parentElement.removeChild(editedActionButtons);
|
|
663
|
+
}
|
|
664
|
+
this.modal?.closeModal();
|
|
654
665
|
|
|
655
666
|
window?.Sentry?.captureMessage(sentryLogs.bookHasRenewed);
|
|
656
667
|
}
|
|
@@ -673,9 +684,14 @@ export default class IABookActions extends LitElement {
|
|
|
673
684
|
secondsLeft = Math.round(secondsLeft); // round number
|
|
674
685
|
|
|
675
686
|
// re-sync timer if gone off because of background window
|
|
687
|
+
// side effect: updates this.lendingStatus & kicks off lifecycle,
|
|
688
|
+
// if really updated, escape from here
|
|
676
689
|
const resync = await this.reSyncTimerIfGoneOff(secondsLeft);
|
|
677
690
|
|
|
678
|
-
console.log(
|
|
691
|
+
console.log('*** startTimerCountdown = reSyncTimerIfGoneOff ***', {
|
|
692
|
+
secondsLeft,
|
|
693
|
+
resync,
|
|
694
|
+
});
|
|
679
695
|
|
|
680
696
|
if (resync) {
|
|
681
697
|
console.log('have resyncd, will end startTimerCountdown here - ');
|
|
@@ -883,7 +899,6 @@ export default class IABookActions extends LitElement {
|
|
|
883
899
|
|
|
884
900
|
/* show error message if something went wrong */
|
|
885
901
|
async showErrorModal(errorMsg, action) {
|
|
886
|
-
await this.useModalManager();
|
|
887
902
|
|
|
888
903
|
const modalConfig = new ModalConfig({
|
|
889
904
|
title: 'Lending error',
|
|
@@ -948,6 +963,10 @@ export default class IABookActions extends LitElement {
|
|
|
948
963
|
display: block;
|
|
949
964
|
}
|
|
950
965
|
|
|
966
|
+
.hide {
|
|
967
|
+
display: none;
|
|
968
|
+
}
|
|
969
|
+
|
|
951
970
|
.lending-wrapper {
|
|
952
971
|
width: 100%;
|
|
953
972
|
margin: 0 auto;
|