Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 9 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@
- [ ] Make sure to include translations for the quotes in the description (or another comment) so we can verify their content.
- [ ] Adding a language?
- Make sure to follow the [languages documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to `packages/schemas/src/languages.ts`
- [ ] Add language to exactly one group in `frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `packages/schemas/src/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- Also please add a screenshot of the theme, it would be extra awesome if you do so!
- [ ] Add some screenshot of the theme, especially with different test settings (colorful, flip colors) to your pull request
- [ ] Adding a layout?
- [ ] Make sure to follow the [layouts documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [ ] Add layout to `packages/schemas/src/layouts.ts`
- [ ] Add layout json file to `frontend/static/layouts`
- [ ] Adding a font?
- Make sure to follow the [themes documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/FONTS.md)
- [ ] Add font file to `frontend/static/webfonts`
- [ ] Add font to `packages/schemas/src/fonts.ts`
- [ ] Add font to `frontend/src/ts/constants/fonts.ts`
- [ ] Check if any open issues are related to this PR; if so, be sure to tag them below.
- [ ] Make sure the PR title follows the Conventional Commits standard. (https://www.conventionalcommits.org for more info)
- [ ] Make sure to include your GitHub username prefixed with @ inside parentheses at the end of the PR title.
Expand Down
57 changes: 57 additions & 0 deletions docs/FONTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
### **Table of Contents**

- [Forking Monkeytype](#forking-monkeytype)
- [Adding fonts](#adding-fonts)
- [Committing Languages](#committing-languages)
- [Language Guidelines](#language-guidelines)

### Forking Monkeytype

First, you will have to make a personal copy of the Monkeytype repository, also known as "forking". Go to the [Monkeytype repo](https://github.com/monkeytypegame/monkeytype/) and then click the "fork" button.

<img width="1552" alt="Screenshot showing location of the fork button on GitHub." src="https://user-images.githubusercontent.com/83455454/149194972-23343642-7a1f-4c0c-b5f2-36f4b39a2639.png">

## Adding Fonts

Once you have forked the repository you can now add your font. Place the font file in `./frontend/static/webfonts` e.g. `My-Font.woff2`.

> [!NOTE]
> Your font needs to be in the `.woff2` format. Your filename cannot include spaces.

Open `./packages/schemas/src/fonts.ts` and add the new font at the _end_ of the `KnownFontNameSchema` list like this:

```typescript
const KnownFontNameSchema = z.enum(
[
"Roboto_Mono",
"Noto_Naskh_Arabic",
...
"My_Font",
```

Call it whatever you want but make sure you replace spaces with underscores.

Then, go to `./frontend/src/ts/constants/fonts.ts` and add the following code to the _end_ of the `Fonts` object near to the very end of the file:

```typescript
export const Fonts: Record<KnownFontName, FontConfig> = {
...
My_Font: {
fileName: "My-Font.woff2",
}
```

### Committing Languages

Once you have created your language, you now need to create a pull request to the main Monkeytype repository. Go to the branch where you created your languages on GitHub. Then make sure your branch is up to date. Once it is up to date, click "contribute".

Update branch:
<img width="1552" alt="Screenshot showing how to update the fork to match the main Monkeytype repository" src="https://user-images.githubusercontent.com/83455454/149186547-5b9fe4fd-b944-4eed-a959-db43f96198bf.png">

Create a pull request:
<img width="1552" alt="Screenshot showing how to create a pull request to the main Monkeytype repository" src="https://user-images.githubusercontent.com/83455454/149186637-66dae488-05ae-45c4-9217-65bc36c4927b.png">

## Language Guidelines

Make sure your language follows the [Language guidelines](./CONTRIBUTING.md#language-guidelines).

2 changes: 1 addition & 1 deletion docs/LANGUAGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The contents of the file should be as follows:
It is recommended that you familiarize yourselves with JSON before adding a language. For the `name` field, put the name of your language. `rightToLeft` indicates how the language is written. If it is written right to left then put `true`, otherwise put `false`.
`ligatures` A ligature occurs when multiple letters are joined together to form a character [more details](<https://en.wikipedia.org/wiki/Ligature_(writing)>). If there's joining in the words, which is the case in languages like (Arabic, Malayalam, Persian, Sanskrit, Central_Kurdish... etc.), then set the value to `true`, otherwise set it to `false`. For `bcp47` put your languages [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). If the words you're adding are ordered by frequency (most common words at the top, least at the bottom) set the value of `orderedByFrequency` to `true`, otherwise `false`. Finally, add your list of words to the `words` field.

Then, go to `packages/contracts/src/schemas/languages.ts` and add your new language name at the _end_ of the `LanguageSchema` enum. Make sure to end the line with a comma. Make sure to add all your language names if you have created multiple word lists of differing lengths in the same language.
Then, go to `packages/schemas/src/languages.ts` and add your new language name at the _end_ of the `LanguageSchema` enum. Make sure to end the line with a comma. Make sure to add all your language names if you have created multiple word lists of differing lengths in the same language.

```typescript
export const LanguageSchema = z.enum([
Expand Down
2 changes: 1 addition & 1 deletion docs/LAYOUTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ For iso the number of keys need to be exactly thirteen for `row1`, twelve for `r



In addition to the layout file you need to add your layout to the `packages/contracts/src/schemas/layouts.ts` file. Just append your layout name (without the `.json`) at the __end__ of the `LayoutNameSchema`. Remember to add a comma like this:
In addition to the layout file you need to add your layout to the `packages/schemas/src/layouts.ts` file. Just append your layout name (without the `.json`) at the __end__ of the `LayoutNameSchema`. Remember to add a comma like this:

```ts
export const LayoutNameSchema = z.enum([
Expand Down
2 changes: 1 addition & 1 deletion docs/THEMES.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Here is an image showing what all the properties correspond to:
<img width="1552" alt="Screenshot showing the page elements controlled by each color property" src="https://user-images.githubusercontent.com/83455454/149196967-abb69795-0d38-466b-a867-5aaa46452976.png">

Change the corresponding hex codes to create your theme.
Then, go to `./packages/contracts/src/schemas/themes.ts` and add your new theme name at the _end_ of the `ThemeNameSchema` enum. Make sure to end the line with a comma.
Then, go to `./packages/schemas/src/themes.ts` and add your new theme name at the _end_ of the `ThemeNameSchema` enum. Make sure to end the line with a comma.

```typescript
export const ThemeNameSchema = z.enum([
Expand Down
45 changes: 45 additions & 0 deletions frontend/__tests__/constants/fonts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Fonts } from "../../src/ts/constants/fonts";
import { readdirSync } from "fs";
const ignoredFonts = new Set([
"GallaudetRegular.woff2", //used for asl
"Vazirmatn-Regular.woff2", //default font
]);
describe("fonts", () => {
it("should have all related font files", () => {
const fontFiles = listFontFiles();
const expectedFontFiles = Object.entries(Fonts)
.filter(([_name, config]) => !config.systemFont)
.map(([_name, config]) => config.fileName as string);

const missingFontFiles = expectedFontFiles
.filter((fileName) => !fontFiles.includes(fileName))
.map((name) => `fontend/static/webfonts/${name}`);

expect(missingFontFiles, "missing font files").toEqual([]);
});

it("should not have additional font files", () => {
const fontFiles = listFontFiles();

const expectedFontFiles = new Set(
Object.entries(Fonts)
.filter(([_name, config]) => !config.systemFont)
.map(([_name, config]) => config.fileName as string)
);

const additionalFontFiles = fontFiles
.filter((name) => !expectedFontFiles.has(name))
.map((name) => `fontend/static/webfonts/${name}`);

expect(
additionalFontFiles,
"additional font files not declared in frontend/src/ts/constants/fonts.ts"
).toEqual([]);
});
});

function listFontFiles() {
return readdirSync(import.meta.dirname + "/../../static/webfonts").filter(
(it) => !ignoredFonts.has(it)
);
}
30 changes: 12 additions & 18 deletions frontend/scripts/font-preview.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from "url";
import Fonts from "../static/fonts/_list.json";

import subsetFont from "subset-font";
import { Fonts } from "../src/ts/constants/fonts";
import { KnownFontName } from "@monkeytype/schemas/fonts";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand All @@ -14,31 +16,23 @@ export async function generatePreviewFonts(
const targetDir = __dirname + "/../static/webfonts-preview";
fs.mkdirSync(targetDir, { recursive: true });

const srcFiles = fs.readdirSync(srcDir);

for (const font of Fonts) {
for (const name of Object.keys(Fonts)) {
const font = Fonts[name as KnownFontName];
if (font.systemFont) continue;

const display = (font.display ?? font.name) + "Fontfamily";
const includedCharacters =
(font.display ?? name.replaceAll("_", " ")) + "Fontfamily";

const fileNames = srcFiles.filter((it) =>
it.startsWith(font.name.replaceAll(" ", "") + "-")
);

if (fileNames.length !== 1)
throw new Error(
`cannot find font file for ${font.name}. Candidates: ${fileNames}`
);
const fileName = fileNames[0];
const fileName = font.fileName;

await generateSubset(
srcDir + "/" + fileName,
targetDir + "/" + fileName,
display
includedCharacters
);
if (debug) {
console.log(
`Processing ${font.name} with file ${fileName} to display "${display}".`
`Processing ${name} with file ${fileName} to display "${includedCharacters}".`
);
}
}
Expand All @@ -47,10 +41,10 @@ export async function generatePreviewFonts(
async function generateSubset(
source: string,
target: string,
name: string
includedCharacters: string
): Promise<void> {
const font = fs.readFileSync(source);
const subset = await subsetFont(font, name, {
const subset = await subsetFont(font, includedCharacters, {
targetFormat: "woff2",
});
fs.writeFileSync(target, subset);
Expand Down
27 changes: 0 additions & 27 deletions frontend/scripts/json-validation.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,6 @@ function findDuplicates(words) {

function validateOthers() {
return new Promise((resolve, reject) => {
//fonts
const fontsData = JSON.parse(
fs.readFileSync("./static/fonts/_list.json", {
encoding: "utf8",
flag: "r",
})
);
const fontsSchema = {
type: "array",
items: {
type: "object",
properties: {
name: {
type: "string",
},
},
required: ["name"],
},
};
const fontsValidator = ajv.compile(fontsSchema);
if (fontsValidator(fontsData)) {
console.log("Fonts JSON schema is \u001b[32mvalid\u001b[0m");
} else {
console.log("Fonts JSON schema is \u001b[31minvalid\u001b[0m");
return reject(new Error(fontsValidator.errors[0].message));
}

//challenges
const challengesSchema = {
type: "array",
Expand Down
Loading
Loading