aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/components
diff options
context:
space:
mode:
authorRyan Mehri <[email protected]>2020-05-15 10:49:22 -0600
committerGitHub <[email protected]>2020-05-15 10:49:22 -0600
commitd0c8ea3198794091d9e71e1513c3f4f3a4851c92 (patch)
tree24cd91db97508a5d1a0c8051c32719d3dfc60bba /frontend/src/components
parentMerge pull request #22 from jackyzha0/paste-modal (diff)
parentfix typo (diff)
downloadctrl-v-d0c8ea3198794091d9e71e1513c3f4f3a4851c92.tar.xz
ctrl-v-d0c8ea3198794091d9e71e1513c3f4f3a4851c92.zip
Merge pull request #23 from jackyzha0/code-render
Code render
Diffstat (limited to 'frontend/src/components')
-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
4 files changed, 181 insertions, 61 deletions
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