|
@@ -13,12 +13,25 @@ import ChatMessageGroup from './ChatMessageGroup';
|
13
|
13
|
* @extends AbstractMessageContainer
|
14
|
14
|
*/
|
15
|
15
|
export default class MessageContainer extends AbstractMessageContainer {
|
|
16
|
+ /**
|
|
17
|
+ * Whether or not chat has been scrolled to the bottom of the screen. Used
|
|
18
|
+ * to determine if chat should be scrolled automatically to the bottom when
|
|
19
|
+ * the {@code ChatInput} resizes.
|
|
20
|
+ */
|
|
21
|
+ _isScrolledToBottom: boolean;
|
|
22
|
+
|
16
|
23
|
/**
|
17
|
24
|
* Reference to the HTML element at the end of the list of displayed chat
|
18
|
25
|
* messages. Used for scrolling to the end of the chat messages.
|
19
|
26
|
*/
|
20
|
27
|
_messagesListEndRef: Object;
|
21
|
28
|
|
|
29
|
+ /**
|
|
30
|
+ * A React ref to the HTML element containing all {@code ChatMessageGroup}
|
|
31
|
+ * instances.
|
|
32
|
+ */
|
|
33
|
+ _messageListRef: Object;
|
|
34
|
+
|
22
|
35
|
/**
|
23
|
36
|
* Initializes a new {@code MessageContainer} instance.
|
24
|
37
|
*
|
|
@@ -28,7 +41,12 @@ export default class MessageContainer extends AbstractMessageContainer {
|
28
|
41
|
constructor(props: Props) {
|
29
|
42
|
super(props);
|
30
|
43
|
|
|
44
|
+ this._isScrolledToBottom = true;
|
|
45
|
+
|
|
46
|
+ this._messageListRef = React.createRef();
|
31
|
47
|
this._messagesListEndRef = React.createRef();
|
|
48
|
+
|
|
49
|
+ this._onChatScroll = this._onChatScroll.bind(this);
|
32
|
50
|
}
|
33
|
51
|
|
34
|
52
|
/**
|
|
@@ -50,13 +68,29 @@ export default class MessageContainer extends AbstractMessageContainer {
|
50
|
68
|
});
|
51
|
69
|
|
52
|
70
|
return (
|
53
|
|
- <div id = 'chatconversation'>
|
|
71
|
+ <div
|
|
72
|
+ id = 'chatconversation'
|
|
73
|
+ onScroll = { this._onChatScroll }
|
|
74
|
+ ref = { this._messageListRef }>
|
54
|
75
|
{ messages }
|
55
|
76
|
<div ref = { this._messagesListEndRef } />
|
56
|
77
|
</div>
|
57
|
78
|
);
|
58
|
79
|
}
|
59
|
80
|
|
|
81
|
+ /**
|
|
82
|
+ * Scrolls to the bottom again if the instance had previously been scrolled
|
|
83
|
+ * to the bottom. This method is used when a resize has occurred below the
|
|
84
|
+ * instance and bottom scroll needs to be maintained.
|
|
85
|
+ *
|
|
86
|
+ * @returns {void}
|
|
87
|
+ */
|
|
88
|
+ maybeUpdateBottomScroll() {
|
|
89
|
+ if (this._isScrolledToBottom) {
|
|
90
|
+ this.scrollToBottom(false);
|
|
91
|
+ }
|
|
92
|
+ }
|
|
93
|
+
|
60
|
94
|
/**
|
61
|
95
|
* Automatically scrolls the displayed chat messages down to the latest.
|
62
|
96
|
*
|
|
@@ -71,4 +105,19 @@ export default class MessageContainer extends AbstractMessageContainer {
|
71
|
105
|
}
|
72
|
106
|
|
73
|
107
|
_getMessagesGroupedBySender: () => Array<Array<Object>>;
|
|
108
|
+
|
|
109
|
+ _onChatScroll: () => void;
|
|
110
|
+
|
|
111
|
+ /**
|
|
112
|
+ * Callback invoked to listen to the current scroll location.
|
|
113
|
+ *
|
|
114
|
+ * @private
|
|
115
|
+ * @returns {void}
|
|
116
|
+ */
|
|
117
|
+ _onChatScroll() {
|
|
118
|
+ const element = this._messageListRef.current;
|
|
119
|
+
|
|
120
|
+ this._isScrolledToBottom
|
|
121
|
+ = element.scrollHeight - element.scrollTop === element.clientHeight;
|
|
122
|
+ }
|
74
|
123
|
}
|