Implement sent message history (up/down keys).

This includes preserving and restoring partially entered text per room. This
is mostly ported straight from Angular.
pull/1/head
Kegan Dougal 2015-07-16 15:22:46 +01:00
parent 41bab56133
commit b043889169
1 changed files with 105 additions and 1 deletions

View File

@ -22,7 +22,9 @@ var dis = require("../../dispatcher");
var KeyCode = { var KeyCode = {
ENTER: 13, ENTER: 13,
TAB: 9, TAB: 9,
SHIFT: 16 SHIFT: 16,
UP: 38,
DOWN: 40
}; };
module.exports = { module.exports = {
@ -33,10 +35,105 @@ module.exports = {
original: null, original: null,
index: 0 index: 0
}; };
this.sentHistory = {
// The list of typed messages. Index 0 is more recent
data: [],
// The position in data currently displayed
position: -1,
// The room the history is for.
roomId: null,
// The original text before they hit UP
originalText: null,
// The textarea element to set text to.
element: null,
init: function(element, roomId) {
this.roomId = roomId;
this.element = element;
this.position = -1;
var storedData = window.sessionStorage.getItem(
"history_" + roomId
);
if (storedData) {
this.data = JSON.parse(storedData);
}
if (this.roomId) {
this.setLastTextEntry();
}
},
push: function(text) {
// store a message in the sent history
this.data.unshift(text);
window.sessionStorage.setItem(
"history_" + this.roomId,
JSON.stringify(this.data)
);
// reset history position
this.position = -1;
this.originalText = null;
},
// move in the history. Returns true if we managed to move.
next: function(offset) {
if (this.position === -1) {
// user is going into the history, save the current line.
this.originalText = this.element.value;
}
else {
// user may have modified this line in the history; remember it.
this.data[this.position] = this.element.value;
}
if (offset > 0 && this.position === (this.data.length - 1)) {
// we've run out of history
return false;
}
// retrieve the next item (bounded).
var newPosition = this.position + offset;
newPosition = Math.max(-1, newPosition);
newPosition = Math.min(newPosition, this.data.length - 1);
this.position = newPosition;
if (this.position !== -1) {
// show the message
this.element.value = this.data[this.position];
}
else if (this.originalText) {
// restore the original text the user was typing.
this.element.value = this.originalText;
}
return true;
},
saveLastTextEntry: function() {
// save the currently entered text in order to restore it later.
// NB: This isn't 'originalText' because we want to restore
// sent history items too!
var text = this.element.value;
window.sessionStorage.setItem("input_" + this.roomId, text);
},
setLastTextEntry: function() {
var text = window.sessionStorage.getItem("input_" + this.roomId);
if (text) {
this.element.value = text;
}
}
};
},
componentDidMount: function() {
this.sentHistory.init(
this.refs.textarea.getDOMNode(),
this.props.room.roomId
);
}, },
componentWillUnmount: function() { componentWillUnmount: function() {
dis.unregister(this.dispatcherRef); dis.unregister(this.dispatcherRef);
this.sentHistory.saveLastTextEntry();
}, },
onAction: function(payload) { onAction: function(payload) {
@ -49,6 +146,7 @@ module.exports = {
onKeyDown: function (ev) { onKeyDown: function (ev) {
if (ev.keyCode === KeyCode.ENTER) { if (ev.keyCode === KeyCode.ENTER) {
this.sentHistory.push(this.refs.textarea.getDOMNode().value);
this.onEnter(ev); this.onEnter(ev);
} }
else if (ev.keyCode === KeyCode.TAB) { else if (ev.keyCode === KeyCode.TAB) {
@ -58,6 +156,12 @@ module.exports = {
} }
this.onTab(ev, members); this.onTab(ev, members);
} }
else if (ev.keyCode === KeyCode.UP || ev.keyCode === KeyCode.DOWN) {
this.sentHistory.next(
ev.keyCode === KeyCode.UP ? 1 : -1
);
ev.preventDefault();
}
else if (ev.keyCode !== KeyCode.SHIFT && this.tabStruct.completing) { else if (ev.keyCode !== KeyCode.SHIFT && this.tabStruct.completing) {
// they're resuming typing; reset tab complete state vars. // they're resuming typing; reset tab complete state vars.
this.tabStruct.completing = false; this.tabStruct.completing = false;