Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/core/components/copy-to-clipboard-btn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,34 @@ import PropTypes from "prop-types"
* @constructor
*/
export default class CopyToClipboardBtn extends React.Component {
constructor(props) {
super(props)
this.state = { copied: false }
this.timerRef = null
}

handleCopy = () => {
this.setState({ copied: true })
if (this.timerRef) clearTimeout(this.timerRef)
this.timerRef = setTimeout(() => this.setState({ copied: false }), 1500)
}

componentWillUnmount() {
if (this.timerRef) clearTimeout(this.timerRef)
}

render() {
let { getComponent } = this.props
const { copied } = this.state

const CopyIcon = getComponent("CopyIcon")

return (
<div className="view-line-link copy-to-clipboard" title="Copy to clipboard">
<CopyToClipboard text={this.props.textToCopy}>
<CopyToClipboard text={this.props.textToCopy} onCopy={this.handleCopy}>
<CopyIcon />
</CopyToClipboard>
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
</div>
)
}
Expand Down
20 changes: 19 additions & 1 deletion src/core/components/curl.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,34 @@ export default class Curl extends React.Component {
request: PropTypes.object.isRequired
}

constructor(props) {
super(props)
this.state = { copied: false }
this.timerRef = null
}

handleCopy = () => {
this.setState({ copied: true })
if (this.timerRef) clearTimeout(this.timerRef)
this.timerRef = setTimeout(() => this.setState({ copied: false }), 1500)
}

componentWillUnmount() {
if (this.timerRef) clearTimeout(this.timerRef)
}

render() {
const { request, getComponent } = this.props
const { copied } = this.state
const curl = requestSnippetGenerator_curl_bash(request)
const SyntaxHighlighter = getComponent("SyntaxHighlighter", true)

return (
<div className="curl-command">
<h4>Curl</h4>
<div className="copy-to-clipboard">
<CopyToClipboard text={curl}><button/></CopyToClipboard>
<CopyToClipboard text={curl} onCopy={this.handleCopy}><button/></CopyToClipboard>
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
</div>
<div>
<SyntaxHighlighter
Expand Down
13 changes: 11 additions & 2 deletions src/core/plugins/request-snippets/request-snippets.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef, useEffect, useState } from "react"
import React, { useRef, useEffect, useState, useCallback } from "react"
import classNames from "classnames"
import PropTypes from "prop-types"
import { CopyToClipboard } from "react-copy-to-clipboard"
Expand Down Expand Up @@ -42,6 +42,14 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getComponent }) =>

const [activeLanguage, setActiveLanguage] = useState(requestSnippetsSelectors.getSnippetGenerators()?.keySeq().first())
const [isExpanded, setIsExpanded] = useState(requestSnippetsSelectors?.getDefaultExpanded())
const [copied, setCopied] = useState(false)
const copyTimerRef = useRef(null)

const handleCopy = useCallback(() => {
setCopied(true)
if (copyTimerRef.current) clearTimeout(copyTimerRef.current)
copyTimerRef.current = setTimeout(() => setCopied(false), 1500)
}, [])

const snippetGenerators = requestSnippetsSelectors.getSnippetGenerators()
const activeGenerator = snippetGenerators.get(activeLanguage)
Expand Down Expand Up @@ -132,9 +140,10 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getComponent }) =>
}
</div>
<div className="copy-to-clipboard">
<CopyToClipboard text={snippet}>
<CopyToClipboard text={snippet} onCopy={handleCopy}>
<button />
</CopyToClipboard>
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
</div>
<div>
<SyntaxHighlighter
Expand Down
13 changes: 11 additions & 2 deletions src/core/plugins/syntax-highlighting/components/HighlightCode.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @prettier
*/
import React, { useRef, useEffect } from "react"
import React, { useRef, useEffect, useState, useCallback } from "react"
import PropTypes from "prop-types"
import classNames from "classnames"
import saveAs from "js-file-download"
Expand All @@ -17,6 +17,14 @@ const HighlightCode = ({
children,
}) => {
const rootRef = useRef(null)
const [copied, setCopied] = useState(false)
const copyTimerRef = useRef(null)

const handleCopy = useCallback(() => {
setCopied(true)
if (copyTimerRef.current) clearTimeout(copyTimerRef.current)
copyTimerRef.current = setTimeout(() => setCopied(false), 1500)
}, [])
const SyntaxHighlighter = getComponent("SyntaxHighlighter", true)

const handleDownload = () => {
Expand Down Expand Up @@ -69,9 +77,10 @@ const HighlightCode = ({
<div className="highlight-code" ref={rootRef}>
{canCopy && (
<div className="copy-to-clipboard">
<CopyToClipboard text={children}>
<CopyToClipboard text={children} onCopy={handleCopy}>
<button />
</CopyToClipboard>
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
</div>
)}

Expand Down
28 changes: 28 additions & 0 deletions src/style/_buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,34 @@ button {
background: #5e626f;
}

.copy-to-clipboard__toast {
position: absolute;
right: calc(100% + 8px);
top: 50%;
transform: translateY(-50%);
background: #333;
color: #fff;
font-size: 11px;
font-family: sans-serif;
line-height: 1;
padding: 4px 8px;
border-radius: 4px;
white-space: nowrap;
pointer-events: none;
animation: copy-toast-fade-in 0.15s ease-out;
}

@keyframes copy-toast-fade-in {
from {
opacity: 0;
transform: translateY(-50%) translateX(4px);
}
to {
opacity: 1;
transform: translateY(-50%) translateX(0);
}
}

.opblock-control-arrow {
border: none;
text-align: center;
Expand Down