@elliemae/ds-chat 2.1.0-rc.0 → 2.1.0-rc.1

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.
@@ -19,6 +19,7 @@ var React = require('react');
19
19
  var reactDesc = require('react-desc');
20
20
  var reactVirtual = require('react-virtual');
21
21
  var DSButton = require('@elliemae/ds-button');
22
+ var lodash = require('lodash');
22
23
  var ChatBubble = require('../bubble/ChatBubble.js');
23
24
  var props$1 = require('../bubble/props.js');
24
25
  var MessageDelimiter = require('../message-delimiter/MessageDelimiter.js');
@@ -67,6 +68,7 @@ const ChatContainerMessagesList = props$2 => {
67
68
  isLoading,
68
69
  bannerRef
69
70
  } = props$2;
71
+ const pendingOnScroll = React__default["default"].useRef(false);
70
72
  const loadMoreRef = React__default["default"].useRef(null);
71
73
  const virtualListRef = React__default["default"].useRef(); // estimateSize should not be really required given what was stated on
72
74
  // https://github.com/tannerlinsley/react-virtual/issues/23
@@ -86,9 +88,15 @@ const ChatContainerMessagesList = props$2 => {
86
88
  })), {}, {
87
89
  estimateSize: React__default["default"].useCallback(() => 80, [])
88
90
  }));
89
- const onScrollStop = React__default["default"].useCallback(() => {
91
+ const debouncedScroll = React__default["default"].useMemo(() => lodash.debounce(() => {
90
92
  var _virtualListRef$curre;
91
93
 
94
+ if (document.visibilityState === 'hidden') {
95
+ pendingOnScroll.current = true;
96
+ return [];
97
+ }
98
+
99
+ pendingOnScroll.current = false;
92
100
  const {
93
101
  bottom,
94
102
  top
@@ -97,15 +105,15 @@ const ChatContainerMessagesList = props$2 => {
97
105
  const indexList = [];
98
106
  list.forEach(item => {
99
107
  const {
100
- top: itemTop,
101
- bottom: itemBottom
108
+ top: itemTop
102
109
  } = item.getBoundingClientRect();
103
110
  const itemPadding = 10;
104
- if (itemTop + itemPadding < bottom && itemBottom - itemPadding > top) indexList.push(item.dataset.index);
111
+ if (itemTop + itemPadding < bottom && itemTop + itemPadding > top) indexList.push(item.dataset.index);
105
112
  });
106
113
  if (onScrollEnds) onScrollEnds(indexList);
107
114
  return indexList;
108
- }, [onScrollEnds]);
115
+ }, 500), [onScrollEnds]);
116
+ const onScrollStop = React__default["default"].useCallback(debouncedScroll, [debouncedScroll]);
109
117
  const onlyFocus = React__default["default"].useCallback(index => {
110
118
  setTimeout(() => {
111
119
  virtualListRef.current.querySelector("[data-index=\"".concat(index, "\"]")).focus();
@@ -117,7 +125,8 @@ const ChatContainerMessagesList = props$2 => {
117
125
  };
118
126
  vScroll(index, b);
119
127
  onlyFocus(index);
120
- }, [onlyFocus, vScroll]);
128
+ onScrollStop();
129
+ }, [onScrollStop, onlyFocus, vScroll]);
121
130
  React__default["default"].useEffect(() => {
122
131
  if (actionRef && actionRef.current) {
123
132
  actionRef.current.scrollToIndex = function (a) {
@@ -125,6 +134,7 @@ const ChatContainerMessagesList = props$2 => {
125
134
  align: 'center'
126
135
  };
127
136
  vScroll(a, b);
137
+ onScrollStop();
128
138
  };
129
139
 
130
140
  actionRef.current.getMessagesInView = onScrollStop;
@@ -138,7 +148,7 @@ const ChatContainerMessagesList = props$2 => {
138
148
 
139
149
  actionRef.current.focusToIndexWithoutScroll = onlyFocus;
140
150
 
141
- actionRef.current.focusToList = a => {
151
+ actionRef.current.focusToList = () => {
142
152
  var _virtualListRef$curre2;
143
153
 
144
154
  (_virtualListRef$curre2 = virtualListRef.current) === null || _virtualListRef$curre2 === void 0 ? void 0 : _virtualListRef$curre2.focus();
@@ -232,7 +242,13 @@ const ChatContainerMessagesList = props$2 => {
232
242
 
233
243
  case 'ArrowDown':
234
244
  e.preventDefault();
235
- onlyFocus(onScrollStop().pop());
245
+
246
+ if (document.activeElement === loadMoreRef.current) {
247
+ virtualListRef.current.querySelector("[data-index=\"0\"]").focus();
248
+ } else {
249
+ onlyFocus(onScrollStop().pop());
250
+ }
251
+
236
252
  break;
237
253
 
238
254
  case 'Home':
@@ -274,6 +290,9 @@ const ChatContainerMessagesList = props$2 => {
274
290
  break;
275
291
  }
276
292
  }, [actionRef, hasMoreItems, messages.length, onScrollStop, onlyFocus, scrollAndFocus]);
293
+ const checkPendingOnScroll = React__default["default"].useCallback(() => {
294
+ if (pendingOnScroll.current === true) onScrollStop();
295
+ }, [onScrollStop]);
277
296
  React__default["default"].useEffect(() => {
278
297
  let handlerCallback = null;
279
298
  const localVirtualRef = virtualListRef.current;
@@ -287,11 +306,13 @@ const ChatContainerMessagesList = props$2 => {
287
306
  virtualListRef.current.addEventListener('scroll', onScroll);
288
307
  }
289
308
 
309
+ document.addEventListener('visibilitychange', checkPendingOnScroll);
290
310
  return () => {
291
311
  if (handlerCallback) clearTimeout(handlerCallback);
292
312
  if (onScrollEnds) localVirtualRef.removeEventListener('scroll', onScroll);
313
+ document.removeEventListener('visibilitychange', checkPendingOnScroll);
293
314
  };
294
- }, [onScrollStop, onScrollEnds]);
315
+ }, [onScrollStop, onScrollEnds, checkPendingOnScroll]);
295
316
  const render = React__default["default"].useMemo(() => virtualItems.map(virtualItem => {
296
317
  const {
297
318
  index,
@@ -15,6 +15,7 @@ import React from 'react';
15
15
  import { describe } from 'react-desc';
16
16
  import { useVirtual } from 'react-virtual';
17
17
  import DSButton from '@elliemae/ds-button';
18
+ import { debounce } from 'lodash';
18
19
  import { ChatBubble } from '../bubble/ChatBubble.js';
19
20
  import { BUBBLE_TYPES } from '../bubble/props.js';
20
21
  import { MessageDelimiter } from '../message-delimiter/MessageDelimiter.js';
@@ -56,6 +57,7 @@ const ChatContainerMessagesList = props => {
56
57
  isLoading,
57
58
  bannerRef
58
59
  } = props;
60
+ const pendingOnScroll = React.useRef(false);
59
61
  const loadMoreRef = React.useRef(null);
60
62
  const virtualListRef = React.useRef(); // estimateSize should not be really required given what was stated on
61
63
  // https://github.com/tannerlinsley/react-virtual/issues/23
@@ -75,9 +77,15 @@ const ChatContainerMessagesList = props => {
75
77
  })), {}, {
76
78
  estimateSize: React.useCallback(() => 80, [])
77
79
  }));
78
- const onScrollStop = React.useCallback(() => {
80
+ const debouncedScroll = React.useMemo(() => debounce(() => {
79
81
  var _virtualListRef$curre;
80
82
 
83
+ if (document.visibilityState === 'hidden') {
84
+ pendingOnScroll.current = true;
85
+ return [];
86
+ }
87
+
88
+ pendingOnScroll.current = false;
81
89
  const {
82
90
  bottom,
83
91
  top
@@ -86,15 +94,15 @@ const ChatContainerMessagesList = props => {
86
94
  const indexList = [];
87
95
  list.forEach(item => {
88
96
  const {
89
- top: itemTop,
90
- bottom: itemBottom
97
+ top: itemTop
91
98
  } = item.getBoundingClientRect();
92
99
  const itemPadding = 10;
93
- if (itemTop + itemPadding < bottom && itemBottom - itemPadding > top) indexList.push(item.dataset.index);
100
+ if (itemTop + itemPadding < bottom && itemTop + itemPadding > top) indexList.push(item.dataset.index);
94
101
  });
95
102
  if (onScrollEnds) onScrollEnds(indexList);
96
103
  return indexList;
97
- }, [onScrollEnds]);
104
+ }, 500), [onScrollEnds]);
105
+ const onScrollStop = React.useCallback(debouncedScroll, [debouncedScroll]);
98
106
  const onlyFocus = React.useCallback(index => {
99
107
  setTimeout(() => {
100
108
  virtualListRef.current.querySelector("[data-index=\"".concat(index, "\"]")).focus();
@@ -106,7 +114,8 @@ const ChatContainerMessagesList = props => {
106
114
  };
107
115
  vScroll(index, b);
108
116
  onlyFocus(index);
109
- }, [onlyFocus, vScroll]);
117
+ onScrollStop();
118
+ }, [onScrollStop, onlyFocus, vScroll]);
110
119
  React.useEffect(() => {
111
120
  if (actionRef && actionRef.current) {
112
121
  actionRef.current.scrollToIndex = function (a) {
@@ -114,6 +123,7 @@ const ChatContainerMessagesList = props => {
114
123
  align: 'center'
115
124
  };
116
125
  vScroll(a, b);
126
+ onScrollStop();
117
127
  };
118
128
 
119
129
  actionRef.current.getMessagesInView = onScrollStop;
@@ -127,7 +137,7 @@ const ChatContainerMessagesList = props => {
127
137
 
128
138
  actionRef.current.focusToIndexWithoutScroll = onlyFocus;
129
139
 
130
- actionRef.current.focusToList = a => {
140
+ actionRef.current.focusToList = () => {
131
141
  var _virtualListRef$curre2;
132
142
 
133
143
  (_virtualListRef$curre2 = virtualListRef.current) === null || _virtualListRef$curre2 === void 0 ? void 0 : _virtualListRef$curre2.focus();
@@ -221,7 +231,13 @@ const ChatContainerMessagesList = props => {
221
231
 
222
232
  case 'ArrowDown':
223
233
  e.preventDefault();
224
- onlyFocus(onScrollStop().pop());
234
+
235
+ if (document.activeElement === loadMoreRef.current) {
236
+ virtualListRef.current.querySelector("[data-index=\"0\"]").focus();
237
+ } else {
238
+ onlyFocus(onScrollStop().pop());
239
+ }
240
+
225
241
  break;
226
242
 
227
243
  case 'Home':
@@ -263,6 +279,9 @@ const ChatContainerMessagesList = props => {
263
279
  break;
264
280
  }
265
281
  }, [actionRef, hasMoreItems, messages.length, onScrollStop, onlyFocus, scrollAndFocus]);
282
+ const checkPendingOnScroll = React.useCallback(() => {
283
+ if (pendingOnScroll.current === true) onScrollStop();
284
+ }, [onScrollStop]);
266
285
  React.useEffect(() => {
267
286
  let handlerCallback = null;
268
287
  const localVirtualRef = virtualListRef.current;
@@ -276,11 +295,13 @@ const ChatContainerMessagesList = props => {
276
295
  virtualListRef.current.addEventListener('scroll', onScroll);
277
296
  }
278
297
 
298
+ document.addEventListener('visibilitychange', checkPendingOnScroll);
279
299
  return () => {
280
300
  if (handlerCallback) clearTimeout(handlerCallback);
281
301
  if (onScrollEnds) localVirtualRef.removeEventListener('scroll', onScroll);
302
+ document.removeEventListener('visibilitychange', checkPendingOnScroll);
282
303
  };
283
- }, [onScrollStop, onScrollEnds]);
304
+ }, [onScrollStop, onScrollEnds, checkPendingOnScroll]);
284
305
  const render = React.useMemo(() => virtualItems.map(virtualItem => {
285
306
  const {
286
307
  index,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-chat",
3
- "version": "2.1.0-rc.0",
3
+ "version": "2.1.0-rc.1",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Chat",
6
6
  "module": "./esm/index.js",
@@ -305,15 +305,15 @@
305
305
  "generateSubmodules": true
306
306
  },
307
307
  "dependencies": {
308
- "@elliemae/ds-banner": "2.1.0-rc.0",
309
- "@elliemae/ds-button": "2.1.0-rc.0",
310
- "@elliemae/ds-grid": "2.1.0-rc.0",
311
- "@elliemae/ds-icons": "2.1.0-rc.0",
312
- "@elliemae/ds-indeterminate-progress-indicator": "2.1.0-rc.0",
313
- "@elliemae/ds-props-helpers": "2.1.0-rc.0",
314
- "@elliemae/ds-system": "2.1.0-rc.0",
315
- "@elliemae/ds-tooltip": "2.1.0-rc.0",
316
- "@elliemae/ds-truncated-tooltip-text": "2.1.0-rc.0",
308
+ "@elliemae/ds-banner": "2.1.0-rc.1",
309
+ "@elliemae/ds-button": "2.1.0-rc.1",
310
+ "@elliemae/ds-grid": "2.1.0-rc.1",
311
+ "@elliemae/ds-icons": "2.1.0-rc.1",
312
+ "@elliemae/ds-indeterminate-progress-indicator": "2.1.0-rc.1",
313
+ "@elliemae/ds-props-helpers": "2.1.0-rc.1",
314
+ "@elliemae/ds-system": "2.1.0-rc.1",
315
+ "@elliemae/ds-tooltip": "2.1.0-rc.1",
316
+ "@elliemae/ds-truncated-tooltip-text": "2.1.0-rc.1",
317
317
  "prop-types": "~15.7.2",
318
318
  "react-desc": "~4.1.2",
319
319
  "react-virtual": "~2.3.2"