@internetarchive/ia-book-actions 0.1.4 → 0.1.5
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 +3 -3
- package/package.json +1 -1
- package/src/components/timer-countdown.js +81 -23
- package/src/ia-book-actions.js +21 -14
- package/demo/with-bookreader.html +0 -146
package/demo/index.html
CHANGED
|
@@ -131,11 +131,11 @@
|
|
|
131
131
|
iaBookActions.returnUrl = 'https://openlibrary.org';
|
|
132
132
|
iaBookActions.localCache = localCache;
|
|
133
133
|
|
|
134
|
-
let loanTotalTime2Min = { loanTotalTime: 20, loanRenewAtLast: 15, pageChangedInLast:
|
|
135
|
-
let loanTotalTime5Min = { loanTotalTime: 300, loanRenewAtLast:
|
|
134
|
+
let loanTotalTime2Min = { loanTotalTime: 20, loanRenewAtLast: 15, pageChangedInLast: 5 };
|
|
135
|
+
let loanTotalTime5Min = { loanTotalTime: 300, loanRenewAtLast: 290, pageChangedInLast: 15 };
|
|
136
136
|
let loanTotalTime1Hour = { loanTotalTime: 3600, loanRenewAtLast: 600, pageChangedInLast: 900 };
|
|
137
137
|
|
|
138
|
-
iaBookActions.loanRenewTimeConfig =
|
|
138
|
+
iaBookActions.loanRenewTimeConfig = loanTotalTime5Min;
|
|
139
139
|
|
|
140
140
|
let lendingStatus1 = iaBookActions.lendingStatus;
|
|
141
141
|
let secondsLeftOnLoan = iaBookActions.loanRenewTimeConfig.loanTotalTime;
|
package/package.json
CHANGED
|
@@ -31,6 +31,12 @@ export default class TimerCountdown extends LitElement {
|
|
|
31
31
|
*/
|
|
32
32
|
this.loanRenewAtLast = 0;
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* store time when timer is started
|
|
36
|
+
* @type {string}
|
|
37
|
+
*/
|
|
38
|
+
this.timeWhenTimerStart = '';
|
|
39
|
+
|
|
34
40
|
/**
|
|
35
41
|
* delay seconds in setInterval function
|
|
36
42
|
* @type {number}
|
|
@@ -42,32 +48,36 @@ export default class TimerCountdown extends LitElement {
|
|
|
42
48
|
window?.IALendingIntervals?.clearTimerCountdown();
|
|
43
49
|
}
|
|
44
50
|
|
|
51
|
+
firstUpdated() {
|
|
52
|
+
this.timerCountdown();
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
updated(changed) {
|
|
46
56
|
if (changed.has('secondsLeftOnLoan') && this.secondsLeftOnLoan > 0) {
|
|
47
|
-
this.disconnectedCallback();
|
|
48
|
-
|
|
49
57
|
this.timerCountdown();
|
|
50
58
|
}
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
timerCountdown() {
|
|
62
|
+
this.disconnectedCallback();
|
|
63
|
+
|
|
54
64
|
// - let just execute setInterval in every 1 minute
|
|
55
65
|
this.timerExecutionSeconds = 60;
|
|
66
|
+
let secondsLeft = this.secondsLeftOnLoan;
|
|
67
|
+
|
|
68
|
+
// store current time
|
|
69
|
+
this.timeWhenTimerStart = new Date();
|
|
56
70
|
|
|
57
71
|
/**
|
|
58
72
|
* set interval in window object
|
|
59
73
|
* @see ia-lending-intervals.js
|
|
60
74
|
*/
|
|
61
|
-
window.IALendingIntervals.timerCountdown = setInterval(() => {
|
|
62
|
-
|
|
63
|
-
|
|
75
|
+
window.IALendingIntervals.timerCountdown = setInterval(async () => {
|
|
76
|
+
secondsLeft -= this.timerExecutionSeconds;
|
|
77
|
+
secondsLeft = Math.round(secondsLeft); // round number
|
|
64
78
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
secondsLeft,
|
|
68
|
-
' ||| timeLeftInMin',
|
|
69
|
-
Math.ceil(secondsLeft / 60)
|
|
70
|
-
);
|
|
79
|
+
// re-sync timer is gone off
|
|
80
|
+
await this.reSyncTimerIfGoneOff(secondsLeft);
|
|
71
81
|
|
|
72
82
|
/**
|
|
73
83
|
* execute from last 10th minute to 0th minute
|
|
@@ -76,26 +86,74 @@ export default class TimerCountdown extends LitElement {
|
|
|
76
86
|
* @see IABookActions::bindLoanRenewEvents
|
|
77
87
|
*/
|
|
78
88
|
if (secondsLeft <= this.loanRenewAtLast) {
|
|
79
|
-
this.
|
|
80
|
-
new CustomEvent('IABookActions:loanRenew', {
|
|
81
|
-
detail: {
|
|
82
|
-
hasPageChanged: false,
|
|
83
|
-
secondsLeft,
|
|
84
|
-
},
|
|
85
|
-
bubbles: true,
|
|
86
|
-
composed: true,
|
|
87
|
-
})
|
|
88
|
-
);
|
|
89
|
+
this.dispatchLoanRenewEvent(secondsLeft);
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
// clear interval
|
|
92
|
-
if (secondsLeft <=
|
|
92
|
+
// clear interval in secondsLeft if less
|
|
93
|
+
if (secondsLeft <= this.timerExecutionSeconds) {
|
|
93
94
|
this.disconnectedCallback();
|
|
94
95
|
window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
|
|
95
96
|
}
|
|
96
97
|
}, this.timerExecutionSeconds * 1000);
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
/**
|
|
101
|
+
* dispatch loan renew attempt event
|
|
102
|
+
*
|
|
103
|
+
* @param {number} secondsLeft
|
|
104
|
+
* @memberof TimerCountdown
|
|
105
|
+
*/
|
|
106
|
+
dispatchLoanRenewEvent(secondsLeft) {
|
|
107
|
+
this.dispatchEvent(
|
|
108
|
+
new CustomEvent('IABookActions:loanRenew', {
|
|
109
|
+
detail: {
|
|
110
|
+
hasPageChanged: false,
|
|
111
|
+
secondsLeft,
|
|
112
|
+
},
|
|
113
|
+
bubbles: true,
|
|
114
|
+
composed: true,
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* helper function to determine if timer is not in sync properly
|
|
121
|
+
*
|
|
122
|
+
* @param {number} timerSecondsLeft - actual seconds left get from setInterval
|
|
123
|
+
*
|
|
124
|
+
* @memberof TimerCountdown
|
|
125
|
+
*/
|
|
126
|
+
async reSyncTimerIfGoneOff(timerSecondsLeft) {
|
|
127
|
+
// debug info
|
|
128
|
+
console.log(
|
|
129
|
+
new Date().toLocaleTimeString(),
|
|
130
|
+
'timeLeftInSec',
|
|
131
|
+
timerSecondsLeft,
|
|
132
|
+
' ||| timeLeftInMin',
|
|
133
|
+
Math.ceil(timerSecondsLeft / 60)
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const currentTime = new Date();
|
|
137
|
+
|
|
138
|
+
// current time - loan time
|
|
139
|
+
const diffInSeconds =
|
|
140
|
+
currentTime.getTime() / 1000 - this.timeWhenTimerStart.getTime() / 1000;
|
|
141
|
+
|
|
142
|
+
const secondsShouldLeft = this.secondsLeftOnLoan - diffInSeconds;
|
|
143
|
+
|
|
144
|
+
// convert in minutes
|
|
145
|
+
const whatIsleft = Math.round(timerSecondsLeft);
|
|
146
|
+
const whatShouldLeft = Math.round(secondsShouldLeft);
|
|
147
|
+
|
|
148
|
+
if (whatIsleft !== whatShouldLeft) {
|
|
149
|
+
// debug info
|
|
150
|
+
console.log(
|
|
151
|
+
`timer is gone off, let's re-sync, whatIsleft -> ${whatIsleft}, whatShouldLeft -> ${whatShouldLeft}`
|
|
152
|
+
);
|
|
153
|
+
this.secondsLeftOnLoan = secondsShouldLeft; // the seconds should left in timer again
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
99
157
|
/**
|
|
100
158
|
* get remaining time with timeunit
|
|
101
159
|
*
|
package/src/ia-book-actions.js
CHANGED
|
@@ -240,7 +240,7 @@ export default class IABookActions extends LitElement {
|
|
|
240
240
|
*/
|
|
241
241
|
setTimeout(
|
|
242
242
|
() => {
|
|
243
|
-
this.startLoanTokenPoller();
|
|
243
|
+
if (!hasExpired) this.startLoanTokenPoller();
|
|
244
244
|
},
|
|
245
245
|
|
|
246
246
|
// if book is renew while reading, let's wait to execute create-token api
|
|
@@ -260,12 +260,13 @@ export default class IABookActions extends LitElement {
|
|
|
260
260
|
* dispatched this event from bookreader page changed
|
|
261
261
|
*/
|
|
262
262
|
window.addEventListener('BookReader:userAction', () => {
|
|
263
|
+
console.log('user action');
|
|
264
|
+
this.suppressToast = true;
|
|
265
|
+
this.closeToastManager();
|
|
266
|
+
|
|
263
267
|
if (this.borrowType === 'browsed') {
|
|
264
|
-
this.suppressToast = false;
|
|
265
268
|
this.autoLoanRenewChecker(true);
|
|
266
269
|
}
|
|
267
|
-
|
|
268
|
-
return nothing;
|
|
269
270
|
});
|
|
270
271
|
|
|
271
272
|
/**
|
|
@@ -320,6 +321,16 @@ export default class IABookActions extends LitElement {
|
|
|
320
321
|
this.loanRenewResult = this.loanRenewHelper.result;
|
|
321
322
|
}
|
|
322
323
|
|
|
324
|
+
/**
|
|
325
|
+
* close/hide toast message
|
|
326
|
+
*/
|
|
327
|
+
async closeToastManager() {
|
|
328
|
+
const toastTemplate = this.shadowRoot.querySelector('toast-template');
|
|
329
|
+
if (toastTemplate) {
|
|
330
|
+
toastTemplate?.remove();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
323
334
|
/**
|
|
324
335
|
* Show toast messages on some specific loan renew features. e.g.
|
|
325
336
|
* - show message when book is auto renewed
|
|
@@ -329,14 +340,11 @@ export default class IABookActions extends LitElement {
|
|
|
329
340
|
async showToastMessage() {
|
|
330
341
|
if (this.suppressToast) return;
|
|
331
342
|
|
|
332
|
-
|
|
333
|
-
if (!iaBookActions) return;
|
|
334
|
-
|
|
335
|
-
let toastTemplate = iaBookActions.querySelector('toast-template');
|
|
343
|
+
let toastTemplate = this.shadowRoot.querySelector('toast-template');
|
|
336
344
|
if (!toastTemplate) {
|
|
337
345
|
toastTemplate = document.createElement('toast-template');
|
|
338
346
|
}
|
|
339
|
-
await
|
|
347
|
+
await this.shadowRoot.appendChild(toastTemplate);
|
|
340
348
|
|
|
341
349
|
// if secondsLeft < 60, consider it 1 minute
|
|
342
350
|
let { secondsLeft } = this.loanRenewResult;
|
|
@@ -573,8 +581,7 @@ export default class IABookActions extends LitElement {
|
|
|
573
581
|
* @param {string} event.detail.data.error - error message
|
|
574
582
|
*/
|
|
575
583
|
handleLendingActionError(event) {
|
|
576
|
-
|
|
577
|
-
this.handleToggleActionGroup();
|
|
584
|
+
this.disableActionGroup = false;
|
|
578
585
|
|
|
579
586
|
// clear all intervals for lending system when error occured
|
|
580
587
|
window?.IALendingIntervals?.clearAll();
|
|
@@ -582,7 +589,9 @@ export default class IABookActions extends LitElement {
|
|
|
582
589
|
const action = event?.detail?.action;
|
|
583
590
|
const errorMsg = event?.detail?.data?.error;
|
|
584
591
|
|
|
585
|
-
|
|
592
|
+
// template not show create_token errors
|
|
593
|
+
if (errorMsg && action !== 'create_token')
|
|
594
|
+
this.showErrorModal(errorMsg, action);
|
|
586
595
|
|
|
587
596
|
// if error related to loan token
|
|
588
597
|
// - clear tokenPoller interval
|
|
@@ -616,8 +625,6 @@ export default class IABookActions extends LitElement {
|
|
|
616
625
|
|
|
617
626
|
/* show error message if something went wrong */
|
|
618
627
|
async showErrorModal(errorMsg, action) {
|
|
619
|
-
this.disableActionGroup = false;
|
|
620
|
-
|
|
621
628
|
// check if this.modal passed as prop
|
|
622
629
|
if (!this.modal) {
|
|
623
630
|
this.modal = document.querySelector('modal-manager');
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en-GB">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
|
7
|
-
<style>
|
|
8
|
-
html {
|
|
9
|
-
font-size: 10px;
|
|
10
|
-
/* This is to match petabox's base font size */
|
|
11
|
-
}
|
|
12
|
-
body {
|
|
13
|
-
margin: 0;
|
|
14
|
-
text-align: center;
|
|
15
|
-
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
16
|
-
}
|
|
17
|
-
#demo {
|
|
18
|
-
height: 50px;
|
|
19
|
-
}
|
|
20
|
-
ia-book-actions {
|
|
21
|
-
--white: #fff;
|
|
22
|
-
--black: #000;
|
|
23
|
-
--primaryBGColor: var(--black);
|
|
24
|
-
--secondaryBGColor: #222;
|
|
25
|
-
--tertiaryBGColor: #333;
|
|
26
|
-
--primaryTextColor: var(--white);
|
|
27
|
-
--primaryCTAFill: #194880;
|
|
28
|
-
--primaryCTABorder: #c5d1df;
|
|
29
|
-
--secondaryCTAFill: #333;
|
|
30
|
-
--secondaryCTABorder: #999;
|
|
31
|
-
--secondaryCTAFillRGB: 51, 51, 51;
|
|
32
|
-
--primaryErrorCTAFill: #e51c26;
|
|
33
|
-
--primaryErrorCTABorder: #f8c6c8;
|
|
34
|
-
--primaryCTAFillRGB: 25, 72, 128;
|
|
35
|
-
--primaryErrorCTAFillRGB: 229, 28, 38;
|
|
36
|
-
--primaryDisableCTAFill: #767676;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
fieldset {
|
|
40
|
-
width: fit-content;
|
|
41
|
-
margin-top: 50px;
|
|
42
|
-
}
|
|
43
|
-
fieldset legend {
|
|
44
|
-
text-align: left;
|
|
45
|
-
font-size: 12px;
|
|
46
|
-
}
|
|
47
|
-
td {
|
|
48
|
-
color: white;
|
|
49
|
-
font-size: 14px;
|
|
50
|
-
border-radius: 5%;
|
|
51
|
-
display: table-cell;
|
|
52
|
-
text-align: initial;
|
|
53
|
-
margin: 5px 0;
|
|
54
|
-
width: max-content;
|
|
55
|
-
display: block;
|
|
56
|
-
}
|
|
57
|
-
label {
|
|
58
|
-
padding: 10px;
|
|
59
|
-
display: block;
|
|
60
|
-
cursor: pointer;
|
|
61
|
-
margin: 2px;
|
|
62
|
-
background: #4e545a;
|
|
63
|
-
border-radius: 10px;
|
|
64
|
-
}
|
|
65
|
-
input[type="radio"], input[type="checkbox"] {
|
|
66
|
-
margin-top: 0;
|
|
67
|
-
vertical-align: middle;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.initial td {
|
|
71
|
-
float: left;
|
|
72
|
-
margin: 2px;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
body.modal-manager-open {
|
|
76
|
-
overflow: hidden;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
modal-manager[mode='closed'] {
|
|
80
|
-
display: none;
|
|
81
|
-
}
|
|
82
|
-
</style>
|
|
83
|
-
</head>
|
|
84
|
-
|
|
85
|
-
<body>
|
|
86
|
-
<ia-bookreader class="focus-on-child-only" signedin="" fullscreen="">
|
|
87
|
-
<div slot="header">
|
|
88
|
-
<ia-book-actions></ia-book-actions>
|
|
89
|
-
</div>
|
|
90
|
-
<div slot="main">
|
|
91
|
-
<div id="BookReader"></div>
|
|
92
|
-
</div>
|
|
93
|
-
</ia-bookreader>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
<script type="module">
|
|
97
|
-
/* eslint-disable */
|
|
98
|
-
import '@internetarchive/bookreader';
|
|
99
|
-
import '@internetarchive/bookreader/BookReader/jquery-1.10.1.js';
|
|
100
|
-
import '@internetarchive/bookreader/BookReader/BookReader.js';
|
|
101
|
-
import '../src/ia-book-actions.js';
|
|
102
|
-
import {
|
|
103
|
-
defaultLendingStatus,
|
|
104
|
-
canBrowseAndBorrow,
|
|
105
|
-
} from '../src/assets/data/lending-get-status-service.js';
|
|
106
|
-
import { ModalConfig } from '@internetarchive/modal-manager';
|
|
107
|
-
|
|
108
|
-
const userid = '@neeraj-archive';
|
|
109
|
-
const identifier = 'naturalhistoryof00unse_4111';
|
|
110
|
-
let bwbPurchaseUrl = 'https://www.betterworldbooks.com/product/detail/cambridge-ancient-hist-v04-0521044863';
|
|
111
|
-
|
|
112
|
-
let iaBookActions = document.querySelector('ia-book-actions');
|
|
113
|
-
|
|
114
|
-
// for debugging
|
|
115
|
-
window.iaBookActions = iaBookActions;
|
|
116
|
-
|
|
117
|
-
const modalConfig = new ModalConfig();
|
|
118
|
-
modalConfig.headerColor = '#d9534f';
|
|
119
|
-
|
|
120
|
-
let lendingBarPostInit = function lendingBarPostInit() {
|
|
121
|
-
setTimeout(function() {
|
|
122
|
-
console.log('executed', 'br.init()');
|
|
123
|
-
}, 100);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// set defaultLendingStatus for unavailable (without borrowables) book
|
|
127
|
-
iaBookActions.userid = userid;
|
|
128
|
-
iaBookActions.identifier = identifier;
|
|
129
|
-
iaBookActions.bookTitle = 'Contemporary Black biography. Volume 39 : profiles from the interContemporary Black biography. Volume 39';
|
|
130
|
-
iaBookActions.lendingStatus = canBrowseAndBorrow;
|
|
131
|
-
iaBookActions.bwbPurchaseUrl = '';
|
|
132
|
-
iaBookActions.modalConfig = modalConfig;
|
|
133
|
-
iaBookActions.lendingBarPostInit = lendingBarPostInit;
|
|
134
|
-
iaBookActions.tokenDelay = 2000; // 2 seconds
|
|
135
|
-
iaBookActions.returnUrl = 'https://openlibrary.org';
|
|
136
|
-
|
|
137
|
-
let lendingStatus1 = iaBookActions.lendingStatus;
|
|
138
|
-
|
|
139
|
-
const manifest = await fetch('https://ia801302.us.archive.org/BookReader/BookReaderJSIA.php?id=goody&itemPath=/29/items/goody&server=ia801302.us.archive.org&format=jsonp&subPrefix=goody&requestUri=/details/goody/mode/1up%3Fview%3Dtheater%26ui%3Dembed%26wrapper%3Dfalse');
|
|
140
|
-
|
|
141
|
-
console.log('manifest ****', manifest).then(res => res.json());
|
|
142
|
-
</script>
|
|
143
|
-
|
|
144
|
-
</div>
|
|
145
|
-
</body>
|
|
146
|
-
</html>
|