@internetarchive/ia-book-actions 0.0.29-alpha9 → 0.0.29-beta1

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,18 +87,13 @@
87
87
 
88
88
  <script type="module">
89
89
  /* eslint-disable */
90
+
90
91
  import '../src/ia-book-actions.js';
91
92
  import {
92
93
  defaultLendingStatus,
93
94
  canBrowseAndBorrow,
94
95
  } from '../src/assets/data/lending-get-status-service.js';
95
96
  import { ModalConfig } from '@internetarchive/modal-manager';
96
- import { LocalCache } from '@internetarchive/local-cache';
97
-
98
- const localCache = new LocalCache({
99
- namespace: '1HourLoanStorage',
100
- defaultTTL: 1 * 60, // 1 minute
101
- });
102
97
 
103
98
  const userid = '@neeraj-archive';
104
99
  const identifier = 'naturalhistoryof00unse_4111';
@@ -126,15 +121,8 @@
126
121
  iaBookActions.lendingBarPostInit = lendingBarPostInit;
127
122
  iaBookActions.tokenDelay = 2000; // 2 seconds
128
123
  iaBookActions.returnUrl = 'https://openlibrary.org';
129
- iaBookActions.localCache = localCache;
130
- iaBookActions.autoRenewConfig = {
131
- totalTime: 60, // 60 second = 1 min
132
- autoCheckAt: 55, // totalTime - 10th minute
133
- FlippedInLast: 15, // within last 15 second/minute
134
- };
135
124
 
136
125
  let lendingStatus1 = iaBookActions.lendingStatus;
137
- let secondsLeftOnLoan = iaBookActions.autoRenewConfig.totalTime;
138
126
 
139
127
  document.querySelectorAll('.titleBar input[type=checkbox]').forEach((item) => {
140
128
  item.addEventListener('click', (e) => {
@@ -146,21 +134,6 @@
146
134
  });
147
135
  });
148
136
 
149
- document.querySelectorAll('.autoRenew input[type=checkbox]').forEach((item) => {
150
- item.addEventListener('click', (e) => {
151
- if (e.target.checked) {
152
- iaBookActions.autoRenew = true;
153
- iaBookActions.resetTimerCountdown = true;
154
- lendingStatus1.secondsLeftOnLoan = secondsLeftOnLoan;
155
- } else {
156
- iaBookActions.autoRenew = false;
157
- }
158
-
159
- let lending = {...defaultLendingStatus, ...lendingStatus1};
160
- iaBookActions.lendingStatus = lending;
161
- });
162
- });
163
-
164
137
  document.querySelectorAll('.errorEnable input[type=checkbox]').forEach((item) => {
165
138
  if (window.location.href.indexOf('?error=true') !== -1) {
166
139
  item.checked = true;
@@ -214,24 +187,12 @@
214
187
  });
215
188
 
216
189
  document.querySelectorAll('.availableToBrowse input[type=radio]').forEach((item) => {
217
- item.addEventListener('click', async (e) => {
190
+ item.addEventListener('click', (e) => {
218
191
  if (e.target.value === 'user_has_browsed') {
219
192
  lendingStatus1.user_has_browsed = true;
220
193
  lendingStatus1.available_to_browse = false;
221
- lendingStatus1.secondsLeftOnLoan = secondsLeftOnLoan;
194
+ lendingStatus1.secondsLeftOnLoan = 10;
222
195
  lendingStatus1.browsingExpired = false;
223
-
224
- try {
225
- // set a value
226
- await localCache.set({
227
- key: `${identifier}-loanTime`,
228
- value: new Date(), // current time
229
- ttl: Number(iaBookActions.autoRenewConfig.totalTime),
230
- })
231
-
232
- await localCache.delete(`${identifier}-pageFlipTime`);
233
- } catch (error) {}
234
-
235
196
  } else if(e.target.value === 'browsingExpired') {
236
197
  lendingStatus1.user_has_browsed = true;
237
198
  lendingStatus1.available_to_browse = false;
@@ -311,7 +272,6 @@
311
272
  <table class="initial">
312
273
  <tr colspan='5'>
313
274
  <td class="errorEnable"><label><input type="checkbox" name="errorEnable" value="errorEnable" />Do you want to see error response?</label></td>
314
- <td class="autoRenew"><label><input type="checkbox" name="autoRenew" value="autoRenew" />Do you want to auto-renew 1 hour</label></td>
315
275
  </tr>
316
276
  <tr>
317
277
  <td class="userState">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "0.0.29-alpha9",
3
+ "version": "0.0.29-beta1",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -43,12 +43,6 @@
43
43
  "sinon": "^13.0.2"
44
44
  },
45
45
  "eslintConfig": {
46
- "rules": {
47
- "no-console": "off",
48
- "no-unused-expressions": "off",
49
- "class-methods-use-this": "off",
50
- "lit-a11y/click-events-have-key-events": "off"
51
- },
52
46
  "extends": [
53
47
  "@open-wc/eslint-config",
54
48
  "eslint-config-prettier"
@@ -60,6 +54,7 @@
60
54
  },
61
55
  "husky": {
62
56
  "hooks": {
57
+ "pre-commit": "lint-staged"
63
58
  }
64
59
  },
65
60
  "lint-staged": {
@@ -100,7 +100,7 @@ export const canBrowseAndBorrow = {
100
100
  // userid: "",
101
101
  bookUrl: '/details/practicalorganic00plim',
102
102
  daysLeftOnLoan: 0,
103
- isAdmin: false,
103
+ isAdmin: true,
104
104
  isArchiveOrgLending: true,
105
105
  isAvailable: false,
106
106
  isAvailableForBrowsing: false,
@@ -28,8 +28,6 @@ export class CollapsibleActionGroup extends ActionsHandler {
28
28
  dropdownArrow: { type: String },
29
29
  disabled: { type: Boolean },
30
30
  returnUrl: { type: String },
31
- localCache: { type: Function },
32
- browseAgainNow: { type: Boolean },
33
31
  };
34
32
  }
35
33
 
@@ -49,8 +47,6 @@ export class CollapsibleActionGroup extends ActionsHandler {
49
47
  this.loaderIcon = 'https://archive.org/upload/images/tree/loading.gif';
50
48
  this.disabled = false;
51
49
  this.returnUrl = '';
52
- this.localCache = undefined;
53
- this.browseAgainNow = false;
54
50
  }
55
51
 
56
52
  updated(changed) {
@@ -60,16 +56,6 @@ export class CollapsibleActionGroup extends ActionsHandler {
60
56
  ) {
61
57
  this.resetActions();
62
58
  }
63
-
64
- if (changed.has('browseAgainNow') && this.browseAgainNow === true) {
65
- this.dispatchEvent(
66
- new CustomEvent('autoBrowseBook', {
67
- detail: {
68
- event: { autoRenewed1Hour: 'browseBook' },
69
- },
70
- })
71
- );
72
- }
73
59
  }
74
60
 
75
61
  /**
@@ -55,7 +55,7 @@ export class InfoIcon extends LitElement {
55
55
  .more-info-icon.mobile {
56
56
  position: absolute;
57
57
  top: 4px;
58
- right: 55px;
58
+ right: 10px;
59
59
  margin-top: 15px;
60
60
  }
61
61
  .hidden {
@@ -202,11 +202,15 @@ export default class ActionsConfig {
202
202
  if (this.lendingStatus.user_has_borrowed || !this.lendingStatus.isAdmin)
203
203
  return null;
204
204
 
205
+ // keep existing params and add new one
206
+ const url = new URL(window.location.href);
207
+ url.searchParams.append('admin', 1);
208
+
205
209
  return {
206
210
  id: 'adminAccess',
207
211
  text: 'Admin Access',
208
212
  title: 'You have administrative privileges to read this book',
209
- url: '?admin=1',
213
+ url: url.search,
210
214
  target: '_self',
211
215
  className: 'danger',
212
216
  analyticsEvent: {
@@ -17,9 +17,8 @@ export default class ActionsHandler extends LitElement {
17
17
  super();
18
18
  this.identifier = '';
19
19
  this.ajaxTimeout = 6000;
20
- this.returnUrl = '';
21
- this.autoRenewConfig = {};
22
20
  this.bindEvents();
21
+ this.returnUrl = '';
23
22
  }
24
23
 
25
24
  sendEvent(eventCategory, eventAction) {
@@ -30,7 +29,7 @@ export default class ActionsHandler extends LitElement {
30
29
  );
31
30
  }
32
31
 
33
- async bindEvents() {
32
+ bindEvents() {
34
33
  this.addEventListener('browseBook', ({ detail }) => {
35
34
  this.handleBrowseIt();
36
35
  this.setConsecutiveLoanCounts();
@@ -45,13 +44,6 @@ export default class ActionsHandler extends LitElement {
45
44
  this.sendEvent(category, action);
46
45
  });
47
46
 
48
- this.addEventListener('autoBrowseBook', ({ detail }) => {
49
- console.log('auto renew handlerExecuted!!');
50
- this.handleAutoBrowseIt();
51
- const { category, action } = detail.event;
52
- this.sendEvent(category, action);
53
- });
54
-
55
47
  this.addEventListener('returnNow', ({ detail }) => {
56
48
  this.handleReturnIt();
57
49
  const { category, action } = detail.event;
@@ -106,7 +98,6 @@ export default class ActionsHandler extends LitElement {
106
98
  handleBrowseIt() {
107
99
  const action = 'browse_book';
108
100
  this.dispatchToggleActionGroup();
109
- this.setBrowseTimeSession();
110
101
 
111
102
  ActionsHandlerService({
112
103
  action,
@@ -120,22 +111,6 @@ export default class ActionsHandler extends LitElement {
120
111
  });
121
112
  }
122
113
 
123
- handleAutoBrowseIt() {
124
- const action = 'renew_loan';
125
- this.setBrowseTimeSession();
126
-
127
- ActionsHandlerService({
128
- action,
129
- identifier: this.identifier,
130
- success: () => {
131
- // console.log('success!');
132
- },
133
- error: data => {
134
- this.dispatchActionError(action, data);
135
- },
136
- });
137
- }
138
-
139
114
  handleReturnIt() {
140
115
  const action = 'return_loan';
141
116
  this.dispatchToggleActionGroup();
@@ -286,21 +261,6 @@ export default class ActionsHandler extends LitElement {
286
261
  }
287
262
  }
288
263
 
289
- async setBrowseTimeSession() {
290
- try {
291
- // set a value
292
- await this.localCache.set({
293
- key: `${this.identifier}-loanTime`,
294
- value: new Date(), // current time
295
- ttl: Number(this.autoRenewConfig.totalTime),
296
- });
297
-
298
- await this.localCache.delete(`${this.identifier}-pageFlipTime`);
299
- } catch (error) {
300
- console.log(error);
301
- }
302
- }
303
-
304
264
  deleteLoanCookies() {
305
265
  const date = new Date();
306
266
  date.setTime(date.getTime() - 24 * 60 * 60 * 1000); // one day ago
@@ -1,21 +1,17 @@
1
1
  /* eslint-disable camelcase */
2
- import { html, css, LitElement, nothing } from 'lit';
2
+ import { html, css, LitElement } from 'lit';
3
3
 
4
4
  import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
5
5
  import { ModalConfig } from '@internetarchive/modal-manager';
6
- import { LocalCache } from '@internetarchive/local-cache';
7
6
 
8
7
  import './components/collapsible-action-group.js';
9
8
  import './components/book-title-bar.js';
10
9
  import './components/text-group.js';
11
10
  import './components/info-icon.js';
12
- import './components/timer-countdown.js';
13
- import './components/toast-message.js';
14
11
 
15
12
  import { GetLendingActions } from './core/services/get-lending-actions.js';
16
13
  import { mobileContainerWidth } from './core/config/constants.js';
17
14
  import { LoanTokenPoller } from './core/services/loan-token-poller.js';
18
- import { OneHourAutoRenew } from './core/services/one-hour-auto-renew.js';
19
15
 
20
16
  export const events = {
21
17
  browseExpired: 'IABookReader:BrowsingHasExpired',
@@ -40,12 +36,6 @@ export default class IABookActions extends LitElement {
40
36
  disableActionGroup: { type: Boolean },
41
37
  modal: { Object },
42
38
  tokenDelay: { type: Number },
43
- toastTexts: { type: String },
44
- remainingTime: { type: Number },
45
- resetTimerCountdown: { type: Boolean },
46
- localCache: { type: Object },
47
- autoRenewConfig: { type: Object },
48
- browseAgainNow: { type: Boolean },
49
39
  };
50
40
  }
51
41
 
@@ -64,11 +54,6 @@ export default class IABookActions extends LitElement {
64
54
  this.disableActionGroup = false;
65
55
  this.modal = undefined;
66
56
  this.tokenDelay = 120000; // 2 minutes
67
- this.localCache = new LocalCache({
68
- namespace: '1HourLoanStorage',
69
- });
70
- this.autoRenewConfig = {};
71
- this.autoRenewRes = undefined;
72
57
 
73
58
  // private props
74
59
  this.primaryActions = [];
@@ -78,12 +63,6 @@ export default class IABookActions extends LitElement {
78
63
  this.lendingOptions = {};
79
64
  this.borrowType = ''; // (browsed|borrowed)
80
65
  this.consecutiveLoanCounts = 1; // consecutive loan count
81
- this.browseAgainNow = false;
82
- this.browserTimer = undefined;
83
- this.hideToast = true;
84
-
85
- this.bindAutoRenewEvent();
86
- this.resetTimerCountdown = false;
87
66
  }
88
67
 
89
68
  disconnectedCallback() {
@@ -100,7 +79,6 @@ export default class IABookActions extends LitElement {
100
79
  }
101
80
 
102
81
  updated(changed) {
103
- // console.log(changed)
104
82
  if (changed.has('lendingStatus') || changed.has('bwbPurchaseUrl')) {
105
83
  this.setupLendingToolbarActions();
106
84
  this.update();
@@ -112,74 +90,12 @@ export default class IABookActions extends LitElement {
112
90
  }
113
91
  }
114
92
 
115
- bindAutoRenewEvent() {
116
- // dispatched this event from timer-countdown
117
- this.addEventListener('autoRenewAttempt', async event => {
118
- const isPageClick = event.detail.bookPageChange;
119
-
120
- // early return if user is not browsed book
121
- if (isPageClick && this.borrowType !== 'browsed') return nothing;
122
-
123
- this.autoRenewRes = await new OneHourAutoRenew(
124
- isPageClick,
125
- this.identifier,
126
- this.localCache,
127
- this.autoRenewConfig,
128
- this.lendingStatus.user_has_browsed &&
129
- !this.lendingStatus.browsingExpired
130
- );
131
- console.log(this.autoRenewRes);
132
-
133
- this.toastTexts = this.autoRenewRes.toastTexts;
134
- this.hideToast = this.autoRenewRes.hideToast;
135
- this.browseAgainNow = this.autoRenewRes.browseAgainNow;
136
-
137
- if (this.browseAgainNow) {
138
- this.tokenPoller.disconnectedInterval();
139
-
140
- // start tokenPoller after 2 minute
141
- setTimeout(() => {
142
- this.startLoanTokenPoller();
143
- }, this.tokenDelay);
144
-
145
- await this.browseHasRenew();
146
- }
147
-
148
- return nothing;
149
- });
150
- }
151
-
152
- async browseHasExpired() {
93
+ browseHasExpired() {
153
94
  const currStatus = { ...this.lendingStatus, browsingExpired: true };
154
95
  this.lendingStatus = currStatus;
155
- this.browseAgainNow = false;
156
-
157
- // remove respected key:value
158
- await this.localCache.delete(`${this.identifier}-loanTime`);
159
- await this.localCache.delete(`${this.identifier}-pageFlipTime`);
160
-
161
- // show message after browsed book is expired.
162
- this.toastTexts = 'This book has been auto-returned due to inactivity.';
163
- }
164
-
165
- async browseHasRenew() {
166
- const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
167
- const secondsLeft = (loanTime - new Date()) / 1000; // different in seconds
168
-
169
- const currStatus = {
170
- ...this.lendingStatus,
171
- user_has_browsed: true,
172
- browsingExpired: false,
173
- secondsLeftOnLoan: secondsLeft,
174
- };
175
- this.lendingStatus = currStatus;
176
-
177
- this.startBrowseTimer();
178
96
  }
179
97
 
180
98
  startBrowseTimer() {
181
- clearTimeout(this.browserTimer);
182
-
183
99
  const {
184
100
  browsingExpired,
185
101
  user_has_browsed,
@@ -189,9 +105,8 @@ export default class IABookActions extends LitElement {
189
105
  return;
190
106
  }
191
107
 
192
- // expired book and show browse again button
193
108
  const timeLeft = secondsLeftOnLoan * 1000;
194
- this.browserTimer = setTimeout(() => {
109
+ setTimeout(() => {
195
110
  this.browseHasExpired();
196
111
  }, timeLeft);
197
112
  }
@@ -249,13 +164,16 @@ export default class IABookActions extends LitElement {
249
164
  });
250
165
 
251
166
  this.borrowType = actions.borrowType;
252
- this.remainingTime = this.lendingStatus.secondsLeftOnLoan;
253
167
 
254
168
  const hasExpired =
255
169
  'browsingExpired' in this.lendingStatus &&
256
170
  this.lendingStatus?.browsingExpired;
257
171
  if (hasExpired) {
258
- window?.Sentry?.captureMessage('setupLendingToolbarActions hasExpired');
172
+ if (!this.tokenPoller.disconnectedInterval) {
173
+ window?.Sentry?.captureMessage(
174
+ 'setupLendingToolbarActions hasExpired - no tokenPoller'
175
+ );
176
+ }
259
177
  this.tokenPoller?.disconnectedInterval();
260
178
  /** Global event - always fire */
261
179
  this.dispatchEvent(
@@ -302,30 +220,8 @@ export default class IABookActions extends LitElement {
302
220
  ></book-title-bar>`;
303
221
  }
304
222
 
305
- get timerCountdownTemplate() {
306
- // console.log(this.borrowType, this.remainingTime, this.autoRenewConfig.autoCheckAt, this.resetTimerCountdown);
307
- return this.borrowType === 'browsed'
308
- ? html`<timer-countdown
309
- time=${Number(this.remainingTime)}
310
- .autoCheckAt=${this.autoRenewConfig.autoCheckAt}
311
- ?resetTimerCountdown=${this.resetTimerCountdown}
312
- ></timer-countdown>`
313
- : nothing;
314
- }
315
-
316
- get toastMessageTemplate() {
317
- return html`
318
- <toast-message
319
- .texts=${this.toastTexts}
320
- ?dismisOnClick=${Boolean(true)}
321
- ?hideToast=${this.hideToast}
322
- ></toast-message>
323
- `;
324
- }
325
-
326
223
  get bookActionBar() {
327
224
  return html`
328
- <button @click=${() => this.pageFlipEvent()}>Page Flip</button>
329
225
  <collapsible-action-group
330
226
  .userid=${this.userid}
331
227
  .identifier=${this.identifier}
@@ -335,30 +231,16 @@ export default class IABookActions extends LitElement {
335
231
  .width=${this.width}
336
232
  .borrowType=${this.borrowType}
337
233
  .returnUrl=${this.returnUrl}
338
- .localCache=${this.localCache}
339
- .autoRenewConfig=${this.autoRenewConfig}
340
234
  ?hasAdminAccess=${this.hasAdminAccess}
341
235
  ?disabled=${this.disableActionGroup}
342
- ?browseAgainNow=${this.browseAgainNow}
343
236
  @lendingActionError=${this.handleLendingActionError}
344
237
  @toggleActionGroup=${this.handleToggleActionGroup}
345
238
  >
346
239
  </collapsible-action-group>
347
240
  ${this.textGroupTemplate} ${this.infoIconTemplate}
348
- ${this.timerCountdownTemplate} ${this.toastMessageTemplate}
349
241
  `;
350
242
  }
351
243
 
352
- // will move this function to bookreader...
353
- pageFlipEvent() {
354
- // dispatch event to say book page has flipped
355
- document.querySelector('ia-book-actions').dispatchEvent(
356
- new CustomEvent('autoRenewAttempt', {
357
- detail: { bookPageChange: true },
358
- })
359
- );
360
- }
361
-
362
244
  /**
363
245
  * enable access of borrowed/browsed books
364
246
  */
@@ -523,10 +405,6 @@ export default class IABookActions extends LitElement {
523
405
  justify-content: center;
524
406
  flex-wrap: wrap;
525
407
  }
526
-
527
- toast-message {
528
- --messageHeightFromTop: 17%;
529
- }
530
408
  `;
531
409
  }
532
410
  }
@@ -1,113 +0,0 @@
1
- import { html, css, LitElement } from 'lit';
2
-
3
- export default class TimerCountdown extends LitElement {
4
- static get properties() {
5
- return {
6
- time: { type: Number },
7
- autoCheckAt: { type: Number },
8
- resetTimerCountdown: { type: Boolean },
9
- };
10
- }
11
-
12
- constructor() {
13
- super();
14
- this.time = 0;
15
- this.autoCheckAt = 0;
16
- this.timerInterval = undefined;
17
- this.resetTimerCountdown = false;
18
- }
19
-
20
- disconnectedCallback() {
21
- clearInterval(this.timerInterval);
22
- }
23
-
24
- updated(changed) {
25
- if (changed.has('time') && this.time > 0) {
26
- clearInterval(this.timerInterval);
27
- this.timerCountdown();
28
- }
29
- }
30
-
31
- timerCountdown() {
32
- this.timerInterval = setInterval(() => {
33
- this.time -= 1;
34
-
35
- // execute 50th minute check
36
- if (Math.round(this.time) === this.autoCheckAt) {
37
- this.dispatchEvent(
38
- new CustomEvent('autoRenewAttempt', {
39
- detail: {
40
- remainingT: this.time,
41
- bookPageChange: false,
42
- },
43
- bubbles: true,
44
- composed: true,
45
- })
46
- );
47
- }
48
-
49
- if (this.time === 0) clearInterval(this.timerInterval);
50
- }, 1000);
51
- }
52
-
53
- render() {
54
- return html`<div id="countdown">
55
- <div id="countdown-number">${Math.round(this.time)}</div>
56
- <svg>
57
- <circle r="18" cx="20" cy="20"></circle>
58
- </svg>
59
- </div>`;
60
- }
61
-
62
- static get styles() {
63
- return css`
64
- :host {
65
- right: 5px;
66
- font-size: 14px;
67
- position: absolute;
68
- }
69
- #countdown-number {
70
- color: white;
71
- display: inline-block;
72
- line-height: 40px;
73
- margin-right: 12px;
74
- }
75
-
76
- svg {
77
- position: absolute;
78
- top: 0;
79
- right: 0;
80
- width: 40px;
81
- height: 40px;
82
- transform: rotateY(-180deg) rotateZ(-90deg);
83
- }
84
-
85
- svg circle {
86
- stroke-dasharray: 113px;
87
- stroke-dashoffset: 0px;
88
- stroke-linecap: round;
89
- stroke-width: 3px;
90
- stroke: white;
91
- fill: none;
92
- animation: countdown 60s linear infinite forwards;
93
- }
94
-
95
- @keyframes countdown {
96
- from {
97
- stroke-dashoffset: 0px;
98
- }
99
- to {
100
- stroke-dashoffset: 113px;
101
- }
102
- }
103
- .hidden {
104
- display: none;
105
- }
106
- .visible {
107
- display: inline-block;
108
- }
109
- `;
110
- }
111
- }
112
-
113
- window.customElements.define('timer-countdown', TimerCountdown);
@@ -1,78 +0,0 @@
1
- import { html, css, LitElement, nothing } from 'lit';
2
-
3
- export class ToastMessage extends LitElement {
4
- static get properties() {
5
- return {
6
- texts: { type: String },
7
- dismisOnClick: { type: Boolean },
8
- hideToast: { type: Boolean },
9
- };
10
- }
11
-
12
- constructor() {
13
- super();
14
- this.texts = '';
15
- this.textClass = '';
16
- this.hideToast = false;
17
- }
18
-
19
- render() {
20
- return !this.hideToast
21
- ? html`
22
- <span
23
- class="toast-message fade-in ${this.textClass}"
24
- title="Click/tap to close"
25
- @click=${() => {
26
- this.dismisOnClick ? (this.hideToast = true) : nothing;
27
- }}
28
- >${this.texts}</span
29
- >
30
- `
31
- : nothing;
32
- }
33
-
34
- static get styles() {
35
- const heightFromTop = css`var(--messageHeightFromTop, 15%)`;
36
-
37
- return css`
38
- :host {
39
- display: inline-block;
40
- }
41
- .toast-message {
42
- z-index: 2;
43
- position: absolute;
44
- top: ${heightFromTop};
45
- font-size: 1.4rem;
46
- font-family: 'Helvetica Neue';
47
- color: #fff;
48
- left: 50%;
49
- background: #333;
50
- border: 1px solid #fff;
51
- border-radius: 5px;
52
- box-shadow: 1px 1px 2px;
53
- padding: 10px;
54
- width: fit-content;
55
- transform: translate(-50%, -50%);
56
- cursor: pointer;
57
- animation: fadeIn 5s;
58
- @keyframes fadeIn {
59
- 0% {
60
- opacity: 0;
61
- }
62
- 100% {
63
- opacity: 1;
64
- }
65
- }
66
- }
67
-
68
- .hidden {
69
- display: none;
70
- }
71
- .visible {
72
- display: inline-block;
73
- }
74
- `;
75
- }
76
- }
77
-
78
- window.customElements.define('toast-message', ToastMessage);
@@ -1,169 +0,0 @@
1
- import { nothing } from 'lit';
2
-
3
- /**
4
- * This class is used to determine if use is eligible for auto renew loan.
5
- *
6
- */
7
- export class OneHourAutoRenew {
8
- constructor(
9
- isPageClick,
10
- identifier,
11
- localCache,
12
- autoRenewConfig,
13
- userHasBrowsed
14
- ) {
15
- this.isPageClick = isPageClick;
16
- this.identifier = identifier;
17
- this.localCache = localCache;
18
- this.autoRenewConfig = autoRenewConfig;
19
- this.userHasBrowsed = userHasBrowsed;
20
-
21
- // messages for auto return machenism
22
- this.autoRenewMessage = 'This book has been renewed for another hour.';
23
- this.autoReturnMessage =
24
- 'This book has been auto-returned due to inactivity.';
25
- this.autoReturnWarning =
26
- 'This book will be auto-returned in 10 minutes unless you turn a page.';
27
-
28
- // private props
29
- this.resultRes = {
30
- toastTexts: '',
31
- hideToast: true,
32
- renewNow: false,
33
- browseAgainNow: false,
34
- };
35
-
36
- return this.handleBookAutoRenew();
37
- }
38
-
39
- handleBookAutoRenew() {
40
- try {
41
- // if page is not clicked in last 15 minutes,
42
- // instantaly renew it if user viewed new page in last 10 minutes
43
- if (this.isPageClick) {
44
- console.log('page flipped!!');
45
- return this.userFlippedBookPage(); // user clicked on page
46
- }
47
- console.log('auto checker!');
48
- return this.autoCheckerTimer(); // auto checker at 50th minute
49
- } catch (error) {
50
- console.log(error);
51
- }
52
-
53
- return nothing;
54
- }
55
-
56
- async setPageFlippedTime() {
57
- // set pageFlipTime time in localStorage
58
- await this.localCache.set({
59
- key: `${this.identifier}-pageFlipTime`,
60
- value: new Date(), // current time
61
- ttl: Number(this.autoRenewConfig.totalTime),
62
- });
63
- }
64
-
65
- async userFlippedBookPage() {
66
- const {
67
- totalTime, // 60
68
- autoCheckAt, // 50
69
- } = this.autoRenewConfig;
70
- const currentTime = new Date();
71
- const loanTime = await this.localCache.get(`${this.identifier}-loanTime`);
72
-
73
- const lastTimeFrame = this.changeTime(
74
- loanTime,
75
- totalTime - autoCheckAt,
76
- 'add'
77
- ); // 50 seconds
78
-
79
- if (currentTime >= lastTimeFrame) {
80
- console.log('1 YES NOW BORROW IT AGAIN NOW!');
81
- this.resultRes.toastTexts = this.autoRenewMessage;
82
- this.resultRes.hideToast = false;
83
- this.resultRes.renewNow = true;
84
- this.resultRes.browseAgainNow = true;
85
-
86
- this.setNewBrowseTime();
87
- }
88
-
89
- this.setPageFlippedTime();
90
- return this.resultRes;
91
- }
92
-
93
- async autoCheckerTimer() {
94
- const currentTime = new Date();
95
- const { FlippedInLast } = this.autoRenewConfig;
96
- const lastPageFlipTime = await this.localCache.get(
97
- `${this.identifier}-pageFlipTime`
98
- );
99
-
100
- // last 15 min if used flipped a page.
101
- const lastFlipTimeFrame = this.changeTime(
102
- currentTime,
103
- FlippedInLast,
104
- 'sub'
105
- ); // 15 seconds
106
-
107
- if (
108
- lastPageFlipTime === undefined ||
109
- lastPageFlipTime <= lastFlipTimeFrame
110
- ) {
111
- // not viewed
112
- console.log('2 not viewed, warning message!');
113
- this.resultRes.toastTexts = this.autoReturnWarning;
114
- this.resultRes.hideToast = false;
115
- } else if (lastPageFlipTime >= lastFlipTimeFrame) {
116
- // viewed in last time frame
117
- console.log('3 viewed, auto renew and message!');
118
- this.resultRes.toastTexts = this.autoRenewMessage;
119
- this.resultRes.browseAgainNow = true;
120
- this.resultRes.hideToast = false;
121
- this.resultRes.renewNow = true;
122
-
123
- this.setNewBrowseTime();
124
- }
125
-
126
- return this.resultRes;
127
- }
128
-
129
- async setNewBrowseTime() {
130
- try {
131
- // last 15 min if used flipped a page.
132
- const expireDate = this.changeTime(
133
- new Date(),
134
- this.autoRenewConfig.totalTime,
135
- 'add'
136
- ); // 15 seconds
137
-
138
- // set a value
139
- await this.localCache.set({
140
- key: `${this.identifier}-loanTime`,
141
- value: expireDate, // expireDate time
142
- ttl: Number(this.autoRenewConfig.totalTime),
143
- });
144
-
145
- // delete pageFlipTime when book is auto renew at nth minute
146
- await this.localCache.delete(`${this.identifier}-pageFlipTime`);
147
- } catch (error) {
148
- console.log(error);
149
- }
150
- }
151
-
152
- changeTime(date, minutes, op) {
153
- if (date === undefined) return nothing;
154
-
155
- if (op === 'sub') {
156
- return new Date(date.getTime() - minutes * 1000);
157
- }
158
-
159
- return new Date(date.getTime() + minutes * 1000);
160
- }
161
-
162
- sendEvent(eventCategory, eventAction) {
163
- window?.archive_analytics?.send_event(
164
- eventCategory,
165
- eventAction,
166
- `identifier=${this.identifier}`
167
- );
168
- }
169
- }