Skip to content

Commit b752555

Browse files
committed
initial fixes
1 parent 1e338d2 commit b752555

13 files changed

+51
-50
lines changed

gatsby-node.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ exports.createSchemaCustomization = ({ actions }) => {
495495
type Xdm implements Node {
496496
body: String
497497
fileAbsolutePath: String
498-
frontmatter: XdmFrontmatter
498+
frontmatter: XdmFrontmatter!
499499
isIncomplete: Boolean
500500
cppOc: Int
501501
javaOc: Int
@@ -506,7 +506,7 @@ exports.createSchemaCustomization = ({ actions }) => {
506506
507507
type XdmFrontmatter implements Node {
508508
id: String
509-
title: String
509+
title: String!
510510
author: String
511511
contributors: String
512512
description: String

src/api/(parsers)/usaco.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
export default function parseUsaco(url: string, htmlContent: string) {
22
const id = url.split('=').at(-1);
3+
if (!id) throw new Error(`${url} does not contain problem id`);
34
const problem = htmlContent.match(/<h2> Problem (\d). (.*) <\/h2>/);
5+
if (!problem) throw new Error(`Problem title not found at url ${url}`);
46
const number = problem[1],
57
title = problem[2];
68
const contest = htmlContent.match(
79
/<h2> USACO (\d+) (December|January|February|(?:US Open)) Contest, (Bronze|Silver|Gold|Platinum) <\/h2>/
810
);
11+
if (!contest) throw new Error(`Contest not found at url ${url}`);
912
// year and month could be used someday idk
1013
const year = contest[1],
1114
month = contest[2],

src/atoms/editor.ts

+15-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { WritableAtom, atom } from 'jotai';
1+
import { atom } from 'jotai';
22
import { atomFamily, atomWithStorage } from 'jotai/utils';
33
import { Octokit } from 'octokit';
44
import { fetchFileContent } from '../components/Editor/editorUtils';
@@ -8,7 +8,7 @@ import { formatProblems } from '../utils/prettierFormatter';
88
export type EditorFile = {
99
path: string;
1010
markdown: string;
11-
problems: string;
11+
problems?: string;
1212
};
1313

1414
export const filesFamily = atomFamily((path: string) => {
@@ -47,16 +47,13 @@ const baseActiveFileAtom = atomWithStorage(
4747
'guide:editor:activeFile',
4848
null as string | null
4949
);
50-
// Writable type needed if strictNullChecks is false
51-
// TODO: remove this when strictNullChecks is true
52-
export type Writable<T> = WritableAtom<T, any[], unknown>;
5350
export const branchAtom = atomWithStorage('guide:editor:branch', null);
54-
export const tokenAtom = atom(null) as Writable<string | null>;
51+
export const tokenAtom = atom(null);
5552
export const octokitAtom = atom(get =>
5653
get(tokenAtom) === null ? null : new Octokit({ auth: get(tokenAtom) })
5754
);
58-
export const forkAtom = atom(undefined) as Writable<string | undefined | null>;
59-
export const baseTabAtom = atom('content') as Writable<'content' | 'problems'>;
55+
export const forkAtom = atom(undefined);
56+
export const baseTabAtom = atom('content');
6057
export const editingSolutionAtom = atom(get => {
6158
const activeFile = get(activeFileAtom);
6259
return activeFile && activeFile.path.startsWith('solutions');
@@ -84,10 +81,10 @@ export const githubInfoAtom = atom(
8481
async get => (await get(octokitAtom)?.request('GET /user'))?.data
8582
);
8683
export const activeFileAtom = atom(
87-
get =>
88-
get(baseActiveFileAtom) === null
89-
? null
90-
: get(filesFamily(get(baseActiveFileAtom))),
84+
get => {
85+
const activeFile = get(baseActiveFileAtom);
86+
return activeFile ? get(filesFamily(activeFile)) : null;
87+
},
9188
(get, set, nextActiveFilePath) => {
9289
set(baseActiveFileAtom, nextActiveFilePath);
9390
}
@@ -100,7 +97,7 @@ export const filesListAtom = atomWithStorage<string[]>(
10097

10198
export const openOrCreateExistingFileAtom = atom(
10299
null,
103-
async (get, set, filePath: string | null) => {
100+
async (get, set, filePath: string) => {
104101
if (get(filesListAtom).find(f => f === filePath)) {
105102
set(activeFileAtom, filePath);
106103
} else {
@@ -201,7 +198,8 @@ $\\texttt{func(var)}$
201198
problems: '',
202199
};
203200

204-
const updateProblemJSON = (json: string) => {
201+
const updateProblemJSON = (json: string | undefined) => {
202+
if (!json) return undefined;
205203
const updated = JSON.parse(json);
206204
Object.keys(updated).forEach(key => {
207205
if (key === 'MODULE_ID') return;
@@ -252,17 +250,17 @@ export const closeFileAtom = atom(null, (get, set, filePath: string) => {
252250
filesListAtom,
253251
get(filesListAtom).filter(file => file !== filePath)
254252
);
255-
if (get(activeFileAtom).path === filePath) {
253+
if (get(activeFileAtom)?.path === filePath) {
256254
const remainingFiles = get(filesListAtom);
257255
set(activeFileAtom, remainingFiles.length > 0 ? remainingFiles[0] : null);
258256
}
259-
set(filesFamily(filePath), null);
257+
filesFamily.remove(filePath);
260258
});
261259

262260
const baseMonacoEditorInstanceAtom = atom({ monaco: null });
263261
export const monacoEditorInstanceAtom = atom(
264262
get => get(baseMonacoEditorInstanceAtom),
265-
(get, _set, val) => {
263+
(get, _set, val: any) => {
266264
get(baseMonacoEditorInstanceAtom).monaco = val;
267265
}
268266
);

src/components/Confetti/Particles.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { defaultShapes } from './confetti-shapes.js';
44
import type { Particle, Shape } from './types';
55

66
type State = {
7-
particles: Array<Particle>;
7+
particles: (Particle | null)[];
88
};
99

1010
type ChildFnProps = {
11-
particles: Array<Particle>;
11+
particles: Particle[];
1212
generateParticles: () => void;
1313
};
1414

@@ -78,7 +78,7 @@ class Particles extends React.PureComponent<Props, State> {
7878
};
7979

8080
state = {
81-
particles: [],
81+
particles: [] as Particle[],
8282
};
8383

8484
animationFrameId: number;

src/components/Confetti/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export type Particle = {
22
birth: number;
3-
initialPosition: [number, number];
4-
currentPosition: [number, number];
3+
initialPosition: { x: number; y: number };
4+
currentPosition: { x: number; y: number };
55
spinForce: number;
66
twistForce: number;
77
currentSpin: number;

src/models/module.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ export class ModuleLinkInfo {
1515
public id: string,
1616
public section: SectionID,
1717
public title: string,
18-
public description?: string,
18+
public description?: string | null,
1919
public frequency?: ModuleFrequency,
20-
public isIncomplete?: boolean,
21-
public cppOc: number = 0,
22-
public javaOc: number = 0,
23-
public pyOc: number = 0,
20+
public isIncomplete?: boolean | null,
21+
public cppOc: number | null = 0,
22+
public javaOc: number | null = 0,
23+
public pyOc: number | null = 0,
2424
public probs?: any,
2525
public gitAuthorTime?: any
2626
) {

src/pages/editor.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default function EditorPageContainer(props: PageProps): JSX.Element {
1919
setHasMounted(true);
2020
}, []);
2121
if (!hasMounted) {
22-
return null;
22+
return <></>;
2323
}
2424
return <EditorPage {...props} />;
2525
}

src/stories/Tooltip.stories.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ const Template: Story<ComponentProps<typeof Tooltip>> = args => {
2222
const [show, setShow] = React.useState<boolean>(false);
2323
React.useEffect(() => {
2424
if (ref.current) setShow(true);
25-
}, [ref.current]);
25+
}, []);
2626

2727
return (
2828
<div className="my-8" ref={ref}>
2929
{show && (
30-
<Tooltip {...args} appendTo={() => ref.current} showOnCreate={true}>
30+
<Tooltip {...args} appendTo={() => ref.current!} showOnCreate={true}>
3131
<span className="bg-gray-100 p-2 dark:bg-gray-700">
3232
Hover over me!
3333
</span>
@@ -67,7 +67,7 @@ const TextTooltipTemplate: Story<
6767
const [show, setShow] = React.useState<boolean>(false);
6868
React.useEffect(() => {
6969
if (ref.current) setShow(true);
70-
}, [ref.current]);
70+
}, []);
7171

7272
return (
7373
<div className="my-8" ref={ref}>
@@ -121,7 +121,7 @@ const AsteriskTooltipTemplate: Story<
121121
{show && (
122122
<AsteriskComponent
123123
{...args}
124-
appendTo={() => ref.current}
124+
appendTo={() => ref.current!}
125125
showOnCreate={true}
126126
/>
127127
)}

src/templates/moduleTemplate.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export default function Template(props): JSX.Element {
2525
window.requestAnimationFrame(() => {
2626
try {
2727
const anchor = document.getElementById(hash.substring(1));
28+
if (!anchor) throw new Error(`The anchor "${hash}" doesn't exist`);
2829
const offset = anchor.getBoundingClientRect().top + window.scrollY;
2930
window.scroll({ top: offset, left: 0 });
3031
} catch (e) {

src/templates/syllabusTemplate.tsx

+11-13
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,17 @@ export default function Template(props) {
146146
);
147147
const moduleProgressInfo = useModulesProgressInfo(moduleIDs);
148148
const problemIDs = [
149-
...new Set(data.problems.edges.map(x => x.node.uniqueId) as string[]),
149+
...new Set(data.problems.nodes.map(x => x.uniqueId) as string[]),
150150
];
151151
const problemsProgressInfo = useProblemsProgressInfo(problemIDs);
152152

153153
const useProgressBarForCategory = (category: (typeof section)[0]) => {
154154
const categoryModuleIDs = category.items.map(
155155
module => module.frontmatter.id
156156
);
157-
const categoryProblemIDs = data.problems.edges
158-
.filter(x => categoryModuleIDs.includes(x.node.module.frontmatter.id))
159-
.map(x => x.node.uniqueId);
157+
const categoryProblemIDs = data.problems.nodes
158+
.filter(x => categoryModuleIDs.includes(x.module?.frontmatter.id ?? ''))
159+
.map(x => x.uniqueId);
160160
const problemsProgressInfo = useProblemsProgressInfo(categoryProblemIDs);
161161
return (
162162
categoryProblemIDs.length > 1 && (
@@ -249,7 +249,7 @@ export default function Template(props) {
249249
item.javaOc,
250250
item.pyOc,
251251
[],
252-
item.fields.gitAuthorTime
252+
item.fields?.gitAuthorTime
253253
)
254254
}
255255
/>
@@ -293,14 +293,12 @@ export const pageQuery = graphql`
293293
problems: allProblemInfo(
294294
filter: { module: { fields: { division: { eq: $division } } } }
295295
) {
296-
edges {
297-
node {
298-
uniqueId
299-
name
300-
module {
301-
frontmatter {
302-
id
303-
}
296+
nodes {
297+
uniqueId
298+
name
299+
module {
300+
frontmatter {
301+
id
304302
}
305303
}
306304
}

src/utils/extract-searchable-text.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export default function extractSearchableText(node) {
2424
}
2525

2626
function all(values) {
27-
const result = [];
27+
const result: string[] = [];
2828
const length = values.length;
2929
let index = -1;
3030

src/utils/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const getModulesForDivision = (
1717
}
1818
return {
1919
...allModules[k2 as string],
20-
slug: `/${division}/${allModules[k2 as string].frontmatter.id}`,
20+
slug: `/${division}/${allModules[k2 as string].frontmatter?.id}`,
2121
};
2222
}),
2323
description: k.description,

tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"module": "esnext",
1212
"moduleResolution": "node",
1313
"skipLibCheck": true,
14-
"strict": false
14+
"strict": false,
15+
"strictNullChecks": true
1516
}
1617
}

0 commit comments

Comments
 (0)