Applied formatting

This commit is contained in:
Samuel Maier 2022-02-19 22:24:29 +01:00
parent 5f77d0e5ee
commit ef03b13ed4
2 changed files with 86 additions and 70 deletions

View file

@ -30,7 +30,12 @@ import useStorage from "use-local-storage-state";
import Editor from "@monaco-editor/react";
import { editor } from "monaco-editor/esm/vs/editor/editor.api";
import rustpadRaw from "../rustpad-server/src/rustpad.rs?raw";
import { getFileExtension, getLanguage, Language, languages } from "./languages";
import {
getFileExtension,
getLanguage,
Language,
languages,
} from "./languages";
import animals from "./animals.json";
import Rustpad, { UserInfo } from "./rustpad";
import useHash from "./useHash";
@ -46,19 +51,24 @@ function getWsUri(id: string) {
);
}
function useKeyboardCtrlIntercept(key: string, reaction: (event: KeyboardEvent) => unknown) {
function useKeyboardCtrlIntercept(
key: string,
reaction: (event: KeyboardEvent) => unknown
) {
useEffect(() => {
const wrappedReaction: typeof reaction = (event) => {
if (!(event.metaKey || event.ctrlKey)) return;
if (event.key.toLowerCase() !== key.toLowerCase()) return;
event.preventDefault();
reaction(event);
}
};
const controller = new AbortController();
window.addEventListener("keydown", wrappedReaction, {signal: controller.signal});
window.addEventListener("keydown", wrappedReaction, {
signal: controller.signal,
});
return () => controller.abort()
}, [key, reaction])
return () => controller.abort();
}, [key, reaction]);
}
function generateName() {
@ -69,10 +79,10 @@ function generateHue() {
return Math.floor(Math.random() * 360);
}
/**
/**
* This appears to still be the best way to download a file while suggesting a filename.
*
* According to [mdn](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download)
*
* According to [mdn](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download)
* the download attribute gets ignored on URIs that are not either `same-origin` or use the `blob` or `data` schemes.
*/
function downloadUri(uri: string, filename: string) {
@ -82,11 +92,16 @@ function downloadUri(uri: string, filename: string) {
downloadAnchor.click();
}
async function eventToAsync<EventType extends keyof HTMLElementEventMap>(element: HTMLElement, eventType: EventType) {
async function eventToAsync<EventType extends keyof HTMLElementEventMap>(
element: HTMLElement,
eventType: EventType
) {
const abortController = new AbortController();
const evt = await new Promise<HTMLElementEventMap[EventType]>((resolve) => {
element.addEventListener(eventType, (event) => resolve(event), {signal: abortController.signal});
})
element.addEventListener(eventType, (event) => resolve(event), {
signal: abortController.signal,
});
});
abortController.abort();
return evt;
}
@ -198,12 +213,12 @@ function App() {
{
range: model.getFullModelRange(),
text: newText,
}
},
],
() => null
);
editor.setPosition({ column: 0, lineNumber: 0});
};
editor.setPosition({ column: 0, lineNumber: 0 });
}
function handleLoadSample() {
setText(rustpadRaw);
@ -217,7 +232,7 @@ function App() {
setText(text);
const newLanguage = getLanguage(file.name);
if (newLanguage !== language) handleChangeLanguage(newLanguage);
};
}
function handleDownloadFile() {
const model = editor?.getModel();
@ -229,9 +244,9 @@ function App() {
const url = URL.createObjectURL(file);
downloadUri(url, fileName);
URL.revokeObjectURL(url);
};
}
useKeyboardCtrlIntercept('s', handleDownloadFile);
useKeyboardCtrlIntercept("s", handleDownloadFile);
function handleDarkMode() {
setDarkMode(!darkMode);
@ -288,7 +303,9 @@ function App() {
bgColor={darkMode ? "#3c3c3c" : "white"}
borderColor={darkMode ? "#3c3c3c" : "white"}
value={language}
onChange={(event) => handleChangeLanguage(event.target.value as Language)}
onChange={(event) =>
handleChangeLanguage(event.target.value as Language)
}
>
{languages.map((lang) => (
<option key={lang} value={lang} style={{ color: "black" }}>
@ -323,48 +340,45 @@ function App() {
</InputGroup>
<Heading mt={4} mb={1.5} size="sm">
Upload & Download
Upload & Download
</Heading>
<Text>
You can also upload with drag&drop and downlod with Ctrl + S
</Text>
<ButtonGroup
size="sm"
display="flex"
>
<Button
size="sm"
colorScheme={darkMode ? "whiteAlpha" : "blackAlpha"}
borderColor={darkMode ? "purple.400" : "purple.600"}
color={darkMode ? "purple.400" : "purple.600"}
variant="outline"
leftIcon={<VscCloudUpload />}
mt={1}
flex="auto"
onClick={async () => {
const file = await uploadFile();
if (!file) return;
handleUploadFile(file);
}}
>
Upload
</Button>
<Button
size="sm"
colorScheme={darkMode ? "whiteAlpha" : "blackAlpha"}
borderColor={darkMode ? "purple.400" : "purple.600"}
color={darkMode ? "purple.400" : "purple.600"}
variant="outline"
leftIcon={<VscCloudDownload />}
mt={1}
flex="auto"
onClick={(event) => {
event.preventDefault();
handleDownloadFile();
}}
>
Download
</Button>
<ButtonGroup size="sm" display="flex">
<Button
size="sm"
colorScheme={darkMode ? "whiteAlpha" : "blackAlpha"}
borderColor={darkMode ? "purple.400" : "purple.600"}
color={darkMode ? "purple.400" : "purple.600"}
variant="outline"
leftIcon={<VscCloudUpload />}
mt={1}
flex="auto"
onClick={async () => {
const file = await uploadFile();
if (!file) return;
handleUploadFile(file);
}}
>
Upload
</Button>
<Button
size="sm"
colorScheme={darkMode ? "whiteAlpha" : "blackAlpha"}
borderColor={darkMode ? "purple.400" : "purple.600"}
color={darkMode ? "purple.400" : "purple.600"}
variant="outline"
leftIcon={<VscCloudDownload />}
mt={1}
flex="auto"
onClick={(event) => {
event.preventDefault();
handleDownloadFile();
}}
>
Download
</Button>
</ButtonGroup>
<Heading mt={4} mb={1.5} size="sm">

View file

@ -78,13 +78,13 @@ export const languages = [
"vb",
"verilog",
"xml",
"yaml"
"yaml",
] as const;
export type Language = typeof languages[number];
/** The default extension of the known programming languages (to be used on download) */
const defaultExtensions: {[key in Language]?: string} = {
const defaultExtensions: { [key in Language]?: string } = {
typescript: "ts",
rust: "rs",
cpp: "cpp",
@ -92,30 +92,32 @@ const defaultExtensions: {[key in Language]?: string} = {
html: "html",
};
type LanguageExtensions = {[key in string]: Language};
type LanguageExtensions = { [key in string]: Language };
/**
/**
* Additional extensions that refer to known languages, to detect filetype on upload.
* NO NEED to add the default file extensions.
*/
const additionalExtensionsToLanguage: LanguageExtensions = {
"yml": "yaml",
"cc": "cpp",
yml: "yaml",
cc: "cpp",
};
/** Used on download to determine file extension. */
export function getFileExtension(language: Language) {
return defaultExtensions[language] ?? "txt";
};
}
/** invert key value */
const defaultExtensionsToLanguage = Object.entries(defaultExtensions)
.reduce((defaultExtensionsToLanguage, [key, value]) => {
const defaultExtensionsToLanguage = Object.entries(defaultExtensions).reduce(
(defaultExtensionsToLanguage, [key, value]) => {
return {
...defaultExtensionsToLanguage,
[value]: key as Language
}
}, {} as LanguageExtensions);
[value]: key as Language,
};
},
{} as LanguageExtensions
);
const extensionsToLanguage: LanguageExtensions = {
...defaultExtensionsToLanguage,
@ -125,4 +127,4 @@ const extensionsToLanguage: LanguageExtensions = {
/** Used to detect programming language on upload based on file name */
export function getLanguage(fileName: string): Language {
return extensionsToLanguage[fileName.split(".")[1]] ?? "plaintext";
};
}