diff options
| author | jackyzha0 <[email protected]> | 2020-07-18 14:51:54 -0700 |
|---|---|---|
| committer | jackyzha0 <[email protected]> | 2020-07-18 14:51:54 -0700 |
| commit | d80bc9f45c4ab06a8a8bc38fc436bb5345225514 (patch) | |
| tree | e4d0317c70fe487ec85530b65e51982ead61e80a /frontend/src | |
| parent | refactor renderers (diff) | |
| download | ctrl-v-d80bc9f45c4ab06a8a8bc38fc436bb5345225514.tar.xz ctrl-v-d80bc9f45c4ab06a8a8bc38fc436bb5345225514.zip | |
refactor newpaste
Diffstat (limited to 'frontend/src')
| -rw-r--r-- | frontend/src/components/Inputs.js | 233 | ||||
| -rw-r--r-- | frontend/src/components/NewPaste.js | 187 | ||||
| -rw-r--r-- | frontend/src/components/Options.js | 36 | ||||
| -rw-r--r-- | frontend/src/helpers/httpHelper.js | 12 |
4 files changed, 206 insertions, 262 deletions
diff --git a/frontend/src/components/Inputs.js b/frontend/src/components/Inputs.js index 08cf3fc..a9b08b7 100644 --- a/frontend/src/components/Inputs.js +++ b/frontend/src/components/Inputs.js @@ -15,43 +15,33 @@ const FlexChild = styled.div` margin-left: 2em; ` -class TitleInput extends React.Component { - render() { - return ( - <RelPositioning> - <FloatingLabel - label="title" - id={this.props.id} - value={this.props.value} /> - <input - name="title" - readOnly={this.props.readOnly} - className="lt-shadow" - placeholder="Title" - id={this.props.id} - type="text" - autoFocus - autoComplete="off" - onChange={this.props.onChange} - value={this.props.value} /> - <CharLimit - content={this.props.value} - maxLength={this.props.maxLength} /> - </RelPositioning> - ); - } +const TitleInput = (props) => { + return ( + <RelPositioning> + <FloatingLabel + label="title" + id={props.id} + value={props.value} /> + <input + name="title" + readOnly={props.readOnly} + className="lt-shadow" + placeholder="Title" + id={props.id} + type="text" + autoFocus + autoComplete="off" + onChange={props.onChange} + value={props.value} /> + <CharLimit + content={props.value} + maxLength={props.maxLength} /> + </RelPositioning> + ); } -class PasteInput extends React.Component { - - constructor(props) { - super(props) - - this.textArea = React.createRef() - this.handleKeyDown = this.handleKeyDown.bind(this) - } - - handleKeyDown(e) { +const PasteInput = (props) => { + function handleKeyDown(e) { if (e.keyCode === 9) { // tab was pressed // prevent autofocus on next intput @@ -61,96 +51,83 @@ class PasteInput extends React.Component { const start = e.target.selectionStart const end = e.target.selectionEnd - this.props.insertTabCallback(start, end) + props.insertTabCallback(start, end) // set cursor position to be at start e.target.selectionEnd = end + 4; } } - render() { - return ( + return ( + <RelPositioning> + <FloatingLabel + label="content" + id={props.id} + value={props.content} /> + <textarea + name="content" + readOnly={props.readOnly} + placeholder="Paste your text here" + value={props.content} + id={props.id} + required + onChange={props.onChange} + onKeyDown={handleKeyDown} + className="lt-shadow" /> + <CharLimit + content={props.content} + maxLength={props.maxLength} /> + </RelPositioning> + ); +} + +const PassInput = (props) => { + return ( + <FlexChild> <RelPositioning> <FloatingLabel - label="content" - id={this.props.id} - value={this.props.content} /> - <textarea - name="content" - readOnly={this.props.readOnly} - placeholder="Paste your text here" - value={this.props.content} - id={this.props.id} - required - onChange={this.props.onChange} - onKeyDown={this.handleKeyDown} - className="lt-shadow" /> - <CharLimit - content={this.props.content} - maxLength={this.props.maxLength} /> + label="password" + id={props.id} + value={props.value} /> + <input + name="pass" + className="lt-shadow" + placeholder="password" + type="password" + autoComplete="off" + onChange={props.onChange} + value={props.value} + id={props.id} /> </RelPositioning> - ); - } -} - -class PassInput extends React.Component { - render() { - return ( - <FlexChild> - <RelPositioning> - <FloatingLabel - label="password" - id={this.props.id} - value={this.props.value} /> - <input - name="pass" - className="lt-shadow" - placeholder="password" - type="password" - autoComplete="off" - onChange={this.props.onChange} - value={this.props.value} - id={this.props.id} /> - </RelPositioning> - </FlexChild> - ); - } + </FlexChild> + ); } -class GenericDropdown extends React.Component { - - constructor(props) { - super(props) - - this._onSelect = this._onSelect.bind(this) - } - - _onSelect(option) { - this.props.onChange({ +const GenericDropdown = (props) => { + function _onSelect(option) { + props.onChange({ target: { - name: this.props.label, + name: props.label, value: option.label } }); } - render() { - return ( - <FlexChild> - <Dropdown - options={this.props.options} - onChange={this._onSelect} - callBackRef={this.props.onChange} - value={this.props.value} - placeholder={this.props.placeholder} - id={this.props.id} /> - <FloatingLabel - label={this.props.label} - id={this.props.id} - value={this.props.value} /> - </FlexChild> - ); - } + return ( + <FlexChild> + <Dropdown + options={props.options} + onChange={_onSelect} + callBackRef={props.onChange} + value={props.value} + placeholder={props.placeholder} + id={props.id} /> + <FloatingLabel + label={props.label} + id={props.id} + value={props.value} /> + </FlexChild> + ); } const ExpiryInput = (props) => { @@ -210,27 +187,25 @@ const ThemeInput = (props) => { ); } -class PasteURLInput extends React.Component { - render() { - return ( - <FlexChild> - <RelPositioning> - <FloatingLabel - label="url" - id={this.props.id} - value={this.props.id} /> - <input - name="paste_url" - className="lt-shadow" - type="text" - readOnly - autoFocus - id={this.props.id} - value={this.props.fullURL} /> - </RelPositioning> - </FlexChild> - ); - } +const PasteURLInput = ({id, fullURL}) => { + return ( + <FlexChild> + <RelPositioning> + <FloatingLabel + label="url" + id={id} + value={id} /> + <input + name="paste_url" + className="lt-shadow" + type="text" + readOnly + autoFocus + id={id} + value={fullURL} /> + </RelPositioning> + </FlexChild> + ); } export { TitleInput, PasteInput, PassInput, ExpiryInput, PasteURLInput, LangInput, ThemeInput }
\ No newline at end of file diff --git a/frontend/src/components/NewPaste.js b/frontend/src/components/NewPaste.js index afe1fc3..9729655 100644 --- a/frontend/src/components/NewPaste.js +++ b/frontend/src/components/NewPaste.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import { TitleInput, PasteInput } from './Inputs' import OptionsContainer from './Options' import Error from './Err' @@ -35,114 +35,85 @@ const PreviewWrapper = styled.div` margin: 2em; ` -class NewPaste extends React.Component { - constructor(props) { - super(props); - this.state = { - title: '', - content: '', - pass: '', - language: LANGS.raw, - expiry: '', - hash: '', - error: '', - preview: false, - }; - - this.handleChange = this.handleChange.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - this.togglePreview = this.togglePreview.bind(this); - this.renderPreview = this.renderPreview.bind(this); - this.insertTab = this.insertTab.bind(this); - this.ErrorLabel = React.createRef(); - } - - componentDidUpdate() { - if (this.state.title === "") { +const NewPaste = () => { + const [title, setTitle] = useState(''); + const [content, setContent] = useState(''); + const [pass, setPass] = useState(''); + const [language, setLanguage] = useState(LANGS.raw); + const [expiry, setExpiry] = useState(''); + const [hash, setHash] = useState(''); + const [isPreview, setIsPreview] = useState(false); + const ErrorLabel = useRef(null); + + useEffect(() => { + if (title === "") { document.title = `ctrl-v`; } else { - document.title = `ctrl-v | ${this.state.title}`; + document.title = `ctrl-v | ${title}`; } - } - - handleChange(event) { - const target = event.target; - const name = target.name; + }, [title]) - this.setState({ - [name]: target.value - }); - } - - togglePreview() { - const state = this.state.preview - this.setState({ preview: !state }) - } - - handleSubmit(event) { - event.preventDefault(); + function handleSubmit(e) { + e.preventDefault(); // prevent resubmission - if (!this.state.hash) { - PostNewPaste(this.state) + if (!hash) { + PostNewPaste(title, content, language, pass, expiry) .then((response) => { // on success, redir - this.setState({ hash: response.data.hash }) + setHash(response.data.hash) }).catch((error) => { const resp = error.response // some weird err if (resp !== undefined) { const errTxt = `${resp.status}: ${resp.data}` - this.ErrorLabel.current.showMessage(errTxt) + ErrorLabel.current.showMessage(errTxt) } else { // some weird err (e.g. network) - this.ErrorLabel.current.showMessage(error) + ErrorLabel.current.showMessage(error) } }); } } - insertTab(start, end) { - const oldContent = this.state.content - this.setState({ - content: oldContent.substring(0, start) + ' ' + oldContent.substring(end) - }) + function insertTab(start, end) { + setContent(content.substring(0, start) + ' ' + content.substring(end)) } - renderPreview() { + function renderPreview() { const pasteInput = <PasteInput - onChange={this.handleChange} - insertTabCallback={this.insertTab} - content={this.state.content} + onChange={(e) => { setContent(e.target.value) }} + insertTabCallback={insertTab} + content={content} maxLength="100000" id="pasteInput" /> - var preview - switch (this.state.language) { - case 'latex': - preview = - <PreviewWrapper> - <Latex - content={this.state.content} /> - </PreviewWrapper> - break - case 'markdown': - preview = - <PreviewWrapper> - <Markdown - content={this.state.content} /> - </PreviewWrapper> - break - default: - preview = - <CodeRenderer - lang={this.state.language} - theme='atom' - content={this.state.content} /> - } + if (isPreview) { + var preview + switch (language) { + case 'latex': + preview = + <PreviewWrapper> + <Latex + content={content} /> + </PreviewWrapper> + break + case 'markdown': + preview = + <PreviewWrapper> + <Markdown + content={content} /> + </PreviewWrapper> + break + default: + preview = + <CodeRenderer + lang={language} + theme='atom' + content={content} /> + } - if (this.state.preview) { return ( <Flex> <FlexLeft> @@ -160,33 +131,33 @@ class NewPaste extends React.Component { } } - render() { - return ( - <form onSubmit={this.handleSubmit}> - <PasteModal hash={this.state.hash} /> - <TitleInput - onChange={this.handleChange} - value={this.state.title} - maxLength="100" - id="titleInput" /> - {this.renderPreview()} - <OptionsContainer - pass={this.state.pass} - expiry={this.state.expiry} - lang={this.state.language} - onChange={this.handleChange} /> - <input className="lt-button lt-shadow lt-hover" type="submit" value="new paste" /> - <Button - className="lt-shadow lt-hover" - type="button" - onClick={this.togglePreview} > - preview - </Button> - <br /> - <Error ref={this.ErrorLabel} /> - </form> - ); - } + return ( + <form onSubmit={handleSubmit}> + <PasteModal hash={hash} /> + <TitleInput + onChange={(e) => {setTitle(e.target.value)}} + value={title} + maxLength="100" + id="titleInput" /> + {renderPreview()} + <OptionsContainer + pass={pass} + expiry={expiry} + lang={language} + onPassChange={(e) => { setPass(e.target.value) }} + onLangChange={(e) => { setLanguage(e.target.value) }} + onExpiryChange={(e) => { setExpiry(e.target.value) }} /> + <input className="lt-button lt-shadow lt-hover" type="submit" value="new paste" /> + <Button + className="lt-shadow lt-hover" + type="button" + onClick={() => setIsPreview(!isPreview)}> + preview + </Button> + <br /> + <Error ref={ErrorLabel} /> + </form> + ); } export default NewPaste
\ No newline at end of file diff --git a/frontend/src/components/Options.js b/frontend/src/components/Options.js index 26391c1..09f92f3 100644 --- a/frontend/src/components/Options.js +++ b/frontend/src/components/Options.js @@ -14,25 +14,23 @@ const Flex = styled.div` } ` -class OptionsContainer extends React.Component { - render() { - return ( - <Flex> - <PassInput - value={this.props.pass} - onChange={this.props.onChange} - id="passwordInput" /> - <LangInput - value={this.props.lang} - onChange={this.props.onChange} - id="langInput" /> - <ExpiryInput - value={this.props.expiry} - onChange={this.props.onChange} - id="expiryInput" /> - </Flex> - ); - } +const OptionsContainer = ({pass, lang, expiry, onPassChange, onLangChange, onExpiryChange}) => { + return ( + <Flex> + <PassInput + value={pass} + onChange={onPassChange} + id="passwordInput" /> + <LangInput + value={lang} + onChange={onLangChange} + id="langInput" /> + <ExpiryInput + value={expiry} + onChange={onExpiryChange} + id="expiryInput" /> + </Flex> + ); } export default OptionsContainer
\ No newline at end of file diff --git a/frontend/src/helpers/httpHelper.js b/frontend/src/helpers/httpHelper.js index ca77ed7..99b9513 100644 --- a/frontend/src/helpers/httpHelper.js +++ b/frontend/src/helpers/httpHelper.js @@ -21,13 +21,13 @@ export function FetchPasswordPaste(hash, pass) { }) } -export function PostNewPaste(state) { +export function PostNewPaste(title, content, language, pass, expiry) { var bodyFormData = new FormData(); - bodyFormData.set('title', state.title); - bodyFormData.set('content', state.content); - bodyFormData.set('language', state.language); - bodyFormData.set('password', state.pass); - bodyFormData.set('expiry', parseExpiry(state.expiry)); + bodyFormData.set('title', title); + bodyFormData.set('content', content); + bodyFormData.set('language', language); + bodyFormData.set('password', pass); + bodyFormData.set('expiry', parseExpiry(expiry)); return axios({ method: 'post', |