@internetarchive/ia-book-actions 0.1.9 → 0.1.11-a1
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 -1
- package/demo/with-bookreader.html +146 -0
- package/package.json +3 -2
- package/src/assets/data/lending-get-status-service.js +2 -2
- package/src/components/collapsible-action-group.js +10 -4
- package/src/components/confirmation-modal.js +0 -0
- package/src/components/timer-countdown.js +48 -30
- package/src/core/config/ia-lending-intervals.js +8 -2
- package/src/core/services/actions-handler/actions-handler.js +1 -1
- package/src/core/services/get-lending-actions.js +3 -4
- package/src/core/services/loan-analytics.js +8 -8
- package/src/core/services/loan-renew-helper.js +13 -6
- package/src/ia-book-actions.js +288 -114
- package/test/core/services/loan-renew-helper.test.js +1 -1
- package/test/ia-book-actions.test.js +5 -3
package/demo/index.html
CHANGED
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
|
|
89
89
|
<body>
|
|
90
90
|
<ia-book-actions></ia-book-actions>
|
|
91
|
+
<modal-manager></modal-manager>
|
|
91
92
|
|
|
92
93
|
<script type="module">
|
|
93
94
|
/* eslint-disable */
|
|
@@ -97,6 +98,7 @@
|
|
|
97
98
|
defaultLendingStatus,
|
|
98
99
|
canBrowseAndBorrow,
|
|
99
100
|
} from '../src/assets/data/lending-get-status-service.js';
|
|
101
|
+
import '@internetarchive/modal-manager';
|
|
100
102
|
import { ModalConfig } from '@internetarchive/modal-manager';
|
|
101
103
|
import { LocalCache } from '@internetarchive/local-cache';
|
|
102
104
|
|
|
@@ -290,7 +292,7 @@
|
|
|
290
292
|
|
|
291
293
|
document.querySelector('.pageChangedEvent').addEventListener('click', () => {
|
|
292
294
|
// dispatch event to say book page has flipped
|
|
293
|
-
|
|
295
|
+
window.dispatchEvent(
|
|
294
296
|
new CustomEvent('BookReader:userAction', {
|
|
295
297
|
detail: {},
|
|
296
298
|
bubbles: true,
|
|
@@ -0,0 +1,146 @@
|
|
|
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>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/ia-book-actions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11-a1",
|
|
4
4
|
"description": "Bookreader actions for borrowable book",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -18,9 +18,10 @@
|
|
|
18
18
|
"test:watch": "web-test-runner --watch --playwright --browsers chromium firefox webkit"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@internetarchive/ia-activity-indicator": "^0.0.4",
|
|
21
22
|
"@internetarchive/icon-info": "^1.2.6",
|
|
22
23
|
"@internetarchive/local-cache": "^0.2.1",
|
|
23
|
-
"@internetarchive/modal-manager": "^0.2.
|
|
24
|
+
"@internetarchive/modal-manager": "^0.2.12",
|
|
24
25
|
"@internetarchive/shared-resize-observer": "^0.2.0",
|
|
25
26
|
"@internetarchive/toast-manager": "0.1.0",
|
|
26
27
|
"lit": "^2.5.0"
|
|
@@ -100,7 +100,7 @@ export const canBrowseAndBorrow = {
|
|
|
100
100
|
// userid: "",
|
|
101
101
|
bookUrl: '/details/practicalorganic00plim',
|
|
102
102
|
daysLeftOnLoan: 0,
|
|
103
|
-
isAdmin:
|
|
103
|
+
isAdmin: false,
|
|
104
104
|
isArchiveOrgLending: true,
|
|
105
105
|
isAvailable: false,
|
|
106
106
|
isAvailableForBrowsing: false,
|
|
@@ -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: 155,
|
|
122
122
|
shouldProtectImages: true,
|
|
123
123
|
totalWaitlistCount: 0,
|
|
124
124
|
userHasBorrowed: false,
|
|
@@ -30,6 +30,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
30
30
|
returnUrl: { type: String },
|
|
31
31
|
autoRenew: { type: Boolean },
|
|
32
32
|
autoReturn: { type: Boolean },
|
|
33
|
+
returnNow: { type: Boolean },
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -51,6 +52,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
51
52
|
this.returnUrl = '';
|
|
52
53
|
this.autoRenew = false;
|
|
53
54
|
this.autoReturn = false;
|
|
55
|
+
this.returnNow = false;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
updated(changed) {
|
|
@@ -68,18 +70,22 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
68
70
|
if (changed.has('autoReturn') && this.autoReturn === true) {
|
|
69
71
|
this.dispatchLoanEvent('autoReturn');
|
|
70
72
|
}
|
|
73
|
+
|
|
74
|
+
if (changed.has('returnNow') && this.returnNow === true) {
|
|
75
|
+
this.dispatchLoanEvent('returnNow', { borrowType: 'browse' });
|
|
76
|
+
}
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
/**
|
|
74
|
-
* dispatch event when book is auto renewed / returned
|
|
80
|
+
* dispatch event when book is auto auto-renewed / auto-returned / returned
|
|
75
81
|
* listen these events in action-handler.js to execute ajax call on petabox.
|
|
76
82
|
* @see ActionsHandler
|
|
77
83
|
*
|
|
78
|
-
* @param {string} event - autoRenew|autoReturn
|
|
84
|
+
* @param {string} event - autoRenew|autoReturn|returnNow
|
|
79
85
|
* @memberof CollapsibleActionGroup
|
|
80
86
|
*/
|
|
81
|
-
dispatchLoanEvent(event) {
|
|
82
|
-
this.dispatchEvent(new
|
|
87
|
+
dispatchLoanEvent(event, detail) {
|
|
88
|
+
this.dispatchEvent(new CustomEvent(event, { detail }));
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
/**
|
|
File without changes
|
|
@@ -41,15 +41,18 @@ export default class TimerCountdown extends LitElement {
|
|
|
41
41
|
* delay seconds in setInterval function
|
|
42
42
|
* @type {number}
|
|
43
43
|
*/
|
|
44
|
-
this.timerExecutionSeconds =
|
|
44
|
+
this.timerExecutionSeconds = 30;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
connectedCallback() {
|
|
48
|
+
super.connectedCallback();
|
|
49
|
+
console.log('connectedCallback - timerCountdown');
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
disconnectedCallback() {
|
|
53
|
+
console.log('disconnectedCallback - timerCountdown IN', window.IALendingIntervals);
|
|
54
|
+
window?.IALendingIntervals?.clearTimerCountdown();
|
|
55
|
+
console.log('disconnectedCallback - timerCountdown cleared', window.IALendingIntervals);
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
updated(changed) {
|
|
@@ -58,41 +61,52 @@ export default class TimerCountdown extends LitElement {
|
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
|
|
64
|
+
async timerInterval() {
|
|
65
|
+
let secondsLeft = this.secondsLeftOnLoan;
|
|
66
|
+
|
|
67
|
+
secondsLeft -= this.timerExecutionSeconds;
|
|
68
|
+
secondsLeft = Math.round(secondsLeft); // round number
|
|
69
|
+
|
|
70
|
+
// re-sync timer if gone off because of background window
|
|
71
|
+
|
|
72
|
+
// do we need a window.focus anywhere?
|
|
73
|
+
await this.reSyncTimerIfGoneOff(secondsLeft);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* execute from last 10th minute to 0th minute // arbitrary?
|
|
77
|
+
* - 10th - to check if user has viewed
|
|
78
|
+
* - till 0th - to show warning msg with remaining time to auto expired
|
|
79
|
+
* @see IABookActions::bindLoanRenewEvents
|
|
80
|
+
*/
|
|
81
|
+
if (secondsLeft <= this.loanRenewAtLast) {
|
|
82
|
+
this.dispatchLoanRenewEvent(secondsLeft);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// clear interval in secondsLeft if less
|
|
86
|
+
if (secondsLeft <= this.timerExecutionSeconds) {
|
|
87
|
+
this.disconnectedCallback();
|
|
88
|
+
window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
61
92
|
timerCountdown() {
|
|
93
|
+
console.log('TIMER COUNTDOWN', window.IALendingIntervals, this.timerExecutionSeconds );
|
|
62
94
|
this.disconnectedCallback();
|
|
63
95
|
|
|
64
|
-
|
|
96
|
+
|
|
65
97
|
|
|
66
98
|
// store current time
|
|
67
99
|
this.timeWhenTimerStart = new Date();
|
|
68
100
|
|
|
101
|
+
// this.dispatchLoanRenewEvent(secondsLeft);
|
|
69
102
|
/**
|
|
70
103
|
* set interval in window object
|
|
71
104
|
* @see ia-lending-intervals.js
|
|
72
105
|
*/
|
|
73
|
-
window.IALendingIntervals.timerCountdown = setInterval(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// re-sync timer if gone off because of background window
|
|
78
|
-
await this.reSyncTimerIfGoneOff(secondsLeft);
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* execute from last 10th minute to 0th minute
|
|
82
|
-
* - 10th - to check if user has viewed
|
|
83
|
-
* - till 0th - to show warning msg with remaining time to auto expired
|
|
84
|
-
* @see IABookActions::bindLoanRenewEvents
|
|
85
|
-
*/
|
|
86
|
-
if (secondsLeft <= this.loanRenewAtLast) {
|
|
87
|
-
this.dispatchLoanRenewEvent(secondsLeft);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// clear interval in secondsLeft if less
|
|
91
|
-
if (secondsLeft <= this.timerExecutionSeconds) {
|
|
92
|
-
this.disconnectedCallback();
|
|
93
|
-
window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
|
|
94
|
-
}
|
|
95
|
-
}, this.timerExecutionSeconds * 1000);
|
|
106
|
+
window.IALendingIntervals.timerCountdown = setInterval(
|
|
107
|
+
() => this.timerInterval(),
|
|
108
|
+
this.timerExecutionSeconds * 1000
|
|
109
|
+
);
|
|
96
110
|
}
|
|
97
111
|
|
|
98
112
|
/**
|
|
@@ -150,6 +164,9 @@ export default class TimerCountdown extends LitElement {
|
|
|
150
164
|
);
|
|
151
165
|
this.secondsLeftOnLoan = secondsShouldLeft; // the seconds should left in timer again
|
|
152
166
|
}
|
|
167
|
+
|
|
168
|
+
// when do we resync timer?
|
|
169
|
+
// return true or false?
|
|
153
170
|
}
|
|
154
171
|
|
|
155
172
|
/**
|
|
@@ -171,6 +188,7 @@ export default class TimerCountdown extends LitElement {
|
|
|
171
188
|
}
|
|
172
189
|
|
|
173
190
|
render() {
|
|
191
|
+
console.log("TIMER COUNTDOWN RENDER");
|
|
174
192
|
return html`
|
|
175
193
|
<svg
|
|
176
194
|
width="14"
|
|
@@ -178,7 +196,7 @@ export default class TimerCountdown extends LitElement {
|
|
|
178
196
|
viewBox="0 0 100 100"
|
|
179
197
|
xmlns="http://www.w3.org/2000/svg"
|
|
180
198
|
>
|
|
181
|
-
<circle class="circle" cx="50" cy="50" r="50" />
|
|
199
|
+
<circle id="timer-countdown" class="circle" cx="50" cy="50" r="50" />
|
|
182
200
|
</svg>
|
|
183
201
|
<span class="sr-only">${this.remainingTime} left</span>
|
|
184
202
|
`;
|
|
@@ -41,7 +41,13 @@ window.IALendingIntervals = {
|
|
|
41
41
|
* clear all intervals being used acros lending system
|
|
42
42
|
*/
|
|
43
43
|
clearAll: () => {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
try {
|
|
45
|
+
|
|
46
|
+
window.clearInterval(window?.IALendingIntervals.tokenPoller);
|
|
47
|
+
window.clearInterval(window?.IALendingIntervals.timerCountdown);
|
|
48
|
+
} catch(e) {
|
|
49
|
+
console.error(e);
|
|
50
|
+
}
|
|
51
|
+
|
|
46
52
|
},
|
|
47
53
|
};
|
|
@@ -164,7 +164,7 @@ export default class ActionsHandler extends LitElement {
|
|
|
164
164
|
/**
|
|
165
165
|
* excute function when loan is returning
|
|
166
166
|
*
|
|
167
|
-
* @param {
|
|
167
|
+
* @param {'returnNow' | ''} type
|
|
168
168
|
*/
|
|
169
169
|
handleReturnIt(type = '') {
|
|
170
170
|
const action = 'return_loan';
|
|
@@ -40,7 +40,7 @@ import ActionsConfig from './actions-config.js';
|
|
|
40
40
|
* @enum {string}
|
|
41
41
|
*/
|
|
42
42
|
export const bookTitles = {
|
|
43
|
-
available_1hr: 'Renews
|
|
43
|
+
available_1hr: 'Renews automatically as long as pages are turned.',
|
|
44
44
|
available_14d: 'This book can be borrowed for 14 days.',
|
|
45
45
|
available_pd: 'Book available to patrons with print disabilities.',
|
|
46
46
|
available_waitlist: 'A waitlist is available.',
|
|
@@ -49,7 +49,7 @@ export const bookTitles = {
|
|
|
49
49
|
being_borrowed: 'Another patron is using this book. Please check back later.',
|
|
50
50
|
eligible_pd: 'You are eligible for print-disabled access.',
|
|
51
51
|
on_waitlist: 'You are on the waitlist for this book.',
|
|
52
|
-
session_expired: '',
|
|
52
|
+
session_expired: 'Renews automatically as long as pages are turned.',
|
|
53
53
|
unavailable: 'This book is not available at this time.',
|
|
54
54
|
};
|
|
55
55
|
|
|
@@ -98,8 +98,7 @@ export class GetLendingActions {
|
|
|
98
98
|
let isBrowsing =
|
|
99
99
|
lendingStatus.user_has_browsed && !lendingStatus.browsingExpired;
|
|
100
100
|
if (isBrowsing) {
|
|
101
|
-
primaryTitleText =
|
|
102
|
-
'Returns automatically after 25 minutes of inactivity.';
|
|
101
|
+
primaryTitleText = bookTitles.available_1hr;
|
|
103
102
|
} else {
|
|
104
103
|
primaryTitleText = `Your loan of this book has ${lendingStatus.daysLeftOnLoan} days left.`;
|
|
105
104
|
}
|
|
@@ -144,14 +144,14 @@ export default class LoanAnanlytics {
|
|
|
144
144
|
* @memberof LoanAnanlytics
|
|
145
145
|
*/
|
|
146
146
|
sendEvent(eventCategory, eventAction, label, extraParams) {
|
|
147
|
-
console.log(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
);
|
|
147
|
+
// console.log(
|
|
148
|
+
// 'eventCategory:-',
|
|
149
|
+
// eventCategory,
|
|
150
|
+
// '\t||\teventAction:-',
|
|
151
|
+
// eventAction,
|
|
152
|
+
// '\t||\tlabel:-',
|
|
153
|
+
// label
|
|
154
|
+
// );
|
|
155
155
|
|
|
156
156
|
window?.archive_analytics?.send_event_no_sampling(
|
|
157
157
|
eventCategory,
|
|
@@ -16,7 +16,7 @@ export class LoanRenewHelper {
|
|
|
16
16
|
this.loanRenewMessage =
|
|
17
17
|
'This book has been renewed for #time #unitsOfTime.';
|
|
18
18
|
this.loanReturnWarning =
|
|
19
|
-
'
|
|
19
|
+
'With no action, this book will be auto-returned in #time #unitsOfTime.';
|
|
20
20
|
|
|
21
21
|
// private props
|
|
22
22
|
this.result = {
|
|
@@ -26,11 +26,14 @@ export class LoanRenewHelper {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
handleLoanRenew() {
|
|
29
|
+
console.log('handleLoanRenew', this.hasPageChanged);
|
|
29
30
|
try {
|
|
30
31
|
if (this.hasPageChanged) {
|
|
31
|
-
|
|
32
|
+
this.pageChanged(); // user clicked on page
|
|
33
|
+
return;
|
|
32
34
|
}
|
|
33
|
-
|
|
35
|
+
this.autoChecker(); // auto checker at last 10th minute
|
|
36
|
+
return;
|
|
34
37
|
} catch (error) {
|
|
35
38
|
console.log(error);
|
|
36
39
|
}
|
|
@@ -39,7 +42,7 @@ export class LoanRenewHelper {
|
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
|
-
* Trigger this function when user has browsed a book and change the
|
|
45
|
+
* Trigger this function when user has browsed a book and change the page
|
|
43
46
|
* - every time user change the page, we set current time in indexedDB
|
|
44
47
|
* - also check if need to auto renew current loan
|
|
45
48
|
*
|
|
@@ -54,13 +57,16 @@ export class LoanRenewHelper {
|
|
|
54
57
|
|
|
55
58
|
const lastTimeFrame = this.changeTime(loanTime, loanRenewAtLast, 'sub');
|
|
56
59
|
|
|
60
|
+
console.log("PAGE CHANGED ~~~~~~~~~ lastTimeFram, loanTime", { lastTimeFrame, loanTime });
|
|
61
|
+
|
|
57
62
|
// if user viewed new page in last 10 minutes, renew immediately
|
|
58
63
|
if (lastTimeFrame !== null && currentTime >= lastTimeFrame) {
|
|
59
64
|
this.result.texts = this.loanRenewMessage;
|
|
60
65
|
this.result.renewNow = true;
|
|
61
66
|
}
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
console.log("PAGE CHANGED ~~~~~~~~~ ", this.result);
|
|
68
|
+
debugger;
|
|
69
|
+
await this.setPageChangedTime();
|
|
64
70
|
return this.result;
|
|
65
71
|
}
|
|
66
72
|
|
|
@@ -71,6 +77,7 @@ export class LoanRenewHelper {
|
|
|
71
77
|
* @returns {this.result}
|
|
72
78
|
*/
|
|
73
79
|
async autoChecker() {
|
|
80
|
+
console.log('autoChecker ***!!!!!');
|
|
74
81
|
const { pageChangedInLast } = this.loanRenewTimeConfig;
|
|
75
82
|
const pageChangedTime = await this.localCache.get(
|
|
76
83
|
`${this.identifier}-pageChangedTime`
|
package/src/ia-book-actions.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
|
+
/* eslint-disable class-methods-use-this */
|
|
2
3
|
import { html, css, LitElement, nothing } from 'lit';
|
|
3
4
|
|
|
4
5
|
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
|
|
@@ -23,12 +24,28 @@ export const events = {
|
|
|
23
24
|
browseExpired: 'IABookReader:BrowsingHasExpired',
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* custom styling for modal-manager buttons
|
|
29
|
+
* TODO: lets allow modal-manager to know ia-button classes
|
|
30
|
+
*/
|
|
31
|
+
export const modalButtonStyle = {
|
|
32
|
+
iaButton:
|
|
33
|
+
'min-height:3.5rem;cursor:pointer;color:white;border-radius:0.4rem;border:1px solid #c5d1df;padding:4px 8px;width:auto;user-select:none;',
|
|
34
|
+
renew: 'background:#194880;width:110px;',
|
|
35
|
+
return: 'background:#d9534f;width:120px;',
|
|
36
|
+
loaderIcon:
|
|
37
|
+
'display:inline-block;width:20px;height:20px;margin-top:2px;color:white;--activityIndicatorLoadingRingColor:#fff;--activityIndicatorLoadingDotColor:#fff;',
|
|
38
|
+
refresh:
|
|
39
|
+
'background:none;font-size:inherit;border:0;padding:0;color:#0000ee;cursor:pointer;text-decoration:underline',
|
|
40
|
+
};
|
|
41
|
+
|
|
26
42
|
export default class IABookActions extends LitElement {
|
|
27
43
|
static get properties() {
|
|
28
44
|
return {
|
|
29
45
|
userid: { type: String },
|
|
30
46
|
identifier: { type: String },
|
|
31
47
|
bookTitle: { type: String },
|
|
48
|
+
/** */
|
|
32
49
|
lendingStatus: { type: Object },
|
|
33
50
|
returnUrl: { type: String },
|
|
34
51
|
width: { type: Number },
|
|
@@ -61,7 +78,7 @@ export default class IABookActions extends LitElement {
|
|
|
61
78
|
this.barType = 'action'; // 'title'|'action'
|
|
62
79
|
this.sharedObserver = undefined;
|
|
63
80
|
this.disableActionGroup = false;
|
|
64
|
-
this.modal = undefined;
|
|
81
|
+
// this.modal = undefined;
|
|
65
82
|
this.tokenDelay = 120; // in seconds
|
|
66
83
|
|
|
67
84
|
// private props
|
|
@@ -71,10 +88,19 @@ export default class IABookActions extends LitElement {
|
|
|
71
88
|
this.secondaryActions = [];
|
|
72
89
|
this.lendingOptions = {};
|
|
73
90
|
this.borrowType = ''; // (browsed|borrowed)
|
|
74
|
-
this.
|
|
91
|
+
this.browseTimer = undefined;
|
|
92
|
+
|
|
93
|
+
/** @deprecated */
|
|
94
|
+
this.toast = undefined;
|
|
95
|
+
/** @deprecated */
|
|
75
96
|
this.suppressToast = false;
|
|
97
|
+
/** @deprecated */
|
|
76
98
|
this.suppressAutoRenew = false;
|
|
77
|
-
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* when user click on [return the book] button on warning modal
|
|
102
|
+
*/
|
|
103
|
+
this.returnNow = false;
|
|
78
104
|
|
|
79
105
|
/**
|
|
80
106
|
* contains one hour auto-loan-renew time configuration
|
|
@@ -103,6 +129,11 @@ export default class IABookActions extends LitElement {
|
|
|
103
129
|
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
|
104
130
|
}
|
|
105
131
|
|
|
132
|
+
connectedCallback() {
|
|
133
|
+
super.connectedCallback();
|
|
134
|
+
console.log('connectedCallback - ia-book-actions');
|
|
135
|
+
}
|
|
136
|
+
|
|
106
137
|
disconnectedCallback() {
|
|
107
138
|
// clear all intervals for lending system
|
|
108
139
|
window?.IALendingIntervals?.clearAll();
|
|
@@ -112,21 +143,28 @@ export default class IABookActions extends LitElement {
|
|
|
112
143
|
}
|
|
113
144
|
|
|
114
145
|
firstUpdated() {
|
|
146
|
+
// window.focus => reset timer & also1w3w
|
|
147
|
+
window.addEventListener('focus', () => {
|
|
148
|
+
console.log('window focus ~~~~~~');
|
|
149
|
+
});
|
|
150
|
+
|
|
115
151
|
// bind auto loan renew events
|
|
116
152
|
this.bindLoanRenewEvents();
|
|
117
153
|
|
|
118
154
|
// localCache used for auto-loan-renew
|
|
119
155
|
this.localCache = new LocalCache({
|
|
120
|
-
namespace:
|
|
156
|
+
namespace: `loanRenew-${this.identifier || 'unknown_book'}`,
|
|
121
157
|
});
|
|
122
158
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
159
|
+
this.sharedObserver = new SharedResizeObserver();
|
|
160
|
+
this.setupResizeObserver();
|
|
161
|
+
|
|
162
|
+
const modal = this.modal;
|
|
163
|
+
console.log('modal', modal);
|
|
127
164
|
}
|
|
128
165
|
|
|
129
166
|
updated(changed) {
|
|
167
|
+
console.log('UPDATED', this.lendingStatus);
|
|
130
168
|
if (changed.has('lendingStatus') || changed.has('bwbPurchaseUrl')) {
|
|
131
169
|
this.setupLendingToolbarActions();
|
|
132
170
|
this.update();
|
|
@@ -138,6 +176,19 @@ export default class IABookActions extends LitElement {
|
|
|
138
176
|
}
|
|
139
177
|
}
|
|
140
178
|
|
|
179
|
+
render() {
|
|
180
|
+
console.log("RENDER IABookActions", this.barType);
|
|
181
|
+
if (this.barType === 'title') {
|
|
182
|
+
return html`<section class="lending-wrapper">
|
|
183
|
+
${this.bookTitleBar}
|
|
184
|
+
</section>`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return html`<section class="lending-wrapper">
|
|
188
|
+
${this.bookActionBar}
|
|
189
|
+
</section>`;
|
|
190
|
+
}
|
|
191
|
+
|
|
141
192
|
/** SharedObserver resize handler */
|
|
142
193
|
handleResize(entry) {
|
|
143
194
|
// if you are observing multiple targets,
|
|
@@ -153,7 +204,8 @@ export default class IABookActions extends LitElement {
|
|
|
153
204
|
|
|
154
205
|
/** Removes observer */
|
|
155
206
|
disconnectResizeObserver() {
|
|
156
|
-
this.sharedObserver
|
|
207
|
+
if (!this.sharedObserver) return;
|
|
208
|
+
this.sharedObserver.removeObserver({
|
|
157
209
|
handler: this,
|
|
158
210
|
target: this.shadowRoot.host,
|
|
159
211
|
});
|
|
@@ -164,7 +216,9 @@ export default class IABookActions extends LitElement {
|
|
|
164
216
|
setupResizeObserver() {
|
|
165
217
|
if (!this.shadowRoot) return;
|
|
166
218
|
this.sharedObserver?.addObserver({
|
|
167
|
-
handler:
|
|
219
|
+
handler: {
|
|
220
|
+
handleResize: this.handleResize.bind(this),
|
|
221
|
+
},
|
|
168
222
|
target: this.shadowRoot.host,
|
|
169
223
|
});
|
|
170
224
|
}
|
|
@@ -218,8 +272,9 @@ export default class IABookActions extends LitElement {
|
|
|
218
272
|
}
|
|
219
273
|
|
|
220
274
|
if (this.borrowType === 'browsed') {
|
|
275
|
+
console.log('this.borrowType', this.borrowType);
|
|
221
276
|
// start timer for browsed.
|
|
222
|
-
this.startBrowseTimer();
|
|
277
|
+
await this.startBrowseTimer();
|
|
223
278
|
}
|
|
224
279
|
|
|
225
280
|
// early return if not borrowed or no action-bar
|
|
@@ -233,6 +288,7 @@ export default class IABookActions extends LitElement {
|
|
|
233
288
|
setTimeout(() => {
|
|
234
289
|
this.resetTimerCountState();
|
|
235
290
|
}, 100);
|
|
291
|
+
return;
|
|
236
292
|
}
|
|
237
293
|
|
|
238
294
|
/**
|
|
@@ -248,57 +304,26 @@ export default class IABookActions extends LitElement {
|
|
|
248
304
|
* Bind 1 hour loan auto renew event,
|
|
249
305
|
* There are two events we want to use,
|
|
250
306
|
* 1. BookReader:userAction - dispatched from bookreader side
|
|
251
|
-
* 2.
|
|
252
|
-
* 3. IABookActions:loanRenew - dispatched from timer-countdown component
|
|
307
|
+
* 2. IABookActions:loanRenew - dispatched from timer-countdown component
|
|
253
308
|
*/
|
|
254
309
|
bindLoanRenewEvents() {
|
|
255
310
|
/**
|
|
256
311
|
* dispatched this event from bookreader page changed
|
|
257
312
|
*/
|
|
258
313
|
window.addEventListener('BookReader:userAction', () => {
|
|
259
|
-
console.log('
|
|
260
|
-
suppressAutoRenew: this.suppressAutoRenew,
|
|
261
|
-
borrowType: this.borrowType,
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
this.suppressToast = true;
|
|
265
|
-
this.closeToastManager();
|
|
266
|
-
|
|
267
|
-
if (this.suppressAutoRenew) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
314
|
+
console.log('BookReader:userAction **** , ', this.borrowType);
|
|
271
315
|
if (this.borrowType === 'browsed') {
|
|
272
316
|
this.autoLoanRenewChecker(true);
|
|
273
317
|
}
|
|
274
318
|
});
|
|
275
319
|
|
|
276
|
-
/**
|
|
277
|
-
* detect click-event on document to close toast-template
|
|
278
|
-
*/
|
|
279
|
-
document.addEventListener('click', e => {
|
|
280
|
-
console.log('*** top level click handler to remove toast on click');
|
|
281
|
-
if (this.loanRenewHelper && this.loanRenewResult.secondsLeft > 0) {
|
|
282
|
-
this.suppressToast = true;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// reload when user click on book-page and book is EXPIRED
|
|
286
|
-
const hasExpired =
|
|
287
|
-
'browsingExpired' in this.lendingStatus &&
|
|
288
|
-
this.lendingStatus?.browsingExpired;
|
|
289
|
-
if (hasExpired && e.target.nodeName !== 'IA-BOOK-ACTIONS') {
|
|
290
|
-
window.location?.reload();
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
|
|
294
320
|
/**
|
|
295
321
|
* this event dispatched from timer-countdown component for:
|
|
296
|
-
* 1. user turned book page after showing auto-returned warning
|
|
297
|
-
* 2. show warning
|
|
322
|
+
* 1. user turned book page after showing auto-returned warning modal
|
|
323
|
+
* 2. show warning modal having remaining time
|
|
298
324
|
* @see TimerCountdown::timerCountdown
|
|
299
325
|
*/
|
|
300
326
|
this.addEventListener('IABookActions:loanRenew', async event => {
|
|
301
|
-
console.log('** IABookActions:loanRenew', event.detail);
|
|
302
327
|
await this.autoLoanRenewChecker(false);
|
|
303
328
|
|
|
304
329
|
/**
|
|
@@ -311,19 +336,22 @@ export default class IABookActions extends LitElement {
|
|
|
311
336
|
let secondsLeft = event?.detail?.secondsLeft;
|
|
312
337
|
if (secondsLeft < 50) {
|
|
313
338
|
this.suppressAutoRenew = true;
|
|
339
|
+
console.log("BROWSER TIMER IN secondsLeft < 50!!",secondsLeft, secondsLeft < 50);
|
|
340
|
+
console.log("BROWSER TIMER IN secondsLeft < 50!! this.loanRenewResult",this.loanRenewResult);
|
|
341
|
+
|
|
314
342
|
this.browseHasExpired();
|
|
315
343
|
}
|
|
316
344
|
|
|
317
|
-
// show warning
|
|
345
|
+
// show warning modal with remaining time to auto returned it.
|
|
318
346
|
if (this.loanRenewResult.renewNow === false) {
|
|
319
347
|
/**
|
|
320
348
|
* so compensate for the 50 second buffer to handle above race conditions
|
|
321
349
|
* let's reduce 1 min from warning texts and early return the book when 1 min left.
|
|
322
350
|
*/
|
|
323
351
|
secondsLeft -= 60;
|
|
324
|
-
|
|
325
352
|
this.loanRenewResult.secondsLeft = secondsLeft;
|
|
326
|
-
|
|
353
|
+
|
|
354
|
+
this.showWarningModal();
|
|
327
355
|
}
|
|
328
356
|
});
|
|
329
357
|
}
|
|
@@ -335,29 +363,174 @@ export default class IABookActions extends LitElement {
|
|
|
335
363
|
* @param {Boolean} hasPageChanged
|
|
336
364
|
*/
|
|
337
365
|
async autoLoanRenewChecker(hasPageChanged = false) {
|
|
338
|
-
this.loanRenewHelper
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
this.
|
|
342
|
-
|
|
343
|
-
|
|
366
|
+
console.log('autoLoanRenewChecker &&&&', this.loanRenewHelper);
|
|
367
|
+
// something is up here
|
|
368
|
+
if (!this.loanRenewHelper) {
|
|
369
|
+
this.loanRenewHelper = new LoanRenewHelper(
|
|
370
|
+
hasPageChanged,
|
|
371
|
+
this.identifier,
|
|
372
|
+
this.localCache,
|
|
373
|
+
this.loanRenewTimeConfig
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
|
|
344
377
|
|
|
345
378
|
await this.loanRenewHelper.handleLoanRenew();
|
|
346
379
|
this.loanRenewResult = this.loanRenewHelper.result;
|
|
347
380
|
}
|
|
348
381
|
|
|
349
382
|
/**
|
|
383
|
+
* create / select the modal-manager component on DOM
|
|
384
|
+
* @memberof IABookActions
|
|
385
|
+
*/
|
|
386
|
+
// async useModalManager() {
|
|
387
|
+
// if (!this.modal) {
|
|
388
|
+
// this.modal = document.querySelector('modal-manager');
|
|
389
|
+
|
|
390
|
+
// if (!this.modal) this.modal = document.createElement('modal-manager');
|
|
391
|
+
// }
|
|
392
|
+
|
|
393
|
+
// this.modal.id = 'action-bar-modal';
|
|
394
|
+
// await document.body.appendChild(this.modal);
|
|
395
|
+
// }
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Show the waring modal to ask user if they are still reading
|
|
399
|
+
*/
|
|
400
|
+
async showWarningModal() {
|
|
401
|
+
console.log('****** showWarningModal ****** clearing intervals');
|
|
402
|
+
// await this.useModalManager();
|
|
403
|
+
console.log('showWarningModal window?.IALendingInterval BEFORE', window?.IALendingIntervals);
|
|
404
|
+
|
|
405
|
+
window?.IALendingIntervals?.clearAll();
|
|
406
|
+
console.log('showWarningModal window?.IALendingIntervals AFTER', window?.IALendingIntervals);
|
|
407
|
+
|
|
408
|
+
// if secondsLeft < 60, consider it 1 minute
|
|
409
|
+
let { secondsLeft } = this.loanRenewResult;
|
|
410
|
+
if (secondsLeft === undefined) {
|
|
411
|
+
secondsLeft = this.lendingStatus.secondsLeftOnLoan;
|
|
412
|
+
} else {
|
|
413
|
+
secondsLeft = secondsLeft > 60 ? secondsLeft : 60;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const config = new ModalConfig();
|
|
417
|
+
config.headline = 'Are you still here?';
|
|
418
|
+
config.showCloseButton = false;
|
|
419
|
+
config.closeOnBackdropClick = false;
|
|
420
|
+
config.message = this.loanRenewHelper?.getMessageTexts(
|
|
421
|
+
this.loanRenewResult.texts,
|
|
422
|
+
secondsLeft
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
const customContent = html`<br />
|
|
426
|
+
<div id="custom-buttons" style="display:flex;justify-content:center;">
|
|
427
|
+
<button
|
|
428
|
+
style="${modalButtonStyle.iaButton} ${modalButtonStyle.renew}"
|
|
429
|
+
@click=${event => {
|
|
430
|
+
this.changeModalState(event);
|
|
431
|
+
this.autoLoanRenewChecker(true);
|
|
432
|
+
}}
|
|
433
|
+
>
|
|
434
|
+
Keep reading
|
|
435
|
+
</button>
|
|
436
|
+
<button
|
|
437
|
+
style="${modalButtonStyle.iaButton} ${modalButtonStyle.return}"
|
|
438
|
+
@click=${event => {
|
|
439
|
+
this.changeModalState(event);
|
|
440
|
+
document.querySelector('ia-book-actions').disableActionGroup = true;
|
|
441
|
+
this.returnNow = true;
|
|
442
|
+
}}
|
|
443
|
+
>
|
|
444
|
+
Return the book
|
|
445
|
+
</button>
|
|
446
|
+
</div> `;
|
|
447
|
+
|
|
448
|
+
this.modal.showModal({ config, customModalContent: customContent });
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* helper function to change button click states on modal-manager
|
|
453
|
+
* - add loader on button click
|
|
454
|
+
* - change button appearance
|
|
455
|
+
*
|
|
456
|
+
* @param {Event} event
|
|
457
|
+
*/
|
|
458
|
+
changeModalState(event) {
|
|
459
|
+
if (event.target === undefined) return;
|
|
460
|
+
|
|
461
|
+
const button = event.target;
|
|
462
|
+
button.innerHTML = `<ia-activity-indicator
|
|
463
|
+
mode="processing"
|
|
464
|
+
style=${modalButtonStyle.loaderIcon}
|
|
465
|
+
></ia-activity-indicator>`;
|
|
466
|
+
|
|
467
|
+
const parentElement = event.target.parentNode;
|
|
468
|
+
parentElement.style.pointerEvents = 'none';
|
|
469
|
+
parentElement.style.opacity = 0.8;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Show modal when book is auto returned
|
|
474
|
+
*/
|
|
475
|
+
async showExpiredModal() {
|
|
476
|
+
// await this.useModalManager();
|
|
477
|
+
|
|
478
|
+
const config = new ModalConfig();
|
|
479
|
+
config.headline = '';
|
|
480
|
+
config.showCloseButton = false;
|
|
481
|
+
config.closeOnBackdropClick = false;
|
|
482
|
+
config.message = 'This book has been returned due to inactivity.';
|
|
483
|
+
|
|
484
|
+
const customContent = html`<br />
|
|
485
|
+
<div style="text-align: center">
|
|
486
|
+
<button
|
|
487
|
+
style="${modalButtonStyle.iaButton} ${modalButtonStyle.renew}"
|
|
488
|
+
@click=${() => {
|
|
489
|
+
window.location?.reload();
|
|
490
|
+
}}
|
|
491
|
+
>
|
|
492
|
+
Okay
|
|
493
|
+
</button>
|
|
494
|
+
</div> `;
|
|
495
|
+
|
|
496
|
+
this.modal?.showModal({ config, customModalContent: customContent });
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* close/hide modal-manager
|
|
501
|
+
*/
|
|
502
|
+
async closeModalManager() {
|
|
503
|
+
this.modal = document.querySelector('modal-manager');
|
|
504
|
+
this.modal?.closeModal();
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* @deprecated
|
|
509
|
+
* create / select the toast-template component on DOM
|
|
510
|
+
*
|
|
511
|
+
* @memberof IABookActions
|
|
512
|
+
*/
|
|
513
|
+
async useToastManager() {
|
|
514
|
+
if (!this.toast) {
|
|
515
|
+
this.toast = this.shadowRoot.querySelector('toast-template');
|
|
516
|
+
|
|
517
|
+
if (!this.toast) this.toast = document.createElement('toast-template');
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
await this.shadowRoot.appendChild(this.toast);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* @deprecated
|
|
350
525
|
* close/hide toast message
|
|
351
526
|
*/
|
|
352
527
|
async closeToastManager() {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (toastTemplate) {
|
|
356
|
-
toastTemplate?.remove();
|
|
357
|
-
}
|
|
528
|
+
this.toast = this.shadowRoot.querySelector('toast-template');
|
|
529
|
+
this.toast?.remove();
|
|
358
530
|
}
|
|
359
531
|
|
|
360
532
|
/**
|
|
533
|
+
* @deprecated
|
|
361
534
|
* Show toast messages on some specific loan renew features. e.g.
|
|
362
535
|
* - show message when book is auto renewed
|
|
363
536
|
* - show message when book is expired
|
|
@@ -370,11 +543,7 @@ export default class IABookActions extends LitElement {
|
|
|
370
543
|
});
|
|
371
544
|
if (this.suppressToast) return;
|
|
372
545
|
|
|
373
|
-
|
|
374
|
-
if (!toastTemplate) {
|
|
375
|
-
toastTemplate = document.createElement('toast-template');
|
|
376
|
-
}
|
|
377
|
-
await this.shadowRoot.appendChild(toastTemplate);
|
|
546
|
+
await this.useToastManager();
|
|
378
547
|
|
|
379
548
|
// if secondsLeft < 60, consider it 1 minute
|
|
380
549
|
let { secondsLeft } = this.loanRenewResult;
|
|
@@ -391,12 +560,15 @@ export default class IABookActions extends LitElement {
|
|
|
391
560
|
secondsLeft
|
|
392
561
|
);
|
|
393
562
|
|
|
394
|
-
|
|
563
|
+
this.toast?.showToast({
|
|
395
564
|
config,
|
|
396
565
|
});
|
|
397
566
|
}
|
|
398
567
|
|
|
399
568
|
async browseHasRenew() {
|
|
569
|
+
console.log('****** browseHasRenew ******');
|
|
570
|
+
window?.IALendingIntervals?.clearAll();
|
|
571
|
+
|
|
400
572
|
const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
|
|
401
573
|
const secondsLeft = (loanTime - new Date()) / 1000; // different in seconds
|
|
402
574
|
|
|
@@ -407,30 +579,13 @@ export default class IABookActions extends LitElement {
|
|
|
407
579
|
secondsLeftOnLoan: secondsLeft,
|
|
408
580
|
};
|
|
409
581
|
this.lendingStatus = currStatus;
|
|
410
|
-
|
|
411
|
-
this.startBrowseTimer();
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
startBrowseTimer() {
|
|
415
|
-
clearTimeout(this.browseTimer);
|
|
416
|
-
const {
|
|
417
|
-
browsingExpired,
|
|
418
|
-
user_has_browsed,
|
|
419
|
-
secondsLeftOnLoan,
|
|
420
|
-
} = this.lendingStatus;
|
|
421
|
-
if (!user_has_browsed || browsingExpired) {
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
this.browseTimer = setTimeout(() => {
|
|
426
|
-
this.browseHasExpired();
|
|
427
|
-
}, secondsLeftOnLoan * 1000);
|
|
428
582
|
}
|
|
429
583
|
|
|
430
584
|
/**
|
|
431
585
|
* Execute when loan is expired
|
|
432
586
|
*/
|
|
433
587
|
async browseHasExpired() {
|
|
588
|
+
console.log('browseHasExpired', window?.IALendingIntervals);
|
|
434
589
|
window?.IALendingIntervals?.clearAll();
|
|
435
590
|
|
|
436
591
|
const currStatus = { ...this.lendingStatus, browsingExpired: true };
|
|
@@ -443,14 +598,34 @@ export default class IABookActions extends LitElement {
|
|
|
443
598
|
// show message after browsed book is expired.
|
|
444
599
|
this.loanRenewResult.renewNow = false;
|
|
445
600
|
this.loanRenewResult.texts =
|
|
446
|
-
'This book has been
|
|
601
|
+
'This book has been returned due to inactivity.';
|
|
447
602
|
|
|
448
|
-
this.
|
|
449
|
-
this.showToastMessage();
|
|
603
|
+
this.showExpiredModal();
|
|
450
604
|
|
|
451
605
|
window?.Sentry?.captureMessage(sentryLogs.browseHasExpired);
|
|
452
606
|
}
|
|
453
607
|
|
|
608
|
+
async startBrowseTimer() {
|
|
609
|
+
clearTimeout(this.browseTimer);
|
|
610
|
+
|
|
611
|
+
const {
|
|
612
|
+
browsingExpired,
|
|
613
|
+
user_has_browsed,
|
|
614
|
+
secondsLeftOnLoan,
|
|
615
|
+
} = this.lendingStatus;
|
|
616
|
+
if (!user_has_browsed || browsingExpired) {
|
|
617
|
+
console.log('user not browsed', this.lendingStatus);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
console.log('user browsed', this.lendingStatus);
|
|
622
|
+
|
|
623
|
+
this.browseTimer = setTimeout(() => {
|
|
624
|
+
console.log("BROWSER TIMER IN TIMEOUT!!");
|
|
625
|
+
this.browseHasExpired();
|
|
626
|
+
}, secondsLeftOnLoan * 1000);
|
|
627
|
+
}
|
|
628
|
+
|
|
454
629
|
/**
|
|
455
630
|
* Reset timer animation state after book renewed
|
|
456
631
|
*/
|
|
@@ -478,16 +653,19 @@ export default class IABookActions extends LitElement {
|
|
|
478
653
|
}, 100);
|
|
479
654
|
}
|
|
480
655
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
656
|
+
get modal () {
|
|
657
|
+
let modal = document.querySelector('modal-manager');
|
|
658
|
+
if (!modal) {
|
|
659
|
+
const newModal = document.createElement('modal-manager');
|
|
660
|
+
document.body.appendChild(newModal);
|
|
661
|
+
modal = newModal;
|
|
486
662
|
}
|
|
487
663
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
664
|
+
if (modal && !modal.id !== 'action-bar-modal') {
|
|
665
|
+
modal.setAttribute('id', 'action-bar-modal');
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
return modal;
|
|
491
669
|
}
|
|
492
670
|
|
|
493
671
|
get bookTitleBar() {
|
|
@@ -498,6 +676,7 @@ export default class IABookActions extends LitElement {
|
|
|
498
676
|
}
|
|
499
677
|
|
|
500
678
|
get timerCountdownTemplate() {
|
|
679
|
+
console.log('timerCountdownTemplatetimerCountdownTemplate');
|
|
501
680
|
return this.borrowType === 'browsed'
|
|
502
681
|
? html`<timer-countdown
|
|
503
682
|
.secondsLeftOnLoan=${Number(this.lendingStatus.secondsLeftOnLoan)}
|
|
@@ -508,6 +687,7 @@ export default class IABookActions extends LitElement {
|
|
|
508
687
|
}
|
|
509
688
|
|
|
510
689
|
get bookActionBar() {
|
|
690
|
+
console.log('~~~~~');
|
|
511
691
|
return html`
|
|
512
692
|
<collapsible-action-group
|
|
513
693
|
.userid=${this.userid}
|
|
@@ -524,6 +704,7 @@ export default class IABookActions extends LitElement {
|
|
|
524
704
|
?disabled=${this.disableActionGroup}
|
|
525
705
|
?autoRenew=${this.loanRenewResult.renewNow}
|
|
526
706
|
?autoReturn=${this.lendingStatus.browsingExpired}
|
|
707
|
+
?returnNow=${this.returnNow}
|
|
527
708
|
@loanAutoRenewed=${this.handleLoanAutoRenewed}
|
|
528
709
|
@lendingActionError=${this.handleLendingActionError}
|
|
529
710
|
@toggleActionGroup=${this.handleToggleActionGroup}
|
|
@@ -545,19 +726,21 @@ export default class IABookActions extends LitElement {
|
|
|
545
726
|
if (this.loanRenewResult.renewNow) {
|
|
546
727
|
window?.IALendingIntervals?.clearAll();
|
|
547
728
|
|
|
548
|
-
this.suppressToast = false;
|
|
549
|
-
await this.browseHasRenew();
|
|
550
|
-
await this.showToastMessage();
|
|
551
|
-
await this.resetTimerCountState();
|
|
552
|
-
|
|
553
|
-
window?.Sentry?.captureMessage(sentryLogs.bookHasRenewed);
|
|
554
|
-
|
|
555
729
|
// testing console....
|
|
556
730
|
console.log('IABookActions: AutoRenewed:- ', {
|
|
557
731
|
ajaxResponse: event?.detail?.data,
|
|
558
732
|
loanRenewResult: this.loanRenewResult,
|
|
559
733
|
secondsLeftOnLoan: Math.round(this.lendingStatus.secondsLeftOnLoan),
|
|
560
734
|
});
|
|
735
|
+
|
|
736
|
+
await this.browseHasRenew();
|
|
737
|
+
await this.resetTimerCountState();
|
|
738
|
+
|
|
739
|
+
// close the modal
|
|
740
|
+
this.modal?.remove();
|
|
741
|
+
this.modal?.showModal({ config: {}, customModalContent: `` });
|
|
742
|
+
|
|
743
|
+
window?.Sentry?.captureMessage(sentryLogs.bookHasRenewed);
|
|
561
744
|
}
|
|
562
745
|
}
|
|
563
746
|
|
|
@@ -602,7 +785,7 @@ export default class IABookActions extends LitElement {
|
|
|
602
785
|
this.disableActionGroup = !this.disableActionGroup;
|
|
603
786
|
}
|
|
604
787
|
|
|
605
|
-
|
|
788
|
+
/**
|
|
606
789
|
* handle lending errors occure during different operation like
|
|
607
790
|
* browse book, borrow book, borrowed book token etc...
|
|
608
791
|
*
|
|
@@ -656,16 +839,7 @@ export default class IABookActions extends LitElement {
|
|
|
656
839
|
|
|
657
840
|
/* show error message if something went wrong */
|
|
658
841
|
async showErrorModal(errorMsg, action) {
|
|
659
|
-
//
|
|
660
|
-
if (!this.modal) {
|
|
661
|
-
this.modal = document.querySelector('modal-manager');
|
|
662
|
-
|
|
663
|
-
// check the DOM if <modal-manager> already there
|
|
664
|
-
if (!this.modal) this.modal = document.createElement('modal-manager');
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
this.modal.id = 'action-bar-modal';
|
|
668
|
-
await document.body.appendChild(this.modal);
|
|
842
|
+
// await this.useModalManager();
|
|
669
843
|
|
|
670
844
|
const modalConfig = new ModalConfig({
|
|
671
845
|
title: 'Lending error',
|
|
@@ -676,7 +850,7 @@ export default class IABookActions extends LitElement {
|
|
|
676
850
|
|
|
677
851
|
if (action === 'create_token') {
|
|
678
852
|
const refreshButton = html`<button
|
|
679
|
-
style="
|
|
853
|
+
style="${modalButtonStyle.refresh}"
|
|
680
854
|
@click=${() => window.location.reload(true)}
|
|
681
855
|
>
|
|
682
856
|
refresh
|
|
@@ -188,7 +188,9 @@ describe('Borrow status actions', () => {
|
|
|
188
188
|
},
|
|
189
189
|
];
|
|
190
190
|
|
|
191
|
-
expect(el.primaryTitle).to.equal(
|
|
191
|
+
expect(el.primaryTitle).to.equal(
|
|
192
|
+
'Renews automatically as long as pages are turned.'
|
|
193
|
+
);
|
|
192
194
|
expect(el.primaryActions.length).to.equal(2);
|
|
193
195
|
expect(el.primaryActions[0].text).to.equal('Log In and Borrow');
|
|
194
196
|
expect(el.primaryActions[0].text).to.equal(expectedPrimaryActions[0].text);
|
|
@@ -274,7 +276,7 @@ describe('Browsing expired status', () => {
|
|
|
274
276
|
expect(el.loanRenewResult.renewNow).to.equal(false);
|
|
275
277
|
expect(el.loanRenewResult.secondsLeft).to.equal(0);
|
|
276
278
|
expect(el.loanRenewResult.texts).to.equal(
|
|
277
|
-
'This book has been
|
|
279
|
+
'This book has been returned due to inactivity.'
|
|
278
280
|
);
|
|
279
281
|
});
|
|
280
282
|
|
|
@@ -347,7 +349,7 @@ describe('Auto renew one hour loan', () => {
|
|
|
347
349
|
});
|
|
348
350
|
el.dispatchEvent(myEvent);
|
|
349
351
|
|
|
350
|
-
await aTimeout(
|
|
352
|
+
await aTimeout(1900); // wait for 1.9 second
|
|
351
353
|
await el.updateComplete;
|
|
352
354
|
|
|
353
355
|
expect(el.loanRenewResult.texts).to.equal(
|