diff --git a/frontend/src/ts/commandline/commandline.ts b/frontend/src/ts/commandline/commandline.ts index 5df7d9e2e87d..11e8c80775f8 100644 --- a/frontend/src/ts/commandline/commandline.ts +++ b/frontend/src/ts/commandline/commandline.ts @@ -243,7 +243,7 @@ async function filterSubgroup(): Promise { } const displaySplit = ( - usingSingleList + usingSingleList && !subgroup.excludeFromSingleList ? (command.singleListDisplayNoIcon ?? "") || command.display : command.display ) @@ -334,7 +334,9 @@ async function getSubgroup(): Promise { return subgroupOverride; } - if (usingSingleList) { + const top = CommandlineLists.getTopOfStack(); + + if (usingSingleList && !top.excludeFromSingleList) { if (cachedSingleSubgroup === null) { cachedSingleSubgroup = await CommandlineLists.getSingleSubgroup(); } else { @@ -342,7 +344,7 @@ async function getSubgroup(): Promise { } } - return CommandlineLists.getTopOfStack(); + return top; } async function getList(): Promise { @@ -355,7 +357,10 @@ async function showCommands(): Promise { throw new Error("Commandline element not found"); } - if (inputValue === "" && usingSingleList) { + const top = CommandlineLists.getTopOfStack(); + const singleListMode = usingSingleList && !top.excludeFromSingleList; + + if (inputValue === "" && singleListMode) { element.innerHTML = ""; return; } @@ -410,7 +415,7 @@ async function showCommands(): Promise { } } const iconHTML = `
${ - usingSingleList || configIcon === "" ? icon : configIcon + singleListMode || configIcon === "" ? icon : configIcon }
`; let customStyle = ""; if (command.customStyle !== undefined && command.customStyle !== "") { @@ -418,7 +423,7 @@ async function showCommands(): Promise { } let display = command.display; - if (usingSingleList) { + if (singleListMode) { display = (command.singleListDisplay ?? "") || command.display; display = display.replace( ``, @@ -455,7 +460,7 @@ async function showCommands(): Promise { } index++; } - if (firstActive !== null && !usingSingleList) { + if (firstActive !== null && !singleListMode) { activeIndex = firstActive; } element.innerHTML = html; diff --git a/frontend/src/ts/commandline/lists.ts b/frontend/src/ts/commandline/lists.ts index fc64161d7733..3a0f8a7a4297 100644 --- a/frontend/src/ts/commandline/lists.ts +++ b/frontend/src/ts/commandline/lists.ts @@ -77,6 +77,8 @@ import CustomThemesListCommands from "./lists/custom-themes-list"; import PresetsCommands from "./lists/presets"; import LayoutsCommands from "./lists/layouts"; import FunboxCommands from "./lists/funbox"; +import CustomLayoutFluidCommands from "./lists/custom-layoutfluid"; +import CustomPolyglotCommands from "./lists/custom-polyglot"; import ThemesCommands from "./lists/themes"; import LoadChallengeCommands, { update as updateLoadChallengeCommands, @@ -98,14 +100,8 @@ import * as ShareTestSettingsPopup from "../modals/share-test-settings"; import * as TestStats from "../test/test-stats"; import * as QuoteSearchModal from "../modals/quote-search"; import * as FPSCounter from "../elements/fps-counter"; -import { - CustomBackgroundSchema, - CustomLayoutFluid, -} from "@monkeytype/contracts/schemas/configs"; +import { CustomBackgroundSchema } from "@monkeytype/contracts/schemas/configs"; import { Command, CommandsSubgroup } from "./types"; -import * as TestLogic from "../test/test-logic"; -import * as ActivePage from "../states/active-page"; -import { Language } from "@monkeytype/contracts/schemas/languages"; const fontsPromise = JSONData.getFontsList(); fontsPromise @@ -189,37 +185,8 @@ export const commands: CommandsSubgroup = { ...LanguagesCommands, ...BritishEnglishCommands, ...FunboxCommands, - { - id: "changeCustomLayoutfluid", - display: "Custom layoutfluid...", - defaultValue: (): string => { - return Config.customLayoutfluid.join(" "); - }, - input: true, - icon: "fa-tint", - exec: ({ input }): void => { - if (input === undefined) return; - UpdateConfig.setCustomLayoutfluid( - input.split(" ") as CustomLayoutFluid - ); - }, - }, - { - id: "changeCustomPolyglot", - display: "Polyglot languages...", - defaultValue: (): string => { - return Config.customPolyglot.join(" "); - }, - input: true, - icon: "fa-language", - exec: ({ input }): void => { - if (input === undefined) return; - void UpdateConfig.setCustomPolyglot(input.split(" ") as Language[]); - if (ActivePage.get() === "test") { - TestLogic.restart(); - } - }, - }, + ...CustomLayoutFluidCommands, + ...CustomPolyglotCommands, //input ...FreedomModeCommands, @@ -462,6 +429,8 @@ const lists = { minAcc: MinAccCommands[0]?.subgroup, minBurst: MinBurstCommands[0]?.subgroup, funbox: FunboxCommands[0]?.subgroup, + customLayoutfluid: CustomLayoutFluidCommands[0]?.subgroup, + customPolyglot: CustomPolyglotCommands[0]?.subgroup, confidenceMode: ConfidenceModeCommands[0]?.subgroup, stopOnError: StopOnErrorCommands[0]?.subgroup, layouts: LayoutsCommands[0]?.subgroup, @@ -538,6 +507,9 @@ function buildSingleListCommands( command: Command, parentCommand?: Command ): Command[] { + if (command.subgroup?.excludeFromSingleList ?? false) + return [parentCommand ?? command]; + const commands: Command[] = []; if (command.subgroup) { if (command.subgroup.beforeList) { diff --git a/frontend/src/ts/commandline/lists/custom-layoutfluid.ts b/frontend/src/ts/commandline/lists/custom-layoutfluid.ts new file mode 100644 index 000000000000..089fd389ae1e --- /dev/null +++ b/frontend/src/ts/commandline/lists/custom-layoutfluid.ts @@ -0,0 +1,35 @@ +import * as UpdateConfig from "../../config"; +import { LayoutsList } from "../../constants/layouts"; +import * as TestLogic from "../../test/test-logic"; +import { capitalizeFirstLetterOfEachWord } from "../../utils/strings"; +import { Command, CommandsSubgroup } from "../types"; + +const subgroup: CommandsSubgroup = { + title: "Custom layoutfluid", + configKey: "customLayoutfluid", + excludeFromSingleList: true, + + list: LayoutsList.map((layout) => ({ + id: "changeCustomLayoutfluid" + capitalizeFirstLetterOfEachWord(layout), + display: layout.replace(/_/g, " "), + configValue: layout, + configValueMode: "include", + sticky: true, + exec: (): void => { + UpdateConfig.toggleCustomLayoutfluid(layout); + TestLogic.restart(); + }, + })), +}; + +const commands: Command[] = [ + { + id: "changeCustomLayoutfluid", + display: "Custom layoutfluid...", + configKey: "customLayoutfluid", + icon: "fa-tint", + subgroup, + }, +]; + +export default commands; diff --git a/frontend/src/ts/commandline/lists/custom-polyglot.ts b/frontend/src/ts/commandline/lists/custom-polyglot.ts new file mode 100644 index 000000000000..6581ce69fbbf --- /dev/null +++ b/frontend/src/ts/commandline/lists/custom-polyglot.ts @@ -0,0 +1,34 @@ +import * as UpdateConfig from "../../config"; +import { LanguageList } from "../../constants/languages"; + +import * as TestLogic from "../../test/test-logic"; +import { capitalizeFirstLetterOfEachWord } from "../../utils/strings"; +import { Command, CommandsSubgroup } from "../types"; + +const subgroup: CommandsSubgroup = { + title: "Polyglot languages", + configKey: "customPolyglot", + excludeFromSingleList: true, + list: LanguageList.map((language) => ({ + id: "changeCustomPolyglot" + capitalizeFirstLetterOfEachWord(language), + display: language.replace(/_/g, " "), + configValue: language, + configValueMode: "include", + sticky: true, + exec: (): void => { + UpdateConfig.toggleCustomPolyglot(language); + TestLogic.restart(); + }, + })), +}; + +const commands: Command[] = [ + { + id: "changeCustomPolyglot", + display: "Polyglot languages...", + icon: "fa-language", + subgroup, + }, +]; + +export default commands; diff --git a/frontend/src/ts/commandline/types.ts b/frontend/src/ts/commandline/types.ts index 4932b274d9af..52655e06a270 100644 --- a/frontend/src/ts/commandline/types.ts +++ b/frontend/src/ts/commandline/types.ts @@ -39,4 +39,5 @@ export type CommandsSubgroup = { configKey?: keyof Config; list: Command[]; beforeList?: () => void; + excludeFromSingleList?: boolean; }; diff --git a/frontend/src/ts/config.ts b/frontend/src/ts/config.ts index 81a854dcab7b..f0dc173e45cc 100644 --- a/frontend/src/ts/config.ts +++ b/frontend/src/ts/config.ts @@ -33,6 +33,7 @@ import { migrateConfig } from "./utils/config"; import { roundTo1 } from "@monkeytype/util/numbers"; import { getDefaultConfig } from "./constants/default-config"; import { parseWithSchema as parseJsonWithSchema } from "@monkeytype/util/json"; +import { LayoutName } from "@monkeytype/contracts/schemas/layouts"; const configLS = new LocalStorageWithSchema({ key: "config", @@ -1888,6 +1889,21 @@ export function setCustomLayoutfluid( return true; } +export function toggleCustomLayoutfluid( + value: LayoutName, + nosave?: boolean +): boolean { + let newConfig = config.customLayoutfluid; + + if (newConfig.includes(value)) { + newConfig = newConfig.filter((it) => it !== value); + } else { + newConfig.push(value); + } + + return setCustomLayoutfluid(newConfig, nosave); +} + export function setCustomPolyglot( value: ConfigSchemas.CustomPolyglot, nosave?: boolean @@ -1908,6 +1924,22 @@ export function setCustomPolyglot( return true; } +export function toggleCustomPolyglot( + value: Language, + nosave?: boolean +): boolean { + let newConfig = config.customPolyglot; + + if (newConfig.includes(value)) { + newConfig = newConfig.filter((it) => it !== value); + } else { + newConfig.push(value); + newConfig.sort(); + } + + return setCustomPolyglot(newConfig, nosave); +} + export function setCustomBackgroundSize( value: ConfigSchemas.CustomBackgroundSize, nosave?: boolean