feat: flameshot generator

This commit is contained in:
diced 2022-09-24 10:41:03 -07:00
parent 4a753376b7
commit 0d65ee1a32
No known key found for this signature in database
GPG key ID: 370BD1BA142842D1
9 changed files with 183 additions and 80 deletions

View file

@ -82,11 +82,12 @@ The default port is `3000`, once you have accessed it you can see a login screen
# ShareX (Windows) # ShareX (Windows)
This section requires [ShareX](https://www.getsharex.com/). This section requires [ShareX](https://www.getsharex.com/).
After navigating to Zipline, click on the top right corner where it says your username and click Manage Account. Scroll down to see "ShareX Config", select the one you would prefer using. After this you can import the .sxcu into sharex. [More information here](https://zipl.vercel.app/docs/uploaders/sharex) After navigating to Zipline, click on the top right corner where it says your username and click Manage Account. Scroll down to see "ShareX Config", select the one you would prefer using. After this you can import the .sxcu into sharex. [More information here](https://zipl.vercel.app/docs/guides/uploaders/sharex)
# Flameshot (Linux) # Flameshot (Linux)
This section requires [Flameshot](https://www.flameshot.org/), [jq](https://stedolan.github.io/jq/), and [xsel](https://github.com/kfish/xsel). This section requires [Flameshot](https://www.flameshot.org/), [jq](https://stedolan.github.io/jq/), and [xsel](https://github.com/kfish/xsel).
You can either use the script below, or generate one directly from Zipline (just like how you can generate a ShareX config).
To upload files using flameshot we will use a script. Replace $TOKEN and $HOST with your own values, you probably know how to do this if you use linux. To upload files using flameshot we will use a script. Replace $TOKEN and $HOST with your own values, you probably know how to do this if you use linux.
```shell ```shell

View file

@ -23,6 +23,8 @@ module.exports = {
domains: [ domains: [
// For sharex icon in manage user // For sharex icon in manage user
'getsharex.com', 'getsharex.com',
// For flameshot icon, and maybe in the future other stuff from github
'raw.githubusercontent.com',
], ],
}, },
poweredByHeader: false, poweredByHeader: false,

View file

@ -0,0 +1,7 @@
// https://github.com/flameshot-org/flameshot/blob/master/data/img/app/flameshot.svg
import Image from 'next/image';
export default function FlameshotIcon({ ...props }) {
return <Image src='https://raw.githubusercontent.com/flameshot-org/flameshot/master/data/img/app/flameshot.svg' width={24} height={24} {...props} />;
}

View file

@ -3,5 +3,5 @@
import Image from 'next/image'; import Image from 'next/image';
export default function ShareXIcon({ ...props }) { export default function ShareXIcon({ ...props }) {
return <Image src='https://getsharex.com/img/ShareX_Logo.svg' width={15} height={15} {...props} />; return <Image src='https://getsharex.com/img/ShareX_Logo.svg' width={24} height={24} {...props} />;
} }

View file

@ -25,6 +25,8 @@ import TagIcon from './TagIcon';
import ClockIcon from './ClockIcon'; import ClockIcon from './ClockIcon';
import ExternalLinkIcon from './ExternalLinkIcon'; import ExternalLinkIcon from './ExternalLinkIcon';
import ShareXIcon from './ShareXIcon'; import ShareXIcon from './ShareXIcon';
import DownloadIcon from './DownloadIcon';
import FlameshotIcon from './FlameshotIcon';
export { export {
ActivityIcon, ActivityIcon,
@ -54,4 +56,6 @@ export {
ClockIcon, ClockIcon,
ExternalLinkIcon, ExternalLinkIcon,
ShareXIcon, ShareXIcon,
DownloadIcon,
FlameshotIcon,
}; };

View file

@ -0,0 +1,72 @@
import { Button, Checkbox, Group, Modal, NumberInput, Select, Title } from '@mantine/core';
import { useForm } from '@mantine/form';
import { DownloadIcon } from 'components/icons';
import { useState } from 'react';
import { GeneratorModal } from './GeneratorModal';
export default function Flameshot({ user, open, setOpen }) {
const onSubmit = values => {
const curl = [
'curl',
'-H',
'"Content-Type: multipart/form-data"',
'-H',
`"authorization: ${user?.token}"`,
'-F',
'file=@/tmp/ss.png',
`${window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '')}/api/upload`,
];
const extraHeaders = {};
if (values.format !== 'RANDOM') {
extraHeaders['Format'] = values.format;
} else {
delete extraHeaders['Format'];
}
if (values.imageCompression !== 0) {
extraHeaders['Image-Compression-Percent'] = values.imageCompression;
} else {
delete extraHeaders['Image-Compression-Percent'];
}
if (values.zeroWidthSpace) {
extraHeaders['Zws'] = 'true';
} else {
delete extraHeaders['Zws'];
}
if (values.embed) {
extraHeaders['Embed'] = 'true';
} else {
delete extraHeaders['Embed'];
}
for (const [key, value] of Object.entries(extraHeaders)) {
curl.push('-H');
curl.push(`"${key}: ${value}"`);
}
const shell = `#!/bin/bash
flameshot gui -r > /tmp/ss.png;
${curl.join(' ')} | jq -r '.files[0]' | tr -d '\n' | xsel -ib;
`;
const pseudoElement = document.createElement('a');
pseudoElement.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(shell));
pseudoElement.setAttribute('download', 'zipline.sh');
pseudoElement.style.display = 'none';
document.body.appendChild(pseudoElement);
pseudoElement.click();
pseudoElement.parentNode.removeChild(pseudoElement);
};
return <GeneratorModal
opened={open}
onClose={() => setOpen(false)}
title='Flameshot'
desc='To use this script, you need Flameshot, curl, jq, and xsel installed. This script is intended for use on Linux only.'
onSubmit={onSubmit}
/>;
}

View file

@ -0,0 +1,77 @@
import { Modal, Select, NumberInput, Group, Checkbox, Button, Title, Text } from '@mantine/core';
import { useForm } from '@mantine/form';
import { DownloadIcon } from 'components/icons';
export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
const form = useForm({
initialValues: {
format: 'RANDOM',
imageCompression: 0,
zeroWidthSpace: false,
embed: false,
},
});
return (
<Modal
opened={opened}
onClose={onClose}
title={<Title order={3}>{title}</Title>}
size='lg'
>
{other.desc && <Text>{other.desc}</Text>}
<form onSubmit={form.onSubmit(values => onSubmit(values))}>
<Select
label='Select file name format'
data={[
{ value: 'RANDOM', label: 'Random (alphanumeric)' },
{ value: 'DATE', label: 'Date' },
{ value: 'UUID', label: 'UUID' },
{ value: 'NAME', label: 'Name (keeps original file name)' },
]}
id='format'
{...form.getInputProps('format')}
/>
<NumberInput
label={'Image Compression (leave at 0 if you don\'t want to compress)'}
max={100}
min={0}
mt='md'
id='imageCompression'
{...form.getInputProps('imageCompression')}
/>
<Group grow mt='md'>
<Checkbox
label='Zero Width Space'
id='zeroWidthSpace'
{...form.getInputProps('zeroWidthSpace', { type: 'checkbox' })}
/>
<Checkbox
label='Embed'
id='embed'
{...form.getInputProps('embed', { type: 'checkbox' })}
/>
</Group>
<Group grow>
<Button
mt='md'
onClick={form.reset}
>
Reset
</Button>
<Button
mt='md'
rightIcon={<DownloadIcon />}
type='submit'
>
Download
</Button>
</Group>
</form>
</Modal>
);
}

View file

@ -1,7 +1,8 @@
import { Button, Checkbox, Group, Modal, NumberInput, Select, Title } from '@mantine/core'; import { Button, Checkbox, Group, Modal, NumberInput, Select, Title } from '@mantine/core';
import { useForm } from '@mantine/form'; import { useForm } from '@mantine/form';
import DownloadIcon from 'components/icons/DownloadIcon'; import { DownloadIcon } from 'components/icons';
import { useState } from 'react'; import { useState } from 'react';
import { GeneratorModal } from './GeneratorModal';
export default function ShareX({ user, open, setOpen }) { export default function ShareX({ user, open, setOpen }) {
const [config, setConfig] = useState({ const [config, setConfig] = useState({
@ -18,16 +19,7 @@ export default function ShareX({ user, open, setOpen }) {
FileFormName: 'file', FileFormName: 'file',
}); });
const form = useForm({ const onSubmit = values => {
initialValues: {
format: 'RANDOM',
imageCompression: 0,
zeroWidthSpace: false,
embed: false,
},
});
const download = values => {
if (values.format !== 'RANDOM') { if (values.format !== 'RANDOM') {
config.Headers['Format'] = values.format; config.Headers['Format'] = values.format;
setConfig(config); setConfig(config);
@ -69,66 +61,10 @@ export default function ShareX({ user, open, setOpen }) {
pseudoElement.parentNode.removeChild(pseudoElement); pseudoElement.parentNode.removeChild(pseudoElement);
}; };
return ( return <GeneratorModal
<Modal opened={open}
opened={open} onClose={() => setOpen(false)}
onClose={() => setOpen(false)} title='ShareX'
title={<Title order={3}>ShareX</Title>} onSubmit={onSubmit}
size='lg' />;
>
<form onSubmit={form.onSubmit(values => download(values))}>
<Select
label='Select file name format'
data={[
{ value: 'RANDOM', label: 'Random (alphanumeric)' },
{ value: 'DATE', label: 'Date' },
{ value: 'UUID', label: 'UUID' },
{ value: 'NAME', label: 'Name (keeps original file name)' },
]}
id='format'
{...form.getInputProps('format')}
/>
<NumberInput
label={'Image Compression (leave at 0 if you don\'t want to compress)'}
max={100}
min={0}
mt='md'
id='imageCompression'
{...form.getInputProps('imageCompression')}
/>
<Group grow mt='md'>
<Checkbox
label='Zero Width Space'
id='zeroWidthSpace'
{...form.getInputProps('zeroWidthSpace', { type: 'checkbox' })}
/>
<Checkbox
label='Embed'
id='embed'
{...form.getInputProps('embed', { type: 'checkbox' })}
/>
</Group>
<Group grow>
<Button
mt='md'
onClick={form.reset}
>
Reset
</Button>
<Button
mt='md'
rightIcon={<DownloadIcon />}
type='submit'
>
Download
</Button>
</Group>
</form>
</Modal>
);
} }

View file

@ -3,7 +3,7 @@ import { useForm } from '@mantine/form';
import { randomId, useInterval } from '@mantine/hooks'; import { randomId, useInterval } from '@mantine/hooks';
import { useModals } from '@mantine/modals'; import { useModals } from '@mantine/modals';
import { showNotification, updateNotification } from '@mantine/notifications'; import { showNotification, updateNotification } from '@mantine/notifications';
import { CrossIcon, DeleteIcon, SettingsIcon, ShareXIcon } from 'components/icons'; import { CrossIcon, DeleteIcon, FlameshotIcon, SettingsIcon, ShareXIcon } from 'components/icons';
import DownloadIcon from 'components/icons/DownloadIcon'; import DownloadIcon from 'components/icons/DownloadIcon';
import Link from 'components/Link'; import Link from 'components/Link';
import MutedText from 'components/MutedText'; import MutedText from 'components/MutedText';
@ -13,6 +13,7 @@ import { bytesToRead } from 'lib/clientUtils';
import { updateUser } from 'lib/redux/reducers/user'; import { updateUser } from 'lib/redux/reducers/user';
import { useStoreDispatch, useStoreSelector } from 'lib/redux/store'; import { useStoreDispatch, useStoreSelector } from 'lib/redux/store';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import Flameshot from './Flameshot';
import ShareX from './ShareX'; import ShareX from './ShareX';
function ExportDataTooltip({ children }) { function ExportDataTooltip({ children }) {
@ -24,7 +25,8 @@ export default function Manage() {
const dispatch = useStoreDispatch(); const dispatch = useStoreDispatch();
const modals = useModals(); const modals = useModals();
const [open, setOpen] = useState(false); const [shareXOpen, setShareXOpen] = useState(false);
const [flameshotOpen, setFlameshotOpen] = useState(false);
const [exports, setExports] = useState([]); const [exports, setExports] = useState([]);
const [file, setFile] = useState<File>(null); const [file, setFile] = useState<File>(null);
const [fileDataURL, setFileDataURL] = useState(user.avatar ?? null); const [fileDataURL, setFileDataURL] = useState(user.avatar ?? null);
@ -297,12 +299,14 @@ export default function Manage() {
)} )}
</Card> </Card>
<Title my='md'>ShareX Config</Title> <Title my='md'>Uploaders</Title>
<Group> <Group>
<Button onClick={() => setOpen(true)} rightIcon={<ShareXIcon />}>Generate ShareX Config</Button> <Button size='xl' onClick={() => setShareXOpen(true)} rightIcon={<ShareXIcon />}>Generate ShareX Config</Button>
<Button size='xl' onClick={() => setFlameshotOpen(true)} rightIcon={<FlameshotIcon />}>Generate Flameshot Script</Button>
</Group> </Group>
<ShareX user={user} open={open} setOpen={setOpen} /> <ShareX user={user} open={shareXOpen} setOpen={setShareXOpen} />
<Flameshot user={user} open={flameshotOpen} setOpen={setFlameshotOpen} />
</> </>
); );
} }