feat: add text uplading

This commit is contained in:
dicedtomato 2022-07-09 23:54:55 +00:00 committed by GitHub
parent 964199f8a9
commit 2f90193d7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 174 additions and 35 deletions

View file

@ -0,0 +1,21 @@
import { createStyles, MantineSize, Textarea } from '@mantine/core';
const useStyles = createStyles((theme, { size }: { size: MantineSize }) => ({
input: {
fontFamily: 'monospace',
fontSize: theme.fn.size({ size, sizes: theme.fontSizes }) - 2,
height: '100vh',
},
}));
export default function CodeInput({ ...props }) {
const { classes } = useStyles({ size: 'md' }, { name: 'CodeInput' });
return (
<Textarea
classNames={{ input: classes.input }}
autoComplete='nope'
{...props}
/>
);
}

View file

@ -2,7 +2,7 @@ import { AppShell, Box, Burger, Divider, Group, Header, MediaQuery, Navbar, Pape
import { useClipboard } from '@mantine/hooks'; import { useClipboard } from '@mantine/hooks';
import { useModals } from '@mantine/modals'; import { useModals } from '@mantine/modals';
import { useNotifications } from '@mantine/notifications'; import { useNotifications } from '@mantine/notifications';
import { CheckIcon, CopyIcon, Cross1Icon, FileIcon, GearIcon, HomeIcon, Link1Icon, MixerHorizontalIcon, Pencil1Icon, PersonIcon, PinRightIcon, ResetIcon, UploadIcon } from '@modulz/radix-icons'; import { CheckIcon, CopyIcon, Cross1Icon, FileIcon, GearIcon, HomeIcon, Link1Icon, MixerHorizontalIcon, Pencil1Icon, PersonIcon, PinRightIcon, ResetIcon, TextIcon, UploadIcon } from '@modulz/radix-icons';
import useFetch from 'hooks/useFetch'; import useFetch from 'hooks/useFetch';
import { updateUser } from 'lib/redux/reducers/user'; import { updateUser } from 'lib/redux/reducers/user';
import { useStoreDispatch } from 'lib/redux/store'; import { useStoreDispatch } from 'lib/redux/store';
@ -88,6 +88,11 @@ const items = [
text: 'Upload', text: 'Upload',
link: '/dashboard/upload', link: '/dashboard/upload',
}, },
{
icon: <TextIcon />,
text: 'Upload Text',
link: '/dashboard/text',
},
]; ];
export default function Layout({ children, user }) { export default function Layout({ children, user }) {

View file

@ -0,0 +1,87 @@
import { Button, Collapse, Group, Progress, Select, Title, useMantineTheme } from '@mantine/core';
import { randomId, useClipboard } from '@mantine/hooks';
import { useNotifications } from '@mantine/notifications';
import { CrossCircledIcon, LetterCaseCapitalizeIcon, LetterCaseLowercaseIcon, UploadIcon } from '@modulz/radix-icons';
import CodeInput from 'components/CodeInput';
import Dropzone from 'components/dropzone/Dropzone';
import FileDropzone from 'components/dropzone/DropzoneFile';
import Link from 'components/Link';
import exts from 'lib/exts';
import { useStoreSelector } from 'lib/redux/store';
import { useEffect, useState } from 'react';
export default function Upload() {
const notif = useNotifications();
const clipboard = useClipboard();
const user = useStoreSelector(state => state.user);
const [progress, setProgress] = useState(0);
const [loading, setLoading] = useState(false);
const [value, setValue] = useState('');
const [lang, setLang] = useState('txt');
console.log(lang);
const handleUpload = async () => {
setProgress(0);
setLoading(true);
const file = new File([value], 'text.' + lang);
const id = notif.showNotification({
title: 'Uploading...',
message: '',
loading: true,
autoClose: false,
});
const req = new XMLHttpRequest();
req.upload.addEventListener('progress', e => {
if (e.lengthComputable) {
setProgress(Math.round(e.loaded / e.total * 100));
}
});
req.addEventListener('load', e => {
// @ts-ignore not sure why it thinks response doesnt exist, but it does.
const json = JSON.parse(e.target.response);
setLoading(false);
if (!json.error) {
notif.updateNotification(id, {
title: 'Upload Successful',
message: <>Copied first file to clipboard! <br />{json.files.map(x => (<Link key={x} href={x}>{x}<br /></Link>))}</>,
});
}
});
const body = new FormData();
body.append('file', file);
req.open('POST', '/api/upload');
req.setRequestHeader('Authorization', user.token);
req.send(body);
};
return (
<>
<Title mb='md'>Upload Text</Title>
<CodeInput
value={value}
onChange={e => setValue(e.target.value)}
/>
<Group position='right' mt='md'>
<Select
value={lang}
onChange={setLang}
dropdownPosition='top'
data={Object.keys(exts).map(x => ({ value: x, label: exts[x] }))}
icon={<LetterCaseCapitalizeIcon />}
/>
<Button leftIcon={<UploadIcon />} onClick={handleUpload}>Upload</Button>
</Group>
</>
);
}

View file

@ -1,40 +1,45 @@
// https://github.com/toptal/haste-server/blob/master/static/application.js#L167-L174 // https://github.com/toptal/haste-server/blob/master/static/application.js#L167-L174
// Popular extension map // Popular extension map
const exts = { const exts = {
rb: 'ruby', 'md': 'Markdown',
py: 'python', 'css': 'CSS',
pl: 'perl', 'js': 'JavaScript',
php: 'php', 'json': 'JSON',
scala: 'scala', 'html': 'HTML',
go: 'go', 'ts': 'TypeScript',
xml: 'xml', 'java': 'Java',
html: 'xml', 'py': 'Python',
htm: 'xml', 'rb': 'Ruby',
css: 'css', 'sh': 'Shell',
js: 'javascript', 'php': 'PHP',
json: 'json', 'pl': 'Perl',
vbs: 'vbscript', 'sql': 'SQL',
lua: 'lua', 'xml': 'XML',
pas: 'delphi', 'yml': 'YAML',
java: 'java', 'yaml': 'YAML',
cpp: 'cpp', 'c': 'C',
cc: 'cpp', 'cpp': 'C++',
m: 'objectivec', 'cs': 'C#',
vala: 'vala', 'go': 'Go',
sql: 'sql', 'h': 'C/C++ Header',
sm: 'smalltalk', 'txt': 'Text',
lisp: 'lisp', 'dockerfile': 'Dockerfile',
ini: 'ini', 'toml': 'TOML',
diff: 'diff', 'ini': 'INI',
bash: 'bash', 'bat': 'Batch File',
sh: 'bash', 'tex': 'TeX',
tex: 'tex', 'r': 'R',
erl: 'erlang', 'lua': 'Lua',
hs: 'haskell', 'ps1': 'PowerShell',
md: 'markdown', 'rst': 'reStructuredText',
txt: '', 'rs': 'Rust',
coffee: 'coffee', 'swift': 'Swift',
swift: 'swift', 'scss': 'SCSS',
'less': 'LESS',
'scala': 'Scala',
'kotlin': 'Kotlin',
'vb': 'Visual Basic',
'vim': 'Vim Script',
}; };
export default exts; export default exts;

View file

@ -0,0 +1,21 @@
import React from 'react';
import useLogin from 'hooks/useLogin';
import Layout from 'components/Layout';
import UploadText from 'components/pages/UploadText';
import { LoadingOverlay } from '@mantine/core';
export default function UploadTextPage() {
const { user, loading } = useLogin();
if (loading) return <LoadingOverlay visible={loading} />;
return (
<Layout
user={user}
>
<UploadText/>
</Layout>
);
}
UploadTextPage.title = 'Zipline - Upload Text';