@internetarchive/ia-book-actions 0.0.29-alpha21 → 0.0.29-alpha23
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/package.json +2 -2
- package/src/assets/data/lending-get-status-service.js +1 -1
- package/src/components/info-icon.js +0 -6
- package/src/components/timer-countdown.js +14 -16
- package/src/core/services/actions-config.js +2 -2
- package/src/core/services/loan-renew-helper.js +8 -2
- package/src/ia-book-actions.js +28 -5
- package/test/components/collapsible-action-group.test.js +2 -2
- package/test/core/services/get-lending-actions.test.js +4 -4
- package/test/ia-book-actions.test.js +4 -4
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-alpha23",
|
|
4
4
|
"description": "Bookreader actions for borrowable book",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@internetarchive/local-cache": "^0.2.0",
|
|
23
23
|
"@internetarchive/modal-manager": "^0.2.1",
|
|
24
24
|
"@internetarchive/shared-resize-observer": "^0.2.0",
|
|
25
|
-
"@internetarchive/toast-manager": "0.0.1-
|
|
25
|
+
"@internetarchive/toast-manager": "0.0.1-alpha9",
|
|
26
26
|
"lit": "^2.5.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
@@ -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: 12,
|
|
122
122
|
shouldProtectImages: true,
|
|
123
123
|
totalWaitlistCount: 0,
|
|
124
124
|
userHasBorrowed: false,
|
|
@@ -58,55 +58,53 @@ export default class TimerCountdown extends LitElement {
|
|
|
58
58
|
render() {
|
|
59
59
|
return html`
|
|
60
60
|
<svg
|
|
61
|
-
width="
|
|
62
|
-
height="
|
|
61
|
+
width="16"
|
|
62
|
+
height="16"
|
|
63
63
|
viewBox="0 0 100 100"
|
|
64
64
|
xmlns="http://www.w3.org/2000/svg"
|
|
65
65
|
>
|
|
66
66
|
<circle class="circle" cx="50" cy="50" r="50" />
|
|
67
67
|
</svg>
|
|
68
|
+
<span>${Math.round(this.time)}</span>
|
|
68
69
|
`;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
static get styles() {
|
|
72
73
|
const white = css`var(--white, #fff)`;
|
|
73
|
-
const
|
|
74
|
+
const timerSecondsLeft = css`var(--timerSeconds, 6000s)`;
|
|
75
|
+
const timerStrokeLeft = css`var(--timerStroke, 315)`;
|
|
74
76
|
|
|
75
77
|
return css`
|
|
76
78
|
:host {
|
|
77
79
|
right: 5px;
|
|
78
|
-
font-size: 14px;
|
|
79
80
|
position: absolute;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
@keyframes circletimer {
|
|
83
84
|
0% {
|
|
84
|
-
stroke-dashoffset:
|
|
85
|
-
stroke-dasharray:
|
|
85
|
+
stroke-dashoffset: ${timerStrokeLeft};
|
|
86
|
+
stroke-dasharray: 315;
|
|
86
87
|
}
|
|
87
88
|
100% {
|
|
88
89
|
stroke-dashoffset: 0;
|
|
89
|
-
stroke-dasharray:
|
|
90
|
+
stroke-dasharray: 315;
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
svg {
|
|
94
|
-
background-color:
|
|
95
|
-
position: absolute;
|
|
96
|
-
top: 50%;
|
|
97
|
-
right: 0;
|
|
95
|
+
background-color: ${white};
|
|
98
96
|
border-radius: 50px;
|
|
99
97
|
border: 2px solid ${white};
|
|
100
|
-
transform:
|
|
98
|
+
transform: rotateZ(-90deg);
|
|
101
99
|
}
|
|
102
100
|
|
|
103
101
|
svg .circle {
|
|
104
|
-
stroke:
|
|
102
|
+
stroke: #000;
|
|
105
103
|
stroke-width: 100px;
|
|
106
|
-
fill:
|
|
107
|
-
stroke-dashoffset:
|
|
104
|
+
fill: ${white};
|
|
105
|
+
stroke-dashoffset: 315;
|
|
108
106
|
stroke-dasharray: 0;
|
|
109
|
-
animation: ${
|
|
107
|
+
animation: ${timerSecondsLeft} circletimer linear;
|
|
110
108
|
}
|
|
111
109
|
`;
|
|
112
110
|
}
|
|
@@ -36,7 +36,7 @@ export default class ActionsConfig {
|
|
|
36
36
|
firstBrowseConfig() {
|
|
37
37
|
return {
|
|
38
38
|
id: 'browseBook',
|
|
39
|
-
text: 'Borrow for 1 hour'
|
|
39
|
+
text: 'Borrow', // changed texts from 'Borrow for 1 hour' to 'Borrow'
|
|
40
40
|
className: 'primary',
|
|
41
41
|
analyticsEvent: {
|
|
42
42
|
category: this.analyticsCategories.preview,
|
|
@@ -48,7 +48,7 @@ export default class ActionsConfig {
|
|
|
48
48
|
browseAgainConfig() {
|
|
49
49
|
return {
|
|
50
50
|
id: 'browseBookAgain',
|
|
51
|
-
text: 'Borrow again'
|
|
51
|
+
text: 'Borrow', // changed texts fro 'Borrow again' to 'Borrow'
|
|
52
52
|
className: 'primary',
|
|
53
53
|
analyticsEvent: {
|
|
54
54
|
category: this.analyticsCategories.browse,
|
|
@@ -5,8 +5,9 @@ import { ToastConfig } from '@internetarchive/toast-manager';
|
|
|
5
5
|
* This class is used to determine if use is eligible for auto renew loan.
|
|
6
6
|
*/
|
|
7
7
|
export class LoanRenewHelper {
|
|
8
|
-
constructor(hasPageChanged, identifier, localCache, loanRenewConfig) {
|
|
8
|
+
constructor(hasPageChanged, hideToast, identifier, localCache, loanRenewConfig) {
|
|
9
9
|
this.hasPageChanged = hasPageChanged;
|
|
10
|
+
this.hideToast = hideToast;
|
|
10
11
|
this.identifier = identifier;
|
|
11
12
|
this.localCache = localCache;
|
|
12
13
|
this.loanRenewConfig = loanRenewConfig;
|
|
@@ -64,6 +65,7 @@ export class LoanRenewHelper {
|
|
|
64
65
|
if (currentTime >= lastTimeFrame) {
|
|
65
66
|
this.result.texts = this.loanRenewMessage;
|
|
66
67
|
this.result.renewNow = true;
|
|
68
|
+
console.log('manually renewed by page click!');
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
this.setPageChangedTime();
|
|
@@ -97,9 +99,11 @@ export class LoanRenewHelper {
|
|
|
97
99
|
this.result.texts = this.loanReturnWarning;
|
|
98
100
|
this.result.renewNow = false; // not viewed
|
|
99
101
|
this.showToastMessage();
|
|
102
|
+
console.log('not viewed!');
|
|
100
103
|
} else if (lastPageFlipTime >= lastFlipTimeFrame) {
|
|
101
104
|
this.result.texts = '';
|
|
102
105
|
this.result.renewNow = true; // viewed in last time frame
|
|
106
|
+
console.log('silently renewed!');
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
return this.result;
|
|
@@ -123,6 +127,8 @@ export class LoanRenewHelper {
|
|
|
123
127
|
* - show warninig msg when book is about to auto returned
|
|
124
128
|
*/
|
|
125
129
|
async showToastMessage() {
|
|
130
|
+
if (this.hideToast) return false;
|
|
131
|
+
|
|
126
132
|
const iaBookActions = document.querySelector('ia-book-actions').shadowRoot;
|
|
127
133
|
let toastTemplate = iaBookActions.querySelector('toast-template');
|
|
128
134
|
if (!toastTemplate) {
|
|
@@ -148,7 +154,7 @@ export class LoanRenewHelper {
|
|
|
148
154
|
* @returns {Object} Date
|
|
149
155
|
*/
|
|
150
156
|
changeTime(date, minutes, op) {
|
|
151
|
-
if (date === undefined) return
|
|
157
|
+
if (date === undefined) return null;
|
|
152
158
|
|
|
153
159
|
if (op === 'sub') {
|
|
154
160
|
return new Date(date.getTime() - minutes * 1000);
|
package/src/ia-book-actions.js
CHANGED
|
@@ -73,6 +73,7 @@ export default class IABookActions extends LitElement {
|
|
|
73
73
|
// loan auto renew
|
|
74
74
|
this.browserTimer = undefined;
|
|
75
75
|
this.loanRenewConfig = {};
|
|
76
|
+
this.hideToast = false;
|
|
76
77
|
|
|
77
78
|
/**
|
|
78
79
|
* contains loan auto-renew response
|
|
@@ -232,15 +233,20 @@ export default class IABookActions extends LitElement {
|
|
|
232
233
|
*/
|
|
233
234
|
bindLoanRenewEvents() {
|
|
234
235
|
// dispatched this event from bookreader page changed
|
|
235
|
-
window.addEventListener('BookReader:pageChanged',
|
|
236
|
-
|
|
237
|
-
if (this.borrowType === 'browsed') {
|
|
236
|
+
window.addEventListener('BookReader:pageChanged', event => {
|
|
237
|
+
if (this.borrowType === 'browsed' && event.detail.hasPageChanged) {
|
|
238
238
|
this.autoLoanRenewChecker(true);
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
return nothing;
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
+
document.addEventListener('click', () => {
|
|
245
|
+
if (this.loanRenewHelper && this.loanRenewHelper.result.renewNow === false) {
|
|
246
|
+
this.hideToast = true;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
244
250
|
/**
|
|
245
251
|
* this event dispatched from timer-countdown component for:
|
|
246
252
|
* 1. user turned book page after showing auto-returned warning message
|
|
@@ -262,12 +268,14 @@ export default class IABookActions extends LitElement {
|
|
|
262
268
|
async autoLoanRenewChecker(hasPageChanged = false) {
|
|
263
269
|
this.loanRenewHelper = new LoanRenewHelper(
|
|
264
270
|
hasPageChanged,
|
|
271
|
+
this.hideToast,
|
|
265
272
|
this.identifier,
|
|
266
273
|
this.localCache,
|
|
267
274
|
this.loanRenewConfig
|
|
268
275
|
);
|
|
269
276
|
|
|
270
277
|
await this.loanRenewHelper.handleLoanRenew();
|
|
278
|
+
console.log(this.loanRenewResult);
|
|
271
279
|
this.loanRenewResult = this.loanRenewHelper.result;
|
|
272
280
|
}
|
|
273
281
|
|
|
@@ -327,12 +335,26 @@ export default class IABookActions extends LitElement {
|
|
|
327
335
|
* Reset timer animation state after book renewed
|
|
328
336
|
*/
|
|
329
337
|
async resetTimerCountState() {
|
|
338
|
+
const secondsLeft = Number(this.lendingStatus.secondsLeftOnLoan);
|
|
339
|
+
|
|
330
340
|
const timerCountdown = this.shadowRoot.querySelector('timer-countdown');
|
|
331
341
|
const animationCircle = timerCountdown.shadowRoot.querySelector('.circle');
|
|
332
342
|
|
|
343
|
+
// the perimeter of the circle
|
|
344
|
+
const circleStroke = 315; // (π * 2 * radius)
|
|
345
|
+
const strokeDashOffset =
|
|
346
|
+
(secondsLeft / this.loanRenewConfig.totalTime) *
|
|
347
|
+
circleStroke;
|
|
348
|
+
|
|
349
|
+
// set seconds left in loan expire
|
|
350
|
+
timerCountdown.style?.setProperty(
|
|
351
|
+
'--timerSeconds',
|
|
352
|
+
`${secondsLeft}s`
|
|
353
|
+
);
|
|
354
|
+
// set circle stroke offset left in loan expire
|
|
333
355
|
timerCountdown.style?.setProperty(
|
|
334
|
-
'--
|
|
335
|
-
`${Number(
|
|
356
|
+
'--timerStroke',
|
|
357
|
+
`${Number(strokeDashOffset)}`
|
|
336
358
|
);
|
|
337
359
|
|
|
338
360
|
animationCircle.style.animationName = 'none';
|
|
@@ -403,6 +425,7 @@ export default class IABookActions extends LitElement {
|
|
|
403
425
|
*/
|
|
404
426
|
async handleLoanAutoRenewed() {
|
|
405
427
|
if (this.loanRenewResult.renewNow) {
|
|
428
|
+
this.hideToast = false;
|
|
406
429
|
this.tokenPoller.disconnectedInterval();
|
|
407
430
|
await this.loanRenewHelper.showToastMessage();
|
|
408
431
|
await this.browseHasRenew();
|
|
@@ -6,7 +6,7 @@ const container = ({
|
|
|
6
6
|
{
|
|
7
7
|
analyticsEvent: { action: 'Browse', category: 'Lending' },
|
|
8
8
|
className: 'ia-button primary',
|
|
9
|
-
text: 'Borrow
|
|
9
|
+
text: 'Borrow',
|
|
10
10
|
id: 'browseBook',
|
|
11
11
|
},
|
|
12
12
|
{
|
|
@@ -40,7 +40,7 @@ describe('<collapsible-action-group>', () => {
|
|
|
40
40
|
.true;
|
|
41
41
|
|
|
42
42
|
const primaryButton = primaryActionContainer.querySelector('.ia-button');
|
|
43
|
-
expect(primaryButton.innerText).to.equal('Borrow
|
|
43
|
+
expect(primaryButton.innerText).to.equal('Borrow');
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
it('check if loader is active and action-group is disabled', async () => {
|
|
@@ -25,7 +25,7 @@ describe('Get Lending Actions', () => {
|
|
|
25
25
|
|
|
26
26
|
expect(actions.primaryTitle).to.equal(bookTitles.available_1hr);
|
|
27
27
|
expect(actions.primaryActions.length).to.equal(3);
|
|
28
|
-
expect(actions.primaryActions[0].text).to.equal('Borrow
|
|
28
|
+
expect(actions.primaryActions[0].text).to.equal('Borrow');
|
|
29
29
|
expect(actions.primaryActions[1].text).to.equal('Borrow for 14 days');
|
|
30
30
|
expect(actions.secondaryActions[1].text).to.equal('Purchase at');
|
|
31
31
|
});
|
|
@@ -111,7 +111,7 @@ describe('Get Lending Actions', () => {
|
|
|
111
111
|
expect(actions.primaryTitle).to.equal(bookTitles.claim_waitlist);
|
|
112
112
|
expect(actions.primaryActions.length).to.equal(3);
|
|
113
113
|
expect(actions.primaryActions[0].text).to.equal('Borrow for 14 days');
|
|
114
|
-
expect(actions.primaryActions[1].text).to.equal('Borrow
|
|
114
|
+
expect(actions.primaryActions[1].text).to.equal('Borrow');
|
|
115
115
|
expect(actions.primaryActions[2].text).to.equal('Leave Waitlist');
|
|
116
116
|
expect(spy.called).to.be.true;
|
|
117
117
|
});
|
|
@@ -138,7 +138,7 @@ describe('Get Lending Actions', () => {
|
|
|
138
138
|
expect(actions.primaryTitle).to.equal(bookTitles.on_waitlist);
|
|
139
139
|
expect(actions.primaryActions.length).to.equal(2);
|
|
140
140
|
expect(actions.primaryActions[0].text).to.equal('Leave Waitlist');
|
|
141
|
-
expect(actions.primaryActions[1].text).to.equal('Borrow
|
|
141
|
+
expect(actions.primaryActions[1].text).to.equal('Borrow');
|
|
142
142
|
expect(claimSpy.called).to.be.false;
|
|
143
143
|
expect(waitlistSpy.called).to.be.true;
|
|
144
144
|
});
|
|
@@ -162,7 +162,7 @@ describe('Get Lending Actions', () => {
|
|
|
162
162
|
expect(actions.primaryTitle).to.equal(bookTitles.on_waitlist);
|
|
163
163
|
expect(actions.primaryActions.length).to.equal(2);
|
|
164
164
|
expect(actions.primaryActions[0].text).to.equal('Leave Waitlist');
|
|
165
|
-
expect(actions.primaryActions[1].text).to.equal('Borrow
|
|
165
|
+
expect(actions.primaryActions[1].text).to.equal('Borrow');
|
|
166
166
|
expect(waitlistSpy.called).to.be.true;
|
|
167
167
|
});
|
|
168
168
|
});
|
|
@@ -81,7 +81,7 @@ describe('Primary Actions data', () => {
|
|
|
81
81
|
);
|
|
82
82
|
const expectedPrimaryActions = [
|
|
83
83
|
{
|
|
84
|
-
text: 'Borrow for 1 hour'
|
|
84
|
+
text: 'Borrow', // changed from 'Borrow for 1 hour'
|
|
85
85
|
callback: () => {},
|
|
86
86
|
className: 'ia-button primary',
|
|
87
87
|
},
|
|
@@ -161,7 +161,7 @@ describe('Borrow status actions', () => {
|
|
|
161
161
|
|
|
162
162
|
// removed available_to_borrow from lending bar
|
|
163
163
|
expect(el.lendingStatus.available_to_borrow).to.be.false;
|
|
164
|
-
expect(el.primaryActions[0].text).to.equal('Borrow
|
|
164
|
+
expect(el.primaryActions[0].text).to.equal('Borrow');
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
it('Check action for borrowable book without user', async () => {
|
|
@@ -251,7 +251,7 @@ describe('Browsing expired status', () => {
|
|
|
251
251
|
await aTimeout(1500); // wait for 1.5 second
|
|
252
252
|
await el.updateComplete;
|
|
253
253
|
|
|
254
|
-
expect(el.primaryActions[0].text).to.equal('Borrow
|
|
254
|
+
expect(el.primaryActions[0].text).to.equal('Borrow');
|
|
255
255
|
});
|
|
256
256
|
|
|
257
257
|
it('Expiring book cancels interval & emits event', async () => {
|
|
@@ -286,7 +286,7 @@ describe('Browsing expired status', () => {
|
|
|
286
286
|
await aTimeout(1500); // wait for 1.5 sec
|
|
287
287
|
|
|
288
288
|
expect(eventReceived).to.equal(true);
|
|
289
|
-
expect(el.primaryActions[0].text).to.equal('Borrow
|
|
289
|
+
expect(el.primaryActions[0].text).to.equal('Borrow');
|
|
290
290
|
expect(el.tokenPoller.loanTokenInterval).to.equal(undefined);
|
|
291
291
|
});
|
|
292
292
|
});
|