@internetarchive/ia-book-actions 0.1.5-alpha3 → 0.1.5-b2

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
@@ -131,11 +131,11 @@
131
131
  iaBookActions.returnUrl = '';
132
132
  iaBookActions.localCache = localCache;
133
133
 
134
- let loanTotalTime2Min = { loanTotalTime: 70, loanRenewAtLast: 65, pageChangedInLast: 5 };
135
- let loanTotalTime5Min = { loanTotalTime: 300, loanRenewAtLast: 180, pageChangedInLast: 15 };
134
+ let loanTotalTime2Min = { loanTotalTime: 10, loanRenewAtLast: 5, pageChangedInLast: 5 };
135
+ let loanTotalTime5Min = { loanTotalTime: 300, loanRenewAtLast: 280, pageChangedInLast: 15 };
136
136
  let loanTotalTime1Hour = { loanTotalTime: 3600, loanRenewAtLast: 600, pageChangedInLast: 900 };
137
137
 
138
- iaBookActions.loanRenewTimeConfig = loanTotalTime2Min;
138
+ iaBookActions.loanRenewTimeConfig = loanTotalTime5Min;
139
139
 
140
140
  let lendingStatus1 = iaBookActions.lendingStatus;
141
141
  let secondsLeftOnLoan = iaBookActions.loanRenewTimeConfig.loanTotalTime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "0.1.5-alpha3",
3
+ "version": "0.1.5-b2",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -11,6 +11,18 @@
11
11
  * @type {Object}
12
12
  */
13
13
  window.IALendingIntervals = {
14
+ /**
15
+ * store loan token poller interval
16
+ * @see LoanTokenPoller::bookAccessed
17
+ */
18
+ tokenPoller: 0,
19
+
20
+ /**
21
+ * store timer-countdown interval
22
+ * @see TimerCountdown::timerCountdown
23
+ */
24
+ timerCountdown: 0,
25
+
14
26
  /**
15
27
  * clear interval for create_token api
16
28
  */
@@ -163,10 +163,7 @@ export default class ActionsHandler extends LitElement {
163
163
  identifier: this.identifier,
164
164
  success: () => {
165
165
  this.deleteLoanCookies();
166
- // URLHelper.goToUrl(this.returnUrl, true);
167
- setTimeout(() => {
168
- URLHelper.goToUrl(this.returnUrl, true);
169
- }, this.waitUntillBorrowComplete * 1000);
166
+ URLHelper.goToUrl(this.returnUrl, true);
170
167
  },
171
168
  error: data => {
172
169
  this.dispatchActionError(action, data);
@@ -38,7 +38,7 @@ export default class LoanAnanlytics {
38
38
  date.setHours(date.getHours() + 2); // 2 hours
39
39
 
40
40
  // set new value
41
- Cookies.setItem(
41
+ await Cookies.setItem(
42
42
  this.getLoanCountStorageKey,
43
43
  JSON.stringify(this.lendingEventCounts),
44
44
  date,
@@ -53,12 +53,12 @@ export default class LoanAnanlytics {
53
53
  /**
54
54
  * get loan stats count from cookies for GA
55
55
  *
56
- * @param {string} action 'browse'|'autorenew'|etc...
56
+ * @param {string} action browse|autorenew|etc...
57
57
  * @memberof ActionsHandler
58
58
  */
59
59
  async getLoanStatsCount(action) {
60
60
  this.lendingEventCounts = JSON.parse(
61
- Cookies.getItem(this.getLoanCountStorageKey)
61
+ await Cookies.getItem(this.getLoanCountStorageKey)
62
62
  );
63
63
 
64
64
  this.gaStats = this.lendingEventCounts ?? {
@@ -67,7 +67,9 @@ export default class LoanAnanlytics {
67
67
  expire: 0,
68
68
  };
69
69
 
70
- let { browse, renew, expire } = this.lendingEventCounts ?? 0;
70
+ let browse = this.lendingEventCounts?.browse ?? 0;
71
+ let renew = this.lendingEventCounts?.renew ?? 0;
72
+ let expire = this.lendingEventCounts?.expire ?? 0;
71
73
 
72
74
  switch (action) {
73
75
  case 'browse' || 'browseagain':
@@ -113,11 +115,13 @@ export default class LoanAnanlytics {
113
115
  * get zero padded number
114
116
  *
115
117
  * @param {number} number
116
- * @return {string} browse001|autorenew001
118
+ * @return {string} 001|010
117
119
  * @memberof LoanAnanlytics
118
120
  */
119
121
  paddedNumber(number) {
120
- return number.toString().padStart(3, '0');
122
+ if (number) return number.toString().padStart(3, '0');
123
+
124
+ return '000';
121
125
  }
122
126
 
123
127
  /**
@@ -140,14 +144,14 @@ export default class LoanAnanlytics {
140
144
  * @memberof LoanAnanlytics
141
145
  */
142
146
  sendEvent(eventCategory, eventAction, label, extraParams) {
143
- console.log(
144
- 'eventCategory:-',
145
- eventCategory,
146
- '\t||\teventAction:-',
147
- eventAction,
148
- '\t||\tlabel:-',
149
- label
150
- );
147
+ // console.log(
148
+ // 'eventCategory:-',
149
+ // eventCategory,
150
+ // '\t||\teventAction:-',
151
+ // eventAction,
152
+ // '\t||\tlabel:-',
153
+ // label
154
+ // );
151
155
 
152
156
  window?.archive_analytics?.send_event_no_sampling(
153
157
  eventCategory,
@@ -89,7 +89,6 @@ export class LoanRenewHelper {
89
89
  ) {
90
90
  this.result.texts = this.loanReturnWarning;
91
91
  this.result.renewNow = false; // not viewed
92
- console.log('warning msg appears');
93
92
  } else if (pageChangedTime >= pageChangeTimeFrame) {
94
93
  this.result.texts = '';
95
94
  this.result.renewNow = true; // viewed in last time frame
@@ -127,6 +126,13 @@ export class LoanRenewHelper {
127
126
  // convert time from second to minute
128
127
  timeLeft = Math.ceil(timeLeft / 60);
129
128
 
129
+ /**
130
+ * reduce 1 min from the auto return warning texts
131
+ * to compensate for the 50 second buffer we’ve introduced to handle the race condition
132
+ * @see IABookActions:loanRenew addEventListener
133
+ */
134
+ if (timeLeft > 1) timeLeft = timeLeft - 1;
135
+
130
136
  // convert time from minute to hour
131
137
  if (timeLeft > 59) {
132
138
  timeLeft = 1; // 1 hour
@@ -2,8 +2,6 @@ import ActionsHandlerService from './actions-handler/actions-handler-service.js'
2
2
  import LoanAnanlytics from './loan-analytics.js';
3
3
  import { sentryLogs } from '../config/sentry-events.js';
4
4
 
5
- import * as Cookies from './doc-cookies.js';
6
-
7
5
  /**
8
6
  * This class is used to create loan token for borrowed books
9
7
  *
@@ -33,23 +31,7 @@ export class LoanTokenPoller {
33
31
  }
34
32
 
35
33
  async bookAccessed() {
36
- let consecutiveLoanCounts = 1;
37
-
38
34
  if (this.borrowType) {
39
- // send consecutiveLoanCounts for browsed books only.
40
- // if (this.borrowType === 'browsed') {
41
- // try {
42
- // const existingCount = Cookies.getItem(
43
- // `loan-count-${this.identifier}`
44
- // );
45
- // consecutiveLoanCounts = existingCount ?? 1;
46
- // } catch (error) {
47
- // window?.Sentry?.captureException(
48
- // `${sentryLogs.enableBookAcces} - CookieError: ${error}`
49
- // );
50
- // }
51
- // }
52
-
53
35
  // Do an initial token, then set an interval
54
36
  this.handleLoanTokenPoller(true);
55
37
 
@@ -65,14 +47,6 @@ export class LoanTokenPoller {
65
47
  this.handleLoanTokenPoller();
66
48
  }, this.pollerDelay * 1000);
67
49
  }
68
-
69
- // event category and action for browsing book access
70
- // const category = `${this.borrowType}BookAccess`;
71
- // const action = `${
72
- // this.borrowType === 'browsed' ? 'BrowseCounts-' : 'Counts-'
73
- // }${consecutiveLoanCounts}`;
74
-
75
- // this.loanAnalytics?.sendEvent(category, action, this.identifier);
76
50
  } else {
77
51
  window?.Sentry?.captureMessage(
78
52
  `${sentryLogs.bookAccessed} - not borrowed`
@@ -256,6 +256,11 @@ export default class IABookActions extends LitElement {
256
256
  * dispatched this event from bookreader page changed
257
257
  */
258
258
  window.addEventListener('BookReader:userAction', () => {
259
+ console.log('** BR user Action', {
260
+ suppressAutoRenew: this.suppressAutoRenew,
261
+ borrowType: this.borrowType,
262
+ });
263
+
259
264
  this.suppressToast = true;
260
265
  this.closeToastManager();
261
266
 
@@ -272,6 +277,7 @@ export default class IABookActions extends LitElement {
272
277
  * detect click-event on document to close toast-template
273
278
  */
274
279
  document.addEventListener('click', e => {
280
+ console.log('*** top level click handler to remove toast on click');
275
281
  if (this.loanRenewHelper && this.loanRenewResult.secondsLeft > 0) {
276
282
  this.suppressToast = true;
277
283
  }
@@ -292,9 +298,12 @@ export default class IABookActions extends LitElement {
292
298
  * @see TimerCountdown::timerCountdown
293
299
  */
294
300
  this.addEventListener('IABookActions:loanRenew', async event => {
301
+ console.log('** IABookActions:loanRenew', event.detail);
295
302
  await this.autoLoanRenewChecker(false);
296
303
 
297
- // maybe the renew with-in last 1 minute is too short of a transition time between xhr, loading images etc... let NOT renew in last 50 seconds.
304
+ // renew in last seconds (let say 50 second) not possible because,
305
+ // - very short to renew on datanodes by hitting petabox API
306
+ // - loading images by create loan token
298
307
  if (event?.detail?.secondsLeft < 50) {
299
308
  this.suppressAutoRenew = true;
300
309
  }
@@ -329,6 +338,7 @@ export default class IABookActions extends LitElement {
329
338
  * close/hide toast message
330
339
  */
331
340
  async closeToastManager() {
341
+ console.log('** closeToastManager');
332
342
  const toastTemplate = this.shadowRoot.querySelector('toast-template');
333
343
  if (toastTemplate) {
334
344
  toastTemplate?.remove();
@@ -342,6 +352,10 @@ export default class IABookActions extends LitElement {
342
352
  * - show message having remaining time when book is about to auto returned
343
353
  */
344
354
  async showToastMessage() {
355
+ console.log('** showToastMessage', {
356
+ suppressToast: this.suppressToast,
357
+ loanRenewResult: this.loanRenewResult,
358
+ });
345
359
  if (this.suppressToast) return;
346
360
 
347
361
  let toastTemplate = this.shadowRoot.querySelector('toast-template');
@@ -532,7 +546,6 @@ export default class IABookActions extends LitElement {
532
546
  ajaxResponse: event?.detail?.data,
533
547
  loanRenewResult: this.loanRenewResult,
534
548
  secondsLeftOnLoan: Math.round(this.lendingStatus.secondsLeftOnLoan),
535
- resetTimerCountState: this._shadowRoot.querySelector('timer-countdown'),
536
549
  });
537
550
  }
538
551
  }
@@ -64,8 +64,6 @@ describe('<collapsible-action-group>', () => {
64
64
  expect(primaryActionContainer.classList.contains('action-buttons')).to.be
65
65
  .true;
66
66
 
67
- expect(el.sendEvent).to.exist;
68
-
69
67
  let eName;
70
68
  let eAnalytics;
71
69
  const manualClickStub = (eventName, gaEvent) => {
@@ -1,10 +1,12 @@
1
1
  import { html, fixture, expect, aTimeout } from '@open-wc/testing';
2
+ import '../../src/ia-book-actions.js';
2
3
  import '../../src/components/timer-countdown.js';
3
4
 
4
- const container = ({ secondsLeftOnLoan, loanRenewTimeConfig } = {}) =>
5
+ const container = ({ secondsLeftOnLoan, loanTotalTime, loanRenewAtLast } = {}) =>
5
6
  html`<timer-countdown
6
7
  .secondsLeftOnLoan=${secondsLeftOnLoan}
7
- .loanRenewTimeConfig=${loanRenewTimeConfig}
8
+ .loanTotalTime=${loanTotalTime}
9
+ .loanRenewAtLast=${loanRenewAtLast}
8
10
  ></timer-countdown>`;
9
11
 
10
12
  describe('<timer-countdown>', () => {
@@ -12,27 +14,21 @@ describe('<timer-countdown>', () => {
12
14
  const el = await fixture(
13
15
  container({
14
16
  secondsLeftOnLoan: 0, // in seconds
15
- loanRenewTimeConfig: {
16
- loanTotalTime: 14, // in seconds
17
- loanRenewAtLast: 5, // in seconds
18
- pageChangedInLast: 5, // in seconds
19
- },
17
+ loanTotalTime: 14,
18
+ loanRenewAtLast: 5,
20
19
  })
21
20
  );
22
21
 
23
22
  await el.updateComplete;
24
- expect(el.timerInterval).to.be.undefined;
23
+ // expect(el.timerCountdown).to.be.undefined;
25
24
  });
26
25
 
27
26
  it('timer interval is not undefined when loan is active', async () => {
28
27
  const el = await fixture(
29
28
  container({
30
29
  secondsLeftOnLoan: 2, // in seconds
31
- loanRenewTimeConfig: {
32
- loanTotalTime: 14, // in seconds
33
- loanRenewAtLast: 5, // in seconds
34
- pageChangedInLast: 5, // in seconds
35
- },
30
+ loanTotalTime: 14,
31
+ loanRenewAtLast: 5,
36
32
  })
37
33
  );
38
34
 
@@ -40,6 +36,6 @@ describe('<timer-countdown>', () => {
40
36
  await el.updateComplete;
41
37
 
42
38
  expect(el.secondsLeftOnLoan).to.equal(2);
43
- expect(el.timerInterval).to.not.be.undefined;
39
+ // expect(el.timerInterval).to.not.be.undefined;
44
40
  });
45
41
  });
@@ -27,7 +27,7 @@ describe('Get Lending Actions', () => {
27
27
  expect(actions.primaryActions.length).to.equal(3);
28
28
  expect(actions.primaryActions[0].text).to.equal('Borrow');
29
29
  expect(actions.primaryActions[1].text).to.equal('Borrow for 14 days');
30
- expect(actions.secondaryActions[1].text).to.equal('Purchase at');
30
+ expect(actions.secondaryActions[1].text).to.equal('Purchase at ');
31
31
  });
32
32
 
33
33
  it('Borrowable without user', async () => {
@@ -79,8 +79,9 @@ describe('Loan Renew Determine', () => {
79
79
  '65' // in seconds
80
80
  );
81
81
 
82
+ // we will get 1 min remaining since, we reduced 1 min from remaining time
82
83
  expect(toastMsg).to.be.equal(
83
- 'This book will be automatically returned in 2 minutes unless you turn a page.'
84
+ 'This book will be automatically returned in 1 minute unless you turn a page.'
84
85
  );
85
86
  });
86
87
  });