Add basic autocompletion

This commit is contained in:
Simon Ser
2020-06-29 12:36:17 +02:00
parent 2f284f183a
commit 20be67503b
2 changed files with 53 additions and 3 deletions
+22 -1
View File
@@ -55,6 +55,7 @@ export default class App extends Component {
this.handleComposerSubmit = this.handleComposerSubmit.bind(this); this.handleComposerSubmit = this.handleComposerSubmit.bind(this);
this.handleNickClick = this.handleNickClick.bind(this); this.handleNickClick = this.handleNickClick.bind(this);
this.handleJoinClick = this.handleJoinClick.bind(this); this.handleJoinClick = this.handleJoinClick.bind(this);
this.autocomplete = this.autocomplete.bind(this);
if (window.localStorage && localStorage.getItem("autoconnect")) { if (window.localStorage && localStorage.getItem("autoconnect")) {
var connectParams = JSON.parse(localStorage.getItem("autoconnect")); var connectParams = JSON.parse(localStorage.getItem("autoconnect"));
@@ -554,6 +555,26 @@ export default class App extends Component {
this.client.send({ command: "JOIN", params: [channel] }); this.client.send({ command: "JOIN", params: [channel] });
} }
autocomplete(prefix) {
if (!this.state.activeBuffer) {
return null;
}
var buf = this.state.buffers.get(this.state.activeBuffer);
prefix = prefix.toLowerCase();
var repl = null;
for (var nick of buf.members.keys()) {
if (nick.toLowerCase().startsWith(prefix)) {
if (repl) {
return null;
}
repl = nick;
}
}
return repl;
}
componentDidMount() { componentDidMount() {
if (this.state.connectParams.autoconnect) { if (this.state.connectParams.autoconnect) {
this.connect(this.state.connectParams); this.connect(this.state.connectParams);
@@ -609,7 +630,7 @@ export default class App extends Component {
</section> </section>
</> </>
${memberList} ${memberList}
<${Composer} ref=${this.composer} readOnly=${this.state.activeBuffer == SERVER_BUFFER} onSubmit=${this.handleComposerSubmit}/> <${Composer} ref=${this.composer} readOnly=${this.state.activeBuffer == SERVER_BUFFER} onSubmit=${this.handleComposerSubmit} autocomplete=${this.autocomplete}/>
`; `;
} }
} }
+31 -2
View File
@@ -11,6 +11,7 @@ export default class Composer extends Component {
this.handleInput = this.handleInput.bind(this); this.handleInput = this.handleInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this); this.handleSubmit = this.handleSubmit.bind(this);
this.handleInputKeyDown = this.handleInputKeyDown.bind(this);
this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this); this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this);
} }
@@ -24,8 +25,36 @@ export default class Composer extends Component {
this.setState({ text: "" }); this.setState({ text: "" });
} }
handleInputKeyDown(event) {
if (!this.props.autocomplete || event.key !== "Tab") {
return;
}
var text = this.state.text;
var i;
for (i = text.length - 1; i >= 0; i--) {
if (text[i] === " ") {
break;
}
}
var prefix = text.slice(i + 1);
if (!prefix) {
return;
}
event.preventDefault();
var repl = this.props.autocomplete(prefix);
if (!repl) {
return;
}
text = text.slice(0, i + 1) + repl;
this.setState({ text });
}
handleWindowKeyDown(event) { handleWindowKeyDown(event) {
if (document.activeElement == document.body && event.key == "/" && !this.state.text) { if (document.activeElement === document.body && event.key === "/" && !this.state.text) {
event.preventDefault(); event.preventDefault();
this.setState({ text: "/" }, () => { this.setState({ text: "/" }, () => {
this.focus(); this.focus();
@@ -49,7 +78,7 @@ export default class Composer extends Component {
render() { render() {
return html` return html`
<form id="composer" class="${this.props.readOnly && !this.state.text ? "read-only" : ""}" onInput=${this.handleInput} onSubmit=${this.handleSubmit}> <form id="composer" class="${this.props.readOnly && !this.state.text ? "read-only" : ""}" onInput=${this.handleInput} onSubmit=${this.handleSubmit}>
<input type="text" name="text" ref=${this.textInput} value=${this.state.text} placeholder="Type a message"/> <input type="text" name="text" ref=${this.textInput} value=${this.state.text} placeholder="Type a message" onKeyDown=${this.handleInputKeyDown}/>
</form> </form>
`; `;
} }