+const MAX_PROMPT_ITEMS = 20;
+
function undisplay(element) {
element.style.display="none";
}
const category_input = this.category.current;
const category = category_input.value;
- if (/[0-9]/.test(category))
- category_input.setCustomValidity("");
+ const match = category.match(/[0-9]+/);
+ if (match) {
+ const num_items = parseInt(match[0], 10);
+ if (num_items <= MAX_PROMPT_ITEMS)
+ category_input.setCustomValidity("");
+ }
}
- handle_submit(event) {
+ async handle_submit(event) {
const form = event.currentTarget;
const category_input = this.category.current;
const category = category_input.value;
return;
}
- fetch_post_json("prompts", {
- items: parseInt(match[0], 10),
+ const num_items = parseInt(match[0], 10);
+
+ if (num_items > MAX_PROMPT_ITEMS) {
+ category_input.setCustomValidity(`Maximum number of items is ${MAX_PROMPT_ITEMS}`);
+ form.reportValidity();
+ return;
+ }
+
+ const response = await fetch_post_json("prompts", {
+ items: num_items,
prompt: category
});
+ if (response.status === 200) {
+ const result = await response.json();
+ console.log(result);
+ if (! result.valid) {
+ add_message("danger", result.message);
+ return;
+ }
+ } else {
+ add_message("danger", "An error occurred submitting your category");
+ }
+
form.reset();
}
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>
);
})}
{state.scores.words.map(word => {
return (
<li key={word.word}>
- {word.word}:
- {word.players.map(p => {
- return (
- <span key={p}>{p}{" "}</span>
- );
- })}
+ {`${word.word}: ${word.players.join(', ')}`}
</li>
);
})}