mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-19 23:06:15 +08:00
feat(custom text): remember custom text settings between sessions
closes #4182
This commit is contained in:
parent
09ce4bd672
commit
2dcb1072e1
|
@ -132,7 +132,8 @@ describe("local-storage-with-schema.ts", () => {
|
|||
expect(localStorage.getItem).toHaveBeenCalledWith("config");
|
||||
expect(migrateFnMock).toHaveBeenCalledWith(
|
||||
existingValue,
|
||||
expect.any(Array)
|
||||
expect.any(Array),
|
||||
defaultObject
|
||||
);
|
||||
expect(localStorage.setItem).toHaveBeenCalledWith(
|
||||
"config",
|
||||
|
@ -166,7 +167,8 @@ describe("local-storage-with-schema.ts", () => {
|
|||
expect(localStorage.getItem).toHaveBeenCalledWith("config");
|
||||
expect(migrateFnMock).toHaveBeenCalledWith(
|
||||
existingValue,
|
||||
expect.any(Array)
|
||||
expect.any(Array),
|
||||
defaultObject
|
||||
);
|
||||
expect(localStorage.setItem).toHaveBeenCalledWith(
|
||||
"config",
|
||||
|
|
|
@ -551,6 +551,23 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group" data-id="delimiter">
|
||||
<div class="title">
|
||||
<i class="fas fa-fw fa-grip-lines-vertical"></i>
|
||||
Word delimiter
|
||||
</div>
|
||||
<div class="sub">
|
||||
Change how words are separated. Using the pipe delimiter allows you to
|
||||
randomize groups of words.
|
||||
</div>
|
||||
<div class="groupInputs">
|
||||
<div class="buttonGroup">
|
||||
<button value="true">pipe</button>
|
||||
<button value="false">space</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group" data-id="fancy">
|
||||
<div class="title">
|
||||
<i class="fas fa-fw fa-pen-fancy"></i>
|
||||
|
@ -584,23 +601,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group" data-id="delimiter">
|
||||
<div class="title">
|
||||
<i class="fas fa-fw fa-grip-lines-vertical"></i>
|
||||
Word delimiter
|
||||
</div>
|
||||
<div class="sub">
|
||||
Change how words are separated. Using the pipe delimiter allows you to
|
||||
randomize groups of words.
|
||||
</div>
|
||||
<div class="groupInputs">
|
||||
<div class="buttonGroup">
|
||||
<button value="true">pipe</button>
|
||||
<button value="false">space</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group" data-id="newlines">
|
||||
<div class="title">
|
||||
<i class="fas fa-fw fa-level-down-alt fa-rotate-90"></i>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import {
|
||||
CustomTextLimitMode,
|
||||
CustomTextLimitModeSchema,
|
||||
CustomTextMode,
|
||||
CustomTextModeSchema,
|
||||
} from "@monkeytype/contracts/schemas/util";
|
||||
import { LocalStorageWithSchema } from "../utils/local-storage-with-schema";
|
||||
import { z } from "zod";
|
||||
|
||||
//zod schema for an object with string keys and string values
|
||||
const CustomTextObjectSchema = z.record(z.string(), z.string());
|
||||
type CustomTextObject = z.infer<typeof CustomTextObjectSchema>;
|
||||
|
||||
|
@ -27,83 +28,117 @@ const customTextLongLS = new LocalStorageWithSchema({
|
|||
fallback: {},
|
||||
});
|
||||
|
||||
// function setLocalStorage(data: CustomTextObject): void {
|
||||
// window.localStorage.setItem("customText", JSON.stringify(data));
|
||||
// }
|
||||
const CustomTextSettingsSchema = z.object({
|
||||
text: z.array(z.string()),
|
||||
mode: CustomTextModeSchema,
|
||||
limit: z.object({ value: z.number(), mode: CustomTextLimitModeSchema }),
|
||||
pipeDelimiter: z.boolean(),
|
||||
});
|
||||
|
||||
// function setLocalStorageLong(data: CustomTextLongObject): void {
|
||||
type CustomTextSettings = z.infer<typeof CustomTextSettingsSchema>;
|
||||
|
||||
let text: string[] = [
|
||||
"The",
|
||||
"quick",
|
||||
"brown",
|
||||
"fox",
|
||||
"jumps",
|
||||
"over",
|
||||
"the",
|
||||
"lazy",
|
||||
"dog",
|
||||
];
|
||||
|
||||
let mode: CustomTextMode = "repeat";
|
||||
const limit: MonkeyTypes.CustomTextLimit = {
|
||||
value: 9,
|
||||
mode: "word",
|
||||
const defaultCustomTextSettings: CustomTextSettings = {
|
||||
text: ["The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"],
|
||||
mode: "repeat",
|
||||
limit: { value: 9, mode: "word" },
|
||||
pipeDelimiter: false,
|
||||
};
|
||||
let pipeDelimiter = false;
|
||||
|
||||
const customTextSettings = new LocalStorageWithSchema({
|
||||
key: "customTextSettings",
|
||||
schema: CustomTextSettingsSchema,
|
||||
fallback: defaultCustomTextSettings,
|
||||
migrate: (oldData, _zodIssues, fallback) => {
|
||||
if (typeof oldData !== "object" || oldData === null) {
|
||||
return fallback;
|
||||
}
|
||||
const migratedData = fallback;
|
||||
if (
|
||||
"text" in oldData &&
|
||||
z.array(z.string()).safeParse(migratedData.text).success
|
||||
) {
|
||||
migratedData.text = oldData.text as string[];
|
||||
}
|
||||
return migratedData;
|
||||
},
|
||||
});
|
||||
|
||||
export function getText(): string[] {
|
||||
return text;
|
||||
return customTextSettings.get().text;
|
||||
}
|
||||
|
||||
export function setText(txt: string[]): void {
|
||||
text = txt;
|
||||
limit.value = text.length;
|
||||
const currentSettings = customTextSettings.get();
|
||||
customTextSettings.set({
|
||||
...currentSettings,
|
||||
text: txt,
|
||||
limit: { value: txt.length, mode: currentSettings.limit.mode },
|
||||
});
|
||||
}
|
||||
|
||||
export function getMode(): CustomTextMode {
|
||||
return mode;
|
||||
const currentSettings = customTextSettings.get();
|
||||
return currentSettings.mode;
|
||||
}
|
||||
|
||||
export function setMode(val: CustomTextMode): void {
|
||||
mode = val;
|
||||
limit.value = text.length;
|
||||
const currentSettings = customTextSettings.get();
|
||||
customTextSettings.set({
|
||||
...currentSettings,
|
||||
mode: val,
|
||||
limit: {
|
||||
value: currentSettings.text.length,
|
||||
mode: currentSettings.limit.mode,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function getLimit(): MonkeyTypes.CustomTextLimit {
|
||||
return limit;
|
||||
return customTextSettings.get().limit as MonkeyTypes.CustomTextLimit;
|
||||
}
|
||||
|
||||
export function getLimitValue(): number {
|
||||
return limit.value;
|
||||
return customTextSettings.get().limit.value;
|
||||
}
|
||||
|
||||
export function getLimitMode(): CustomTextLimitMode {
|
||||
return limit.mode;
|
||||
return customTextSettings.get().limit.mode;
|
||||
}
|
||||
|
||||
export function setLimitValue(val: number): void {
|
||||
limit.value = val;
|
||||
const currentSettings = customTextSettings.get();
|
||||
customTextSettings.set({
|
||||
...currentSettings,
|
||||
limit: { value: val, mode: currentSettings.limit.mode },
|
||||
});
|
||||
}
|
||||
|
||||
export function setLimitMode(val: CustomTextLimitMode): void {
|
||||
limit.mode = val;
|
||||
const currentSettings = customTextSettings.get();
|
||||
customTextSettings.set({
|
||||
...currentSettings,
|
||||
limit: { value: currentSettings.limit.value, mode: val },
|
||||
});
|
||||
}
|
||||
|
||||
export function getPipeDelimiter(): boolean {
|
||||
return pipeDelimiter;
|
||||
return customTextSettings.get().pipeDelimiter;
|
||||
}
|
||||
|
||||
export function setPipeDelimiter(val: boolean): void {
|
||||
pipeDelimiter = val;
|
||||
const currentSettings = customTextSettings.get();
|
||||
customTextSettings.set({
|
||||
...currentSettings,
|
||||
pipeDelimiter: val,
|
||||
});
|
||||
}
|
||||
|
||||
export function getData(): MonkeyTypes.CustomTextData {
|
||||
return {
|
||||
text,
|
||||
mode,
|
||||
limit,
|
||||
pipeDelimiter,
|
||||
text: getText(),
|
||||
mode: getMode(),
|
||||
limit: getLimit(),
|
||||
pipeDelimiter: getPipeDelimiter(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue