mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 20:21:35 +00:00
Fix copy to clipboard in any context
This commit is contained in:
parent
91c2ddb166
commit
7eae2cf58c
@ -15,6 +15,7 @@ import {
|
|||||||
} from "@mui/material"
|
} from "@mui/material"
|
||||||
|
|
||||||
import { saveAsJson } from "../../utils/saveFile";
|
import { saveAsJson } from "../../utils/saveFile";
|
||||||
|
import { copyToClipboard } from "../../utils/clipboard";
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import KeyIcon from '@mui/icons-material/Key';
|
import KeyIcon from '@mui/icons-material/Key';
|
||||||
@ -36,7 +37,7 @@ function CredentialTextfield(props){
|
|||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment:
|
endAdornment:
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={props.copiedTitle}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={props.copiedTitle}>
|
||||||
<IconButton onClick={()=> navigator.clipboard.writeText(props.value)}>
|
<IconButton onClick={()=> copyToClipboard(props.value)}>
|
||||||
<ContentCopy/>
|
<ContentCopy/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
|
@ -33,6 +33,7 @@ import PersonAddAltIcon from "@mui/icons-material/PersonAddAlt";
|
|||||||
import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
|
import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
|
||||||
|
|
||||||
import { getCookie } from "../../utils/cookies";
|
import { getCookie } from "../../utils/cookies";
|
||||||
|
import { copyToClipboard } from "../../utils/clipboard";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -75,13 +76,13 @@ const ProfileDialog = ({
|
|||||||
const robotToken = getCookie("robot_token");
|
const robotToken = getCookie("robot_token");
|
||||||
|
|
||||||
if (robotToken) {
|
if (robotToken) {
|
||||||
navigator.clipboard.writeText(robotToken);
|
copyToClipboard(robotToken);
|
||||||
setAppState({copiedToken:true});
|
setAppState({copiedToken:true});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyReferralCodeHandler = () => {
|
const copyReferralCodeHandler = () => {
|
||||||
navigator.clipboard.writeText(`http://${host}/ref/${referralCode}`);
|
copyToClipboard(`http://${host}/ref/${referralCode}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -5,6 +5,7 @@ import ReconnectingWebSocket from 'reconnecting-websocket';
|
|||||||
import { encryptMessage , decryptMessage} from "../utils/pgp";
|
import { encryptMessage , decryptMessage} from "../utils/pgp";
|
||||||
import { getCookie } from "../utils/cookies";
|
import { getCookie } from "../utils/cookies";
|
||||||
import { saveAsJson } from "../utils/saveFile";
|
import { saveAsJson } from "../utils/saveFile";
|
||||||
|
import { copyToClipboard } from "../utils/clipboard";
|
||||||
import { AuditPGPDialog } from "./Dialogs"
|
import { AuditPGPDialog } from "./Dialogs"
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
@ -234,7 +235,7 @@ class Chat extends Component {
|
|||||||
<div style={{width:20}}>
|
<div style={{width:20}}>
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
||||||
<IconButton sx={{height:18,width:18}}
|
<IconButton sx={{height:18,width:18}}
|
||||||
onClick={()=> navigator.clipboard.writeText(this.state.showPGP[props.index] ? props.message.encryptedMessage : props.message.plainTextMessage)}>
|
onClick={()=> copyToClipboard(this.state.showPGP[props.index] ? props.message.encryptedMessage : props.message.plainTextMessage)}>
|
||||||
<ContentCopy sx={{height:16,width:16,color:'#333333'}}/>
|
<ContentCopy sx={{height:16,width:16,color:'#333333'}}/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -19,7 +19,7 @@ import { BuySatsCheckedIcon, BuySatsIcon, SellSatsCheckedIcon, SellSatsIcon} fro
|
|||||||
|
|
||||||
import { getCookie } from "../utils/cookies";
|
import { getCookie } from "../utils/cookies";
|
||||||
import { pn } from "../utils/prettyNumbers";
|
import { pn } from "../utils/prettyNumbers";
|
||||||
|
import { copyToClipboard } from "../utils/clipboard";
|
||||||
|
|
||||||
class MakerPage extends Component {
|
class MakerPage extends Component {
|
||||||
defaultCurrency = 1;
|
defaultCurrency = 1;
|
||||||
@ -732,7 +732,7 @@ class MakerPage extends Component {
|
|||||||
<StoreTokenDialog
|
<StoreTokenDialog
|
||||||
open={this.state.openStoreToken}
|
open={this.state.openStoreToken}
|
||||||
onClose={() => this.setState({openStoreToken:false})}
|
onClose={() => this.setState({openStoreToken:false})}
|
||||||
onClickCopy={()=> (navigator.clipboard.writeText(getCookie("robot_token")) & this.props.setAppState({copiedToken:true}))}
|
onClickCopy={()=> (copyToClipboard(getCookie("robot_token")) & this.props.setAppState({copiedToken:true}))}
|
||||||
copyIconColor={this.props.copiedToken ? "inherit" : "primary"}
|
copyIconColor={this.props.copiedToken ? "inherit" : "primary"}
|
||||||
onClickBack={() => this.setState({openStoreToken:false})}
|
onClickBack={() => this.setState({openStoreToken:false})}
|
||||||
onClickDone={this.handleCreateOfferButtonPressed}
|
onClickDone={this.handleCreateOfferButtonPressed}
|
||||||
|
@ -23,6 +23,7 @@ import { SendReceiveIcon } from "./Icons";
|
|||||||
|
|
||||||
import { getCookie } from "../utils/cookies";
|
import { getCookie } from "../utils/cookies";
|
||||||
import { pn } from "../utils/prettyNumbers";
|
import { pn } from "../utils/prettyNumbers";
|
||||||
|
import { copyToClipboard } from "../utils/clipboard";
|
||||||
|
|
||||||
class OrderPage extends Component {
|
class OrderPage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -359,7 +360,7 @@ class OrderPage extends Component {
|
|||||||
<StoreTokenDialog
|
<StoreTokenDialog
|
||||||
open={this.state.openStoreToken}
|
open={this.state.openStoreToken}
|
||||||
onClose={() => this.setState({openStoreToken:false})}
|
onClose={() => this.setState({openStoreToken:false})}
|
||||||
onClickCopy={()=> (navigator.clipboard.writeText(getCookie("robot_token")) & this.props.setAppState({copiedToken:true}))}
|
onClickCopy={()=> (copyToClipboard(getCookie("robot_token")) & this.props.setAppState({copiedToken:true}))}
|
||||||
copyIconColor={this.props.copiedToken ? "inherit" : "primary"}
|
copyIconColor={this.props.copiedToken ? "inherit" : "primary"}
|
||||||
onClickBack={() => this.setState({openStoreToken:false})}
|
onClickBack={() => this.setState({openStoreToken:false})}
|
||||||
onClickDone={() => this.setState({openStoreToken:false}) &
|
onClickDone={() => this.setState({openStoreToken:false}) &
|
||||||
|
@ -6,6 +6,7 @@ import Countdown, { zeroPad} from 'react-countdown';
|
|||||||
import Chat from "./EncryptedChat"
|
import Chat from "./EncryptedChat"
|
||||||
import MediaQuery from 'react-responsive'
|
import MediaQuery from 'react-responsive'
|
||||||
import QrReader from 'react-qr-reader'
|
import QrReader from 'react-qr-reader'
|
||||||
|
import { copyToClipboard } from "../utils/clipboard";
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import PercentIcon from '@mui/icons-material/Percent';
|
import PercentIcon from '@mui/icons-material/Percent';
|
||||||
@ -216,7 +217,7 @@ class TradeBox extends Component {
|
|||||||
<QRCode value={this.props.data.bond_invoice} size={305} style={{position:'relative', top:'3px'}}/>
|
<QRCode value={this.props.data.bond_invoice} size={305} style={{position:'relative', top:'3px'}}/>
|
||||||
</Box>
|
</Box>
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
||||||
<Button size="small" color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.bond_invoice)}} align="center"> <ContentCopy/>{t("Copy to clipboard")}</Button>
|
<Button size="small" color="inherit" onClick={() => {copyToClipboard(this.props.data.bond_invoice)}} align="center"> <ContentCopy/>{t("Copy to clipboard")}</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
@ -299,7 +300,7 @@ class TradeBox extends Component {
|
|||||||
<QRCode value={this.props.data.escrow_invoice} size={305} style={{position:'relative', top:'3px'}}/>
|
<QRCode value={this.props.data.escrow_invoice} size={305} style={{position:'relative', top:'3px'}}/>
|
||||||
</Box>
|
</Box>
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
||||||
<Button size="small" color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.escrow_invoice)}} align="center"> <ContentCopy/>{t("Copy to clipboard")}</Button>
|
<Button size="small" color="inherit" onClick={() => {copyToClipboard(this.props.data.escrow_invoice)}} align="center"> <ContentCopy/>{t("Copy to clipboard")}</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
@ -1252,7 +1253,7 @@ handleRatingRobosatsChange=(e)=>{
|
|||||||
<Alert severity="success">
|
<Alert severity="success">
|
||||||
<AlertTitle>{t("Your TXID")}
|
<AlertTitle>{t("Your TXID")}
|
||||||
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
||||||
<IconButton color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.txid)}}>
|
<IconButton color="inherit" onClick={() => {copyToClipboard(this.props.data.txid)}}>
|
||||||
<ContentCopy sx={{width:16,height:16}}/>
|
<ContentCopy sx={{width:16,height:16}}/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -17,7 +17,7 @@ import { genBase62Token, tokenStrength } from "../utils/token";
|
|||||||
import { genKey } from "../utils/pgp";
|
import { genKey } from "../utils/pgp";
|
||||||
import { getCookie, writeCookie, deleteCookie } from "../utils/cookies";
|
import { getCookie, writeCookie, deleteCookie } from "../utils/cookies";
|
||||||
import { saveAsJson } from "../utils/saveFile";
|
import { saveAsJson } from "../utils/saveFile";
|
||||||
|
import { copyToClipboard } from "../utils/clipboard";
|
||||||
|
|
||||||
class UserGenPage extends Component {
|
class UserGenPage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -259,7 +259,7 @@ class UserGenPage extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
color={this.props.copiedToken ? "inherit":"primary"}
|
color={this.props.copiedToken ? "inherit":"primary"}
|
||||||
disabled={!(getCookie('robot_token')==this.state.token) || !this.props.avatarLoaded}
|
disabled={!(getCookie('robot_token')==this.state.token) || !this.props.avatarLoaded}
|
||||||
onClick={()=> (navigator.clipboard.writeText(getCookie('robot_token')) & this.props.setAppState({copiedToken:true}))}
|
onClick={()=> (copyToClipboard(getCookie('robot_token')) & this.props.setAppState({copiedToken:true}))}
|
||||||
>
|
>
|
||||||
<ContentCopy sx={{width:18, height:18}}/>
|
<ContentCopy sx={{width:18, height:18}}/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
24
frontend/src/utils/clipboard.js
Normal file
24
frontend/src/utils/clipboard.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export function copyToClipboard(textToCopy) {
|
||||||
|
// navigator clipboard api needs a secure context (https)
|
||||||
|
// this function attempts to copy also on http contexts
|
||||||
|
// useful on the http i2p site and on torified browsers
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
// navigator clipboard api method'
|
||||||
|
return navigator.clipboard.writeText(textToCopy);
|
||||||
|
} else {
|
||||||
|
// text area method
|
||||||
|
let textArea = document.createElement("textarea");
|
||||||
|
textArea.value = textToCopy;
|
||||||
|
// make the textarea out of viewport
|
||||||
|
textArea.style.position = "fixed";
|
||||||
|
textArea.style.left = "-999999px";
|
||||||
|
textArea.style.top = "-999999px";
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
// here the magic happens
|
||||||
|
document.execCommand('copy') ? res() : rej();
|
||||||
|
textArea.remove();
|
||||||
|
});
|
||||||
|
}}
|
Loading…
Reference in New Issue
Block a user