@internetarchive/ia-book-actions 0.0.29-alpha1 → 0.0.29-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/demo/index.html CHANGED
@@ -87,7 +87,6 @@
87
87
 
88
88
  <script type="module">
89
89
  /* eslint-disable */
90
-
91
90
  import '../src/ia-book-actions.js';
92
91
  import {
93
92
  defaultLendingStatus,
@@ -127,33 +126,16 @@
127
126
  iaBookActions.lendingBarPostInit = lendingBarPostInit;
128
127
  iaBookActions.tokenDelay = 2000; // 2 seconds
129
128
  iaBookActions.returnUrl = 'https://openlibrary.org';
130
- // iaBookActions.localCache = localCache;
129
+ iaBookActions.localCache = localCache;
131
130
  iaBookActions.autoRenewTimeConfig = {
132
131
  totalTime: 60, // 60 second = 1 min
133
- autoRenewCheckerAtLast: 10, // totalTime - 10th minute
134
- autoRenewVisitedInLast: 15, // within last 15 second/minute
132
+ autoCheckAt: 55, // totalTime - 10th minute
133
+ FlippedInLast: 15, // within last 15 second/minute
135
134
  };
136
135
 
137
136
  let lendingStatus1 = iaBookActions.lendingStatus;
138
137
  let secondsLeftOnLoan = 60;
139
138
 
140
- document.querySelector('#flip-page').addEventListener('click', async (e) => {
141
- try {
142
- // set pageFlipTime time in localStorage
143
- await localCache.set({
144
- key: `${identifier}-pageFlipTime`,
145
- value: new Date(), // current time
146
- })
147
-
148
- // dispatch event to say book page has flipped
149
- document.querySelector("ia-book-actions").dispatchEvent(
150
- new CustomEvent("bookPageFlip", {
151
- detail: { bookPageChange: true },
152
- })
153
- );
154
- } catch (error) {}
155
- });
156
-
157
139
  document.querySelectorAll('.titleBar input[type=checkbox]').forEach((item) => {
158
140
  item.addEventListener('click', (e) => {
159
141
  if (e.target.checked) {
@@ -244,6 +226,7 @@
244
226
  await localCache.set({
245
227
  key: `${identifier}-loanTime`,
246
228
  value: new Date(), // current time
229
+ ttl: parseInt(iaBookActions.autoRenewTimeConfig.totalTime),
247
230
  })
248
231
 
249
232
  await localCache.delete(`${identifier}-pageFlipTime`);
@@ -330,9 +313,6 @@
330
313
  <td class="errorEnable"><label><input type="checkbox" name="errorEnable" value="errorEnable" />Do you want to see error response?</label></td>
331
314
  <td class="autoRenew"><label><input type="checkbox" name="autoRenew" value="autoRenew" />Do you want to auto-renew 1 hour</label></td>
332
315
  </tr>
333
- <tr>
334
- <td><button id="flip-page">Flip page</button></td>
335
- </tr>
336
316
  <tr>
337
317
  <td class="userState">
338
318
  <label><input type="checkbox" name="user" value="isAdmin" />isAdmin</label>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "0.0.29-alpha1",
3
+ "version": "0.0.29-alpha2",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -29,6 +29,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
29
29
  disabled: { type: Boolean },
30
30
  returnUrl: { type: String },
31
31
  browseAgainNow: { type: Boolean },
32
+ autoRenewTimeConfig: { type: Object },
32
33
  };
33
34
  }
34
35
 
@@ -49,6 +50,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
49
50
  this.disabled = false;
50
51
  this.returnUrl = '';
51
52
  this.browseAgainNow = false;
53
+ this.autoRenewTimeConfig = {};
52
54
  }
53
55
 
54
56
  updated(changed) {
@@ -4,7 +4,7 @@ export default class TimerCountdown extends LitElement {
4
4
  static get properties() {
5
5
  return {
6
6
  time: { type: Number },
7
- autoRenewCheckerAtLast: { type: Number },
7
+ autoCheckAt: { type: Number },
8
8
  resetTimerCountdown: { type: Boolean },
9
9
  };
10
10
  }
@@ -12,7 +12,7 @@ export default class TimerCountdown extends LitElement {
12
12
  constructor() {
13
13
  super();
14
14
  this.time = 60;
15
- this.autoRenewCheckerAtLast = 0;
15
+ this.autoCheckAt = 0;
16
16
  this.timerInterval = undefined;
17
17
  this.resetTimerCountdown = false;
18
18
  }
@@ -37,11 +37,12 @@ export default class TimerCountdown extends LitElement {
37
37
  this.time -= 1;
38
38
 
39
39
  // execute 50th minute check
40
- if (this.time === this.autoRenewCheckerAtLast) {
40
+ if (this.time === this.autoCheckAt) {
41
41
  this.dispatchEvent(
42
- new CustomEvent('autoReturnWarning', {
42
+ new CustomEvent('autoRenewAttempt', {
43
43
  detail: {
44
- remainingT: this.time
44
+ remainingT: this.time,
45
+ bookPageChange: false,
45
46
  },
46
47
  bubbles: true,
47
48
  composed: true,
@@ -19,10 +19,10 @@ export default class ActionsHandler extends LitElement {
19
19
  this.identifier = '';
20
20
  this.ajaxTimeout = 6000;
21
21
  this.returnUrl = '';
22
+ this.autoRenewTimeConfig = {};
22
23
 
23
24
  this.localCache = new LocalCache({
24
25
  namespace: '1HourLoanStorage',
25
- defaultTTL: 1 * 30, // 0.5 minute
26
26
  });
27
27
 
28
28
  this.bindEvents();
@@ -37,8 +37,6 @@ export default class ActionsHandler extends LitElement {
37
37
  }
38
38
 
39
39
  async bindEvents() {
40
- // console.log(await this.localCache.get('loanTime'));
41
-
42
40
  this.addEventListener('browseBook', ({ detail }) => {
43
41
  this.handleBrowseIt();
44
42
  this.setConsecutiveLoanCounts();
@@ -54,9 +52,8 @@ export default class ActionsHandler extends LitElement {
54
52
  });
55
53
 
56
54
  this.addEventListener('autoBrowseBook', ({ detail }) => {
57
- console.log('book has be renewed for you. thank you!!!');
55
+ console.log('auto renew handlerExecuted!!');
58
56
  this.handleAutoBrowseIt();
59
- // this.setConsecutiveLoanCounts();
60
57
  const { category, action } = detail.event;
61
58
  this.sendEvent(category, action);
62
59
  });
@@ -320,6 +317,7 @@ export default class ActionsHandler extends LitElement {
320
317
  await this.localCache.set({
321
318
  key: `${this.identifier}-loanTime`,
322
319
  value: new Date(), // current time
320
+ ttl: parseInt(this.autoRenewTimeConfig.totalTime),
323
321
  })
324
322
 
325
323
  await this.localCache.delete(`${this.identifier}-pageFlipTime`);
@@ -1,97 +1,110 @@
1
- import { nothing } from 'lit';
2
-
3
1
  import ActionsHandlerService from './actions-handler/actions-handler-service.js';
4
- import * as Cookies from './doc-cookies.js';
5
2
 
6
3
  /**
7
- * This class is used to create loan token for borrowed books
4
+ * This class is used to determine if use is eligible for auto renew loan.
8
5
  *
9
6
  * ActionsHandlerService is a function being used to execute
10
7
  */
11
8
  export class OneHourAutoRenew {
12
- constructor(pageClick, identifier, localCache, autoRenewTimeConfig) {
9
+ constructor(pageClick, identifier, localCache, autoRenewTimeConfig, userHasBrowsed) {
13
10
  this.pageClick = pageClick;
14
11
  this.identifier = identifier;
15
12
  this.localCache = localCache;
16
- this.autoRenewTimeConfig = autoRenewTimeConfig; // callback function to be called after loan token is created
17
-
18
- this.autoReturnMessage = 'This book will be automatically returned in 15 seconds unless you turn a page.';
19
- this.autoRenewMessage = 'This book has been renewed for another hour.';
20
-
13
+ this.autoRenewTimeConfig = autoRenewTimeConfig;
14
+ this.userHasBrowsed = userHasBrowsed;
21
15
 
16
+ // private props
22
17
  this.resultRes = {
23
- toastTexts: '',
18
+ toastTexts: null,
24
19
  hideToast: true,
20
+ renewNow: false,
25
21
  };
26
22
 
27
- return this.dd();
23
+ // messages for auto return machenism
24
+ this.autoRenewMessage = 'This book has been renewed for another hour.';
25
+ this.autoReturnMessage = 'This book has been auto-returned due to inactivity.';
26
+ this.autoReturnWarning = 'This book will be auto-returned in 10 minutes unless you turn a page.';
27
+
28
+ return this.handleBookAutoRenew();
28
29
  }
29
30
 
30
- async dd() {
31
+ async handleBookAutoRenew() {
31
32
  try {
32
- const currentDate = new Date();
33
-
34
- const {
35
- totalTime, // 60
36
- autoRenewCheckerAtLast, // 50
37
- autoRenewVisitedInLast, // 15
38
- } = this.autoRenewTimeConfig;
39
-
40
- const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
41
- const lastPageFlipTime = await this.localCache.get(`${this.identifier}-pageFlipTime`);
42
-
43
- const lastFlipTimeFrame = await this.changeTime(
44
- currentDate,
45
- autoRenewVisitedInLast,
46
- 'sub'
47
- ); // 15 seconds
48
-
49
- console.log(lastPageFlipTime, lastFlipTimeFrame)
50
-
51
33
  // if page is not flipped in last 15 minutes,
52
34
  // instantaly renew it if user viewed new page in last 10 minutes
53
- if (this.pageClick === true) {
54
- const lastTimeFrame = await this.changeTime(
55
- loanTime,
56
- totalTime - autoRenewCheckerAtLast,
57
- 'add'
58
- ); // 50 seconds
35
+ if (this.pageClick) {
59
36
  console.log('page flipped!')
37
+ this.setPageFlippedTime();
38
+ return this.userFlippedBookPage(); // user clicked on page
39
+ } else {
40
+ console.log('auto checker!')
41
+ return this.autoCheckerTimer(); // auto checker at 50th minute
42
+ }
60
43
 
61
- if (currentDate >= lastTimeFrame) {
62
- console.log('1 YES NOW BORROW IT AGAIN NOW!');
63
- this.toastTexts = this.autoRenewMessage;
64
- this.hideToast = false;
65
- }
44
+ } catch (error) {
45
+ console.log(error)
46
+ }
47
+ }
66
48
 
67
- return nothing // early return
68
- }
49
+ async setPageFlippedTime() {
50
+ // set pageFlipTime time in localStorage
51
+ await this.localCache.set({
52
+ key: `${this.identifier}-pageFlipTime`,
53
+ value: new Date(), // current time
54
+ ttl: parseInt(this.autoRenewTimeConfig.totalTime),
55
+ })
56
+ }
69
57
 
70
- console.log(lastPageFlipTime, lastFlipTimeFrame)
71
- if (lastPageFlipTime === undefined) { // not viewed
72
- console.log('2 DON\'T BORROW IT!');
73
- this.resultRes.toastTexts = this.autoReturnMessage;
74
- this.resultRes.hideToast = false;
75
- } else if (lastPageFlipTime >= lastFlipTimeFrame) { // viewed in last time frame
76
- console.log('3 YES BORROW IT AGAIN!');
77
- this.resultRes.toastTexts = this.autoRenewMessage;
78
- this.resultRes.hideToast = false;
79
- this.toastTexts = this.autoRenewMessage;
80
- // this.browseAgainNow = true;
81
- this.hideToast = false;
82
- // await this.browseHasRenew();
83
- } else if (lastPageFlipTime <= lastFlipTimeFrame) { // viewed but not in last time frame
84
- console.log('4 DON\'T BORROW IT!');
85
- this.resultRes.toastTexts = this.autoReturnMessage;
86
- this.resultRes.hideToast = false;
87
- }
58
+ async userFlippedBookPage() {
59
+ const {
60
+ totalTime, // 60
61
+ autoCheckAt, // 50
62
+ } = this.autoRenewTimeConfig;
63
+ const currentDate = new Date();
64
+ const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
65
+
66
+ const lastTimeFrame = await this.changeTime(
67
+ loanTime,
68
+ totalTime - autoCheckAt,
69
+ 'add'
70
+ ); // 50 seconds
71
+
72
+ if (currentDate >= lastTimeFrame) {
73
+ console.log('1 YES NOW BORROW IT AGAIN NOW!');
74
+ this.resultRes.toastTexts = this.autoRenewMessage;
75
+ this.resultRes.browseAgainNow = true;
76
+ this.resultRes.hideToast = false;
77
+ this.resultRes.renewNow = true;
78
+ }
88
79
 
89
- // console.log(this.resultRes)
90
- return this.resultRes;
80
+ return this.resultRes;
81
+ }
91
82
 
92
- } catch (error) {
93
- console.log(error)
83
+ async autoCheckerTimer() {
84
+ const currentDate = new Date();
85
+ const { FlippedInLast } = this.autoRenewTimeConfig;
86
+ const lastPageFlipTime = await this.localCache.get(`${this.identifier}-pageFlipTime`);
87
+
88
+ // last 15 min if used flipped a page.
89
+ const lastFlipTimeFrame = await this.changeTime(
90
+ currentDate,
91
+ FlippedInLast,
92
+ 'sub'
93
+ ); // 15 seconds
94
+
95
+ if (lastPageFlipTime === undefined || lastPageFlipTime <= lastFlipTimeFrame) { // not viewed
96
+ console.log('2');
97
+ this.resultRes.toastTexts = this.autoReturnWarning;
98
+ this.resultRes.hideToast = false;
99
+ } else if (lastPageFlipTime >= lastFlipTimeFrame) { // viewed in last time frame
100
+ console.log('3');
101
+ this.resultRes.toastTexts = this.autoRenewMessage;
102
+ this.resultRes.browseAgainNow = true;
103
+ this.resultRes.hideToast = false;
104
+ this.resultRes.renewNow = true;
94
105
  }
106
+
107
+ return this.resultRes;
95
108
  }
96
109
 
97
110
  async changeTime(date, minutes, op) {
@@ -104,6 +117,7 @@ export class OneHourAutoRenew {
104
117
  return new Date(date.getTime() + minutes * 1000);
105
118
  }
106
119
 
120
+
107
121
  sendEvent(eventCategory, eventAction) {
108
122
  window?.archive_analytics?.send_event(
109
123
  eventCategory,
@@ -67,8 +67,7 @@ export default class IABookActions extends LitElement {
67
67
  this.modal = undefined;
68
68
  this.tokenDelay = 120000; // 2 minutes
69
69
  this.localCache = new LocalCache({
70
- namespace: '1HourLoanStorage',
71
- defaultTTL: 1 * 60, // 1 minute
70
+ namespace: '1HourLoanStorage'
72
71
  }),
73
72
  this.autoRenewTimeConfig = {},
74
73
 
@@ -82,41 +81,9 @@ export default class IABookActions extends LitElement {
82
81
  this.consecutiveLoanCounts = 1; // consecutive loan count
83
82
  this.browseAgainNow = false;
84
83
  this.browserTimer = undefined;
85
-
86
- // show toast-message for auto return message
87
84
  this.hideToast = true;
88
- this.autoReturnMessage = 'This book will be automatically returned in 15 seconds unless you turn a page.';
89
- this.autoRenewMessage = 'This book has been renewed for another hour.';
90
-
91
- // dispatched this event from timer-countdown
92
- this.addEventListener('autoReturnWarning', event => {
93
- // const dd = this.autoRenew1 = new OneHourAutoRenew(
94
- // event.detail.bookPageChange,
95
- // this.identifier,
96
- // this.localCache,
97
- // this.autoRenewTimeConfig,
98
- // );
99
- // this.toastTexts = dd.resultRes.toastTexts;
100
- // this.hideToast = dd.resultRes.hideToast;
101
- this.handleBookAutoRenew(event);
102
- });
103
-
104
- // dispatched this event from bookreader side
105
- this.addEventListener('bookPageFlip', event => {
106
- // console.log(e)
107
- // const dd = this.autoRenew1 = new OneHourAutoRenew(
108
- // event.detail.bookPageChange,
109
- // this.identifier,
110
- // this.localCache,
111
- // this.autoRenewTimeConfig,
112
- // );
113
- // this.toastTexts = dd.resultRes.toastTexts;
114
- // this.hideToast = dd.resultRes.hideToast;
115
- // console.log(dd.resultRes)
116
- this.handleBookAutoRenew(event);
117
- // this.browseAgainNow = true;
118
- });
119
85
 
86
+ this.bindAutoRenewEvent();
120
87
  this.resetTimerCountdown = false;
121
88
  }
122
89
 
@@ -148,6 +115,29 @@ export default class IABookActions extends LitElement {
148
115
  }
149
116
  }
150
117
 
118
+ bindAutoRenewEvent() {
119
+ // dispatched this event from timer-countdown
120
+ this.addEventListener('autoRenewAttempt', async event => {
121
+ const isPageFlipped = event.detail.bookPageChange;
122
+
123
+ const dd = await new OneHourAutoRenew(
124
+ isPageFlipped,
125
+ this.identifier,
126
+ this.localCache,
127
+ this.autoRenewTimeConfig,
128
+ this.lendingStatus.user_has_browsed && !this.lendingStatus.browsingExpired
129
+ );
130
+
131
+ this.toastTexts = dd.toastTexts;
132
+ this.hideToast = dd.hideToast;
133
+ this.browseAgainNow = dd.renewNow;
134
+ if (this.browseAgainNow) {
135
+ await this.browseHasRenew();
136
+ }
137
+ // this.handleBookAutoRenew(event);
138
+ });
139
+ }
140
+
151
141
  async browseHasExpired() {
152
142
  const currStatus = { ...this.lendingStatus, browsingExpired: true };
153
143
  this.lendingStatus = currStatus;
@@ -157,7 +147,7 @@ export default class IABookActions extends LitElement {
157
147
  await this.localCache.delete(`${this.identifier}-pageFlipTime`);
158
148
 
159
149
  // show message after browsed book is expired.
160
- this.toastTexts = 'This book has been automatically returned due to inactivity.';
150
+ this.toastTexts = this.autoReturnMessage;
161
151
  }
162
152
 
163
153
  async browseHasRenew() {
@@ -174,14 +164,13 @@ export default class IABookActions extends LitElement {
174
164
 
175
165
  startBrowseTimer() {
176
166
  clearTimeout(this.browserTimer);
167
+
177
168
  const {
178
169
  browsingExpired,
179
170
  user_has_browsed,
180
171
  secondsLeftOnLoan,
181
172
  } = this.lendingStatus;
182
- console.log(this.lendingStatus);
183
173
  if (!user_has_browsed || browsingExpired) {
184
- console.log('attempted renew');
185
174
  return;
186
175
  }
187
176
 
@@ -192,83 +181,6 @@ export default class IABookActions extends LitElement {
192
181
  }, timeLeft);
193
182
  }
194
183
 
195
- async handleBookAutoRenew(event) {
196
- try {
197
- const bookPageChange = event.detail.bookPageChange;
198
- const currentDate = new Date();
199
-
200
- const {
201
- totalTime, // 60
202
- autoRenewCheckerAtLast, // 50
203
- autoRenewVisitedInLast, // 15
204
- } = this.autoRenewTimeConfig;
205
-
206
- const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
207
- const lastPageFlipTime = await this.localCache.get(`${this.identifier}-pageFlipTime`);
208
-
209
- const lastFlipTimeFrame = await this.changeTime(
210
- currentDate,
211
- autoRenewVisitedInLast,
212
- 'sub'
213
- ); // 15 seconds
214
-
215
- console.log(lastPageFlipTime, lastFlipTimeFrame)
216
-
217
- // if page is not flipped in last 15 minutes,
218
- // instantaly renew it if user viewed new page in last 10 minutes
219
- if (bookPageChange === true) {
220
- const lastTimeFrame = await this.changeTime(
221
- loanTime,
222
- totalTime - autoRenewCheckerAtLast,
223
- 'add'
224
- ); // 50 seconds
225
- console.log('page flipped!')
226
-
227
- if (currentDate >= lastTimeFrame) {
228
- console.log('1 YES NOW BORROW IT AGAIN NOW!');
229
- this.toastTexts = this.autoRenewMessage;
230
- this.browseAgainNow = true;
231
- this.hideToast = false;
232
- await this.browseHasRenew();
233
- }
234
-
235
- return nothing // early return
236
- }
237
-
238
- console.log(lastPageFlipTime, lastFlipTimeFrame)
239
- if (lastPageFlipTime === undefined) { // not viewed
240
- console.log('2 DON\'T BORROW IT!');
241
- this.toastTexts = this.autoReturnMessage;
242
- this.hideToast = false;
243
- } else if (lastPageFlipTime >= lastFlipTimeFrame) { // viewed in last time frame
244
- console.log('3 YES BORROW IT AGAIN!');
245
- this.toastTexts = this.autoRenewMessage;
246
- this.browseAgainNow = true;
247
- this.hideToast = false;
248
- await this.browseHasRenew();
249
- } else if (lastPageFlipTime <= lastFlipTimeFrame) { // viewed but not in last time frame
250
- console.log('4 DON\'T BORROW IT!');
251
- this.toastTexts = this.autoReturnMessage;
252
- this.hideToast = false;
253
- } else {
254
- this.browseAgainNow = true;
255
- console.log('5 YES NOW BORROW IT AGAIN NOW!');
256
- }
257
- } catch (error) {
258
- console.log(error)
259
- }
260
- }
261
-
262
- async changeTime(date, minutes, op) {
263
- if (date === undefined) return undefined;
264
-
265
- if (op === 'sub') {
266
- return new Date(date.getTime() - minutes * 1000);
267
- }
268
-
269
- return new Date(date.getTime() + minutes * 1000);
270
- }
271
-
272
184
  /** SharedObserver resize handler */
273
185
  handleResize(entry) {
274
186
  // if you are observing multiple targets,
@@ -379,7 +291,7 @@ export default class IABookActions extends LitElement {
379
291
  return this.borrowType === 'browsed'
380
292
  ? html`<timer-countdown
381
293
  time=${Number(this.remainingTime)}
382
- .autoRenewCheckerAtLast=${this.autoRenewTimeConfig.autoRenewCheckerAtLast}
294
+ .autoCheckAt=${this.autoRenewTimeConfig.autoCheckAt}
383
295
  ?resetTimerCountdown=${this.resetTimerCountdown}
384
296
  ></timer-countdown>`
385
297
  : nothing;
@@ -397,6 +309,7 @@ export default class IABookActions extends LitElement {
397
309
 
398
310
  get bookActionBar() {
399
311
  return html`
312
+ <button @click=${() => this.pageFlipEvent()}>Page Flip</button>
400
313
  <collapsible-action-group
401
314
  .userid=${this.userid}
402
315
  .identifier=${this.identifier}
@@ -407,6 +320,7 @@ export default class IABookActions extends LitElement {
407
320
  .borrowType=${this.borrowType}
408
321
  .returnUrl=${this.returnUrl}
409
322
  .autoRenew=${this.autoRenew}
323
+ .autoRenewTimeConfig=${this.autoRenewTimeConfig}
410
324
  ?hasAdminAccess=${this.hasAdminAccess}
411
325
  ?disabled=${this.disableActionGroup}
412
326
  ?browseAgainNow=${this.browseAgainNow}
@@ -419,6 +333,18 @@ export default class IABookActions extends LitElement {
419
333
  `;
420
334
  }
421
335
 
336
+ // will move this function to bookreader...
337
+ async pageFlipEvent() {
338
+ try {
339
+ // dispatch event to say book page has flipped
340
+ document.querySelector("ia-book-actions").dispatchEvent(
341
+ new CustomEvent("autoRenewAttempt", {
342
+ detail: { bookPageChange: true },
343
+ })
344
+ );
345
+ } catch (error) { console.log(error) }
346
+ }
347
+
422
348
  /**
423
349
  * enable access of borrowed/browsed books
424
350
  */