feat: add text uplading
This commit is contained in:
parent
964199f8a9
commit
2f90193d7e
5 changed files with 174 additions and 35 deletions
21
src/components/CodeInput.tsx
Normal file
21
src/components/CodeInput.tsx
Normal 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}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -2,7 +2,7 @@ import { AppShell, Box, Burger, Divider, Group, Header, MediaQuery, Navbar, Pape
|
|||
import { useClipboard } from '@mantine/hooks';
|
||||
import { useModals } from '@mantine/modals';
|
||||
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 { updateUser } from 'lib/redux/reducers/user';
|
||||
import { useStoreDispatch } from 'lib/redux/store';
|
||||
|
@ -88,6 +88,11 @@ const items = [
|
|||
text: 'Upload',
|
||||
link: '/dashboard/upload',
|
||||
},
|
||||
{
|
||||
icon: <TextIcon />,
|
||||
text: 'Upload Text',
|
||||
link: '/dashboard/text',
|
||||
},
|
||||
];
|
||||
|
||||
export default function Layout({ children, user }) {
|
||||
|
|
87
src/components/pages/UploadText.tsx
Normal file
87
src/components/pages/UploadText.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,40 +1,45 @@
|
|||
// https://github.com/toptal/haste-server/blob/master/static/application.js#L167-L174
|
||||
// Popular extension map
|
||||
const exts = {
|
||||
rb: 'ruby',
|
||||
py: 'python',
|
||||
pl: 'perl',
|
||||
php: 'php',
|
||||
scala: 'scala',
|
||||
go: 'go',
|
||||
xml: 'xml',
|
||||
html: 'xml',
|
||||
htm: 'xml',
|
||||
css: 'css',
|
||||
js: 'javascript',
|
||||
json: 'json',
|
||||
vbs: 'vbscript',
|
||||
lua: 'lua',
|
||||
pas: 'delphi',
|
||||
java: 'java',
|
||||
cpp: 'cpp',
|
||||
cc: 'cpp',
|
||||
m: 'objectivec',
|
||||
vala: 'vala',
|
||||
sql: 'sql',
|
||||
sm: 'smalltalk',
|
||||
lisp: 'lisp',
|
||||
ini: 'ini',
|
||||
diff: 'diff',
|
||||
bash: 'bash',
|
||||
sh: 'bash',
|
||||
tex: 'tex',
|
||||
erl: 'erlang',
|
||||
hs: 'haskell',
|
||||
md: 'markdown',
|
||||
txt: '',
|
||||
coffee: 'coffee',
|
||||
swift: 'swift',
|
||||
'md': 'Markdown',
|
||||
'css': 'CSS',
|
||||
'js': 'JavaScript',
|
||||
'json': 'JSON',
|
||||
'html': 'HTML',
|
||||
'ts': 'TypeScript',
|
||||
'java': 'Java',
|
||||
'py': 'Python',
|
||||
'rb': 'Ruby',
|
||||
'sh': 'Shell',
|
||||
'php': 'PHP',
|
||||
'pl': 'Perl',
|
||||
'sql': 'SQL',
|
||||
'xml': 'XML',
|
||||
'yml': 'YAML',
|
||||
'yaml': 'YAML',
|
||||
'c': 'C',
|
||||
'cpp': 'C++',
|
||||
'cs': 'C#',
|
||||
'go': 'Go',
|
||||
'h': 'C/C++ Header',
|
||||
'txt': 'Text',
|
||||
'dockerfile': 'Dockerfile',
|
||||
'toml': 'TOML',
|
||||
'ini': 'INI',
|
||||
'bat': 'Batch File',
|
||||
'tex': 'TeX',
|
||||
'r': 'R',
|
||||
'lua': 'Lua',
|
||||
'ps1': 'PowerShell',
|
||||
'rst': 'reStructuredText',
|
||||
'rs': 'Rust',
|
||||
'swift': 'Swift',
|
||||
'scss': 'SCSS',
|
||||
'less': 'LESS',
|
||||
'scala': 'Scala',
|
||||
'kotlin': 'Kotlin',
|
||||
'vb': 'Visual Basic',
|
||||
'vim': 'Vim Script',
|
||||
};
|
||||
|
||||
export default exts;
|
21
src/pages/dashboard/text.tsx
Normal file
21
src/pages/dashboard/text.tsx
Normal 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';
|
Loading…
Add table
Reference in a new issue