@internetarchive/ia-book-actions 0.0.7-9 → 0.0.8
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
CHANGED
|
@@ -106,20 +106,19 @@
|
|
|
106
106
|
|
|
107
107
|
let lendingBarPostInit = function lendingBarPostInit() {
|
|
108
108
|
setTimeout(function() {
|
|
109
|
-
console.log('executed');
|
|
110
|
-
// emitLendingActionBarInitEvent();
|
|
111
|
-
// brInit();
|
|
109
|
+
console.log('executed', 'br.init()');
|
|
112
110
|
}, 100);
|
|
113
111
|
}
|
|
112
|
+
|
|
114
113
|
// set defaultLendingStatus for unavailable (without borrowables) book
|
|
115
114
|
iaBookActions.userid = userid;
|
|
116
115
|
iaBookActions.identifier = identifier;
|
|
117
116
|
iaBookActions.bookTitle = 'Contemporary Black biography. Volume 39 : profiles from the interContemporary Black biography. Volume 39';
|
|
118
117
|
iaBookActions.lendingStatus = canBrowseAndBorrow;
|
|
119
118
|
iaBookActions.bwbPurchaseUrl = '';
|
|
120
|
-
iaBookActions.barType = '';
|
|
121
119
|
iaBookActions.modalConfig = modalConfig;
|
|
122
120
|
iaBookActions.lendingBarPostInit = lendingBarPostInit;
|
|
121
|
+
iaBookActions.tokenDelay = 2000; // 2 seconds
|
|
123
122
|
|
|
124
123
|
let lendingStatus1 = iaBookActions.lendingStatus;
|
|
125
124
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/ia-book-actions",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
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/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.
|
|
25
|
+
"@internetarchive/local-cache": "^0.2.0",
|
|
26
26
|
"@internetarchive/modal-manager": "^0.1.0",
|
|
27
27
|
"@internetarchive/shared-resize-observer": "^0.0.1",
|
|
28
28
|
"lit-element": "^2.4.0",
|
|
@@ -16,7 +16,7 @@ export default class ActionsHandler extends LitElement {
|
|
|
16
16
|
constructor(identifier) {
|
|
17
17
|
super();
|
|
18
18
|
this.identifier = identifier;
|
|
19
|
-
this.ajaxTimeout =
|
|
19
|
+
this.ajaxTimeout = 6000;
|
|
20
20
|
this.localCache = new LocalCache();
|
|
21
21
|
this.bindEvents();
|
|
22
22
|
}
|
|
@@ -178,7 +178,6 @@ export default class ActionsHandler extends LitElement {
|
|
|
178
178
|
});
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
|
|
182
181
|
/**
|
|
183
182
|
* Dispatches event when an error occured on action
|
|
184
183
|
* Notes:- toggle <collapsible-action-group> visibility (enable/disable).
|
|
@@ -242,7 +241,7 @@ export default class ActionsHandler extends LitElement {
|
|
|
242
241
|
async setConsecutiveLoanCounts(action = '') {
|
|
243
242
|
try {
|
|
244
243
|
let newCount = 1;
|
|
245
|
-
const storageKey = `
|
|
244
|
+
const storageKey = `loan-count-${this.identifier}`;
|
|
246
245
|
const existingCount = await this.localCache.get(storageKey);
|
|
247
246
|
|
|
248
247
|
// increase browse-count by 1 when you consecutive reading a book.
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { LitElement } from 'lit-element';
|
|
2
1
|
import { LocalCache } from '@internetarchive/local-cache';
|
|
3
|
-
|
|
4
2
|
import ActionsHandlerService from './actions-handler/actions-handler-service.js';
|
|
5
3
|
|
|
6
4
|
/**
|
|
@@ -8,29 +6,33 @@ import ActionsHandlerService from './actions-handler/actions-handler-service.js'
|
|
|
8
6
|
*
|
|
9
7
|
* ActionsHandlerService is a function being used to execute
|
|
10
8
|
*/
|
|
11
|
-
export class LoanTokenPoller
|
|
12
|
-
constructor() {
|
|
13
|
-
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
9
|
+
export class LoanTokenPoller {
|
|
10
|
+
constructor(id, borrowType, successCallback, errorCallback, pollerDelay) {
|
|
11
|
+
this.identifier = id;
|
|
12
|
+
this.borrowType = borrowType;
|
|
13
|
+
this.successCallback = successCallback; // callback function to be called after loan token is created
|
|
14
|
+
this.errorCallback = errorCallback; // callback function to be called after loan token is created
|
|
15
|
+
this.pollerDelay = pollerDelay; // value in ms (1000 ms = 1 sec)
|
|
16
|
+
|
|
16
17
|
this.loanTokenInterval = undefined;
|
|
17
18
|
this.localCache = new LocalCache();
|
|
19
|
+
this.enableBookAccess();
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
disconnectedInterval() {
|
|
23
|
+
clearInterval(this.loanTokenInterval);
|
|
21
24
|
this.loanTokenInterval = undefined;
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
async enableBookAccess(
|
|
25
|
-
this.identifier = identifier
|
|
27
|
+
async enableBookAccess() {
|
|
26
28
|
let consecutiveLoanCounts = 1;
|
|
27
29
|
|
|
28
|
-
if (borrowType) {
|
|
30
|
+
if (this.borrowType) {
|
|
29
31
|
// send consecutiveLoanCounts for browsed books only.
|
|
30
|
-
if (borrowType === 'browsed') {
|
|
32
|
+
if (this.borrowType === 'browsed') {
|
|
31
33
|
try {
|
|
32
34
|
const existingCount = await this.localCache.get(
|
|
33
|
-
|
|
35
|
+
`loan-count-${this.identifier}`
|
|
34
36
|
);
|
|
35
37
|
consecutiveLoanCounts = existingCount ?? 1;
|
|
36
38
|
} catch (error) {
|
|
@@ -39,22 +41,22 @@ export class LoanTokenPoller extends LitElement {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
// Do an initial token, then set an interval
|
|
42
|
-
this.handleLoanTokenPoller();
|
|
44
|
+
this.handleLoanTokenPoller(true);
|
|
43
45
|
|
|
44
46
|
this.loanTokenInterval = setInterval(() => {
|
|
45
47
|
this.handleLoanTokenPoller();
|
|
46
|
-
}, this.
|
|
48
|
+
}, this.pollerDelay);
|
|
47
49
|
|
|
48
50
|
// event category and action for browsing book access
|
|
49
|
-
const category = `${borrowType}BookAccess`;
|
|
51
|
+
const category = `${this.borrowType}BookAccess`;
|
|
50
52
|
const action = `${
|
|
51
|
-
borrowType === 'browsed' ? 'BrowseCounts-' : 'Counts-'
|
|
53
|
+
this.borrowType === 'browsed' ? 'BrowseCounts-' : 'Counts-'
|
|
52
54
|
}${consecutiveLoanCounts}`;
|
|
53
|
-
|
|
55
|
+
|
|
54
56
|
this.sendEvent(category, action);
|
|
55
57
|
} else {
|
|
56
58
|
// if book is not browsed, just clear token polling interval
|
|
57
|
-
|
|
59
|
+
this.disconnectedInterval(); // stop token fetch api
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -68,36 +70,18 @@ export class LoanTokenPoller extends LitElement {
|
|
|
68
70
|
);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
async handleLoanTokenPoller() {
|
|
73
|
+
async handleLoanTokenPoller(isInitial = false) {
|
|
72
74
|
const action = 'create_token';
|
|
73
|
-
// await new Promise(r => setTimeout(r, 3000));
|
|
74
75
|
ActionsHandlerService({
|
|
75
76
|
identifier: this.identifier,
|
|
76
77
|
action,
|
|
77
78
|
error: data => {
|
|
78
|
-
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
this.disconnectedInterval(); // stop token fetch api
|
|
80
|
+
this.errorCallback({ detail: { action, data } });
|
|
81
|
+
},
|
|
82
|
+
success: () => {
|
|
83
|
+
if (isInitial) this.successCallback();
|
|
82
84
|
},
|
|
83
85
|
});
|
|
84
86
|
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Dispatches event when an error occured on action
|
|
88
|
-
* Notes:- toggle <collapsible-action-group> visibility (enable/disable).
|
|
89
|
-
*
|
|
90
|
-
* @param { String } action - name of action like browse_book, borrow_book
|
|
91
|
-
* @param { Object } data - erroneous response from api call
|
|
92
|
-
*
|
|
93
|
-
* @fires ActionsHandler#lendingActionError
|
|
94
|
-
*/
|
|
95
|
-
dispatchActionError(action, data = {}) {
|
|
96
|
-
console.log('disptaced');
|
|
97
|
-
this.dispatchEvent(
|
|
98
|
-
new CustomEvent('lendingActionError', {
|
|
99
|
-
detail: { action, data },
|
|
100
|
-
})
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
87
|
}
|
package/src/ia-book-actions.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
|
-
import { html, css } from 'lit-element';
|
|
2
|
+
import { html, css, LitElement } from 'lit-element';
|
|
3
3
|
|
|
4
4
|
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
|
|
5
5
|
import { ModalConfig } from '@internetarchive/modal-manager';
|
|
@@ -13,7 +13,7 @@ import GetLendingActions from './core/services/get-lending-actions.js';
|
|
|
13
13
|
import { mobileContainerWidth } from './core/config/constants.js';
|
|
14
14
|
import { LoanTokenPoller } from './core/services/loan-token-poller.js';
|
|
15
15
|
|
|
16
|
-
export default class IABookActions extends
|
|
16
|
+
export default class IABookActions extends LitElement {
|
|
17
17
|
static get properties() {
|
|
18
18
|
return {
|
|
19
19
|
userid: { type: String },
|
|
@@ -22,11 +22,15 @@ export default class IABookActions extends LoanTokenPoller {
|
|
|
22
22
|
lendingStatus: { type: Object },
|
|
23
23
|
width: { type: Number },
|
|
24
24
|
bwbPurchaseUrl: { type: String },
|
|
25
|
-
lendingBarPostInit: {
|
|
25
|
+
lendingBarPostInit: {
|
|
26
|
+
type: Function,
|
|
27
|
+
attribute: false,
|
|
28
|
+
},
|
|
26
29
|
barType: { type: String },
|
|
27
30
|
sharedObserver: { attribute: false },
|
|
28
31
|
disableActionGroup: { type: Boolean },
|
|
29
32
|
modal: { Object },
|
|
33
|
+
tokenDelay: { type: Number },
|
|
30
34
|
};
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -43,6 +47,7 @@ export default class IABookActions extends LoanTokenPoller {
|
|
|
43
47
|
this.sharedObserver = undefined;
|
|
44
48
|
this.disableActionGroup = false;
|
|
45
49
|
this.modal = undefined;
|
|
50
|
+
this.tokenDelay = 120000; // 2 minutes
|
|
46
51
|
|
|
47
52
|
// private props
|
|
48
53
|
this.primaryActions = [];
|
|
@@ -157,26 +162,51 @@ export default class IABookActions extends LoanTokenPoller {
|
|
|
157
162
|
this.startBrowseTimer();
|
|
158
163
|
}
|
|
159
164
|
|
|
160
|
-
// enable access of borrowed/browsed books
|
|
161
|
-
if (this.borrowType) {
|
|
162
|
-
await this.enableBookAccess(this.identifier, this.borrowType);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
165
|
/**
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
166
|
+
* enable access of borrowed/browsed books
|
|
167
|
+
*
|
|
168
|
+
* LoanTokenPoller is a class that polls the loan token
|
|
169
|
+
* it takes 5 params
|
|
170
|
+
* 1. this.identifier
|
|
171
|
+
* 2. this.borrowType
|
|
172
|
+
* 3. successCallback - it used to
|
|
173
|
+
* - disptach lendingFlow::PostInit event
|
|
174
|
+
* - initialize bookreader using br.init()
|
|
175
|
+
* 4. errorCallback
|
|
176
|
+
* 5. tokenPollerDelay
|
|
169
177
|
*/
|
|
170
|
-
|
|
171
|
-
|
|
178
|
+
if (this.barType === 'action') {
|
|
179
|
+
if (this.tokenPoller) {
|
|
180
|
+
this.tokenPoller.disconnectedInterval();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const successCallback = () => {
|
|
184
|
+
this.lendingBarPostInit();
|
|
185
|
+
};
|
|
186
|
+
const errorCallback = eventObj => {
|
|
187
|
+
this.handleLendingActionError(eventObj);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
this.tokenPoller = new LoanTokenPoller(
|
|
191
|
+
this.identifier,
|
|
192
|
+
this.borrowType,
|
|
193
|
+
successCallback,
|
|
194
|
+
errorCallback,
|
|
195
|
+
this.tokenDelay // 1000 ms = 1 sec
|
|
196
|
+
);
|
|
197
|
+
}
|
|
172
198
|
}
|
|
173
199
|
|
|
174
200
|
render() {
|
|
175
201
|
if (this.barType === 'title') {
|
|
176
|
-
return html`<section class="lending-wrapper"
|
|
202
|
+
return html`<section class="lending-wrapper">
|
|
203
|
+
${this.bookTitleBar}
|
|
204
|
+
</section>`;
|
|
177
205
|
}
|
|
178
206
|
|
|
179
|
-
return html`<section class="lending-wrapper"
|
|
207
|
+
return html`<section class="lending-wrapper">
|
|
208
|
+
${this.bookActionBar}
|
|
209
|
+
</section>`;
|
|
180
210
|
}
|
|
181
211
|
|
|
182
212
|
get bookTitleBar() {
|
|
@@ -273,12 +303,18 @@ export default class IABookActions extends LoanTokenPoller {
|
|
|
273
303
|
});
|
|
274
304
|
|
|
275
305
|
if (action === 'create_token') {
|
|
306
|
+
const refreshButton = html`<button
|
|
307
|
+
style="background:none;font-size:inherit;border:0;padding:0;color:#0000ee;cursor:pointer;text-decoration:underline"
|
|
308
|
+
@click=${() => window.location.reload(true)}
|
|
309
|
+
>
|
|
310
|
+
refresh
|
|
311
|
+
</button>`;
|
|
312
|
+
|
|
276
313
|
modalConfig.closeOnBackdropClick = false;
|
|
277
314
|
modalConfig.showCloseButton = false;
|
|
278
315
|
modalConfig.message = html` Uh oh, something went wrong trying to access
|
|
279
316
|
this book.<br />
|
|
280
|
-
Please
|
|
281
|
-
try again or send us an email to
|
|
317
|
+
Please ${refreshButton} to try again or send us an email to
|
|
282
318
|
<a
|
|
283
319
|
href="mailto:info@archive.org?subject=Help: cannot access my borrowed book: ${this
|
|
284
320
|
.identifier}"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { expect } from '@open-wc/testing';
|
|
2
|
+
import Sinon from 'sinon';
|
|
3
|
+
|
|
4
|
+
import { LocalCache } from '@internetarchive/local-cache';
|
|
5
|
+
import { LoanTokenPoller } from '../../../src/core/services/loan-token-poller.js';
|
|
6
|
+
|
|
7
|
+
describe('Get Loan Token', () => {
|
|
8
|
+
it('get loan token for browsed books', async () => {
|
|
9
|
+
const localCacheStub = new LocalCache();
|
|
10
|
+
const localCacheGetSpy = Sinon.spy(localCacheStub, 'get');
|
|
11
|
+
|
|
12
|
+
const tokenPoller = new LoanTokenPoller(
|
|
13
|
+
'identifier1',
|
|
14
|
+
'browsed',
|
|
15
|
+
() => {
|
|
16
|
+
console.log('success callback is executed!');
|
|
17
|
+
},
|
|
18
|
+
() => {
|
|
19
|
+
console.log('error callback is executed!');
|
|
20
|
+
},
|
|
21
|
+
2000 // 2 minutes'
|
|
22
|
+
);
|
|
23
|
+
const successCallbackSpy = Sinon.stub(tokenPoller, 'successCallback');
|
|
24
|
+
successCallbackSpy();
|
|
25
|
+
expect(successCallbackSpy.callCount).to.equal(1);
|
|
26
|
+
|
|
27
|
+
localCacheGetSpy();
|
|
28
|
+
expect(localCacheGetSpy.callCount).to.equal(1);
|
|
29
|
+
|
|
30
|
+
expect(tokenPoller.localCache.namespace).to.equal('LocalCache');
|
|
31
|
+
expect(tokenPoller.localCache.get).to.be.a('function');
|
|
32
|
+
|
|
33
|
+
tokenPoller.disconnectedInterval(); // clear token poller interval
|
|
34
|
+
expect(tokenPoller.loanTokenInterval).to.equal(undefined);
|
|
35
|
+
|
|
36
|
+
tokenPoller.handleLoanTokenPoller(true);
|
|
37
|
+
expect(tokenPoller.errorCallback).to.be.a('function');
|
|
38
|
+
expect(tokenPoller.successCallback).have;
|
|
39
|
+
});
|
|
40
|
+
});
|