aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/package.json2
-rw-r--r--frontend/src/components/Inputs.js102
-rw-r--r--frontend/src/components/PasteInfo.js30
-rw-r--r--frontend/src/components/ViewPaste.js54
-rw-r--r--frontend/src/components/renderers/Code.js56
-rw-r--r--frontend/src/css/index.css30
-rw-r--r--package.json5
-rw-r--r--yarn.lock15
8 files changed, 211 insertions, 83 deletions
diff --git a/frontend/package.json b/frontend/package.json
index 2fbee85..aff8c49 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -13,8 +13,10 @@
"react-dom": "^16.13.1",
"react-dropdown": "^1.7.0",
"react-modal": "^3.11.2",
+ "react-render-html": "^0.6.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
+ "react-syntax-highlighter": "^12.2.1",
"styled-components": "^5.1.0",
"use-clipboard-copy": "^0.1.2"
},
diff --git a/frontend/src/components/Inputs.js b/frontend/src/components/Inputs.js
index 4bb7b33..b96ceb0 100644
--- a/frontend/src/components/Inputs.js
+++ b/frontend/src/components/Inputs.js
@@ -3,6 +3,7 @@ import CharLimit from './decorators/CharLimit'
import styled from 'styled-components'
import FloatingLabel from './decorators/FloatingLabel'
import Dropdown from 'react-dropdown';
+import { LANGS, THEMES } from './renderers/Code';
const RelPositioning = styled.div`
position: relative;
@@ -89,37 +90,35 @@ class PassInput extends React.Component {
}
}
-class ExpiryInput extends React.Component {
-
+class GenericDropdown extends React.Component {
+
+ constructor(props) {
+ super(props)
+
+ this._onSelect = this._onSelect.bind(this)
+ }
+
_onSelect(option) {
- this.callBackRef({target: {
- name: 'expiry',
- value: option.label
- }});
+ this.props.onChange({
+ target: {
+ name: this.props.label,
+ value: option.label
+ }
+ });
}
render() {
- const options = [
- '5 years',
- '1 year',
- '1 month',
- '1 week',
- '1 day',
- '1 hour',
- '10 min',
- ];
-
return (
<FlexChild>
- <Dropdown
- options={options}
- onChange={this._onSelect}
+ <Dropdown
+ options={this.props.options}
+ onChange={this._onSelect}
callBackRef={this.props.onChange}
- value={this.props.value}
- placeholder="1 week"
+ value={this.props.value}
+ placeholder={this.props.placeholder}
id={this.props.id} />
<FloatingLabel
- label="expiry"
+ label={this.props.label}
id={this.props.id}
value={this.props.value} />
</FlexChild>
@@ -127,6 +126,63 @@ class ExpiryInput extends React.Component {
}
}
+const ExpiryInput = (props) => {
+ const options = [
+ '5 years',
+ '1 year',
+ '1 month',
+ '1 week',
+ '1 day',
+ '1 hour',
+ '10 min',
+ ];
+
+ return (
+ <GenericDropdown
+ {...props}
+ options={options}
+ placeholder='1 week'
+ label='expiry'
+ />
+ );
+}
+
+const LangInput = (props) => {
+ const options = Object.entries(LANGS).map((key, _) => {
+ return {
+ 'value': key[1],
+ 'label': key[0]
+ }
+ })
+
+ return (
+ <GenericDropdown
+ {...props}
+ options={options}
+ placeholder={LANGS.raw}
+ label='language'
+ />
+ );
+}
+
+const ThemeInput = (props) => {
+ const options = Object.entries(THEMES).map((key, _) => {
+ return {
+ 'value': key[1],
+ 'label': key[0]
+ }
+ })
+
+ return (
+ <GenericDropdown
+ {...props}
+ options={options}
+ placeholder={'atom'}
+ label='theme'
+ />
+ );
+}
+
class PasteURLInput extends React.Component {
render() {
return (
@@ -150,4 +206,4 @@ class PasteURLInput extends React.Component {
}
}
-export { TitleInput, PasteInput, PassInput, ExpiryInput, PasteURLInput } \ No newline at end of file
+export { TitleInput, PasteInput, PassInput, ExpiryInput, PasteURLInput, LangInput, ThemeInput } \ No newline at end of file
diff --git a/frontend/src/components/PasteInfo.js b/frontend/src/components/PasteInfo.js
index b27cd53..dabbb94 100644
--- a/frontend/src/components/PasteInfo.js
+++ b/frontend/src/components/PasteInfo.js
@@ -1,27 +1,39 @@
import React from 'react';
import styled from 'styled-components'
+import { LangInput, ThemeInput } from './Inputs'
const Bold = styled.span`
font-weight: 700
`
-const FloatLeft = styled.p`
- float: left;
+const StyledDiv = styled.div`
+ margin: 2em 0;
display: inline-block;
- margin: 0;
`
-const FloatRight = styled.p`
+
+const Flex = styled.div`
float: right;
- display: inline-block;
- margin: 0;
- margin-right: -1em;
+ display: flex;
+ flex-direction: row;
+ transform: translateY(0.2em);
`
const PasteInfo = (props) => {
return (
<div>
- <FloatLeft><Bold>mode:&nbsp;</Bold>{props.mode}</FloatLeft>
- <FloatRight><Bold>expires:&nbsp;</Bold>{props.expiry}</FloatRight>
+ <Flex>
+ <LangInput
+ value={props.lang}
+ onChange={props.onChange}
+ id="langInput" />
+ <ThemeInput
+ value={props.theme}
+ onChange={props.onChange}
+ id="themeInput" />
+ </Flex>
+ <StyledDiv>
+ <Bold>expires:&nbsp;</Bold>{props.expiry}
+ </StyledDiv>
</div>
);
}
diff --git a/frontend/src/components/ViewPaste.js b/frontend/src/components/ViewPaste.js
index 835deaf..491c440 100644
--- a/frontend/src/components/ViewPaste.js
+++ b/frontend/src/components/ViewPaste.js
@@ -1,16 +1,11 @@
import React from 'react';
import Error from './Err';
-import { TitleInput, PasteInput } from './Inputs';
+import { TitleInput } from './Inputs';
+import CodeRenderer from './renderers/Code'
import PasteInfo from './PasteInfo';
import PasswordModal from './modals/PasswordModal'
import { FetchPaste, FetchPasswordPaste } from '../helpers/httpHelper'
-
-const RENDER_MODES = Object.freeze({
- RAW: 'raw text',
- MD: 'markdown',
- LATEX: 'latex',
- CODE: 'code',
-})
+import { LANGS } from './renderers/Code'
class ViewPaste extends React.Component {
@@ -25,31 +20,29 @@ class ViewPaste extends React.Component {
expiry: 'no expiry',
error: '',
passError: '',
- mode: RENDER_MODES.RAW,
+ theme: 'atom',
+ language: LANGS.raw,
};
this.handleChange = this.handleChange.bind(this);
+ this.typedPass = this.typedPass.bind(this);
this.validatePass = this.validatePass.bind(this);
this.ErrorLabel = React.createRef();
this.PasswordModal = React.createRef();
}
handleChange(event) {
- this.setState({ enteredPass: event.target.value });
- }
+ const target = event.target;
+ const name = target.name;
+ console.log(target, name)
- drawRightMode() {
- switch (this.state.mode) {
- // TODO: add other renderers
+ this.setState({
+ [name]: target.value
+ });
+ }
- // default render raw
- case RENDER_MODES.RAW:
- default:
- return (<PasteInput
- content={this.state.content}
- id="pasteInput"
- readOnly />);
- }
+ typedPass(event) {
+ this.setState({ enteredPass: event.target.value });
}
validatePass(pass) {
@@ -87,18 +80,22 @@ class ViewPaste extends React.Component {
hasPass={this.state.hasPass}
validPass={this.state.validPass}
value={this.state.enteredPass}
- onChange={this.handleChange}
+ onChange={this.typedPass}
validateCallback={this.validatePass} />
<TitleInput
value={this.state.title}
id="titleInput"
readOnly />
-
- {this.drawRightMode()}
-
+ <CodeRenderer
+ content={this.state.content}
+ lang={this.state.language}
+ theme={this.state.theme}
+ id="pasteInput" />
<PasteInfo
- expiry={this.state.expiry}
- mode={this.state.mode} />
+ lang={this.state.language}
+ theme={this.state.theme}
+ onChange={this.handleChange}
+ expiry={this.state.expiry} />
<Error ref={this.ErrorLabel} />
</div>
);
@@ -111,7 +108,6 @@ class ViewPaste extends React.Component {
}
setStateFromData(data) {
- console.log(data)
this.setState({
title: data.title,
content: data.content,
diff --git a/frontend/src/components/renderers/Code.js b/frontend/src/components/renderers/Code.js
new file mode 100644
index 0000000..12efc67
--- /dev/null
+++ b/frontend/src/components/renderers/Code.js
@@ -0,0 +1,56 @@
+import React from 'react';
+import styled from 'styled-components'
+import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
+import { atomOneLight, ascetic, atomOneDark, dracula, ocean } from 'react-syntax-highlighter/dist/esm/styles/hljs';
+
+export const THEMES = Object.freeze({
+ 'atom': atomOneLight,
+ 'atom dark': atomOneDark,
+ 'plain': ascetic,
+ 'dracula': dracula,
+ 'ocean': ocean,
+})
+
+export const LANGS = Object.freeze({
+ 'go': 'go',
+ 'python': 'python',
+ 'javascript': 'javascript',
+ 'html': 'html',
+ 'css': 'css',
+ 'c': 'c',
+ 'c++': 'cpp',
+ 'c#': 'cs',
+ 'ruby': 'ruby',
+ 'docker': 'dockerfile',
+ 'bash': 'bash',
+ 'raw': 'text',
+ 'java': 'java',
+ 'lisp': 'lisp',
+ 'haskell': 'haskell',
+ 'scala': 'scala',
+ 'markdown': 'markdown',
+ 'makefile': 'makefile',
+ 'php': 'php',
+ 'latex': 'latex',
+ 'yaml': 'yaml'
+})
+
+const RelPositioning = styled.div`
+ position: relative;
+`
+
+const CodeRenderer = (props) => {
+ return (
+ <RelPositioning>
+ <SyntaxHighlighter
+ className="codeBlock lt-shadow"
+ language={props.lang}
+ style={THEMES[props.theme]}
+ showLineNumbers >
+ {props.content}
+ </SyntaxHighlighter>
+ </RelPositioning>
+ );
+};
+
+export default CodeRenderer \ No newline at end of file
diff --git a/frontend/src/css/index.css b/frontend/src/css/index.css
index 32e4065..c0e669c 100644
--- a/frontend/src/css/index.css
+++ b/frontend/src/css/index.css
@@ -25,6 +25,31 @@ textarea, input[type=text], input[type=password], .Dropdown-root {
margin: 1.7em 0;
}
+.codeBlock {
+ width: 100%;
+ font-size: 0.8em;
+ padding: calc(0.8em - 1px) !important;
+ border-radius: 3px;
+ border: 1px solid #565656;
+ background: #faf9f5;
+ outline: none;
+ margin: 1.7em 0;
+}
+
+.codeBlock code:first-child {
+ margin-right: 10px;
+ border-radius: 0;
+ border-right: 1px solid #11111155;
+}
+
+code, pre {
+ background: #00000000;
+ font-family: 'Roboto Mono', monospace;
+ padding: initial;
+ border-radius: 3px;
+ outline: none;
+}
+
.Dropdown-root {
cursor: pointer;
}
@@ -44,7 +69,7 @@ textarea, input[type=text], input[type=password], .Dropdown-root {
}
.Dropdown-placeholder {
- width: 5em;
+ width: 7em;
}
.Dropdown-menu {
@@ -98,7 +123,8 @@ input[type=submit], button[type=submit] {
button[type=button] {
font-family: 'Lora', serif;
- width: 7em;
+ font-weight: 700;
+ width: 8em;
padding: calc(0.8em - 1px) 1.5em;
border-radius: 3px;
color: #111111;
diff --git a/package.json b/package.json
deleted file mode 100644
index e10893d..0000000
--- a/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "dependencies": {
- "use-clipboard-copy": "^0.1.2"
- }
-}
diff --git a/yarn.lock b/yarn.lock
deleted file mode 100644
index 242ac1d..0000000
--- a/yarn.lock
+++ /dev/null
@@ -1,15 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-clipboard-copy@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.1.0.tgz#4c59030a43d4988990564a664baeafba99f78ca4"
- integrity sha512-Xsu1NddBXB89IUauda5BIq3Zq73UWkjkaQlPQbLNvNsd5WBMnTWPNKYR6HGaySOxGYZ+BKxP2E9X4ElnI3yiPA==
-
-use-clipboard-copy@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/use-clipboard-copy/-/use-clipboard-copy-0.1.2.tgz#83b16292dfa8ea262be714252022a8b4ad1c28c5"
- integrity sha512-EkauxqyX+us4+Mfif/f61ew89EAOWIArqFpHR0jSG4SwwuDZzDAOeqO7gkK0vi+DQVADeB1RB3xqU3U0oOO3NQ==
- dependencies:
- clipboard-copy "^3.0.0"