diff --git a/src/TabComplete.js b/src/TabComplete.js index 1a798feba7..a14a7dadc6 100644 --- a/src/TabComplete.js +++ b/src/TabComplete.js @@ -26,16 +26,16 @@ class TabComplete { this.opts = opts; this.tabStruct = { - completing: false, original: null, index: 0 }; + this.completing = false; this.list = []; this.textArea = opts.textArea; } /** - * @param {String[]} completeList + * @param {TabComplete.Entry[]} completeList */ setCompletionList(completeList) { this.list = completeList; @@ -46,7 +46,7 @@ class TabComplete { } isTabCompleting() { - return this.tabStruct.completing; + return this.completing; } next() { @@ -54,6 +54,15 @@ class TabComplete { this.setCompletionOption(); } + /** + * @param {Number} numAheadToPeek + * @return {TabComplete.Entry[]} + */ + peek(numAheadToPeek) { + var current = this.list[this.tabStruct.index]; + return [current]; + } + prev() { this.tabStruct.index --; if (this.tabStruct.index < 0) { @@ -81,8 +90,8 @@ class TabComplete { // FIXME: could do better than linear search here for (var i=0; i < this.list.length; i++) { if (searchIndex < targetIndex) { - if (this.list[i].toLowerCase().indexOf(search[1].toLowerCase()) === 0) { - expansion = this.list[i]; + if (this.list[i].text.toLowerCase().indexOf(search[1].toLowerCase()) === 0) { + expansion = this.list[i].text; searchIndex++; } } @@ -121,6 +130,12 @@ class TabComplete { } } + notifyStateChange() { + if (this.opts.onStateChange) { + this.opts.onStateChange(this.completing); + } + } + /** * @param {DOMEvent} e * @return {Boolean} True if the tab complete state changed as a result of @@ -128,13 +143,11 @@ class TabComplete { */ onKeyDown(ev) { if (ev.keyCode !== KEY_TAB) { - if (ev.keyCode !== KEY_SHIFT && this.tabStruct.completing) { + if (ev.keyCode !== KEY_SHIFT && this.completing) { // they're resuming typing; reset tab complete state vars. - this.tabStruct.completing = false; + this.completing = false; this.tabStruct.index = 0; - if (this.opts.onStateChange) { - this.opts.onStateChange(this.tabStruct.completing); - } + this.notifyStateChange(); return true; } return false; @@ -146,14 +159,11 @@ class TabComplete { } // init struct if necessary - if (!this.tabStruct.completing) { - this.tabStruct.completing = true; + if (!this.completing) { + this.completing = true; this.tabStruct.index = 0; // cache starting text this.tabStruct.original = this.textArea.value; - if (this.opts.onStateChange) { - this.opts.onStateChange(this.tabStruct.completing); - } } if (ev.shiftKey) { @@ -164,10 +174,16 @@ class TabComplete { } // prevent the default TAB operation (typically focus shifting) ev.preventDefault(); + this.notifyStateChange(); return true; } }; +TabComplete.Entry = function(text, image) { + this.text = text; + this.image = image; +}; + module.exports = TabComplete; diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index b7341e4f89..80f65ce0a4 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1290,7 +1290,7 @@ module.exports = React.createClass({ else if (this.tabComplete.isTabCompleting()) { var TabCompleteBar = sdk.getComponent('rooms.TabCompleteBar'); statusBar = ( - + ); } else if (this.state.hasUnsentMessages) { diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index f4a694a123..4d68cace8d 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -31,6 +31,7 @@ var MatrixClientPeg = require("../../../MatrixClientPeg"); var SlashCommands = require("../../../SlashCommands"); var Modal = require("../../../Modal"); var CallHandler = require('../../../CallHandler'); +var TabComplete = require("../../../TabComplete"); var sdk = require('../../../index'); var dis = require("../../../dispatcher"); @@ -228,7 +229,7 @@ module.exports = React.createClass({ } } }).map(function(m) { - return m.name || m.userId; + return new TabComplete.Entry(m.name || m.userId); }); } if (this.props.tabComplete) { diff --git a/src/components/views/rooms/TabCompleteBar.js b/src/components/views/rooms/TabCompleteBar.js index c060202099..af695eccc5 100644 --- a/src/components/views/rooms/TabCompleteBar.js +++ b/src/components/views/rooms/TabCompleteBar.js @@ -22,9 +22,19 @@ var MatrixClientPeg = require("../../../MatrixClientPeg"); module.exports = React.createClass({ displayName: 'TabCompleteBar', + propTypes: { + entries: React.PropTypes.array.isRequired + }, + render: function() { return ( -
Tab Complete
+
+ {this.props.entries.map(function(entry, i) { + return ( +
{entry.text}
+ ); + })} +
); } });