@internetarchive/ia-book-actions 0.0.7-3 → 0.0.7-6
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 -1
- package/src/components/collapsible-action-group.js +25 -16
- package/src/core/services/actions-handler/actions-handler-service.js +6 -2
- package/src/core/services/actions-handler/actions-handler.js +32 -8
- package/src/core/services/get-lending-actions.js +1 -1
- package/src/ia-book-actions.js +16 -7
- package/test/components/collapsible-action-group.test.js +0 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/ia-book-actions",
|
|
3
|
-
"version": "0.0.7-
|
|
3
|
+
"version": "0.0.7-6",
|
|
4
4
|
"description": "Bookreader actions for borrowable book",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"@internetarchive/icon-bookmark": "^1.1.3",
|
|
23
23
|
"@internetarchive/icon-close": "^1.1.3",
|
|
24
24
|
"@internetarchive/icon-info": "^1.2.6",
|
|
25
|
+
"@internetarchive/local-cache": "^0.1.1",
|
|
25
26
|
"@internetarchive/modal-manager": "^0.1.0",
|
|
26
27
|
"@internetarchive/shared-resize-observer": "^0.0.1",
|
|
27
28
|
"lit-element": "^2.4.0",
|
|
@@ -50,42 +50,51 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
50
50
|
this.consecutiveLoanCounts = 1; // consecutive loan count
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
if (changed.has('width')) {
|
|
55
|
-
if (this.isBelowTabletContainer) {
|
|
56
|
-
this.resetActions();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
53
|
+
firstUpdated() {
|
|
60
54
|
// this is execute to fetch loan token
|
|
61
|
-
if (
|
|
55
|
+
if (this.borrowType) {
|
|
62
56
|
this.emitEnableBookAccess();
|
|
63
57
|
}
|
|
64
58
|
}
|
|
65
59
|
|
|
60
|
+
updated(changed) {
|
|
61
|
+
if (changed.has('width') && this.isBelowTabletContainer) {
|
|
62
|
+
this.resetActions();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* Dispatches event when patron is borrowing book.
|
|
68
|
+
* Notes borrow type, and consecutive borrow counts
|
|
68
69
|
*
|
|
69
70
|
* @fires CollapsibleActionGroup#enableBookAccess
|
|
70
71
|
*/
|
|
71
|
-
emitEnableBookAccess() {
|
|
72
|
+
async emitEnableBookAccess() {
|
|
72
73
|
// send consecutiveLoanCounts for browsed books only.
|
|
73
|
-
if (this.borrowType === '
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
if (this.borrowType === 'browsed') {
|
|
75
|
+
try {
|
|
76
|
+
const existingCount = await this.localCache.get(
|
|
77
|
+
'consecutive-loan-count'
|
|
78
|
+
);
|
|
79
|
+
if (existingCount !== undefined) {
|
|
80
|
+
this.consecutiveLoanCounts = existingCount.value ?? 1;
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.log(error);
|
|
84
|
+
}
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
// event category and action for browsing book access
|
|
79
88
|
const eventCategory = `${this.borrowType}BookAccess`;
|
|
80
89
|
const eventAction = `${
|
|
81
|
-
this.borrowType === '
|
|
90
|
+
this.borrowType === 'browsed' ? 'BrowseCounts-' : 'Counts-'
|
|
82
91
|
}${this.consecutiveLoanCounts}`;
|
|
83
92
|
|
|
84
93
|
this.dispatchEvent(
|
|
85
94
|
new CustomEvent('enableBookAccess', {
|
|
86
95
|
detail: {
|
|
87
96
|
event: {
|
|
88
|
-
category: eventCategory, //
|
|
97
|
+
category: eventCategory, // browsedBookAccess | borrowedBookAccess
|
|
89
98
|
action: eventAction, // (BrowseCounts-N|Counts-N)
|
|
90
99
|
},
|
|
91
100
|
borrowType: this.borrowType,
|
|
@@ -226,7 +235,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
226
235
|
}
|
|
227
236
|
|
|
228
237
|
/**
|
|
229
|
-
*
|
|
238
|
+
* Dispatches click events when patron clicks on action buttons
|
|
230
239
|
* @param { string } eventName - actions like 'browseBook', 'borrowBook' etc...
|
|
231
240
|
* @param { object } gaEvent - contains analytics event action and category
|
|
232
241
|
* @param { string } gaEvent.category
|
|
@@ -16,6 +16,11 @@ export default function ActionsHandlerService(options) {
|
|
|
16
16
|
let baseHost = '/services/loans/loan';
|
|
17
17
|
const location = window?.location;
|
|
18
18
|
|
|
19
|
+
// return intentional error on dev environment
|
|
20
|
+
const shouldReturnError =
|
|
21
|
+
location?.href?.indexOf('?error=true') !== -1 &&
|
|
22
|
+
location?.hostname !== 'archive.org';
|
|
23
|
+
|
|
19
24
|
if (location?.pathname === '/demo/') baseHost = `/demo/`;
|
|
20
25
|
|
|
21
26
|
let formData = new FormData();
|
|
@@ -27,12 +32,11 @@ export default function ActionsHandlerService(options) {
|
|
|
27
32
|
body: formData,
|
|
28
33
|
})
|
|
29
34
|
.then(response => {
|
|
30
|
-
let shouldReturnError = location?.href?.indexOf('?error=true') !== -1;
|
|
31
35
|
const tokenError = 'loan token not found. please try again later.';
|
|
32
36
|
const borrowError =
|
|
33
37
|
'This book is not available to borrow at this time. Please try again later.';
|
|
34
38
|
|
|
35
|
-
// return error reponse
|
|
39
|
+
// return error reponse when not production and has ?error=true param...
|
|
36
40
|
const erroneousActions = ['browse_book', 'borrow_book', 'create_token'];
|
|
37
41
|
if (shouldReturnError && erroneousActions.includes(option?.action)) {
|
|
38
42
|
return {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { LitElement } from 'lit-element';
|
|
2
|
+
import { LocalCache } from '@internetarchive/local-cache';
|
|
3
|
+
|
|
2
4
|
import { URLHelper } from '../../config/url-helper.js';
|
|
3
5
|
import ActionsHandlerService from './actions-handler-service.js';
|
|
4
6
|
|
|
@@ -18,6 +20,7 @@ export default class ActionsHandler extends LitElement {
|
|
|
18
20
|
this.loanTokenPollingDelay =
|
|
19
21
|
window.location.pathname === '/demo/' ? 2000 : 120000; // 120000 ms = 2 min
|
|
20
22
|
this.loanTokenInterval = undefined;
|
|
23
|
+
this.localCache = new LocalCache();
|
|
21
24
|
this.bindEvents();
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -211,6 +214,15 @@ export default class ActionsHandler extends LitElement {
|
|
|
211
214
|
});
|
|
212
215
|
}
|
|
213
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Dispatches event when an error occured on action
|
|
219
|
+
* Notes:- toggle <collapsible-action-group> visibility (enable/disable).
|
|
220
|
+
*
|
|
221
|
+
* @param { String } action - name of action like browse_book, borrow_book
|
|
222
|
+
* @param { Object } data - erroneous response from api call
|
|
223
|
+
*
|
|
224
|
+
* @fires ActionsHandler#lendingActionError
|
|
225
|
+
*/
|
|
214
226
|
dispatchActionError(action, data = {}) {
|
|
215
227
|
this.dispatchEvent(
|
|
216
228
|
new CustomEvent('lendingActionError', {
|
|
@@ -219,6 +231,12 @@ export default class ActionsHandler extends LitElement {
|
|
|
219
231
|
);
|
|
220
232
|
}
|
|
221
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Dispatches event when patron is clicked on action buttons.
|
|
236
|
+
* Notes:- toggle <collapsible-action-group> disable/enable.
|
|
237
|
+
*
|
|
238
|
+
* @fires ActionsHandler#toggleActionGroup
|
|
239
|
+
*/
|
|
222
240
|
dispatchToggleActionGroup() {
|
|
223
241
|
this.dispatchEvent(new CustomEvent('toggleActionGroup'));
|
|
224
242
|
}
|
|
@@ -256,19 +274,25 @@ export default class ActionsHandler extends LitElement {
|
|
|
256
274
|
}
|
|
257
275
|
|
|
258
276
|
// save consecutive loan count for borrow
|
|
259
|
-
setConsecutiveLoanCounts(action = '') {
|
|
260
|
-
|
|
261
|
-
if (localStorage) {
|
|
277
|
+
async setConsecutiveLoanCounts(action = '') {
|
|
278
|
+
try {
|
|
262
279
|
let newCount = 1;
|
|
263
280
|
const storageKey = `consecutive-loan-count`;
|
|
264
|
-
const existingCount =
|
|
281
|
+
const existingCount = await this.localCache.get(storageKey);
|
|
265
282
|
|
|
266
|
-
//
|
|
267
|
-
|
|
268
|
-
if (action === 'browseAgain') {
|
|
283
|
+
// increase browse-count by 1 when you consecutive reading a book.
|
|
284
|
+
if (action === 'browseAgain' && existingCount !== undefined) {
|
|
269
285
|
newCount = existingCount ? existingCount + 1 : 1;
|
|
270
286
|
}
|
|
271
|
-
|
|
287
|
+
|
|
288
|
+
// set new value
|
|
289
|
+
await this.localCache.set({
|
|
290
|
+
key: storageKey,
|
|
291
|
+
value: newCount,
|
|
292
|
+
ttl: 7200, // 2 hours
|
|
293
|
+
});
|
|
294
|
+
} catch (error) {
|
|
295
|
+
console.log(error);
|
|
272
296
|
}
|
|
273
297
|
}
|
|
274
298
|
|
package/src/ia-book-actions.js
CHANGED
|
@@ -24,6 +24,7 @@ export default class IABookActions extends LitElement {
|
|
|
24
24
|
barType: { type: String },
|
|
25
25
|
sharedObserver: { attribute: false },
|
|
26
26
|
disableActionGroup: { type: Boolean },
|
|
27
|
+
modal: { Object },
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -37,12 +38,15 @@ export default class IABookActions extends LitElement {
|
|
|
37
38
|
this.bwbPurchaseUrl = '';
|
|
38
39
|
this.barType = 'action'; // 'title'|'action'
|
|
39
40
|
this.sharedObserver = undefined;
|
|
41
|
+
this.disableActionGroup = false;
|
|
42
|
+
this.modal = undefined;
|
|
43
|
+
|
|
44
|
+
// private props
|
|
40
45
|
this.primaryActions = [];
|
|
41
46
|
this.primaryTitle = '';
|
|
42
47
|
this.primaryColor = 'primary';
|
|
43
48
|
this.secondaryActions = [];
|
|
44
49
|
this.lendingOptions = {};
|
|
45
|
-
this.disableActionGroup = false;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
disconnectedCallback() {
|
|
@@ -144,8 +148,8 @@ export default class IABookActions extends LitElement {
|
|
|
144
148
|
});
|
|
145
149
|
|
|
146
150
|
this.borrowType = actions.borrowType;
|
|
147
|
-
if (this.borrowType === '
|
|
148
|
-
// start timer for
|
|
151
|
+
if (this.borrowType === 'browsed') {
|
|
152
|
+
// start timer for browsed.
|
|
149
153
|
// when browse is completed, we shows browse-again button
|
|
150
154
|
this.startBrowseTimer();
|
|
151
155
|
}
|
|
@@ -235,11 +239,15 @@ export default class IABookActions extends LitElement {
|
|
|
235
239
|
async showErrorModal(errorMsg, action) {
|
|
236
240
|
this.disableActionGroup = false;
|
|
237
241
|
|
|
238
|
-
this.modal
|
|
242
|
+
// check if this.modal passed as prop
|
|
239
243
|
if (!this.modal) {
|
|
240
|
-
this.modal = document.
|
|
241
|
-
|
|
244
|
+
this.modal = document.querySelector('modal-manager');
|
|
245
|
+
|
|
246
|
+
// check the DOM if <modal-manager> already there
|
|
247
|
+
if (!this.modal) this.modal = document.createElement('modal-manager');
|
|
242
248
|
}
|
|
249
|
+
|
|
250
|
+
this.modal.id = 'action-bar-modal';
|
|
243
251
|
await document.body.appendChild(this.modal);
|
|
244
252
|
|
|
245
253
|
const modalConfig = new ModalConfig({
|
|
@@ -253,7 +261,8 @@ export default class IABookActions extends LitElement {
|
|
|
253
261
|
modalConfig.showCloseButton = false;
|
|
254
262
|
modalConfig.message = html` Uh oh, something went wrong trying to access
|
|
255
263
|
this book.<br />
|
|
256
|
-
Please <a href="
|
|
264
|
+
Please <a href="${() => window.location.reload(true)}">refresh</a> to
|
|
265
|
+
try again or send us an email to
|
|
257
266
|
<a
|
|
258
267
|
href="mailto:info@archive.org?subject=Help: cannot access my borrowed book: ${this
|
|
259
268
|
.identifier}"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { html, fixture, expect } from '@open-wc/testing';
|
|
2
2
|
import '../../src/components/collapsible-action-group.js';
|
|
3
|
-
import Sinon from 'sinon';
|
|
4
3
|
|
|
5
4
|
const container = ({
|
|
6
5
|
primaryActions = [
|
|
@@ -85,27 +84,3 @@ describe('<collapsible-action-group>', () => {
|
|
|
85
84
|
expect(eAnalytics.action).to.equal('Browse');
|
|
86
85
|
});
|
|
87
86
|
});
|
|
88
|
-
|
|
89
|
-
describe('fetch loan token and localStorage for browsed/borrowsed book', () => {
|
|
90
|
-
beforeEach(() => {
|
|
91
|
-
const localStorageMock = {
|
|
92
|
-
getItem: Sinon.spy(),
|
|
93
|
-
setItem: Sinon.spy(),
|
|
94
|
-
};
|
|
95
|
-
Object.defineProperty(window, 'localStorage', {
|
|
96
|
-
value: localStorageMock,
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('test localStorage function when borrowType is browsing', async () => {
|
|
101
|
-
await fixture(container({ borrowType: 'browsing' }));
|
|
102
|
-
expect(localStorage.getItem).to.be.calledOnce;
|
|
103
|
-
expect(localStorage.getItem).to.be.calledWith('consecutive-loan-count');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('test localStorage function when borrowType is borrowing', async () => {
|
|
107
|
-
await fixture(container({ borrowType: 'borrowing' }));
|
|
108
|
-
expect(localStorage.getItem).to.not.be.calledOnce;
|
|
109
|
-
expect(localStorage.getItem).to.not.be.calledWith('consecutive-loan-count');
|
|
110
|
-
});
|
|
111
|
-
});
|