Skip to content
12 changes: 6 additions & 6 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ When contributing to Monkeytype, it's good to know our best practices, tips, and

## How to Contribute

We have two separate contribution guides based on what you're looking to contribute. If you're simply looking to help us augment our language or quotes data, please refer to [CONTRIBUTING_BASIC.md](./CONTRIBUTING_BASIC.md). This guide will go over how to do so easily and without the need to set up a local development server.
We have two separate contribution guides based on what you're looking to contribute. If you're simply looking to help us augment our language or quotes data, please refer to [CONTRIBUTING_BASIC.md](/docs/CONTRIBUTING_BASIC.md). This guide will go over how to do so easily and without the need to set up a local development server.

If you're looking to make deeper code changes that affect functionality, or will require screenshots of the changes, please refer to [CONTRIBUTING_ADVANCED.md](./CONTRIBUTING_ADVANCED.md).
If you're looking to make deeper code changes that affect functionality, or will require screenshots of the changes, please refer to [CONTRIBUTING_ADVANCED.md](/docs/CONTRIBUTING_ADVANCED.md).

## Standards and Guidelines

Expand Down Expand Up @@ -55,7 +55,7 @@ Before submitting a theme make sure...
- your theme has been added to the `_list` file and the `textColor` property is the theme's main color
- your theme is clear and readable with both `flip test colors` and `colorful mode` enabled and disabled

If you want to contribute themes but don't know how, check [THEMES.md](./THEMES.md)
If you want to contribute themes but don't know how, check [THEMES.md](/docs/THEMES.md)

### Language Guidelines

Expand All @@ -64,7 +64,7 @@ If you want to contribute themes but don't know how, check [THEMES.md](./THEMES.
- Be sure to add your language to the `_list` and `_groups` files
- Make sure the number of words in the file corresponds to the file name (for example: `languageName.json` is 200 words, `languageName_1k.json` is 1000 words, and so on)

If you want to contribute languages but don't know how, check [LANGUAGES.md](./LANGUAGES.md)
If you want to contribute languages but don't know how, check [LANGUAGES.md](/docs/LANGUAGES.md)

### Quote Guidelines

Expand All @@ -78,11 +78,11 @@ If you want to contribute languages but don't know how, check [LANGUAGES.md](./L
- Remember to name your pull request properly. For example, if you are adding new quotes for the language `French`, your pull request should be named `impr(quotes): add French quotes`.


If you want to contribute quotes but don't know how, check [QUOTES.md](./QUOTES.md)
If you want to contribute quotes but don't know how, check [QUOTES.md](/docs/QUOTES.md)

### Layout Guidelines

If you want to contribute layouts but don't know how, check [LAYOUTS.md](./LAYOUTS.md)
If you want to contribute layouts but don't know how, check [LAYOUTS.md](/docs/LAYOUTS.md)

## Questions

Expand Down
2 changes: 1 addition & 1 deletion docs/CONTRIBUTING_ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Follow these steps if you want to work on anything involving the database/accoun

| Manual | Docker (recommended) |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <ol><li>Install [MongoDB Community Edition](https://docs.mongodb.com/manual/administration/install-community/)</li><li>Install [Redis](https://redis.io/docs/install/install-redis/)</li><li>Make sure both are running</li></ol> | <ol><li>Install [Docker](http://www.docker.io/gettingstarted/#h_installation) on your machine</li><li>Run `npm run docker-db-only` from the `./backend` directory</li></ol> |
| <ol><li>Install [MongoDB Community Edition](https://docs.mongodb.com/manual/administration/install-community/)</li><li>Install [Redis](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/)</li><li>Make sure both are running</li></ol> | <ol><li>Install [Docker](http://www.docker.io/gettingstarted/#h_installation) on your machine</li><li>Run `npm run docker-db-only` from the `./backend` directory</li></ol> |

3. (Optional) Install [MongoDB-compass](https://www.mongodb.com/try/download/compass?tck=docs_compass). This tool can be used to see and manipulate your database visually.
- To connect, type `mongodb://localhost:27017` in the connection string box and press connect. The Monkeytype database will be created and shown after the server is started.
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/ts/elements/input-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export type ValidationOptions<T> = (T extends string

export type ValidatedHtmlInputElement = HTMLInputElement & {
isValid: () => boolean | undefined;
setValue: (val: string | null) => void;
};
/**
* adds an 'InputIndicator` to the given `inputElement` and updates its status depending on the given validation
Expand Down Expand Up @@ -197,6 +198,15 @@ export function validateWithIndicator<T>(

const result = inputElement as ValidatedHtmlInputElement;
result.isValid = () => isValid;
result.setValue = (val: string | null) => {
inputElement.value = val ?? "";
if (val === null) {
isValid = undefined;
indicator.hide();
} else {
inputElement.dispatchEvent(new Event("input"));
}
};

return result;
}
Expand Down
35 changes: 32 additions & 3 deletions frontend/src/ts/modals/edit-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import * as Settings from "../pages/settings";
import * as Notifications from "../elements/notifications";
import * as ConnectionState from "../states/connection";
import AnimatedModal from "../utils/animated-modal";
import { PresetType, PresetTypeSchema } from "@monkeytype/schemas/presets";
import {
PresetNameSchema,
PresetType,
PresetTypeSchema,
} from "@monkeytype/schemas/presets";
import { getPreset } from "../controllers/preset-controller";
import {
ConfigGroupName,
Expand All @@ -17,6 +21,10 @@ import {
} from "@monkeytype/schemas/configs";
import { getDefaultConfig } from "../constants/default-config";
import { SnapshotPreset } from "../constants/default-snapshot";
import {
ValidatedHtmlInputElement,
validateWithIndicator,
} from "../elements/input-validation";

const state = {
presetType: "full" as PresetType,
Expand All @@ -26,6 +34,8 @@ const state = {
setPresetToCurrent: false,
};

let presetNameEl: ValidatedHtmlInputElement | null = null;

export function show(action: string, id?: string, name?: string): void {
if (!ConnectionState.get()) {
Notifications.add("You are offline", 0, {
Expand All @@ -39,11 +49,22 @@ export function show(action: string, id?: string, name?: string): void {
beforeAnimation: async () => {
$("#editPresetModal .modal .text").addClass("hidden");
addCheckBoxes();
if (!presetNameEl) {
presetNameEl = validateWithIndicator(
document.querySelector(
"#editPresetModal .modal input"
) as HTMLInputElement,
{
schema: PresetNameSchema,
}
);
}
if (action === "add") {
$("#editPresetModal .modal").attr("data-action", "add");
$("#editPresetModal .modal .popupTitle").html("Add new preset");
$("#editPresetModal .modal .submit").html(`add`);
$("#editPresetModal .modal input").val("");
presetNameEl?.setValue(null);
presetNameEl?.parentElement?.classList.remove("hidden");
$("#editPresetModal .modal input").removeClass("hidden");
$(
"#editPresetModal .modal label.changePresetToCurrentCheckbox"
Expand All @@ -57,7 +78,9 @@ export function show(action: string, id?: string, name?: string): void {
$("#editPresetModal .modal").attr("data-preset-id", id);
$("#editPresetModal .modal .popupTitle").html("Edit preset");
$("#editPresetModal .modal .submit").html(`save`);
$("#editPresetModal .modal input").val(name);
presetNameEl?.setValue(name);
presetNameEl?.parentElement?.classList.remove("hidden");

$("#editPresetModal .modal input").removeClass("hidden");
$(
"#editPresetModal .modal label.changePresetToCurrentCheckbox"
Expand Down Expand Up @@ -85,6 +108,7 @@ export function show(action: string, id?: string, name?: string): void {
$("#editPresetModal .modal .inputs").addClass("hidden");
$("#editPresetModal .modal .presetType").addClass("hidden");
$("#editPresetModal .modal .presetNameTitle").addClass("hidden");
presetNameEl?.parentElement?.classList.add("hidden");
}
updateUI();
},
Expand Down Expand Up @@ -238,6 +262,11 @@ async function apply(): Promise<void> {
return;
}

if (presetNameEl?.isValid() === false) {
Notifications.add("Preset name is not valid", 0);
return;
}

hide();

Loader.show();
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/ts/utils/url-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ export function loadTestSettingsFromUrl(getOverride?: string): void {
const getValue = Misc.findGetParameter("testSettings", getOverride);
if (getValue === null) return;

// if the encoding structure or method ever changes, make sure to support the old data format
// otherwise eiko will be sad

const { data: de, error } = tryCatchSync(() =>
parseJsonWithSchema(decompressFromURI(getValue) ?? "", TestSettingsSchema)
);
Expand Down
102 changes: 102 additions & 0 deletions frontend/static/quotes/english.json
Original file line number Diff line number Diff line change
Expand Up @@ -38799,6 +38799,108 @@
"source": "James Clear, Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones",
"id": 7679,
"length": 381
},
{
"text": "A traveler from beyond the stars, Bard is an agent of serendipity who fights to maintain a balance where life can endure the indifference of chaos. Many Runeterrans sing songs that ponder his extraordinary nature, yet they all agree that the cosmic vagabond is drawn to artifacts of great magical power. Surrounded by a jubilant choir of helpful spirit meeps, it is impossible to mistake his actions as malevolent, as Bard always serves the greater good... in his own odd way.",
"source": "League of Legends",
"id": 7680,
"length": 476
},
{
"text": "The eccentric Professor Cecil B. Heimerdinger is one of the most innovative and esteemed inventors the world has ever known. As the longest serving member of the Council of Piltover, he saw the best and the worst of the city's unending desire for progress. Nonetheless, this brilliant scientist and teacher will always remain dedicated to using his unconventional devices to improve the lives of others.",
"source": "League of Legends",
"id": 7681,
"length": 403
},
{
"text": "An enthusiastic master of dark sorcery, Veigar has embraced powers that few mortals dare approach. As a free-spirited inhabitant of Bandle City, he longed to push beyond the limitations of yordle magic, and turned instead to arcane texts that had been hidden away for thousands of years. Now a stubborn creature with an endless fascination for the mysteries of the universe, Veigar is often underestimated by others - but even though he believes himself truly evil, he possesses an inner morality that leads some to question his deeper motivations.",
"source": "League of Legends",
"id": 7682,
"length": 548
},
{
"text": "Xerath is an Ascended Magus of ancient Shurima, a being of arcane energy writhing in the broken shards of a magical sarcophagus. For millennia, he was trapped beneath the desert sands, but the rise of Shurima freed him from his ancient prison. Driven insane with power, he now seeks to take what he believes is rightfully his and replace the upstart civilizations of the world with one fashioned in his image.",
"source": "League of Legends",
"id": 7683,
"length": 409
},
{
"text": "The whole idea of what happens when you read a book, I find absolutely stunning. Here’s some product of a tree, little black squiggles on it, you open it up, and inside your head is the voice of someone speaking, who may have been dead 3000 years, and there he is talking directly to you, what a magical thing that is.",
"source": "Carl Sagan",
"length": 318,
"id": 7684
},
{
"text": "Mathematics, in an earlier view, is the science of space and quantity; in a later view, it is the science of pattern and deductive structure.",
"source": "Philip J. Davis, Reuben Hersh - The mathematical experience (1981)",
"length": 141,
"id": 7685
},
{
"text": "His Holiness the Flying Spaghetti Monster is Eternal, without beginning and without end, and with a whole tangled mess in the middle.",
"source": "Evangelical Pastafarian church - The Loose Canon, Second Announcement Regarding Canonical Belief",
"length": 133,
"id": 7686
},
{
"text": "We are stuck with technology when all we really want is just stuff that works. How do you recognize something that is still technology? A good clue is if it comes with a manual.",
"source": "Douglas Adams",
"length": 177,
"id": 7687
},
{
"text": "Nothing disturbs me more than the glorification of stupidity.",
"source": "Carl Sagan",
"length": 61,
"id": 7688
},
{
"text": "“Then how,” Dex said, “how does the idea of maybe being meaningless sit well with you?” Mosscap considered. “Because I know that no matter what, I’m wonderful.”",
"source": "Becky Chambers — Monk and Robot",
"length": 160,
"id": 7689
},
{
"text": "I can wait for the galaxy outside to get a little kinder.",
"source": "Becky Chambers — The Long Way to a Small, Angry Planet",
"length": 57,
"id": 7690
},
{
"text": "That’s such an incredibly organic bias, the idea that your squishy physical existence is some sort of pinnacle that all programs aspire to.",
"source": "Becky Chambers — The Long Way to a Small, Angry Planet",
"length": 139,
"id": 7691
},
{
"text": "There are only two hard things in Computer Science: cache invalidation, naming things, and off-by-one error.",
"source": "Phil Karlton",
"length": 108,
"id": 7692
},
{
"text": "You gotta put your past behind you. Look, kid, bad things happen, and you can't do anything about it. Right? Wrong!",
"source": "The Lion King (1994)",
"id": 7693,
"length": 115
},
{
"text": "One often meets his destiny on the road he takes to avoid it. Your mind is like this water my friend; when it is agitated, it is hard to see, but if you allow it to settle, the answer becomes clear.",
"source": "Kung Fu Panda (2008)",
"id": 7694,
"length": 198
},
{
"text": "Yesterday is history, tomorrow is a mystery, but today is a gift. That is why it is called the present.",
"source": "Kung Fu Panda (2008)",
"id": 7695,
"length": 103
},
{
"text": "Your story may not have such a happy beginning, but that doesn't make you who you are. It is the rest of your story. Who you choose to be.",
"source": "Kung Fu Panda 2 (2011)",
"id": 7696,
"length": 138
}
]
}
24 changes: 24 additions & 0 deletions frontend/static/quotes/french.json
Original file line number Diff line number Diff line change
Expand Up @@ -6624,6 +6624,30 @@
"source": "Ken Liu - La ménagerie de papier",
"length": 153,
"id": 1125
},
{
"text": "L’homme de science le sait bien, lui, que seule la science a pu, au fil des siècles, lui apporter l’horloge pointeuse et le parcmètre automatique sans lesquels il n’est pas de bonheur terrestre possible.",
"source": "Pierre Desproges - Vivons heureux en attendant la mort",
"length": 203,
"id": 1126
},
{
"text": "Une situation prérévolutionnaire éclate lorsque ceux d’en haut ne peuvent plus, ceux d’en bas ne veulent plus, et ceux du milieu basculent avec ceux d’en bas.",
"source": "Lénine",
"length": 158,
"id": 1127
},
{
"text": "Il y a des décennies où rien ne se passe et des semaines où des décennies se produisent.",
"source": "Lénine",
"length": 88,
"id": 1128
},
{
"text": "Il n'est pas de sauveurs suprêmes\nNi Dieu, ni César, ni Tribun,\nProducteurs, sauvons-nous nous-mêmes\nDécrétons le salut commun.",
"source": "L'internationale",
"length": 127,
"id": 1129
}
]
}
18 changes: 18 additions & 0 deletions frontend/static/quotes/portuguese.json
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,24 @@
"source": "Tabacaria, Fernando Pessoa",
"length": 88,
"id": 106
},
{
"text": "Entendeu o céu que devia regar com as suas lágrimas o solo da formosa Petrópolis.",
"source": "Linha Reta e Linha Curva, Machado de Assis",
"length": 81,
"id": 107
},
{
"text": "Olhos de ressaca? Vá, de ressaca. É o que me dá ideia daquela feição nova. Traziam não sei que fluido misterioso e enérgico, uma força que arrastava para dentro, como a vaga que se retira da praia, nos dias de ressaca.",
"source": "Dom Casmurro, Machado de Assis",
"length": 218,
"id": 108
},
{
"text": "Apesar de generosa, é exigente, e quer da parte dos seus afilhados algum esforço próprio. A fortuna não é Danaide. Quando vê que um tonel esgota a água que se lhe põe dentro vai levar os seus cântaros a outra parte.",
"source": "Luís Soares, Machado de Assis",
"length": 215,
"id": 109
}
]
}
Loading