Add basic autocompletion
This commit is contained in:
+22
-1
@@ -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
@@ -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>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user