mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-01-10 16:22:55 -05:00
clean up strict types a bit more
This commit is contained in:
@@ -5,7 +5,7 @@ import Link from "../Link";
|
||||
import Captcha from "../Captcha";
|
||||
import { CheckOcticon, XOcticon, MarkdownIcon } from "../Icons";
|
||||
import { styled, css } from "../../lib/styles/stitches.config";
|
||||
import type { FormikHelpers } from "formik";
|
||||
import type { FormikHelpers, FormikProps, FieldInputProps, FieldMetaProps } from "formik";
|
||||
|
||||
// CSS applied to both `<input />` and `<textarea />`
|
||||
const InputStyles = css({
|
||||
@@ -30,6 +30,7 @@ const InputStyles = css({
|
||||
true: {
|
||||
borderColor: "$error",
|
||||
},
|
||||
false: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -89,6 +90,7 @@ const SubmitButton = styled("button", {
|
||||
true: {
|
||||
display: "none",
|
||||
},
|
||||
false: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -117,6 +119,7 @@ const Result = styled("div", {
|
||||
true: {
|
||||
display: "none",
|
||||
},
|
||||
false: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -128,7 +131,7 @@ const ResultIcon = styled("svg", {
|
||||
fill: "currentColor",
|
||||
});
|
||||
|
||||
type Values = {
|
||||
type FormValues = {
|
||||
name: string;
|
||||
email: string;
|
||||
message: string;
|
||||
@@ -145,7 +148,7 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
||||
const [success, setSuccess] = useState(false);
|
||||
const [feedback, setFeedback] = useState("");
|
||||
|
||||
const handleSubmit = (values: Values, { setSubmitting }: FormikHelpers<Values>) => {
|
||||
const handleSubmit = (values: FormValues, { setSubmitting }: FormikHelpers<FormValues>) => {
|
||||
// once a user attempts a submission, this is true and stays true whether or not the next attempt(s) are successful
|
||||
setSubmitted(true);
|
||||
|
||||
@@ -196,8 +199,8 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
||||
message: "",
|
||||
"h-captcha-response": "",
|
||||
}}
|
||||
validate={(values: Values) => {
|
||||
const errors: Partial<Record<keyof Values, boolean>> = {};
|
||||
validate={(values: FormValues) => {
|
||||
const errors: Partial<Record<keyof FormValues, boolean>> = {};
|
||||
|
||||
errors.name = !values.name;
|
||||
errors.email = !values.email; // also loosely validated that it's email-like via browser (not foolproof)
|
||||
@@ -215,43 +218,40 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
||||
return errors;
|
||||
}}
|
||||
>
|
||||
{({ setFieldValue, isSubmitting }) => (
|
||||
{({ setFieldValue, isSubmitting }: FormikProps<FormValues>) => (
|
||||
<Form className={className} name="contact">
|
||||
<Field name="name">
|
||||
{/* @ts-ignore */}
|
||||
{({ field, meta }) => (
|
||||
{({ field, meta }: { field: FieldInputProps<string>; meta: FieldMetaProps<string> }) => (
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
disabled={success}
|
||||
missing={meta.error && meta.touched}
|
||||
missing={!!(meta.error && meta.touched)}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<Field name="email">
|
||||
{/* @ts-ignore */}
|
||||
{({ field, meta }) => (
|
||||
{({ field, meta }: { field: FieldInputProps<string>; meta: FieldMetaProps<string> }) => (
|
||||
<Input
|
||||
type="email"
|
||||
inputMode="email"
|
||||
placeholder="Email"
|
||||
disabled={success}
|
||||
missing={meta.error && meta.touched}
|
||||
missing={!!(meta.error && meta.touched)}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<Field name="message">
|
||||
{/* @ts-ignore */}
|
||||
{({ field, meta }) => (
|
||||
{({ field, meta }: { field: FieldInputProps<string>; meta: FieldMetaProps<string> }) => (
|
||||
<TextArea
|
||||
placeholder="Write something..."
|
||||
minRows={5}
|
||||
disabled={success}
|
||||
missing={meta.error && meta.touched}
|
||||
missing={!!(meta.error && meta.touched)}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -64,8 +64,7 @@ const Image = ({
|
||||
throw new TypeError("'src' should be a string or a valid StaticImageData object.");
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const img = <RoundedImage {...imageProps} />;
|
||||
const img = <RoundedImage {...(imageProps as NextImageProps)} />;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
|
||||
@@ -55,13 +55,15 @@ const PostDate = styled(Time, {
|
||||
});
|
||||
|
||||
export type NotesListProps = {
|
||||
notesByYear: { [key: string]: NoteFrontMatter[] };
|
||||
notesByYear: {
|
||||
[year: string]: NoteFrontMatter[];
|
||||
};
|
||||
};
|
||||
|
||||
const NotesList = ({ notesByYear }: NotesListProps) => {
|
||||
const sections: ReactElement[] = [];
|
||||
|
||||
Object.entries(notesByYear).forEach(([year, notes]: [string, NoteFrontMatter[]]) => {
|
||||
Object.entries(notesByYear).forEach(([year, notes]) => {
|
||||
sections.push(
|
||||
<Section key={year}>
|
||||
<Year>{year}</Year>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useRef, useEffect, useState, memo } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
// @ts-ignore
|
||||
import RFB from "@novnc/novnc/core/rfb.js";
|
||||
import Terminal from "../Terminal";
|
||||
import { styled } from "../../lib/styles/stitches.config";
|
||||
@@ -55,8 +54,7 @@ const VNC = ({ server }: VNCProps) => {
|
||||
const [message, setMessage] = useState({ message: "", anyKey: false });
|
||||
|
||||
// the actual connection and virtual screen (injected by noVNC when it's ready)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const rfbRef = useRef<any>(null);
|
||||
const rfbRef = useRef<RFB | null>(null);
|
||||
const screenRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// ends the session forcefully
|
||||
@@ -93,7 +91,7 @@ const VNC = ({ server }: VNCProps) => {
|
||||
}
|
||||
|
||||
// https://github.com/novnc/noVNC/blob/master/docs/API.md
|
||||
rfbRef.current = new RFB(screenRef.current, server, {
|
||||
rfbRef.current = new RFB(screenRef.current as Element, server, {
|
||||
wsProtocols: ["binary", "base64"],
|
||||
});
|
||||
|
||||
@@ -101,7 +99,7 @@ const VNC = ({ server }: VNCProps) => {
|
||||
rfbRef.current.scaleViewport = true;
|
||||
|
||||
// VM connected
|
||||
rfbRef.current.addEventListener("connect", () => {
|
||||
rfbRef.current?.addEventListener("connect", () => {
|
||||
console.log("successfully connected to VM socket!");
|
||||
|
||||
// finally hide the terminal and show the VNC canvas
|
||||
@@ -111,7 +109,7 @@ const VNC = ({ server }: VNCProps) => {
|
||||
});
|
||||
|
||||
// VM disconnected (on either end)
|
||||
rfbRef.current.addEventListener("disconnect", (detail: unknown) => {
|
||||
rfbRef.current?.addEventListener("disconnect", (detail: unknown) => {
|
||||
console.warn("VM ended session remotely:", detail);
|
||||
|
||||
// hide the display and show the terminal
|
||||
|
||||
@@ -77,17 +77,7 @@ const Video = ({ src, thumbnail, subs, autoplay, className, ...rest }: VideoProp
|
||||
|
||||
return (
|
||||
<Wrapper className={className}>
|
||||
{hasMounted && (
|
||||
<Player
|
||||
width="100%"
|
||||
height="100%"
|
||||
url={url}
|
||||
controls={!autoplay}
|
||||
// @ts-ignore
|
||||
config={config}
|
||||
{...rest}
|
||||
/>
|
||||
)}
|
||||
{hasMounted && <Player width="100%" height="100%" url={url} controls={!autoplay} config={config} {...rest} />}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user