@internetarchive/ia-book-actions 0.1.2 → 0.1.3-alpha2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "0.1.2",
3
+ "version": "0.1.3-alpha2",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -31,12 +31,6 @@ export default class TimerCountdown extends LitElement {
31
31
  */
32
32
  this.loanRenewAtLast = 0;
33
33
 
34
- /**
35
- * setInterval executed interval
36
- * @type {number}
37
- */
38
- this.timerInterval = undefined;
39
-
40
34
  /**
41
35
  * delay seconds in setInterval function
42
36
  * @type {number}
@@ -45,12 +39,13 @@ export default class TimerCountdown extends LitElement {
45
39
  }
46
40
 
47
41
  disconnectedCallback() {
48
- clearInterval(this.timerInterval);
42
+ window?.IALendingIntervals?.clearTimerCountdown();
49
43
  }
50
44
 
51
45
  updated(changed) {
52
46
  if (changed.has('secondsLeftOnLoan') && this.secondsLeftOnLoan > 0) {
53
- clearInterval(this.timerInterval);
47
+ this.disconnectedCallback();
48
+
54
49
  this.timerCountdown();
55
50
  }
56
51
  }
@@ -59,10 +54,21 @@ export default class TimerCountdown extends LitElement {
59
54
  // - let just execute setInterval in every 1 minute
60
55
  this.timerExecutionSeconds = 60;
61
56
 
62
- this.timerInterval = setInterval(() => {
57
+ /**
58
+ * set interval in window object
59
+ * @see ia-lending-intervals.js
60
+ */
61
+ window.IALendingIntervals.timerCountdown = setInterval(() => {
63
62
  this.secondsLeftOnLoan -= this.timerExecutionSeconds;
64
63
  const secondsLeft = Math.round(this.secondsLeftOnLoan);
65
64
 
65
+ console.log(
66
+ 'timeLeftInSec',
67
+ secondsLeft,
68
+ ' ||| timeLeftInMin',
69
+ Math.ceil(secondsLeft / 60)
70
+ );
71
+
66
72
  /**
67
73
  * execute from last 10th minute to 0th minute
68
74
  * - 10th - to check if user has viewed
@@ -84,7 +90,7 @@ export default class TimerCountdown extends LitElement {
84
90
 
85
91
  // clear interval
86
92
  if (secondsLeft <= 60) {
87
- clearInterval(this.timerInterval);
93
+ this.disconnectedCallback();
88
94
  window?.Sentry?.captureMessage(sentryLogs.clearOneHourTimer);
89
95
  }
90
96
  }, this.timerExecutionSeconds * 1000);
@@ -111,8 +117,8 @@ export default class TimerCountdown extends LitElement {
111
117
  render() {
112
118
  return html`
113
119
  <svg
114
- width="16"
115
- height="16"
120
+ width="14"
121
+ height="14"
116
122
  viewBox="0 0 100 100"
117
123
  xmlns="http://www.w3.org/2000/svg"
118
124
  >
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Collection of methods for managing intervals for lending system
3
+ *
4
+ * There are mainly two intervals being used
5
+ * - tokenPoller :- used to create_token for borrowed book
6
+ * - timerCountdown :- reponsible for loan-auto-renew and auto returned warning message
7
+ *
8
+ * @see TimerCountdown::timerCountdown function
9
+ * @see LoanTokenPoller::bookAccessed function
10
+ *
11
+ * @type {Object}
12
+ */
13
+ window.IALendingIntervals = {
14
+ /**
15
+ * clear interval for create_token api
16
+ */
17
+ clearTokenPoller: () => {
18
+ window.clearInterval(window?.IALendingIntervals?.tokenPoller);
19
+ },
20
+
21
+ /**
22
+ * clear interval for graphic timer for one-hour loan renew
23
+ */
24
+ clearTimerCountdown: () => {
25
+ window.clearInterval(window.IALendingIntervals.timerCountdown);
26
+ },
27
+
28
+ /**
29
+ * clear all intervals being used acros lending system
30
+ */
31
+ clearAll: () => {
32
+ window.clearInterval(window?.IALendingIntervals?.tokenPoller);
33
+ window.clearInterval(window?.IALendingIntervals?.timerCountdown);
34
+ },
35
+ };
@@ -13,7 +13,8 @@ export class LoanRenewHelper {
13
13
  this.loanRenewTimeConfig = loanRenewTimeConfig;
14
14
 
15
15
  // messages for auto return machenism
16
- this.loanRenewMessage = 'This book has been renewed for 1 hour.';
16
+ this.loanRenewMessage =
17
+ 'This book has been renewed for #time #unitsOfTime.';
17
18
  this.loanReturnWarning =
18
19
  'This book will be automatically returned in #time #unitsOfTime unless you turn a page.';
19
20
 
@@ -117,7 +118,7 @@ export class LoanRenewHelper {
117
118
  * @returns {String} // texts will be appear in toast template
118
119
  */
119
120
  getMessageTexts(texts, secondsLeft) {
120
- const unitOfTime = 'minute';
121
+ let unitOfTime = 'minute';
121
122
 
122
123
  let toastTexts = texts;
123
124
  let timeLeft = secondsLeft;
@@ -125,6 +126,12 @@ export class LoanRenewHelper {
125
126
  // convert time from second to minute
126
127
  timeLeft = Math.ceil(timeLeft / 60);
127
128
 
129
+ // convert time from minute to hour
130
+ if (timeLeft > 59) {
131
+ timeLeft = 1; // 1 hour
132
+ unitOfTime = 'hour';
133
+ }
134
+
128
135
  // replace #time variable with remaining time
129
136
  toastTexts = toastTexts?.replace(/#time/, timeLeft);
130
137
 
@@ -20,17 +20,8 @@ export class LoanTokenPoller {
20
20
  this.bookAccessed();
21
21
  }
22
22
 
23
- disconnectedInterval() {
24
- clearInterval(this.loanTokenInterval);
25
- this.loanTokenInterval = undefined;
26
-
27
- // temporary disabling sentry notice
28
- // as message is informational, not critical nor an error.
29
- // also, as of 11/28/2022, JS build maps are not working properly on petabox
30
- // and as a result, this comment is not properly grouped.
31
- // if (window.Sentry) {
32
- // window?.Sentry?.captureMessage('loan token interval cleared');
33
- // }
23
+ disconnectedCallback() {
24
+ window?.IALendingIntervals?.clearTokenPoller();
34
25
  }
35
26
 
36
27
  async bookAccessed() {
@@ -59,7 +50,11 @@ export class LoanTokenPoller {
59
50
  // - we don't want to fetch token on interval
60
51
  // - the initial token is enough to set cookies for reading book and readaloud features
61
52
  if (this.borrowType !== 'adminBorrowed') {
62
- this.loanTokenInterval = setInterval(() => {
53
+ /**
54
+ * set interval in window object
55
+ * @see ia-lending-intervals.js
56
+ */
57
+ window.IALendingIntervals.tokenPoller = setInterval(() => {
63
58
  this.handleLoanTokenPoller();
64
59
  }, this.pollerDelay * 1000);
65
60
  }
@@ -77,7 +72,7 @@ export class LoanTokenPoller {
77
72
  );
78
73
 
79
74
  // if book is not browsed, just clear token polling interval
80
- this.disconnectedInterval(); // stop token fetch api
75
+ this.disconnectedCallback();
81
76
  }
82
77
  }
83
78
 
@@ -95,7 +90,6 @@ export class LoanTokenPoller {
95
90
  identifier: this.identifier,
96
91
  action,
97
92
  error: data => {
98
- this.disconnectedInterval(); // stop token fetch api
99
93
  this.errorCallback({ detail: { action, data } });
100
94
 
101
95
  // send error to Sentry
@@ -11,6 +11,7 @@ import './components/book-title-bar.js';
11
11
  import './components/text-group.js';
12
12
  import './components/info-icon.js';
13
13
  import './components/timer-countdown.js';
14
+ import './core/config/ia-lending-intervals.js';
14
15
 
15
16
  import { GetLendingActions } from './core/services/get-lending-actions.js';
16
17
  import { mobileContainerWidth } from './core/config/constants.js';
@@ -102,7 +103,9 @@ export default class IABookActions extends LitElement {
102
103
  }
103
104
 
104
105
  disconnectedCallback() {
105
- this.tokenPoller?.disconnectedInterval();
106
+ // clear all intervals for lending system
107
+ window?.IALendingIntervals?.clearAll();
108
+
106
109
  window?.Sentry?.captureMessage(sentryLogs.disconnectedCallback);
107
110
  this.disconnectResizeObserver();
108
111
  }
@@ -197,7 +200,8 @@ export default class IABookActions extends LitElement {
197
200
  if (!this.tokenPoller) {
198
201
  window?.Sentry?.captureMessage(sentryLogs.bookWasExpired);
199
202
  }
200
- this.tokenPoller?.disconnectedInterval();
203
+ window?.IALendingIntervals?.clearAll();
204
+
201
205
  /** Global event - always fire */
202
206
  this.dispatchEvent(
203
207
  new Event(events.browseExpired, {
@@ -336,7 +340,11 @@ export default class IABookActions extends LitElement {
336
340
 
337
341
  // if secondsLeft < 60, consider it 1 minute
338
342
  let { secondsLeft } = this.loanRenewResult;
339
- secondsLeft = secondsLeft > 60 ? secondsLeft : 60;
343
+ if (secondsLeft === undefined) {
344
+ secondsLeft = this.lendingStatus.secondsLeftOnLoan;
345
+ } else {
346
+ secondsLeft = secondsLeft > 60 ? secondsLeft : 60;
347
+ }
340
348
 
341
349
  const config = new ToastConfig();
342
350
  config.dismisOnClick = true;
@@ -385,7 +393,7 @@ export default class IABookActions extends LitElement {
385
393
  * Execute when loan is expired
386
394
  */
387
395
  async browseHasExpired() {
388
- this.tokenPoller?.disconnectedInterval();
396
+ window?.IALendingIntervals?.clearAll();
389
397
 
390
398
  const currStatus = { ...this.lendingStatus, browsingExpired: true };
391
399
  this.lendingStatus = currStatus;
@@ -495,11 +503,11 @@ export default class IABookActions extends LitElement {
495
503
  */
496
504
  async handleLoanAutoRenewed() {
497
505
  if (this.loanRenewResult.renewNow) {
498
- this.tokenPoller?.disconnectedInterval();
506
+ window?.IALendingIntervals?.clearAll();
499
507
 
500
508
  this.suppressToast = false;
501
- await this.showToastMessage();
502
509
  await this.browseHasRenew();
510
+ await this.showToastMessage();
503
511
  await this.resetTimerCountState();
504
512
 
505
513
  window?.Sentry?.captureMessage(`${sentryLogs.bookHasRenewed}`);
@@ -519,10 +527,6 @@ export default class IABookActions extends LitElement {
519
527
  * @see LoanTokenPoller
520
528
  */
521
529
  startLoanTokenPoller() {
522
- if (this.tokenPoller) {
523
- window?.Sentry?.captureMessage(sentryLogs.clearTokenPoller);
524
- this.tokenPoller?.disconnectedInterval();
525
- }
526
530
  const successCallback = () => {
527
531
  this.lendingBarPostInit();
528
532
  };
@@ -572,6 +576,9 @@ export default class IABookActions extends LitElement {
572
576
  // toggle activity loader
573
577
  this.handleToggleActionGroup();
574
578
 
579
+ // clear all intervals for lending system when error occured
580
+ window?.IALendingIntervals?.clearAll();
581
+
575
582
  const action = event?.detail?.action;
576
583
  const errorMsg = event?.detail?.data?.error;
577
584
 
@@ -581,8 +588,6 @@ export default class IABookActions extends LitElement {
581
588
  // - clear tokenPoller interval
582
589
  // - set user_has_browsed to `false`
583
590
  if (action === 'create_token') {
584
- this.tokenPoller?.disconnectedInterval();
585
-
586
591
  const currStatus = {
587
592
  ...this.lendingStatus,
588
593
  user_has_browsed: false,
@@ -1,146 +0,0 @@
1
- <!doctype html>
2
- <html lang="en-GB">
3
-
4
- <head>
5
- <meta charset="utf-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
7
- <style>
8
- html {
9
- font-size: 10px;
10
- /* This is to match petabox's base font size */
11
- }
12
- body {
13
- margin: 0;
14
- text-align: center;
15
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
16
- }
17
- #demo {
18
- height: 50px;
19
- }
20
- ia-book-actions {
21
- --white: #fff;
22
- --black: #000;
23
- --primaryBGColor: var(--black);
24
- --secondaryBGColor: #222;
25
- --tertiaryBGColor: #333;
26
- --primaryTextColor: var(--white);
27
- --primaryCTAFill: #194880;
28
- --primaryCTABorder: #c5d1df;
29
- --secondaryCTAFill: #333;
30
- --secondaryCTABorder: #999;
31
- --secondaryCTAFillRGB: 51, 51, 51;
32
- --primaryErrorCTAFill: #e51c26;
33
- --primaryErrorCTABorder: #f8c6c8;
34
- --primaryCTAFillRGB: 25, 72, 128;
35
- --primaryErrorCTAFillRGB: 229, 28, 38;
36
- --primaryDisableCTAFill: #767676;
37
- }
38
-
39
- fieldset {
40
- width: fit-content;
41
- margin-top: 50px;
42
- }
43
- fieldset legend {
44
- text-align: left;
45
- font-size: 12px;
46
- }
47
- td {
48
- color: white;
49
- font-size: 14px;
50
- border-radius: 5%;
51
- display: table-cell;
52
- text-align: initial;
53
- margin: 5px 0;
54
- width: max-content;
55
- display: block;
56
- }
57
- label {
58
- padding: 10px;
59
- display: block;
60
- cursor: pointer;
61
- margin: 2px;
62
- background: #4e545a;
63
- border-radius: 10px;
64
- }
65
- input[type="radio"], input[type="checkbox"] {
66
- margin-top: 0;
67
- vertical-align: middle;
68
- }
69
-
70
- .initial td {
71
- float: left;
72
- margin: 2px;
73
- }
74
-
75
- body.modal-manager-open {
76
- overflow: hidden;
77
- }
78
-
79
- modal-manager[mode='closed'] {
80
- display: none;
81
- }
82
- </style>
83
- </head>
84
-
85
- <body>
86
- <ia-bookreader class="focus-on-child-only" signedin="" fullscreen="">
87
- <div slot="header">
88
- <ia-book-actions></ia-book-actions>
89
- </div>
90
- <div slot="main">
91
- <div id="BookReader"></div>
92
- </div>
93
- </ia-bookreader>
94
-
95
-
96
- <script type="module">
97
- /* eslint-disable */
98
- import '@internetarchive/bookreader';
99
- import '@internetarchive/bookreader/BookReader/jquery-1.10.1.js';
100
- import '@internetarchive/bookreader/BookReader/BookReader.js';
101
- import '../src/ia-book-actions.js';
102
- import {
103
- defaultLendingStatus,
104
- canBrowseAndBorrow,
105
- } from '../src/assets/data/lending-get-status-service.js';
106
- import { ModalConfig } from '@internetarchive/modal-manager';
107
-
108
- const userid = '@neeraj-archive';
109
- const identifier = 'naturalhistoryof00unse_4111';
110
- let bwbPurchaseUrl = 'https://www.betterworldbooks.com/product/detail/cambridge-ancient-hist-v04-0521044863';
111
-
112
- let iaBookActions = document.querySelector('ia-book-actions');
113
-
114
- // for debugging
115
- window.iaBookActions = iaBookActions;
116
-
117
- const modalConfig = new ModalConfig();
118
- modalConfig.headerColor = '#d9534f';
119
-
120
- let lendingBarPostInit = function lendingBarPostInit() {
121
- setTimeout(function() {
122
- console.log('executed', 'br.init()');
123
- }, 100);
124
- }
125
-
126
- // set defaultLendingStatus for unavailable (without borrowables) book
127
- iaBookActions.userid = userid;
128
- iaBookActions.identifier = identifier;
129
- iaBookActions.bookTitle = 'Contemporary Black biography. Volume 39 : profiles from the interContemporary Black biography. Volume 39';
130
- iaBookActions.lendingStatus = canBrowseAndBorrow;
131
- iaBookActions.bwbPurchaseUrl = '';
132
- iaBookActions.modalConfig = modalConfig;
133
- iaBookActions.lendingBarPostInit = lendingBarPostInit;
134
- iaBookActions.tokenDelay = 2000; // 2 seconds
135
- iaBookActions.returnUrl = 'https://openlibrary.org';
136
-
137
- let lendingStatus1 = iaBookActions.lendingStatus;
138
-
139
- const manifest = await fetch('https://ia801302.us.archive.org/BookReader/BookReaderJSIA.php?id=goody&itemPath=/29/items/goody&server=ia801302.us.archive.org&format=jsonp&subPrefix=goody&requestUri=/details/goody/mode/1up%3Fview%3Dtheater%26ui%3Dembed%26wrapper%3Dfalse');
140
-
141
- console.log('manifest ****', manifest).then(res => res.json());
142
- </script>
143
-
144
- </div>
145
- </body>
146
- </html>