constructor(props) {
super(props);
+ const word_sets = props.words.map(word => {
+ const set = new Set();
+ set.add(word);
+ return set;
+ });
+
this.state = {
- word_groups: props.words.map(word => [word]),
+ word_sets: word_sets,
submitted: false,
selected: null
};
async handle_submit() {
const response = await fetch_post_json(
`judging/${this.props.prompt.id}`,{
- word_groups: this.state.word_groups
+ word_groups: this.state.word_sets.map(set => Array.from(set))
}
);
handle_click(word) {
if (this.state.selected == word) {
/* Second click on same word removes the word from the group. */
- const new_groups = this.state.word_groups.filter(
- group => (! group.includes(this.state.selected)) || (group.length > 1)).map(
- group => {
- return group.filter(w => w !== this.state.selected);
- }
- );
+ const idx = this.state.word_sets.findIndex(s => s.has(word));
+ const set = this.state.word_sets[idx];
+ if (set.size === 1)
+ return;
+ const new_set = new Set([...set].filter(w => w !== word));
this.setState({
selected: null,
- word_groups: [...new_groups, [word]]
+ word_sets: [...this.state.word_sets.slice(0, idx),
+ new_set,
+ new Set().add(word),
+ ...this.state.word_sets.slice(idx+1)]
});
} else if (this.state.selected) {
/* Click of a second word groups the two together. */
- const new_groups = this.state.word_groups.filter(
- group => (! group.includes(word)) || (group.length > 1)).map(
- group => {
- if (group.includes(this.state.selected)) {
- if (! group.includes(word))
- return [...group, word];
- else
- return group;
- } else {
- return group.filter(w => w !== word);
- }
- }
- );
- this.setState({
- selected: null,
- word_groups: new_groups
- });
+ const idx1 = this.state.word_sets.findIndex(s => s.has(this.state.selected));
+ const idx2 = this.state.word_sets.findIndex(s => s.has(word));
+ const set1 = this.state.word_sets[idx1];
+ const set2 = this.state.word_sets[idx2];
+ const new_set = new Set([...set2, ...set1]);
+ if (idx1 < idx2) {
+ this.setState({
+ selected: null,
+ word_sets: [...this.state.word_sets.slice(0, idx1),
+ ...this.state.word_sets.slice(idx1 + 1, idx2),
+ new_set,
+ ...this.state.word_sets.slice(idx2 + 1)]
+ });
+ } else {
+ this.setState({
+ selected: null,
+ word_sets: [...this.state.word_sets.slice(0, idx2),
+ new_set,
+ ...this.state.word_sets.slice(idx2 + 1, idx1),
+ ...this.state.word_sets.slice(idx1 + 1)]
+ });
+ }
} else {
/* First click of a word selects it. */
this.setState({
what goes around comes around, so it's best to be generous when
judging.
</p>
- {this.state.word_groups.map(word_group => {
+ {this.state.word_sets.map(set => {
return (
<div
className="ambiguity-group"
- key={word_group[0]}
+ key={Array.from(set)[0]}
>
- {word_group.map(word => {
- return (
- <button
- className={this.state.selected === word ?
- btn_selected_class : btn_class }
- key={word}
- onClick={() => this.handle_click(word)}
+ {Array.from(set).map(word => {
+ return (
+ <button
+ className={this.state.selected === word ?
+ btn_selected_class : btn_class }
+ key={word}
+ onClick={() => this.handle_click(word)}
>
- {word}
- </button>
- );
- })}
+ {word}
+ </button>
+ );
+ })}
</div>
);
})}