mirror of
https://github.com/element-hq/element-web
synced 2024-11-28 20:38:55 +03:00
Auto-complete clicked suggestions
This commit is contained in:
parent
0dbb8d5294
commit
e541ddb060
5 changed files with 44 additions and 15 deletions
|
@ -29,6 +29,7 @@ class TabComplete {
|
|||
opts.wordSuffix = opts.wordSuffix || "";
|
||||
opts.allowLooping = opts.allowLooping || false;
|
||||
opts.autoEnterTabComplete = opts.autoEnterTabComplete || false;
|
||||
opts.onClickCompletes = opts.onClickCompletes || false;
|
||||
this.opts = opts;
|
||||
this.completing = false;
|
||||
this.list = []; // full set of tab-completable things
|
||||
|
@ -45,6 +46,14 @@ class TabComplete {
|
|||
*/
|
||||
setCompletionList(completeList) {
|
||||
this.list = completeList;
|
||||
if (this.opts.onClickCompletes) {
|
||||
// assign onClick listeners for each entry to complete the text
|
||||
this.list.forEach((l) => {
|
||||
l.onClick = () => {
|
||||
this.completeTo(l.getText());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,6 +82,17 @@ class TabComplete {
|
|||
this._calculateCompletions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do an auto-complete with the given word. This terminates the tab-complete.
|
||||
* @param {string} someVal
|
||||
*/
|
||||
completeTo(someVal) {
|
||||
this.textArea.value = this._replaceWith(someVal, true);
|
||||
this.stopTabCompleting();
|
||||
// keep focus on the text area
|
||||
this.textArea.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} numAheadToPeek Return *up to* this many elements.
|
||||
* @return {Entry[]}
|
||||
|
@ -184,15 +204,10 @@ class TabComplete {
|
|||
}
|
||||
var looped = this.currentIndex === 0; // catch forward and backward looping
|
||||
|
||||
var suffix = "";
|
||||
|
||||
if (this.currentIndex !== 0) { // don't suffix the original text!
|
||||
suffix = this.isFirstWord ? this.opts.startingWordSuffix : this.opts.wordSuffix;
|
||||
}
|
||||
|
||||
// set textarea to this new value
|
||||
this.textArea.value = this._replaceWith(
|
||||
this.matchedList[this.currentIndex].text + suffix
|
||||
this.matchedList[this.currentIndex].text,
|
||||
this.currentIndex !== 0 // don't suffix the original text!
|
||||
);
|
||||
|
||||
// visual display to the user that we looped - TODO: This should be configurable
|
||||
|
@ -211,8 +226,15 @@ class TabComplete {
|
|||
}
|
||||
}
|
||||
|
||||
_replaceWith(newVal) {
|
||||
return this.originalText.replace(MATCH_REGEX, newVal);
|
||||
_replaceWith(newVal, includeSuffix) {
|
||||
var replacementText = (
|
||||
newVal + (
|
||||
includeSuffix ?
|
||||
(this.isFirstWord ? this.opts.startingWordSuffix : this.opts.wordSuffix) :
|
||||
""
|
||||
)
|
||||
);
|
||||
return this.originalText.replace(MATCH_REGEX, replacementText);
|
||||
}
|
||||
|
||||
_calculateCompletions() {
|
||||
|
|
|
@ -41,6 +41,13 @@ class Entry {
|
|||
getKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this entry is clicked.
|
||||
*/
|
||||
onClick() {
|
||||
// NOP
|
||||
}
|
||||
}
|
||||
|
||||
class MemberEntry extends Entry {
|
||||
|
|
|
@ -93,6 +93,7 @@ module.exports = React.createClass({
|
|||
wordSuffix: " ",
|
||||
allowLooping: false,
|
||||
autoEnterTabComplete: true,
|
||||
onClickCompletes: true,
|
||||
onStateChange: (isCompleting) => {
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
|
|
@ -201,8 +201,8 @@ module.exports = React.createClass({
|
|||
this.onEnter(ev);
|
||||
}
|
||||
else if (ev.keyCode === KeyCode.TAB) {
|
||||
if (this.props.tabComplete && this.props.room) {
|
||||
var memberList = [];
|
||||
if (this.props.room) {
|
||||
// TODO: We should cache this list and only update it when the
|
||||
// member list changes. It's also horrendous that this is done here.
|
||||
memberList = this.props.room.getJoinedMembers().sort(function(a, b) {
|
||||
|
@ -231,8 +231,6 @@ module.exports = React.createClass({
|
|||
}).map(function(m) {
|
||||
return new MemberEntry(m);
|
||||
});
|
||||
}
|
||||
if (this.props.tabComplete) {
|
||||
this.props.tabComplete.setCompletionList(memberList);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,10 +31,11 @@ module.exports = React.createClass({
|
|||
<div className="mx_TabCompleteBar">
|
||||
{this.props.entries.map(function(entry, i) {
|
||||
return (
|
||||
<div key={entry.getKey() || i + ""} className="mx_TabCompleteBar_item">
|
||||
<div key={entry.getKey() || i + ""} className="mx_TabCompleteBar_item"
|
||||
onClick={entry.onClick.bind(entry)} >
|
||||
{entry.getImageJsx()}
|
||||
<span className="mx_TabCompleteBar_text">
|
||||
{entry.text}
|
||||
{entry.getText()}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue