Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions frontend/src/html/popups.html
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,10 @@
autocomplete="off"
title="include"
/>
<label class="checkbox">
<input id="exactMatchOnly" type="checkbox" />
Exact match only
</label>
</div>
<div class="group">
<div class="title">exclude</div>
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/styles/inputs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ label.checkboxWithSub {
}
}

#wordFilterModal #exactMatchOnly {
width: 1.25em;
}

input[type="checkbox"] {
appearance: none;
height: 1.25em;
Expand Down
86 changes: 43 additions & 43 deletions frontend/src/ts/modals/word-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import { LayoutObject } from "@monkeytype/schemas/layouts";
type FilterPreset = {
display: string;
getIncludeString: (layout: LayoutObject) => string[][];
getExcludeString: (layout: LayoutObject) => string[][];
getExcludeString?: (layout: LayoutObject) => string[][];
};

const exactMatchCheckbox = $("#wordFilterModal #exactMatchOnly");

const presets: Record<string, FilterPreset> = {
homeKeys: {
display: "home keys",
Expand All @@ -27,13 +29,6 @@ const presets: Record<string, FilterPreset> = {
const homeKeysRight = layout.keys.row3.slice(6, 10);
return [...homeKeysLeft, ...homeKeysRight];
},
getExcludeString: (layout) => {
const topRow = layout.keys.row2;
const bottomRow = layout.keys.row4;
const homeRowRight = layout.keys.row3.slice(10);
const homeRowMiddle = layout.keys.row3.slice(4, 6);
return [...topRow, ...homeRowMiddle, ...homeRowRight, ...bottomRow];
},
},
leftHand: {
display: "left hand",
Expand All @@ -43,12 +38,6 @@ const presets: Record<string, FilterPreset> = {
const bottomRowInclude = layout.keys.row4.slice(0, 5);
return [...topRowInclude, ...homeRowInclude, ...bottomRowInclude];
},
getExcludeString: (layout) => {
const topRowExclude = layout.keys.row2.slice(5);
const homeRowExclude = layout.keys.row3.slice(5);
const bottomRowExclude = layout.keys.row4.slice(5);
return [...topRowExclude, ...homeRowExclude, ...bottomRowExclude];
},
},
rightHand: {
display: "right hand",
Expand All @@ -58,45 +47,24 @@ const presets: Record<string, FilterPreset> = {
const bottomRowInclude = layout.keys.row4.slice(4);
return [...topRowInclude, ...homeRowInclude, ...bottomRowInclude];
},
getExcludeString: (layout) => {
const topRowExclude = layout.keys.row2.slice(0, 5);
const homeRowExclude = layout.keys.row3.slice(0, 5);
const bottomRowExclude = layout.keys.row4.slice(0, 4);
return [...topRowExclude, ...homeRowExclude, ...bottomRowExclude];
},
},
homeRow: {
display: "home row",
getIncludeString: (layout) => {
return layout.keys.row3;
},
getExcludeString: (layout) => {
const topRowExclude = layout.keys.row2;
const bottomRowExclude = layout.keys.row4;
return [...topRowExclude, ...bottomRowExclude];
},
},
topRow: {
display: "top row",
getIncludeString: (layout) => {
return layout.keys.row2;
},
getExcludeString: (layout) => {
const homeRowExclude = layout.keys.row3;
const bottomRowExclude = layout.keys.row4;
return [...homeRowExclude, ...bottomRowExclude];
},
},
bottomRow: {
display: "bottom row",
getIncludeString: (layout) => {
return layout.keys.row4;
},
getExcludeString: (layout) => {
const topRowExclude = layout.keys.row2;
const homeRowExclude = layout.keys.row3;
return [...topRowExclude, ...homeRowExclude];
},
},
};

Expand Down Expand Up @@ -165,10 +133,18 @@ function hide(hideOptions?: HideOptions<OutgoingData>): void {
}

async function filter(language: Language): Promise<string[]> {
const exactMatchOnly = exactMatchCheckbox.is(":checked");
let filterin = $("#wordFilterModal .wordIncludeInput").val() as string;
filterin = Misc.escapeRegExp(filterin?.trim());
filterin = filterin.replace(/\s+/gi, "|");
const regincl = new RegExp(filterin, "i");
let regincl;

if (exactMatchOnly) {
regincl = new RegExp("^[" + filterin + "]+$", "i");
} else {
regincl = new RegExp(filterin, "i");
}

let filterout = $("#wordFilterModal .wordExcludeInput").val() as string;
filterout = Misc.escapeRegExp(filterout.trim());
filterout = filterout.replace(/\s+/gi, "|");
Expand Down Expand Up @@ -202,7 +178,7 @@ async function filter(language: Language): Promise<string[]> {
}
for (const word of languageWordList.words) {
const test1 = regincl.test(word);
const test2 = regexcl.test(word);
const test2 = exactMatchOnly ? false : regexcl.test(word);
if (
((test1 && !test2) || (test1 && filterout === "")) &&
word.length <= maxLength &&
Expand Down Expand Up @@ -236,6 +212,19 @@ async function apply(set: boolean): Promise<void> {
});
}

function setExactMatchInput(disable: boolean): void {
const wordExcludeInputEl = $("#wordFilterModal #wordExcludeInput");

if (disable) {
$("#wordFilterModal #wordExcludeInput").val("");
wordExcludeInputEl.attr("disabled", "disabled");
} else {
wordExcludeInputEl.removeAttr("disabled");
}

exactMatchCheckbox.prop("checked", disable);
}

function disableButtons(): void {
for (const button of modal.getModal().querySelectorAll("button")) {
button.setAttribute("disabled", "true");
Expand Down Expand Up @@ -270,13 +259,24 @@ async function setup(): Promise<void> {
.map((x) => x[0])
.join(" "),
);
$("#wordExcludeInput").val(
presetToApply
.getExcludeString(layout)
.map((x) => x[0])
.join(" "),
);

if (presetToApply.getExcludeString === undefined) {
setExactMatchInput(true);
} else {
setExactMatchInput(false);
$("#wordExcludeInput").val(
presetToApply
.getExcludeString(layout)
.map((x) => x[0])
.join(" "),
);
}
});

exactMatchCheckbox.on("change", () => {
setExactMatchInput(exactMatchCheckbox.is(":checked"));
});

$("#wordFilterModal button.addButton").on("click", () => {
$("#wordFilterModal .loadingIndicator").removeClass("hidden");
disableButtons();
Expand Down
Loading