Skip to content

Commit

Permalink
Fixing Issue 17 and Issue 10
Browse files Browse the repository at this point in the history
  • Loading branch information
paulofla committed May 27, 2017
1 parent 4909692 commit f20cc50
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 20 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [0.0.26] - 2017-05-12
## [0.0.26] - 2017-05-27

- Fixed #17: Showing some messages twice (Paul.O'Flaherty)
- Fixed #10: Made the conversation scrollable -> This is a temporary fix (Paul.O'Flaherty)

## [0.0.25] - 2017-04-02

Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ This parameter is optional.
<Conversation height={300} messages={messages} turnOffLoop />
```

### Turning on scrollable conversation (Temporary fix - v1 release will have a more supported scrollable conversation)
The conversation is not scrollable by default.

To enable scrolling, add a isScrollable attribute to Conversation.

This parameter is optional.
```
<Conversation height={300} messages={messages} turnOffLoop isScrollable />
```

## Storybook examples

Live stories are displayed [here](http://sevenleaps.github.io/chat-template/).
Expand Down
6 changes: 3 additions & 3 deletions builds/chat-template-min.js

Large diffs are not rendered by default.

62 changes: 57 additions & 5 deletions builds/chat-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -14759,7 +14759,8 @@ var showChatTemplate =

_this.state = {
messages: props.messages ? props.messages.slice() : [],
historicMessages: props.historicMessages ? props.historicMessages.slice() : []
historicMessages: props.historicMessages ? props.historicMessages.slice() : [],
isScrollable: props.isScrollable
};
_this.keyPress = _this.keyPress.bind(_this);
return _this;
Expand All @@ -14774,8 +14775,13 @@ var showChatTemplate =
backColor: '#dcf8c6',
duration: 800
};
this.state.messages.push(message);
this.setState({ messages: this.state.messages });
var messages = this.state.messages;
messages = messages.filter(function (element) {
return element.type !== 'typing';
});
messages.push({ type: 'typing', duration: 500, inbound: true });
messages.push(message);
this.setState({ messages: messages });
}
}, {
key: 'keyPress',
Expand All @@ -14794,7 +14800,7 @@ var showChatTemplate =
return _react2.default.createElement(
'div',
{ className: (0, _aphrodite.css)(style.chat) },
_react2.default.createElement(_Conversation2.default, { styles: chatStyles, historicMessages: this.state.historicMessages, messages: this.state.messages, turnOffLoop: true }),
_react2.default.createElement(_Conversation2.default, { styles: chatStyles, historicMessages: this.state.historicMessages, messages: this.state.messages, turnOffLoop: true, isScrollable: this.state.isScrollable }),
_react2.default.createElement(
'div',
{ className: (0, _aphrodite.css)(style.textInputContainer) },
Expand All @@ -14809,6 +14815,7 @@ var showChatTemplate =

Chat.propTypes = {
turnOffLoop: _react.PropTypes.bool,
isScrollable: _react.PropTypes.bool,
messages: _react.PropTypes.arrayOf(_react.PropTypes.shape({
message: _react.PropTypes.string,
src: _react.PropTypes.string,
Expand Down Expand Up @@ -14956,12 +14963,56 @@ var showChatTemplate =
}
};

_this.paneDidMount = function (node) {
if (node && _this.state.isScrollable) {
node.addEventListener('wheel', function (event) {
var mouseMoveY = event.deltaY;
var conversationDisplayElement = node;
var scrollElement = node.children[0];
var messagesElement = node.children[0].children[1];
var heightOfDisplay = conversationDisplayElement.getBoundingClientRect().height;
var bottomOfDisplay = conversationDisplayElement.getBoundingClientRect().bottom;
var heightOfActualMessages = messagesElement.getBoundingClientRect().height;
var scrollElementClientRect = scrollElement.getBoundingClientRect();
var scrollElementTopOfMessages = scrollElementClientRect.top;

var maxTop = heightOfDisplay - bottomOfDisplay;
var minTop = (heightOfActualMessages - heightOfDisplay) * -1;

var isScrollingEnabled = heightOfActualMessages > heightOfDisplay;

if (isScrollingEnabled) {
var topPixels = void 0;
if (mouseMoveY < 0) {
var isScrollAmountAboveTopMessage = maxTop < scrollElementTopOfMessages - mouseMoveY;
if (isScrollAmountAboveTopMessage) {
topPixels = maxTop;
} else {
var topElementToBeMoved = scrollElementTopOfMessages - mouseMoveY;
topPixels = isScrollAmountAboveTopMessage ? maxTop : topElementToBeMoved;
}
} else {
var isScrollAmountBelowBottomMessage = minTop > scrollElementTopOfMessages - mouseMoveY + maxTop;
if (isScrollAmountBelowBottomMessage) {
topPixels = minTop;
} else {
var _topElementToBeMoved = scrollElementTopOfMessages - mouseMoveY + maxTop;
topPixels = isScrollAmountBelowBottomMessage ? minTop : _topElementToBeMoved;
}
}
scrollElement.style.top = topPixels + 'px';
}
});
}
};

_this.state = {
startingDelay: props.delay || 1000,
messages: props.historicMessages ? props.historicMessages.slice() : [],
historicMessages: props.historicMessages ? props.historicMessages.slice() : [],
messagesToBeDisplayed: props.messages.slice(),
originalMessagesToBeDisplayed: props.messages.slice(),
isScrollable: props.isScrollable,
isTyping: false,
inbound: true,
reset: false,
Expand Down Expand Up @@ -15017,7 +15068,7 @@ var showChatTemplate =
_react2.default.createElement(_ImageLoader2.default, { messages: this.props.messages }),
_react2.default.createElement(
'div',
{ className: (0, _aphrodite.css)(style.messages) },
{ ref: this.paneDidMount, className: (0, _aphrodite.css)(style.messages) },
_react2.default.createElement(_Messages2.default, { key: this.state.reset, height: style.conversation.height, messages: this.state.messages })
),
_react2.default.createElement(
Expand All @@ -15036,6 +15087,7 @@ var showChatTemplate =
delay: _react.PropTypes.number,
height: _react.PropTypes.number,
turnOffLoop: _react.PropTypes.bool,
isScrollable: _react.PropTypes.bool,
messages: _react.PropTypes.arrayOf(_react.PropTypes.shape({
message: _react.PropTypes.string,
src: _react.PropTypes.string,
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chat-template",
"version": "0.0.25",
"version": "0.0.26",
"description": "Chat-Template is a React component that enables quick prototyping of bot conversations.",
"repository": {
"type": "git",
Expand Down Expand Up @@ -56,10 +56,12 @@
},
"dependencies": {
"aphrodite": "0.3.1",
"object-assign-deep": "0.0.4",
"material-ui": "0.15.0",
"object-assign-deep": "0.0.4",
"react-addons-css-transition-group": "15.1.0",
"react-dom": "15.1.0"
"react-dom": "15.1.0",
"react-scroll": "^1.5.2",
"react-scrollbar": "^0.5.1"
},
"main": "dist/index.js",
"engines": {
Expand Down
8 changes: 5 additions & 3 deletions src/Chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Chat extends React.Component {
this.state = {
messages: props.messages ? props.messages.slice() : [],
historicMessages: props.historicMessages ? props.historicMessages.slice() : [],
isScrollable: props.isScrollable,
};
this.keyPress = this.keyPress.bind(this);
}
Expand All @@ -44,9 +45,9 @@ class Chat extends React.Component {
};
let messages = this.state.messages;
messages = messages.filter((element) => element.type !== 'typing');
messages.push({type: 'typing', duration: 500, inbound: true});
messages.push({ type: 'typing', duration: 500, inbound: true });
messages.push(message);
this.setState({ messages: messages });
this.setState({ messages });
}
keyPress(e) {
if (e.key === 'Enter' && e.target.value) {
Expand All @@ -60,7 +61,7 @@ class Chat extends React.Component {

return (
<div className={css(style.chat)}>
<Conversation styles={chatStyles} historicMessages={this.state.historicMessages} messages={this.state.messages} turnOffLoop />
<Conversation styles={chatStyles} historicMessages={this.state.historicMessages} messages={this.state.messages} turnOffLoop isScrollable={this.state.isScrollable} />
<div className={css(style.textInputContainer)}>
<input type="text" onKeyPress={this.keyPress} className={css(style.textInput)} placeholder="Type your message here..." />
</div>
Expand All @@ -70,6 +71,7 @@ class Chat extends React.Component {
}
Chat.propTypes = {
turnOffLoop: PropTypes.bool,
isScrollable: PropTypes.bool,
messages: PropTypes.arrayOf(
PropTypes.shape({
message: PropTypes.string,
Expand Down
48 changes: 46 additions & 2 deletions src/Conversation.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Conversation extends React.Component {
historicMessages: props.historicMessages ? props.historicMessages.slice() : [],
messagesToBeDisplayed: props.messages.slice(),
originalMessagesToBeDisplayed: props.messages.slice(),
isScrollable: props.isScrollable,
isTyping: false,
inbound: true,
reset: false,
Expand Down Expand Up @@ -119,7 +120,49 @@ class Conversation extends React.Component {
});
this.timeoutId = setTimeout(this.showMessage, this.state.startingDelay);
}
}
};
paneDidMount = (node) => {
if (node && this.state.isScrollable) {
node.addEventListener('wheel', (event) => {
const mouseMoveY = event.deltaY;
const conversationDisplayElement = node;
const scrollElement = node.children[0];
const messagesElement = node.children[0].children[1];
const heightOfDisplay = conversationDisplayElement.getBoundingClientRect().height;
const bottomOfDisplay = conversationDisplayElement.getBoundingClientRect().bottom;
const heightOfActualMessages = messagesElement.getBoundingClientRect().height;
const scrollElementClientRect = scrollElement.getBoundingClientRect();
const scrollElementTopOfMessages = scrollElementClientRect.top;

const maxTop = heightOfDisplay - bottomOfDisplay;
const minTop = (heightOfActualMessages - heightOfDisplay) * -1;

const isScrollingEnabled = heightOfActualMessages > heightOfDisplay;

if (isScrollingEnabled) {
let topPixels;
if (mouseMoveY < 0) {
const isScrollAmountAboveTopMessage = maxTop < (scrollElementTopOfMessages - mouseMoveY);
if (isScrollAmountAboveTopMessage) {
topPixels = maxTop;
} else {
const topElementToBeMoved = scrollElementTopOfMessages - mouseMoveY;
topPixels = isScrollAmountAboveTopMessage ? maxTop : topElementToBeMoved;
}
} else {
const isScrollAmountBelowBottomMessage = minTop > (scrollElementTopOfMessages - mouseMoveY + maxTop);
if (isScrollAmountBelowBottomMessage) {
topPixels = minTop;
} else {
const topElementToBeMoved = (scrollElementTopOfMessages - mouseMoveY) + maxTop;
topPixels = isScrollAmountBelowBottomMessage ? minTop : topElementToBeMoved;
}
}
scrollElement.style.top = `${topPixels}px`;
}
});
}
};

render() {
const { isTyping, inbound } = this.state;
Expand All @@ -136,7 +179,7 @@ class Conversation extends React.Component {
return (
<div className={css(style.conversation)}>
<ImageLoader messages={this.props.messages} />
<div className={css(style.messages)}>
<div ref={this.paneDidMount} className={css(style.messages)}>
<Messages key={this.state.reset} height={style.conversation.height} messages={this.state.messages} />
</div>
<div className={css(isInbound && style.inbound, isOutbound && style.outbound, !isTyping && style.noTyping)}>
Expand All @@ -151,6 +194,7 @@ Conversation.propTypes = {
delay: PropTypes.number,
height: PropTypes.number,
turnOffLoop: PropTypes.bool,
isScrollable: PropTypes.bool,
messages: PropTypes.arrayOf(
PropTypes.shape({
message: PropTypes.string,
Expand Down
6 changes: 3 additions & 3 deletions src/stories/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ storiesOf('Chat', module)
</div>
);
})
.add('Ch2at configured styles and ends at the last message and allows the user to add messages', () => {
.add('Chat configured styles and ends at the last message and allows the user to add and scroll messages', () => {
const messagesForConversation = [
{
type: 'typing',
duration: 500,
inbound: true
inbound: true,
},
{
message: 'Press enter to write a message',
Expand All @@ -93,7 +93,7 @@ storiesOf('Chat', module)
];
return (
<div>
<Chat historicMessages={historicMessages} messages={messagesForConversation} turnOffLoop />
<Chat historicMessages={historicMessages} messages={messagesForConversation} turnOffLoop isScrollable />
</div>
);
});

0 comments on commit f20cc50

Please sign in to comment.