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 { 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 }) {
|
||||||
|
|
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
|
// 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;
|
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