add autocompletion

This commit is contained in:
gempir 2020-02-08 13:58:11 +01:00
parent dbdaee0069
commit a86f9e5baa
5 changed files with 52 additions and 17 deletions

View file

@ -4,6 +4,7 @@
"description": "frontend for justlog", "description": "frontend for justlog",
"repository": "github.com/gempir/justlog", "repository": "github.com/gempir/justlog",
"dependencies": { "dependencies": {
"prop-types": "^15.7.2",
"react": "^16.12.0", "react": "^16.12.0",
"react-dom": "^16.12.0", "react-dom": "^16.12.0",
"react-redux": "^7.1.3", "react-redux": "^7.1.3",

View file

@ -1,19 +1,39 @@
import React, { Component } from "react"; import React, { Component } from "react";
export default class AutocompleteInput extends Component { export default class AutocompleteInput extends Component {
render() {
state = {
focused: false,
};
input;
render() {
return <div className="AutocompleteInput"> return <div className="AutocompleteInput">
<input <input
type="text" type="text"
ref={el => this.input = el}
placeholder={this.props.placeholder} placeholder={this.props.placeholder}
onChange={this.props.onChange} onChange={e => this.props.onChange(e.target.value)}
onFocus={() => this.setState({ focused: true })}
onBlur={() => this.setState({ focused: false })}
value={this.props.value} value={this.props.value}
/> />
<ul> {this.state.focused && <ul>
{this.props.autocompletions {this.props.autocompletions
.filter(channel => channel.name.includes(this.props.value)) .filter(completion => completion.includes(this.props.value))
.map(channel => <li key={channel.userID} onClick={() => this.setChannel(channel.name)}>{channel.name}</li>)} .map(completion =>
</ul> <li key={completion} onClick={() => this.handleClick(completion)} onMouseDown={e => e.preventDefault()}>
{completion}
</li>
)}
</ul>}
</div> </div>
} }
handleClick = (completion) => {
this.props.onChange(completion);
this.input.blur();
this.props.onAutocompletionClick(completion);
}
} }

View file

@ -16,6 +16,8 @@ class Filter extends Component {
} }
} }
username;
componentDidMount() { componentDidMount() {
if (this.props.currentChannel && this.props.currentUsername) { if (this.props.currentChannel && this.props.currentUsername) {
this.props.searchLogs(this.props.currentChannel, this.props.currentUsername, this.state.year, this.state.month); this.props.searchLogs(this.props.currentChannel, this.props.currentUsername, this.state.year, this.state.month);
@ -23,18 +25,11 @@ class Filter extends Component {
} }
render() { render() {
const completions = this.props.channels
.filter(channel => channel.name.includes(this.props.currentChannel));
const autocompletions = [];
for (const completion of completions) {
autocompletions.push(<li key={completion.userID} onClick={() => this.setChannel(completion.name)}>{completion.name}</li>);
}
return ( return (
<form className="filter" autoComplete="off" onSubmit={this.onSubmit}> <form className="filter" autoComplete="off" onSubmit={this.onSubmit}>
<AutocompleteInput placeholder="pajlada" onChange={this.onChannelChange} value={this.props.currentChannel} autocompletions={this.props.channels} /> <AutocompleteInput placeholder="pajlada" onChange={this.onChannelChange} value={this.props.currentChannel} onAutocompletionClick={() => this.username.focus()} autocompletions={this.props.channels.map(channel => channel.name)} />
<input <input
ref={el => this.username = el}
type="text" type="text"
placeholder="gempir" placeholder="gempir"
onChange={this.onUsernameChange} onChange={this.onUsernameChange}
@ -45,8 +40,8 @@ class Filter extends Component {
) )
} }
onChannelChange = (e) => { onChannelChange = (channel) => {
this.props.dispatch(setCurrent(e.target.value, this.props.currentUsername)); this.props.dispatch(setCurrent(channel, this.props.currentUsername));
} }
onUsernameChange = (e) => { onUsernameChange = (e) => {

View file

@ -7,9 +7,27 @@
ul { ul {
position: absolute; position: absolute;
z-index: 100;
margin: 0;
padding: 0;
color: white;
list-style-type: none;
background: $grey-medium; background: $grey-medium;
top: 100%; top: 100%;
left: 0; left: 0;
right: 0; right: 0;
@include box-shadow(2);
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
li {
cursor: pointer;
padding: 0.5rem;
font-size: 0.8rem;
&:hover {
background: $grey-light;
}
}
} }
} }

View file

@ -7813,6 +7813,7 @@ fsevents@^1.2.7:
mini-css-extract-plugin: ^0.9.0 mini-css-extract-plugin: ^0.9.0
node-sass: ^4.13.1 node-sass: ^4.13.1
pnp-webpack-plugin: ^1.6.0 pnp-webpack-plugin: ^1.6.0
prop-types: ^15.7.2
react: ^16.12.0 react: ^16.12.0
react-dom: ^16.12.0 react-dom: ^16.12.0
react-redux: ^7.1.3 react-redux: ^7.1.3