2021-03-27 14:17:28 +00:00
|
|
|
import { useState, useEffect, useCallback } from 'react';
|
2021-03-27 11:49:46 +00:00
|
|
|
import styled from 'styled-components';
|
2021-03-26 22:00:12 +00:00
|
|
|
import { gzip } from 'pako';
|
|
|
|
|
import history from 'history/browser';
|
|
|
|
|
import copy from 'copy-to-clipboard';
|
|
|
|
|
|
2021-03-27 13:51:48 +00:00
|
|
|
import { MenuButton, Button } from './Menu';
|
2021-10-28 21:05:35 +01:00
|
|
|
import { languages } from '../util/highlighting';
|
2021-03-27 11:49:46 +00:00
|
|
|
import themes from '../style/themes';
|
2021-10-27 23:37:42 +01:00
|
|
|
import { postUrl } from '../util/constants';
|
2021-03-27 11:49:46 +00:00
|
|
|
|
2021-04-02 13:05:15 +01:00
|
|
|
export default function EditorControls({
|
2022-01-08 19:10:27 +00:00
|
|
|
actualContent,
|
|
|
|
|
setForcedContent,
|
2021-04-02 13:05:15 +01:00
|
|
|
language,
|
|
|
|
|
setLanguage,
|
|
|
|
|
theme,
|
|
|
|
|
setTheme,
|
|
|
|
|
zoom,
|
|
|
|
|
}) {
|
2021-03-26 22:00:12 +00:00
|
|
|
const [saving, setSaving] = useState(false);
|
|
|
|
|
const [recentlySaved, setRecentlySaved] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setRecentlySaved(false);
|
2022-01-08 19:10:27 +00:00
|
|
|
}, [actualContent, language]);
|
2021-03-26 22:00:12 +00:00
|
|
|
|
2021-03-27 14:17:28 +00:00
|
|
|
const save = useCallback(() => {
|
2022-01-08 19:10:27 +00:00
|
|
|
if (!actualContent || recentlySaved) {
|
2021-03-26 22:00:12 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
setSaving(true);
|
2022-01-08 19:10:27 +00:00
|
|
|
saveToBytebin(actualContent, language).then(pasteId => {
|
2021-03-26 22:00:12 +00:00
|
|
|
setSaving(false);
|
|
|
|
|
setRecentlySaved(true);
|
2022-01-08 19:10:27 +00:00
|
|
|
if (pasteId) {
|
|
|
|
|
history.replace({
|
|
|
|
|
pathname: pasteId,
|
|
|
|
|
});
|
|
|
|
|
copy(window.location.href);
|
|
|
|
|
document.title = 'paste | ' + pasteId;
|
|
|
|
|
}
|
2021-03-26 22:00:12 +00:00
|
|
|
});
|
2022-01-08 19:10:27 +00:00
|
|
|
}, [actualContent, language, recentlySaved]);
|
2021-03-27 14:17:28 +00:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2021-04-02 13:05:15 +01:00
|
|
|
const listener = e => {
|
|
|
|
|
if (e.ctrlKey || e.metaKey) {
|
2021-03-27 14:17:28 +00:00
|
|
|
if (e.key === 's' || e.key === 'S') {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
save();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e.key === '=' || e.key === '-') {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
zoom(e.key === '=' ? 1 : -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-02 13:05:15 +01:00
|
|
|
};
|
|
|
|
|
|
2021-03-27 14:17:28 +00:00
|
|
|
window.addEventListener('keydown', listener);
|
|
|
|
|
return () => window.removeEventListener('keydown', listener);
|
|
|
|
|
}, [save, zoom]);
|
2021-03-26 22:00:12 +00:00
|
|
|
|
2021-03-27 11:59:56 +00:00
|
|
|
function reset() {
|
2022-01-08 19:10:27 +00:00
|
|
|
setForcedContent('');
|
2021-03-27 11:59:56 +00:00
|
|
|
setLanguage('plain');
|
|
|
|
|
history.replace({
|
2021-04-02 13:05:15 +01:00
|
|
|
pathname: '/',
|
2021-08-20 23:41:57 +01:00
|
|
|
hash: '',
|
2021-03-27 11:59:56 +00:00
|
|
|
});
|
|
|
|
|
document.title = 'paste';
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-27 11:49:46 +00:00
|
|
|
return (
|
|
|
|
|
<Header>
|
|
|
|
|
<Section>
|
2021-03-27 11:59:56 +00:00
|
|
|
<Button onClick={reset}>[new]</Button>
|
2021-03-27 11:49:46 +00:00
|
|
|
<Button onClick={save}>
|
2021-04-02 13:05:15 +01:00
|
|
|
{recentlySaved ? '[link copied!]' : saving ? '[saving...]' : '[save]'}
|
2021-03-27 11:49:46 +00:00
|
|
|
</Button>
|
2021-04-02 13:05:15 +01:00
|
|
|
<MenuButton
|
|
|
|
|
label="language"
|
|
|
|
|
value={language}
|
|
|
|
|
setValue={setLanguage}
|
2021-10-28 21:05:35 +01:00
|
|
|
ids={languages}
|
2021-04-02 13:05:15 +01:00
|
|
|
/>
|
2021-03-27 11:49:46 +00:00
|
|
|
</Section>
|
|
|
|
|
<Section>
|
2021-03-27 14:17:28 +00:00
|
|
|
<Button onClick={() => zoom(1)}>[+ </Button>
|
2021-03-27 17:01:20 +00:00
|
|
|
<Button onClick={() => zoom(-1)}> -]</Button>
|
2021-04-02 13:05:15 +01:00
|
|
|
<MenuButton
|
|
|
|
|
label="theme"
|
|
|
|
|
value={theme}
|
|
|
|
|
setValue={setTheme}
|
|
|
|
|
ids={Object.keys(themes)}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
className="optional"
|
|
|
|
|
as="a"
|
2022-01-18 21:06:12 +00:00
|
|
|
href="https://github.com/lucko/paste#readme"
|
2021-04-02 13:05:15 +01:00
|
|
|
target="_blank"
|
|
|
|
|
rel="noreferrer"
|
|
|
|
|
>
|
|
|
|
|
[about]
|
|
|
|
|
</Button>
|
2021-03-27 11:49:46 +00:00
|
|
|
</Section>
|
|
|
|
|
</Header>
|
2021-04-02 13:05:15 +01:00
|
|
|
);
|
2021-03-27 11:49:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Header = styled.header`
|
|
|
|
|
position: fixed;
|
2022-01-08 19:10:27 +00:00
|
|
|
top: 0;
|
2021-03-27 11:49:46 +00:00
|
|
|
z-index: 2;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 2em;
|
|
|
|
|
color: ${props => props.theme.primary};
|
|
|
|
|
background: ${props => props.theme.secondary};
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
2021-03-27 14:17:28 +00:00
|
|
|
user-select: none;
|
2021-03-27 11:49:46 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const Section = styled.div`
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
2021-03-27 20:05:15 +00:00
|
|
|
|
|
|
|
|
@media (max-width: 470px) {
|
|
|
|
|
.optional {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-27 11:49:46 +00:00
|
|
|
`;
|
|
|
|
|
|
2021-03-27 13:09:03 +00:00
|
|
|
function langaugeToContentType(language) {
|
|
|
|
|
if (language === 'json') {
|
|
|
|
|
return 'application/json';
|
|
|
|
|
} else {
|
|
|
|
|
return 'text/' + language;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-26 22:00:12 +00:00
|
|
|
async function saveToBytebin(code, language) {
|
|
|
|
|
try {
|
|
|
|
|
const compressed = gzip(code);
|
2021-03-27 13:09:03 +00:00
|
|
|
const contentType = langaugeToContentType(language);
|
2021-03-26 22:00:12 +00:00
|
|
|
|
2021-10-27 23:37:42 +01:00
|
|
|
const resp = await fetch(postUrl, {
|
2021-03-26 22:00:12 +00:00
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': contentType,
|
|
|
|
|
'Content-Encoding': 'gzip',
|
2021-04-02 13:05:15 +01:00
|
|
|
'Accept': 'application/json',
|
2021-03-26 22:00:12 +00:00
|
|
|
},
|
2021-04-02 13:05:15 +01:00
|
|
|
body: compressed,
|
2021-03-26 22:00:12 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (resp.ok) {
|
|
|
|
|
const json = await resp.json();
|
|
|
|
|
return json.key;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|