@internetarchive/ia-book-actions 0.0.29-alpha8 → 0.0.29-beta1
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 -43
- package/package.json +2 -7
- package/src/assets/data/lending-get-status-service.js +1 -1
- package/src/components/collapsible-action-group.js +0 -14
- package/src/components/info-icon.js +1 -1
- package/src/core/services/actions-config.js +5 -1
- package/src/core/services/actions-handler/actions-handler.js +2 -42
- package/src/ia-book-actions.js +8 -124
- package/src/components/timer-countdown.js +0 -113
- package/src/components/toast-message.js +0 -78
- package/src/core/services/one-hour-auto-renew.js +0 -169
package/demo/index.html
CHANGED
|
@@ -87,18 +87,13 @@
|
|
|
87
87
|
|
|
88
88
|
<script type="module">
|
|
89
89
|
/* eslint-disable */
|
|
90
|
+
|
|
90
91
|
import '../src/ia-book-actions.js';
|
|
91
92
|
import {
|
|
92
93
|
defaultLendingStatus,
|
|
93
94
|
canBrowseAndBorrow,
|
|
94
95
|
} from '../src/assets/data/lending-get-status-service.js';
|
|
95
96
|
import { ModalConfig } from '@internetarchive/modal-manager';
|
|
96
|
-
import { LocalCache } from '@internetarchive/local-cache';
|
|
97
|
-
|
|
98
|
-
const localCache = new LocalCache({
|
|
99
|
-
namespace: '1HourLoanStorage',
|
|
100
|
-
defaultTTL: 1 * 60, // 1 minute
|
|
101
|
-
});
|
|
102
97
|
|
|
103
98
|
const userid = '@neeraj-archive';
|
|
104
99
|
const identifier = 'naturalhistoryof00unse_4111';
|
|
@@ -126,15 +121,8 @@
|
|
|
126
121
|
iaBookActions.lendingBarPostInit = lendingBarPostInit;
|
|
127
122
|
iaBookActions.tokenDelay = 2000; // 2 seconds
|
|
128
123
|
iaBookActions.returnUrl = 'https://openlibrary.org';
|
|
129
|
-
iaBookActions.localCache = localCache;
|
|
130
|
-
iaBookActions.autoRenewConfig = {
|
|
131
|
-
totalTime: 60, // 60 second = 1 min
|
|
132
|
-
autoCheckAt: 55, // totalTime - 10th minute
|
|
133
|
-
FlippedInLast: 15, // within last 15 second/minute
|
|
134
|
-
};
|
|
135
124
|
|
|
136
125
|
let lendingStatus1 = iaBookActions.lendingStatus;
|
|
137
|
-
let secondsLeftOnLoan = iaBookActions.autoRenewConfig.totalTime;
|
|
138
126
|
|
|
139
127
|
document.querySelectorAll('.titleBar input[type=checkbox]').forEach((item) => {
|
|
140
128
|
item.addEventListener('click', (e) => {
|
|
@@ -146,21 +134,6 @@
|
|
|
146
134
|
});
|
|
147
135
|
});
|
|
148
136
|
|
|
149
|
-
document.querySelectorAll('.autoRenew input[type=checkbox]').forEach((item) => {
|
|
150
|
-
item.addEventListener('click', (e) => {
|
|
151
|
-
if (e.target.checked) {
|
|
152
|
-
iaBookActions.autoRenew = true;
|
|
153
|
-
iaBookActions.resetTimerCountdown = true;
|
|
154
|
-
lendingStatus1.secondsLeftOnLoan = secondsLeftOnLoan;
|
|
155
|
-
} else {
|
|
156
|
-
iaBookActions.autoRenew = false;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
let lending = {...defaultLendingStatus, ...lendingStatus1};
|
|
160
|
-
iaBookActions.lendingStatus = lending;
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
137
|
document.querySelectorAll('.errorEnable input[type=checkbox]').forEach((item) => {
|
|
165
138
|
if (window.location.href.indexOf('?error=true') !== -1) {
|
|
166
139
|
item.checked = true;
|
|
@@ -214,24 +187,12 @@
|
|
|
214
187
|
});
|
|
215
188
|
|
|
216
189
|
document.querySelectorAll('.availableToBrowse input[type=radio]').forEach((item) => {
|
|
217
|
-
item.addEventListener('click',
|
|
190
|
+
item.addEventListener('click', (e) => {
|
|
218
191
|
if (e.target.value === 'user_has_browsed') {
|
|
219
192
|
lendingStatus1.user_has_browsed = true;
|
|
220
193
|
lendingStatus1.available_to_browse = false;
|
|
221
|
-
lendingStatus1.secondsLeftOnLoan =
|
|
194
|
+
lendingStatus1.secondsLeftOnLoan = 10;
|
|
222
195
|
lendingStatus1.browsingExpired = false;
|
|
223
|
-
|
|
224
|
-
try {
|
|
225
|
-
// set a value
|
|
226
|
-
await localCache.set({
|
|
227
|
-
key: `${identifier}-loanTime`,
|
|
228
|
-
value: new Date(), // current time
|
|
229
|
-
ttl: Number(iaBookActions.autoRenewConfig.totalTime),
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
await localCache.delete(`${identifier}-pageFlipTime`);
|
|
233
|
-
} catch (error) {}
|
|
234
|
-
|
|
235
196
|
} else if(e.target.value === 'browsingExpired') {
|
|
236
197
|
lendingStatus1.user_has_browsed = true;
|
|
237
198
|
lendingStatus1.available_to_browse = false;
|
|
@@ -311,7 +272,6 @@
|
|
|
311
272
|
<table class="initial">
|
|
312
273
|
<tr colspan='5'>
|
|
313
274
|
<td class="errorEnable"><label><input type="checkbox" name="errorEnable" value="errorEnable" />Do you want to see error response?</label></td>
|
|
314
|
-
<td class="autoRenew"><label><input type="checkbox" name="autoRenew" value="autoRenew" />Do you want to auto-renew 1 hour</label></td>
|
|
315
275
|
</tr>
|
|
316
276
|
<tr>
|
|
317
277
|
<td class="userState">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/ia-book-actions",
|
|
3
|
-
"version": "0.0.29-
|
|
3
|
+
"version": "0.0.29-beta1",
|
|
4
4
|
"description": "Bookreader actions for borrowable book",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -43,12 +43,6 @@
|
|
|
43
43
|
"sinon": "^13.0.2"
|
|
44
44
|
},
|
|
45
45
|
"eslintConfig": {
|
|
46
|
-
"rules": {
|
|
47
|
-
"no-console": "off",
|
|
48
|
-
"no-unused-expressions": "off",
|
|
49
|
-
"class-methods-use-this": "off",
|
|
50
|
-
"lit-a11y/click-events-have-key-events": "off"
|
|
51
|
-
},
|
|
52
46
|
"extends": [
|
|
53
47
|
"@open-wc/eslint-config",
|
|
54
48
|
"eslint-config-prettier"
|
|
@@ -60,6 +54,7 @@
|
|
|
60
54
|
},
|
|
61
55
|
"husky": {
|
|
62
56
|
"hooks": {
|
|
57
|
+
"pre-commit": "lint-staged"
|
|
63
58
|
}
|
|
64
59
|
},
|
|
65
60
|
"lint-staged": {
|
|
@@ -100,7 +100,7 @@ export const canBrowseAndBorrow = {
|
|
|
100
100
|
// userid: "",
|
|
101
101
|
bookUrl: '/details/practicalorganic00plim',
|
|
102
102
|
daysLeftOnLoan: 0,
|
|
103
|
-
isAdmin:
|
|
103
|
+
isAdmin: true,
|
|
104
104
|
isArchiveOrgLending: true,
|
|
105
105
|
isAvailable: false,
|
|
106
106
|
isAvailableForBrowsing: false,
|
|
@@ -28,8 +28,6 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
28
28
|
dropdownArrow: { type: String },
|
|
29
29
|
disabled: { type: Boolean },
|
|
30
30
|
returnUrl: { type: String },
|
|
31
|
-
localCache: { type: Function },
|
|
32
|
-
browseAgainNow: { type: Boolean },
|
|
33
31
|
};
|
|
34
32
|
}
|
|
35
33
|
|
|
@@ -49,8 +47,6 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
49
47
|
this.loaderIcon = 'https://archive.org/upload/images/tree/loading.gif';
|
|
50
48
|
this.disabled = false;
|
|
51
49
|
this.returnUrl = '';
|
|
52
|
-
this.localCache = undefined;
|
|
53
|
-
this.browseAgainNow = false;
|
|
54
50
|
}
|
|
55
51
|
|
|
56
52
|
updated(changed) {
|
|
@@ -60,16 +56,6 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
60
56
|
) {
|
|
61
57
|
this.resetActions();
|
|
62
58
|
}
|
|
63
|
-
|
|
64
|
-
if (changed.has('browseAgainNow') && this.browseAgainNow === true) {
|
|
65
|
-
this.dispatchEvent(
|
|
66
|
-
new CustomEvent('autoBrowseBook', {
|
|
67
|
-
detail: {
|
|
68
|
-
event: { autoRenewed1Hour: 'browseBook' },
|
|
69
|
-
},
|
|
70
|
-
})
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
59
|
}
|
|
74
60
|
|
|
75
61
|
/**
|
|
@@ -202,11 +202,15 @@ export default class ActionsConfig {
|
|
|
202
202
|
if (this.lendingStatus.user_has_borrowed || !this.lendingStatus.isAdmin)
|
|
203
203
|
return null;
|
|
204
204
|
|
|
205
|
+
// keep existing params and add new one
|
|
206
|
+
const url = new URL(window.location.href);
|
|
207
|
+
url.searchParams.append('admin', 1);
|
|
208
|
+
|
|
205
209
|
return {
|
|
206
210
|
id: 'adminAccess',
|
|
207
211
|
text: 'Admin Access',
|
|
208
212
|
title: 'You have administrative privileges to read this book',
|
|
209
|
-
url:
|
|
213
|
+
url: url.search,
|
|
210
214
|
target: '_self',
|
|
211
215
|
className: 'danger',
|
|
212
216
|
analyticsEvent: {
|
|
@@ -17,9 +17,8 @@ export default class ActionsHandler extends LitElement {
|
|
|
17
17
|
super();
|
|
18
18
|
this.identifier = '';
|
|
19
19
|
this.ajaxTimeout = 6000;
|
|
20
|
-
this.returnUrl = '';
|
|
21
|
-
this.autoRenewConfig = {};
|
|
22
20
|
this.bindEvents();
|
|
21
|
+
this.returnUrl = '';
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
sendEvent(eventCategory, eventAction) {
|
|
@@ -30,7 +29,7 @@ export default class ActionsHandler extends LitElement {
|
|
|
30
29
|
);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
bindEvents() {
|
|
34
33
|
this.addEventListener('browseBook', ({ detail }) => {
|
|
35
34
|
this.handleBrowseIt();
|
|
36
35
|
this.setConsecutiveLoanCounts();
|
|
@@ -45,13 +44,6 @@ export default class ActionsHandler extends LitElement {
|
|
|
45
44
|
this.sendEvent(category, action);
|
|
46
45
|
});
|
|
47
46
|
|
|
48
|
-
this.addEventListener('autoBrowseBook', ({ detail }) => {
|
|
49
|
-
console.log('auto renew handlerExecuted!!');
|
|
50
|
-
this.handleAutoBrowseIt();
|
|
51
|
-
const { category, action } = detail.event;
|
|
52
|
-
this.sendEvent(category, action);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
47
|
this.addEventListener('returnNow', ({ detail }) => {
|
|
56
48
|
this.handleReturnIt();
|
|
57
49
|
const { category, action } = detail.event;
|
|
@@ -106,7 +98,6 @@ export default class ActionsHandler extends LitElement {
|
|
|
106
98
|
handleBrowseIt() {
|
|
107
99
|
const action = 'browse_book';
|
|
108
100
|
this.dispatchToggleActionGroup();
|
|
109
|
-
this.setBrowseTimeSession();
|
|
110
101
|
|
|
111
102
|
ActionsHandlerService({
|
|
112
103
|
action,
|
|
@@ -120,22 +111,6 @@ export default class ActionsHandler extends LitElement {
|
|
|
120
111
|
});
|
|
121
112
|
}
|
|
122
113
|
|
|
123
|
-
handleAutoBrowseIt() {
|
|
124
|
-
const action = 'renew_loan';
|
|
125
|
-
this.setBrowseTimeSession();
|
|
126
|
-
|
|
127
|
-
ActionsHandlerService({
|
|
128
|
-
action,
|
|
129
|
-
identifier: this.identifier,
|
|
130
|
-
success: () => {
|
|
131
|
-
// console.log('success!');
|
|
132
|
-
},
|
|
133
|
-
error: data => {
|
|
134
|
-
this.dispatchActionError(action, data);
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
114
|
handleReturnIt() {
|
|
140
115
|
const action = 'return_loan';
|
|
141
116
|
this.dispatchToggleActionGroup();
|
|
@@ -286,21 +261,6 @@ export default class ActionsHandler extends LitElement {
|
|
|
286
261
|
}
|
|
287
262
|
}
|
|
288
263
|
|
|
289
|
-
async setBrowseTimeSession() {
|
|
290
|
-
try {
|
|
291
|
-
// set a value
|
|
292
|
-
await this.localCache.set({
|
|
293
|
-
key: `${this.identifier}-loanTime`,
|
|
294
|
-
value: new Date(), // current time
|
|
295
|
-
ttl: Number(this.autoRenewConfig.totalTime),
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
await this.localCache.delete(`${this.identifier}-pageFlipTime`);
|
|
299
|
-
} catch (error) {
|
|
300
|
-
console.log(error);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
264
|
deleteLoanCookies() {
|
|
305
265
|
const date = new Date();
|
|
306
266
|
date.setTime(date.getTime() - 24 * 60 * 60 * 1000); // one day ago
|
package/src/ia-book-actions.js
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
|
-
import { html, css, LitElement
|
|
2
|
+
import { html, css, LitElement } from 'lit';
|
|
3
3
|
|
|
4
4
|
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
|
|
5
5
|
import { ModalConfig } from '@internetarchive/modal-manager';
|
|
6
|
-
import { LocalCache } from '@internetarchive/local-cache';
|
|
7
6
|
|
|
8
7
|
import './components/collapsible-action-group.js';
|
|
9
8
|
import './components/book-title-bar.js';
|
|
10
9
|
import './components/text-group.js';
|
|
11
10
|
import './components/info-icon.js';
|
|
12
|
-
import './components/timer-countdown.js';
|
|
13
|
-
import './components/toast-message.js';
|
|
14
11
|
|
|
15
12
|
import { GetLendingActions } from './core/services/get-lending-actions.js';
|
|
16
13
|
import { mobileContainerWidth } from './core/config/constants.js';
|
|
17
14
|
import { LoanTokenPoller } from './core/services/loan-token-poller.js';
|
|
18
|
-
import { OneHourAutoRenew } from './core/services/one-hour-auto-renew.js';
|
|
19
15
|
|
|
20
16
|
export const events = {
|
|
21
17
|
browseExpired: 'IABookReader:BrowsingHasExpired',
|
|
@@ -40,12 +36,6 @@ export default class IABookActions extends LitElement {
|
|
|
40
36
|
disableActionGroup: { type: Boolean },
|
|
41
37
|
modal: { Object },
|
|
42
38
|
tokenDelay: { type: Number },
|
|
43
|
-
toastTexts: { type: String },
|
|
44
|
-
remainingTime: { type: Number },
|
|
45
|
-
resetTimerCountdown: { type: Boolean },
|
|
46
|
-
localCache: { type: Object },
|
|
47
|
-
autoRenewConfig: { type: Object },
|
|
48
|
-
browseAgainNow: { type: Boolean },
|
|
49
39
|
};
|
|
50
40
|
}
|
|
51
41
|
|
|
@@ -64,11 +54,6 @@ export default class IABookActions extends LitElement {
|
|
|
64
54
|
this.disableActionGroup = false;
|
|
65
55
|
this.modal = undefined;
|
|
66
56
|
this.tokenDelay = 120000; // 2 minutes
|
|
67
|
-
this.localCache = new LocalCache({
|
|
68
|
-
namespace: '1HourLoanStorage',
|
|
69
|
-
});
|
|
70
|
-
this.autoRenewConfig = {};
|
|
71
|
-
this.autoRenewRes = undefined;
|
|
72
57
|
|
|
73
58
|
// private props
|
|
74
59
|
this.primaryActions = [];
|
|
@@ -78,12 +63,6 @@ export default class IABookActions extends LitElement {
|
|
|
78
63
|
this.lendingOptions = {};
|
|
79
64
|
this.borrowType = ''; // (browsed|borrowed)
|
|
80
65
|
this.consecutiveLoanCounts = 1; // consecutive loan count
|
|
81
|
-
this.browseAgainNow = false;
|
|
82
|
-
this.browserTimer = undefined;
|
|
83
|
-
this.hideToast = true;
|
|
84
|
-
|
|
85
|
-
this.bindAutoRenewEvent();
|
|
86
|
-
this.resetTimerCountdown = false;
|
|
87
66
|
}
|
|
88
67
|
|
|
89
68
|
disconnectedCallback() {
|
|
@@ -100,7 +79,6 @@ export default class IABookActions extends LitElement {
|
|
|
100
79
|
}
|
|
101
80
|
|
|
102
81
|
updated(changed) {
|
|
103
|
-
// console.log(changed)
|
|
104
82
|
if (changed.has('lendingStatus') || changed.has('bwbPurchaseUrl')) {
|
|
105
83
|
this.setupLendingToolbarActions();
|
|
106
84
|
this.update();
|
|
@@ -112,68 +90,12 @@ export default class IABookActions extends LitElement {
|
|
|
112
90
|
}
|
|
113
91
|
}
|
|
114
92
|
|
|
115
|
-
|
|
116
|
-
// dispatched this event from timer-countdown
|
|
117
|
-
this.addEventListener('autoRenewAttempt', async event => {
|
|
118
|
-
const isPageClick = event.detail.bookPageChange;
|
|
119
|
-
|
|
120
|
-
// early return if user is not browsed book
|
|
121
|
-
if (isPageClick && this.borrowType !== 'browsed') return nothing;
|
|
122
|
-
|
|
123
|
-
this.autoRenewRes = await new OneHourAutoRenew(
|
|
124
|
-
isPageClick,
|
|
125
|
-
this.identifier,
|
|
126
|
-
this.localCache,
|
|
127
|
-
this.autoRenewConfig,
|
|
128
|
-
this.lendingStatus.user_has_browsed &&
|
|
129
|
-
!this.lendingStatus.browsingExpired
|
|
130
|
-
);
|
|
131
|
-
console.log(this.autoRenewRes);
|
|
132
|
-
|
|
133
|
-
this.toastTexts = this.autoRenewRes.toastTexts;
|
|
134
|
-
this.hideToast = this.autoRenewRes.hideToast;
|
|
135
|
-
this.browseAgainNow = this.autoRenewRes.browseAgainNow;
|
|
136
|
-
|
|
137
|
-
if (this.browseAgainNow) {
|
|
138
|
-
await this.browseHasRenew();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return nothing;
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async browseHasExpired() {
|
|
93
|
+
browseHasExpired() {
|
|
146
94
|
const currStatus = { ...this.lendingStatus, browsingExpired: true };
|
|
147
95
|
this.lendingStatus = currStatus;
|
|
148
|
-
this.browseAgainNow = false;
|
|
149
|
-
|
|
150
|
-
// remove respected key:value
|
|
151
|
-
await this.localCache.delete(`${this.identifier}-loanTime`);
|
|
152
|
-
await this.localCache.delete(`${this.identifier}-pageFlipTime`);
|
|
153
|
-
|
|
154
|
-
// show message after browsed book is expired.
|
|
155
|
-
this.toastTexts = 'This book has been auto-returned due to inactivity.';
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async browseHasRenew() {
|
|
159
|
-
const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
|
|
160
|
-
const secondsLeft = (loanTime - new Date()) / 1000; // different in seconds
|
|
161
|
-
|
|
162
|
-
const currStatus = {
|
|
163
|
-
...this.lendingStatus,
|
|
164
|
-
user_has_browsed: true,
|
|
165
|
-
browsingExpired: false,
|
|
166
|
-
secondsLeftOnLoan: secondsLeft,
|
|
167
|
-
};
|
|
168
|
-
this.lendingStatus = currStatus;
|
|
169
|
-
// this.performUpdate()
|
|
170
|
-
|
|
171
|
-
this.startBrowseTimer();
|
|
172
96
|
}
|
|
173
97
|
|
|
174
98
|
startBrowseTimer() {
|
|
175
|
-
clearTimeout(this.browserTimer);
|
|
176
|
-
|
|
177
99
|
const {
|
|
178
100
|
browsingExpired,
|
|
179
101
|
user_has_browsed,
|
|
@@ -183,9 +105,8 @@ export default class IABookActions extends LitElement {
|
|
|
183
105
|
return;
|
|
184
106
|
}
|
|
185
107
|
|
|
186
|
-
// expired book and show browse again button
|
|
187
108
|
const timeLeft = secondsLeftOnLoan * 1000;
|
|
188
|
-
|
|
109
|
+
setTimeout(() => {
|
|
189
110
|
this.browseHasExpired();
|
|
190
111
|
}, timeLeft);
|
|
191
112
|
}
|
|
@@ -243,13 +164,16 @@ export default class IABookActions extends LitElement {
|
|
|
243
164
|
});
|
|
244
165
|
|
|
245
166
|
this.borrowType = actions.borrowType;
|
|
246
|
-
this.remainingTime = this.lendingStatus.secondsLeftOnLoan;
|
|
247
167
|
|
|
248
168
|
const hasExpired =
|
|
249
169
|
'browsingExpired' in this.lendingStatus &&
|
|
250
170
|
this.lendingStatus?.browsingExpired;
|
|
251
171
|
if (hasExpired) {
|
|
252
|
-
|
|
172
|
+
if (!this.tokenPoller.disconnectedInterval) {
|
|
173
|
+
window?.Sentry?.captureMessage(
|
|
174
|
+
'setupLendingToolbarActions hasExpired - no tokenPoller'
|
|
175
|
+
);
|
|
176
|
+
}
|
|
253
177
|
this.tokenPoller?.disconnectedInterval();
|
|
254
178
|
/** Global event - always fire */
|
|
255
179
|
this.dispatchEvent(
|
|
@@ -296,30 +220,8 @@ export default class IABookActions extends LitElement {
|
|
|
296
220
|
></book-title-bar>`;
|
|
297
221
|
}
|
|
298
222
|
|
|
299
|
-
get timerCountdownTemplate() {
|
|
300
|
-
// console.log(this.borrowType, this.remainingTime, this.autoRenewConfig.autoCheckAt, this.resetTimerCountdown);
|
|
301
|
-
return this.borrowType === 'browsed'
|
|
302
|
-
? html`<timer-countdown
|
|
303
|
-
time=${Number(this.remainingTime)}
|
|
304
|
-
.autoCheckAt=${this.autoRenewConfig.autoCheckAt}
|
|
305
|
-
?resetTimerCountdown=${this.resetTimerCountdown}
|
|
306
|
-
></timer-countdown>`
|
|
307
|
-
: nothing;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
get toastMessageTemplate() {
|
|
311
|
-
return html`
|
|
312
|
-
<toast-message
|
|
313
|
-
.texts=${this.toastTexts}
|
|
314
|
-
?dismisOnClick=${Boolean(true)}
|
|
315
|
-
?hideToast=${this.hideToast}
|
|
316
|
-
></toast-message>
|
|
317
|
-
`;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
223
|
get bookActionBar() {
|
|
321
224
|
return html`
|
|
322
|
-
<button @click=${() => this.pageFlipEvent()}>Page Flip</button>
|
|
323
225
|
<collapsible-action-group
|
|
324
226
|
.userid=${this.userid}
|
|
325
227
|
.identifier=${this.identifier}
|
|
@@ -329,30 +231,16 @@ export default class IABookActions extends LitElement {
|
|
|
329
231
|
.width=${this.width}
|
|
330
232
|
.borrowType=${this.borrowType}
|
|
331
233
|
.returnUrl=${this.returnUrl}
|
|
332
|
-
.localCache=${this.localCache}
|
|
333
|
-
.autoRenewConfig=${this.autoRenewConfig}
|
|
334
234
|
?hasAdminAccess=${this.hasAdminAccess}
|
|
335
235
|
?disabled=${this.disableActionGroup}
|
|
336
|
-
?browseAgainNow=${this.browseAgainNow}
|
|
337
236
|
@lendingActionError=${this.handleLendingActionError}
|
|
338
237
|
@toggleActionGroup=${this.handleToggleActionGroup}
|
|
339
238
|
>
|
|
340
239
|
</collapsible-action-group>
|
|
341
240
|
${this.textGroupTemplate} ${this.infoIconTemplate}
|
|
342
|
-
${this.timerCountdownTemplate} ${this.toastMessageTemplate}
|
|
343
241
|
`;
|
|
344
242
|
}
|
|
345
243
|
|
|
346
|
-
// will move this function to bookreader...
|
|
347
|
-
pageFlipEvent() {
|
|
348
|
-
// dispatch event to say book page has flipped
|
|
349
|
-
document.querySelector('ia-book-actions').dispatchEvent(
|
|
350
|
-
new CustomEvent('autoRenewAttempt', {
|
|
351
|
-
detail: { bookPageChange: true },
|
|
352
|
-
})
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
244
|
/**
|
|
357
245
|
* enable access of borrowed/browsed books
|
|
358
246
|
*/
|
|
@@ -517,10 +405,6 @@ export default class IABookActions extends LitElement {
|
|
|
517
405
|
justify-content: center;
|
|
518
406
|
flex-wrap: wrap;
|
|
519
407
|
}
|
|
520
|
-
|
|
521
|
-
toast-message {
|
|
522
|
-
--messageHeightFromTop: 17%;
|
|
523
|
-
}
|
|
524
408
|
`;
|
|
525
409
|
}
|
|
526
410
|
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { html, css, LitElement } from 'lit';
|
|
2
|
-
|
|
3
|
-
export default class TimerCountdown extends LitElement {
|
|
4
|
-
static get properties() {
|
|
5
|
-
return {
|
|
6
|
-
time: { type: Number },
|
|
7
|
-
autoCheckAt: { type: Number },
|
|
8
|
-
resetTimerCountdown: { type: Boolean },
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
constructor() {
|
|
13
|
-
super();
|
|
14
|
-
this.time = 0;
|
|
15
|
-
this.autoCheckAt = 0;
|
|
16
|
-
this.timerInterval = undefined;
|
|
17
|
-
this.resetTimerCountdown = false;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
disconnectedCallback() {
|
|
21
|
-
clearInterval(this.timerInterval);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
updated(changed) {
|
|
25
|
-
if (changed.has('time') && this.time > 0) {
|
|
26
|
-
clearInterval(this.timerInterval);
|
|
27
|
-
this.timerCountdown();
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
timerCountdown() {
|
|
32
|
-
this.timerInterval = setInterval(() => {
|
|
33
|
-
this.time -= 1;
|
|
34
|
-
|
|
35
|
-
// execute 50th minute check
|
|
36
|
-
if (Math.round(this.time) === this.autoCheckAt) {
|
|
37
|
-
this.dispatchEvent(
|
|
38
|
-
new CustomEvent('autoRenewAttempt', {
|
|
39
|
-
detail: {
|
|
40
|
-
remainingT: this.time,
|
|
41
|
-
bookPageChange: false,
|
|
42
|
-
},
|
|
43
|
-
bubbles: true,
|
|
44
|
-
composed: true,
|
|
45
|
-
})
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (this.time === 0) clearInterval(this.timerInterval);
|
|
50
|
-
}, 1000);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
render() {
|
|
54
|
-
return html`<div id="countdown">
|
|
55
|
-
<div id="countdown-number">${Math.round(this.time)}</div>
|
|
56
|
-
<svg>
|
|
57
|
-
<circle r="18" cx="20" cy="20"></circle>
|
|
58
|
-
</svg>
|
|
59
|
-
</div>`;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
static get styles() {
|
|
63
|
-
return css`
|
|
64
|
-
:host {
|
|
65
|
-
right: 5px;
|
|
66
|
-
font-size: 14px;
|
|
67
|
-
position: absolute;
|
|
68
|
-
}
|
|
69
|
-
#countdown-number {
|
|
70
|
-
color: white;
|
|
71
|
-
display: inline-block;
|
|
72
|
-
line-height: 40px;
|
|
73
|
-
margin-right: 12px;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
svg {
|
|
77
|
-
position: absolute;
|
|
78
|
-
top: 0;
|
|
79
|
-
right: 0;
|
|
80
|
-
width: 40px;
|
|
81
|
-
height: 40px;
|
|
82
|
-
transform: rotateY(-180deg) rotateZ(-90deg);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
svg circle {
|
|
86
|
-
stroke-dasharray: 113px;
|
|
87
|
-
stroke-dashoffset: 0px;
|
|
88
|
-
stroke-linecap: round;
|
|
89
|
-
stroke-width: 3px;
|
|
90
|
-
stroke: white;
|
|
91
|
-
fill: none;
|
|
92
|
-
animation: countdown 60s linear infinite forwards;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@keyframes countdown {
|
|
96
|
-
from {
|
|
97
|
-
stroke-dashoffset: 0px;
|
|
98
|
-
}
|
|
99
|
-
to {
|
|
100
|
-
stroke-dashoffset: 113px;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
.hidden {
|
|
104
|
-
display: none;
|
|
105
|
-
}
|
|
106
|
-
.visible {
|
|
107
|
-
display: inline-block;
|
|
108
|
-
}
|
|
109
|
-
`;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
window.customElements.define('timer-countdown', TimerCountdown);
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { html, css, LitElement, nothing } from 'lit';
|
|
2
|
-
|
|
3
|
-
export class ToastMessage extends LitElement {
|
|
4
|
-
static get properties() {
|
|
5
|
-
return {
|
|
6
|
-
texts: { type: String },
|
|
7
|
-
dismisOnClick: { type: Boolean },
|
|
8
|
-
hideToast: { type: Boolean },
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
constructor() {
|
|
13
|
-
super();
|
|
14
|
-
this.texts = '';
|
|
15
|
-
this.textClass = '';
|
|
16
|
-
this.hideToast = false;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
render() {
|
|
20
|
-
return !this.hideToast
|
|
21
|
-
? html`
|
|
22
|
-
<span
|
|
23
|
-
class="toast-message fade-in ${this.textClass}"
|
|
24
|
-
title="Click/tap to close"
|
|
25
|
-
@click=${() => {
|
|
26
|
-
this.dismisOnClick ? (this.hideToast = true) : nothing;
|
|
27
|
-
}}
|
|
28
|
-
>${this.texts}</span
|
|
29
|
-
>
|
|
30
|
-
`
|
|
31
|
-
: nothing;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
static get styles() {
|
|
35
|
-
const heightFromTop = css`var(--messageHeightFromTop, 15%)`;
|
|
36
|
-
|
|
37
|
-
return css`
|
|
38
|
-
:host {
|
|
39
|
-
display: inline-block;
|
|
40
|
-
}
|
|
41
|
-
.toast-message {
|
|
42
|
-
z-index: 2;
|
|
43
|
-
position: absolute;
|
|
44
|
-
top: ${heightFromTop};
|
|
45
|
-
font-size: 1.4rem;
|
|
46
|
-
font-family: 'Helvetica Neue';
|
|
47
|
-
color: #fff;
|
|
48
|
-
left: 50%;
|
|
49
|
-
background: #333;
|
|
50
|
-
border: 1px solid #fff;
|
|
51
|
-
border-radius: 5px;
|
|
52
|
-
box-shadow: 1px 1px 2px;
|
|
53
|
-
padding: 10px;
|
|
54
|
-
width: fit-content;
|
|
55
|
-
transform: translate(-50%, -50%);
|
|
56
|
-
cursor: pointer;
|
|
57
|
-
animation: fadeIn 5s;
|
|
58
|
-
@keyframes fadeIn {
|
|
59
|
-
0% {
|
|
60
|
-
opacity: 0;
|
|
61
|
-
}
|
|
62
|
-
100% {
|
|
63
|
-
opacity: 1;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.hidden {
|
|
69
|
-
display: none;
|
|
70
|
-
}
|
|
71
|
-
.visible {
|
|
72
|
-
display: inline-block;
|
|
73
|
-
}
|
|
74
|
-
`;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
window.customElements.define('toast-message', ToastMessage);
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { nothing } from 'lit';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This class is used to determine if use is eligible for auto renew loan.
|
|
5
|
-
*
|
|
6
|
-
*/
|
|
7
|
-
export class OneHourAutoRenew {
|
|
8
|
-
constructor(
|
|
9
|
-
isPageClick,
|
|
10
|
-
identifier,
|
|
11
|
-
localCache,
|
|
12
|
-
autoRenewConfig,
|
|
13
|
-
userHasBrowsed
|
|
14
|
-
) {
|
|
15
|
-
this.isPageClick = isPageClick;
|
|
16
|
-
this.identifier = identifier;
|
|
17
|
-
this.localCache = localCache;
|
|
18
|
-
this.autoRenewConfig = autoRenewConfig;
|
|
19
|
-
this.userHasBrowsed = userHasBrowsed;
|
|
20
|
-
|
|
21
|
-
// messages for auto return machenism
|
|
22
|
-
this.autoRenewMessage = 'This book has been renewed for another hour.';
|
|
23
|
-
this.autoReturnMessage =
|
|
24
|
-
'This book has been auto-returned due to inactivity.';
|
|
25
|
-
this.autoReturnWarning =
|
|
26
|
-
'This book will be auto-returned in 10 minutes unless you turn a page.';
|
|
27
|
-
|
|
28
|
-
// private props
|
|
29
|
-
this.resultRes = {
|
|
30
|
-
toastTexts: '',
|
|
31
|
-
hideToast: true,
|
|
32
|
-
renewNow: false,
|
|
33
|
-
browseAgainNow: false,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
return this.handleBookAutoRenew();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
handleBookAutoRenew() {
|
|
40
|
-
try {
|
|
41
|
-
// if page is not clicked in last 15 minutes,
|
|
42
|
-
// instantaly renew it if user viewed new page in last 10 minutes
|
|
43
|
-
if (this.isPageClick) {
|
|
44
|
-
console.log('page flipped!!');
|
|
45
|
-
return this.userFlippedBookPage(); // user clicked on page
|
|
46
|
-
}
|
|
47
|
-
console.log('auto checker!');
|
|
48
|
-
return this.autoCheckerTimer(); // auto checker at 50th minute
|
|
49
|
-
} catch (error) {
|
|
50
|
-
console.log(error);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return nothing;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async setPageFlippedTime() {
|
|
57
|
-
// set pageFlipTime time in localStorage
|
|
58
|
-
await this.localCache.set({
|
|
59
|
-
key: `${this.identifier}-pageFlipTime`,
|
|
60
|
-
value: new Date(), // current time
|
|
61
|
-
ttl: Number(this.autoRenewConfig.totalTime),
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async userFlippedBookPage() {
|
|
66
|
-
const {
|
|
67
|
-
totalTime, // 60
|
|
68
|
-
autoCheckAt, // 50
|
|
69
|
-
} = this.autoRenewConfig;
|
|
70
|
-
const currentTime = new Date();
|
|
71
|
-
const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
|
|
72
|
-
|
|
73
|
-
const lastTimeFrame = this.changeTime(
|
|
74
|
-
loanTime,
|
|
75
|
-
totalTime - autoCheckAt,
|
|
76
|
-
'add'
|
|
77
|
-
); // 50 seconds
|
|
78
|
-
|
|
79
|
-
if (currentTime >= lastTimeFrame) {
|
|
80
|
-
console.log('1 YES NOW BORROW IT AGAIN NOW!');
|
|
81
|
-
this.resultRes.toastTexts = this.autoRenewMessage;
|
|
82
|
-
this.resultRes.hideToast = false;
|
|
83
|
-
this.resultRes.renewNow = true;
|
|
84
|
-
this.resultRes.browseAgainNow = true;
|
|
85
|
-
|
|
86
|
-
this.setNewBrowseTime();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
this.setPageFlippedTime();
|
|
90
|
-
return this.resultRes;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async autoCheckerTimer() {
|
|
94
|
-
const currentTime = new Date();
|
|
95
|
-
const { FlippedInLast } = this.autoRenewConfig;
|
|
96
|
-
const lastPageFlipTime = await this.localCache.get(
|
|
97
|
-
`${this.identifier}-pageFlipTime`
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
// last 15 min if used flipped a page.
|
|
101
|
-
const lastFlipTimeFrame = this.changeTime(
|
|
102
|
-
currentTime,
|
|
103
|
-
FlippedInLast,
|
|
104
|
-
'sub'
|
|
105
|
-
); // 15 seconds
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
lastPageFlipTime === undefined ||
|
|
109
|
-
lastPageFlipTime <= lastFlipTimeFrame
|
|
110
|
-
) {
|
|
111
|
-
// not viewed
|
|
112
|
-
console.log('2 not viewed, warning message!');
|
|
113
|
-
this.resultRes.toastTexts = this.autoReturnWarning;
|
|
114
|
-
this.resultRes.hideToast = false;
|
|
115
|
-
} else if (lastPageFlipTime >= lastFlipTimeFrame) {
|
|
116
|
-
// viewed in last time frame
|
|
117
|
-
console.log('3 viewed, auto renew and message!');
|
|
118
|
-
this.resultRes.toastTexts = this.autoRenewMessage;
|
|
119
|
-
this.resultRes.browseAgainNow = true;
|
|
120
|
-
this.resultRes.hideToast = false;
|
|
121
|
-
this.resultRes.renewNow = true;
|
|
122
|
-
|
|
123
|
-
this.setNewBrowseTime();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return this.resultRes;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async setNewBrowseTime() {
|
|
130
|
-
try {
|
|
131
|
-
// last 15 min if used flipped a page.
|
|
132
|
-
const expireDate = this.changeTime(
|
|
133
|
-
new Date(),
|
|
134
|
-
this.autoRenewConfig.totalTime,
|
|
135
|
-
'add'
|
|
136
|
-
); // 15 seconds
|
|
137
|
-
|
|
138
|
-
// set a value
|
|
139
|
-
await this.localCache.set({
|
|
140
|
-
key: `${this.identifier}-loanTime`,
|
|
141
|
-
value: expireDate, // expireDate time
|
|
142
|
-
ttl: Number(this.autoRenewConfig.totalTime),
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// delete pageFlipTime when book is auto renew at nth minute
|
|
146
|
-
await this.localCache.delete(`${this.identifier}-pageFlipTime`);
|
|
147
|
-
} catch (error) {
|
|
148
|
-
console.log(error);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
changeTime(date, minutes, op) {
|
|
153
|
-
if (date === undefined) return nothing;
|
|
154
|
-
|
|
155
|
-
if (op === 'sub') {
|
|
156
|
-
return new Date(date.getTime() - minutes * 1000);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return new Date(date.getTime() + minutes * 1000);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
sendEvent(eventCategory, eventAction) {
|
|
163
|
-
window?.archive_analytics?.send_event(
|
|
164
|
-
eventCategory,
|
|
165
|
-
eventAction,
|
|
166
|
-
`identifier=${this.identifier}`
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
}
|