mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 20:21:35 +00:00
Functional UnsafeAlert and other Icons (#371)
* Add unsafe alert functional component * Convert icons to functional components * Run lin fix * Fix webln uncaught error
This commit is contained in:
parent
c0b8a6d3ac
commit
9412764f1d
75
frontend/package-lock.json
generated
75
frontend/package-lock.json
generated
@ -40,7 +40,6 @@
|
||||
"react-i18next": "^11.16.2",
|
||||
"react-image": "^4.0.3",
|
||||
"react-qr-code": "^2.0.3",
|
||||
"react-responsive": "^9.0.0-beta.6",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-smooth-image": "^1.1.0",
|
||||
"react-world-flags": "^1.4.0",
|
||||
@ -5429,11 +5428,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-mediaquery": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz",
|
||||
"integrity": "sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q=="
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
|
||||
@ -7442,11 +7436,6 @@
|
||||
"node": ">=10.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hyphenate-style-name": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
||||
},
|
||||
"node_modules/i18next": {
|
||||
"version": "21.9.1",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.9.1.tgz",
|
||||
@ -9986,14 +9975,6 @@
|
||||
"tmpl": "1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/matchmediaquery": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz",
|
||||
"integrity": "sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==",
|
||||
"dependencies": {
|
||||
"css-mediaquery": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/mdn-data": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
||||
@ -13237,23 +13218,6 @@
|
||||
"react": ">= 16.3"
|
||||
}
|
||||
},
|
||||
"node_modules/react-responsive": {
|
||||
"version": "9.0.0-beta.10",
|
||||
"resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-9.0.0-beta.10.tgz",
|
||||
"integrity": "sha512-41H8g4FYP46ln16rsHvs9/0ZoZxAPfnNiHET86/5pgS+Vw8fSKfLBuOS2SAquaxOxq7DgPviFoHmybgVvSKCNQ==",
|
||||
"dependencies": {
|
||||
"hyphenate-style-name": "^1.0.0",
|
||||
"matchmediaquery": "^0.3.0",
|
||||
"prop-types": "^15.6.1",
|
||||
"shallow-equal": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.3.tgz",
|
||||
@ -13691,11 +13655,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shallow-equal": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@ -18899,11 +18858,6 @@
|
||||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"css-mediaquery": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz",
|
||||
"integrity": "sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q=="
|
||||
},
|
||||
"css-select": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
|
||||
@ -20415,11 +20369,6 @@
|
||||
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
|
||||
"dev": true
|
||||
},
|
||||
"hyphenate-style-name": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
||||
},
|
||||
"i18next": {
|
||||
"version": "21.9.1",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.9.1.tgz",
|
||||
@ -22284,14 +22233,6 @@
|
||||
"tmpl": "1.0.5"
|
||||
}
|
||||
},
|
||||
"matchmediaquery": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz",
|
||||
"integrity": "sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==",
|
||||
"requires": {
|
||||
"css-mediaquery": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"mdn-data": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
||||
@ -24515,17 +24456,6 @@
|
||||
"react-draggable": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"react-responsive": {
|
||||
"version": "9.0.0-beta.10",
|
||||
"resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-9.0.0-beta.10.tgz",
|
||||
"integrity": "sha512-41H8g4FYP46ln16rsHvs9/0ZoZxAPfnNiHET86/5pgS+Vw8fSKfLBuOS2SAquaxOxq7DgPviFoHmybgVvSKCNQ==",
|
||||
"requires": {
|
||||
"hyphenate-style-name": "^1.0.0",
|
||||
"matchmediaquery": "^0.3.0",
|
||||
"prop-types": "^15.6.1",
|
||||
"shallow-equal": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.3.tgz",
|
||||
@ -24855,11 +24785,6 @@
|
||||
"kind-of": "^6.0.2"
|
||||
}
|
||||
},
|
||||
"shallow-equal": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
|
@ -78,7 +78,6 @@
|
||||
"react-i18next": "^11.16.2",
|
||||
"react-image": "^4.0.3",
|
||||
"react-qr-code": "^2.0.3",
|
||||
"react-responsive": "^9.0.0-beta.6",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-smooth-image": "^1.1.0",
|
||||
"react-world-flags": "^1.4.0",
|
||||
|
@ -30,11 +30,10 @@ import { EnableTelegramDialog } from '.';
|
||||
import BoltIcon from '@mui/icons-material/Bolt';
|
||||
import SendIcon from '@mui/icons-material/Send';
|
||||
import NumbersIcon from '@mui/icons-material/Numbers';
|
||||
import PasswordIcon from '@mui/icons-material/Password';
|
||||
import ContentCopy from '@mui/icons-material/ContentCopy';
|
||||
import PersonAddAltIcon from '@mui/icons-material/PersonAddAlt';
|
||||
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
|
||||
import { UserNinjaIcon, BitcoinIcon } from '../Icons';
|
||||
import { UserNinjaIcon } from '../Icons';
|
||||
|
||||
import { systemClient } from '../../services/System';
|
||||
import { getHost, getWebln } from '../../utils';
|
||||
@ -76,9 +75,12 @@ const ProfileDialog = ({
|
||||
const [openEnableTelegram, setOpenEnableTelegram] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
getWebln().then((webln) => {
|
||||
setWeblnEnabled(webln !== undefined);
|
||||
});
|
||||
const handleWebln = async (order: Order) => {
|
||||
const webln = await getWebln().catch(() => console.log('WebLN not available'));
|
||||
return webln;
|
||||
};
|
||||
const webln = handleWebln();
|
||||
setWeblnEnabled(webln !== undefined);
|
||||
}, []);
|
||||
|
||||
const copyReferralCodeHandler = () => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function AmbossIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function BasqueCountryFlag(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function BitcoinIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function BitcoinSignIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function BuySatsIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function BuySatsCheckedIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function CataloniaFlag(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function EarthIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function ExportIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function GoldIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function NewTabIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function RoboSatsIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function RoboSatsTextIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function SellSatsIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function SellSatsCheckedIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function SendReceiveIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function TorIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { SvgIcon } from '@mui/material';
|
||||
|
||||
export default function UserNinjaIcon(props) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import DashboardCustomizeIcon from '@mui/icons-material/DashboardCustomize';
|
||||
|
||||
const icons = {
|
||||
@ -424,29 +424,25 @@ const icons = {
|
||||
},
|
||||
};
|
||||
|
||||
export default class PaymentIcon extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const PaymentIcon: React.FC = (props) => {
|
||||
if (props.icon === undefined) {
|
||||
return null;
|
||||
} else if (props.icon === 'custom') {
|
||||
return (
|
||||
<DashboardCustomizeIcon
|
||||
sx={{ ...props, filter: 'drop-shadow(1.5px 1.5px 1.5px rgba(0, 0, 0, 0.2))' }}
|
||||
color='primary'
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<img
|
||||
{...props}
|
||||
src={icons[props.icon].image}
|
||||
style={{ borderRadius: '23%', filter: 'drop-shadow(1.5px 1.5px 2px rgba(0, 0, 0, 0.2))' }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.props.icon === undefined) {
|
||||
return null;
|
||||
} else if (this.props.icon === 'custom') {
|
||||
return (
|
||||
<DashboardCustomizeIcon
|
||||
sx={{ ...this.props, filter: 'drop-shadow(1.5px 1.5px 1.5px rgba(0, 0, 0, 0.2))' }}
|
||||
color='primary'
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<img
|
||||
{...this.props}
|
||||
src={icons[this.props.icon].image}
|
||||
style={{ borderRadius: '23%', filter: 'drop-shadow(1.5px 1.5px 2px rgba(0, 0, 0, 0.2))' }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
export default PaymentIcon;
|
@ -1,4 +1,9 @@
|
||||
export const fiatMethods = [
|
||||
export interface PaymentMethod {
|
||||
name: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export const fiatMethods: PaymentMethod[] = [
|
||||
{ name: 'Revolut', icon: 'revolut' },
|
||||
{ name: 'CashApp', icon: 'cashapp' },
|
||||
{ name: 'Zelle', icon: 'zelle' },
|
||||
@ -78,7 +83,7 @@ export const fiatMethods = [
|
||||
{ name: 'Amazon TR GiftCard', icon: 'amazontr' },
|
||||
];
|
||||
|
||||
export const swapMethods = [
|
||||
export const swapMethods: PaymentMethod[] = [
|
||||
{ name: 'On-Chain BTC', icon: 'onchain' },
|
||||
{ name: 'On-Chain w/ Stowaway', icon: 'stowaway' },
|
||||
{ name: 'RBTC', icon: 'rbtc' },
|
@ -6,8 +6,8 @@ Scripts taken from https://github.com/hsjoberg/blixt-wallet/blob/master/contrib/
|
||||
|
||||
1. Run `cd Icons` and `./gen-webp.sh` to generate the WebP files to used
|
||||
2. Run `cd Icons` and `./gen-code.sh` to generate code to either be used in react js source files
|
||||
3. Copy/Paste and replace the dict from `frontend/src/components/PaymentMethods/Icons/code/code.js` to `frontend/src/components/PaymentMethods/Icons/index.js`
|
||||
4. Add the new entry to `paymentMethods` or `swapMethods` array in `frontend/src/components/PaymentMethods/MethodList.js`
|
||||
3. Copy/Paste and replace the dict from `frontend/src/components/PaymentMethods/Icons/code/code.js` to `frontend/src/components/PaymentMethods/Icons/index.tsx`
|
||||
4. Add the new entry to `paymentMethods` or `swapMethods` array in `frontend/src/components/PaymentMethods/MethodList.ts`
|
||||
|
||||
# Trademarks belong to their respective owners
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PaymentIcon from './Icons';
|
||||
import { Tooltip } from '@mui/material';
|
||||
import { fiatMethods, swapMethods } from './MethodList';
|
||||
@ -7,18 +7,15 @@ import { fiatMethods, swapMethods } from './MethodList';
|
||||
const ns = [{ name: 'not specified', icon: 'notspecified' }];
|
||||
const methods = ns.concat(swapMethods).concat(fiatMethods);
|
||||
|
||||
class StringAsIcons extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
const StringAsIcons: React.FC = (props) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
parseText() {
|
||||
const { t } = this.props;
|
||||
const parseText = () => {
|
||||
const rows = [];
|
||||
let custom_methods = this.props.text;
|
||||
let custom_methods = props.text;
|
||||
// Adds icons for each PaymentMethod that matches
|
||||
methods.forEach((method, i) => {
|
||||
if (this.props.text.includes(method.name)) {
|
||||
if (props.text.includes(method.name)) {
|
||||
custom_methods = custom_methods.replace(method.name, '');
|
||||
rows.push(
|
||||
<Tooltip
|
||||
@ -30,11 +27,11 @@ class StringAsIcons extends Component {
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: this.props.size + 2,
|
||||
height: this.props.size,
|
||||
width: props.size + 2,
|
||||
height: props.size,
|
||||
}}
|
||||
>
|
||||
<PaymentIcon width={this.props.size} height={this.props.size} icon={method.icon} />
|
||||
<PaymentIcon width={props.size} height={props.size} icon={method.icon} />
|
||||
</div>
|
||||
</Tooltip>,
|
||||
);
|
||||
@ -55,32 +52,24 @@ class StringAsIcons extends Component {
|
||||
key={'pushed'}
|
||||
placement='top'
|
||||
enterTouchDelay={0}
|
||||
title={
|
||||
this.props.verbose
|
||||
? this.props.othersText
|
||||
: this.props.othersText + ': ' + custom_methods
|
||||
}
|
||||
title={props.verbose ? props.othersText : props.othersText + ': ' + custom_methods}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
display: 'inline-block',
|
||||
width: this.props.size + 2,
|
||||
maxHeight: this.props.size,
|
||||
width: props.size + 2,
|
||||
maxHeight: props.size,
|
||||
top: '-1px',
|
||||
}}
|
||||
>
|
||||
<PaymentIcon
|
||||
width={this.props.size * 1.1}
|
||||
height={this.props.size * 1.1}
|
||||
icon={'custom'}
|
||||
/>
|
||||
<PaymentIcon width={props.size * 1.1} height={props.size * 1.1} icon={'custom'} />
|
||||
</div>
|
||||
</Tooltip>,
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.verbose) {
|
||||
if (props.verbose) {
|
||||
return (
|
||||
<>
|
||||
{rows}{' '}
|
||||
@ -93,15 +82,11 @@ class StringAsIcons extends Component {
|
||||
} else {
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
{this.parseText()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>{parseText()}</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default withTranslation()(StringAsIcons);
|
||||
export default StringAsIcons;
|
@ -1,4 +1,3 @@
|
||||
export { default as PaymentStringAsIcons } from './StringAsIcons';
|
||||
export { fiatMethods } from './MethodList';
|
||||
export { swapMethods } from './MethodList';
|
||||
export { fiatMethods, swapMethods } from './MethodList';
|
||||
export { default as PaymentIcon } from './Icons';
|
||||
|
@ -1,153 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation, Trans } from 'react-i18next';
|
||||
import { Paper, Alert, AlertTitle, Button, Link } from '@mui/material';
|
||||
import MediaQuery from 'react-responsive';
|
||||
import { getHost } from '../utils';
|
||||
|
||||
class UnsafeAlert extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
show: true,
|
||||
};
|
||||
}
|
||||
|
||||
// To do. Read from Coordinators state Obj.
|
||||
safe_urls = [
|
||||
'robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion',
|
||||
'robotestagw3dcxmd66r4rgksb4nmmr43fh77bzn2ia2eucduyeafnyd.onion',
|
||||
'robodevs7ixniseezbv7uryxhamtz3hvcelzfwpx3rvoipttjomrmpqd.onion',
|
||||
'robosats.i2p',
|
||||
'r7r4sckft6ptmk4r2jajiuqbowqyxiwsle4iyg4fijtoordc6z7a.b32.i2p',
|
||||
];
|
||||
|
||||
checkClient() {
|
||||
const http = new XMLHttpRequest();
|
||||
const host = getHost();
|
||||
const unsafeClient = !this.safe_urls.includes(host);
|
||||
try {
|
||||
http.open('HEAD', `${location.protocol}//${host}/selfhosted`, false);
|
||||
http.send();
|
||||
this.props.setSettings({
|
||||
...this.props.settings,
|
||||
host,
|
||||
unsafeClient,
|
||||
selfhostedClient: http.status === 200,
|
||||
});
|
||||
} catch {
|
||||
this.props.setSettings({
|
||||
...this.props.settings,
|
||||
host,
|
||||
unsafeClient,
|
||||
selfhostedClient: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.checkClient();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
|
||||
// If alert is hidden return null
|
||||
if (!this.state.show) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Show selfhosted notice
|
||||
else if (this.props.settings.selfhostedClient) {
|
||||
return (
|
||||
<div>
|
||||
<Paper elevation={6} className='alertUnsafe'>
|
||||
<Alert
|
||||
severity='success'
|
||||
sx={{ maxHeight: '120px' }}
|
||||
action={
|
||||
<Button color='success' onClick={() => this.setState({ show: false })}>
|
||||
{t('Hide')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<AlertTitle>{t('You are self-hosting RoboSats')}</AlertTitle>
|
||||
{t(
|
||||
'RoboSats client is served from your own node granting you the strongest security and privacy.',
|
||||
)}
|
||||
</Alert>
|
||||
</Paper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Show unsafe alert
|
||||
else if (this.props.settings.unsafeClient) {
|
||||
return (
|
||||
<div>
|
||||
<MediaQuery minWidth={800}>
|
||||
<Paper elevation={6} className='alertUnsafe'>
|
||||
<Alert
|
||||
severity='warning'
|
||||
sx={{ maxHeight: '100px' }}
|
||||
action={<Button onClick={() => this.setState({ show: false })}>{t('Hide')}</Button>}
|
||||
>
|
||||
<AlertTitle>{t('You are not using RoboSats privately')}</AlertTitle>
|
||||
<Trans i18nKey='desktop_unsafe_alert'>
|
||||
<a>
|
||||
Some features are disabled for your protection (e.g. chat) and you will not be
|
||||
able to complete a trade without them. To protect your privacy and fully enable
|
||||
RoboSats, use{' '}
|
||||
</a>
|
||||
<Link href='https://www.torproject.org/download/' target='_blank'>
|
||||
Tor Browser
|
||||
</Link>
|
||||
<a> and visit the </a>
|
||||
<Link
|
||||
href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion'
|
||||
target='_blank'
|
||||
>
|
||||
Onion
|
||||
</Link>
|
||||
<a> site.</a>
|
||||
</Trans>
|
||||
</Alert>
|
||||
</Paper>
|
||||
</MediaQuery>
|
||||
|
||||
<MediaQuery maxWidth={799}>
|
||||
<Paper elevation={6} className='alertUnsafe'>
|
||||
<Alert severity='warning' sx={{ maxHeight: '120px' }}>
|
||||
<AlertTitle>{t('You are not using RoboSats privately')}</AlertTitle>
|
||||
<Trans i18nKey='phone_unsafe_alert'>
|
||||
<a>You will not be able to complete a trade. Use </a>
|
||||
<Link href='https://www.torproject.org/download/' target='_blank'>
|
||||
Tor Browser
|
||||
</Link>
|
||||
<a> and visit the </a>
|
||||
<Link
|
||||
href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion'
|
||||
target='_blank'
|
||||
>
|
||||
Onion
|
||||
</Link>{' '}
|
||||
<a> site.</a>
|
||||
</Trans>
|
||||
<div style={{ width: '100%' }}></div>
|
||||
<div align='center'>
|
||||
<Button
|
||||
className='hideAlertButton'
|
||||
onClick={() => this.setState({ show: false })}
|
||||
>
|
||||
{t('Hide')}
|
||||
</Button>
|
||||
</div>
|
||||
</Alert>
|
||||
</Paper>
|
||||
</MediaQuery>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withTranslation()(UnsafeAlert);
|
136
frontend/src/components/UnsafeAlert.tsx
Normal file
136
frontend/src/components/UnsafeAlert.tsx
Normal file
@ -0,0 +1,136 @@
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { AppContext, AppContextProps } from '../contexts/AppContext';
|
||||
import { useTranslation, Trans } from 'react-i18next';
|
||||
import { Paper, Alert, AlertTitle, Button, Link } from '@mui/material';
|
||||
import { getHost } from '../utils';
|
||||
|
||||
const UnsafeAlert = (): JSX.Element => {
|
||||
const { settings, setSettings, windowSize } = useContext<AppContextProps>(AppContext);
|
||||
const { t } = useTranslation();
|
||||
const [show, setShow] = useState<boolean>(true);
|
||||
|
||||
// To do. Read from Coordinators Obj.
|
||||
const safe_urls = [
|
||||
'robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion',
|
||||
'robotestagw3dcxmd66r4rgksb4nmmr43fh77bzn2ia2eucduyeafnyd.onion',
|
||||
'robodevs7ixniseezbv7uryxhamtz3hvcelzfwpx3rvoipttjomrmpqd.onion',
|
||||
'robosats.i2p',
|
||||
'r7r4sckft6ptmk4r2jajiuqbowqyxiwsle4iyg4fijtoordc6z7a.b32.i2p',
|
||||
];
|
||||
|
||||
const checkClient = () => {
|
||||
const http = new XMLHttpRequest();
|
||||
const host = getHost();
|
||||
const unsafeClient = !safe_urls.includes(host);
|
||||
try {
|
||||
http.open('HEAD', `${location.protocol}//${host}/selfhosted`, false);
|
||||
http.send();
|
||||
setSettings({
|
||||
...settings,
|
||||
host,
|
||||
unsafeClient,
|
||||
selfhostedClient: http.status === 200,
|
||||
});
|
||||
} catch {
|
||||
setSettings({
|
||||
...settings,
|
||||
host,
|
||||
unsafeClient,
|
||||
selfhostedClient: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
checkClient();
|
||||
}, []);
|
||||
|
||||
// If alert is hidden return null
|
||||
if (!show) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
// Show selfhosted notice
|
||||
else if (settings.selfhostedClient) {
|
||||
return (
|
||||
<div>
|
||||
<Paper elevation={6} className='unsafeAlert'>
|
||||
<Alert
|
||||
severity='success'
|
||||
sx={{ maxHeight: '8em' }}
|
||||
action={
|
||||
<Button color='success' onClick={() => setShow(false)}>
|
||||
{t('Hide')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<AlertTitle>{t('You are self-hosting RoboSats')}</AlertTitle>
|
||||
{t(
|
||||
'RoboSats client is served from your own node granting you the strongest security and privacy.',
|
||||
)}
|
||||
</Alert>
|
||||
</Paper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Show unsafe alert
|
||||
else if (settings.unsafeClient) {
|
||||
return (
|
||||
<Paper elevation={6} className='unsafeAlert'>
|
||||
{windowSize.width > 57 ? (
|
||||
<Alert
|
||||
severity='warning'
|
||||
sx={{ maxHeight: '7em' }}
|
||||
action={<Button onClick={() => setShow(false)}>{t('Hide')}</Button>}
|
||||
>
|
||||
<AlertTitle>{t('You are not using RoboSats privately')}</AlertTitle>
|
||||
<Trans i18nKey='desktop_unsafe_alert'>
|
||||
<a>
|
||||
Some features are disabled for your protection (e.g. chat) and you will not be able
|
||||
to complete a trade without them. To protect your privacy and fully enable RoboSats,
|
||||
use{' '}
|
||||
</a>
|
||||
<Link href='https://www.torproject.org/download/' target='_blank'>
|
||||
Tor Browser
|
||||
</Link>
|
||||
<a> and visit the </a>
|
||||
<Link
|
||||
href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion'
|
||||
target='_blank'
|
||||
>
|
||||
Onion
|
||||
</Link>
|
||||
<a> site.</a>
|
||||
</Trans>
|
||||
</Alert>
|
||||
) : (
|
||||
<Alert severity='warning' sx={{ maxHeight: '8em' }}>
|
||||
<AlertTitle>{t('You are not using RoboSats privately')}</AlertTitle>
|
||||
<Trans i18nKey='phone_unsafe_alert'>
|
||||
<a>You will not be able to complete a trade. Use </a>
|
||||
<Link href='https://www.torproject.org/download/' target='_blank'>
|
||||
Tor Browser
|
||||
</Link>
|
||||
<a> and visit the </a>
|
||||
<Link
|
||||
href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion'
|
||||
target='_blank'
|
||||
>
|
||||
Onion
|
||||
</Link>{' '}
|
||||
<a> site.</a>
|
||||
</Trans>
|
||||
<div style={{ display: 'flex', justifyContent: 'center', width: '100%' }}>
|
||||
<Button className='hideAlertButton' onClick={() => setShow(false)}>
|
||||
{t('Hide')}
|
||||
</Button>
|
||||
</div>
|
||||
</Alert>
|
||||
)}
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default UnsafeAlert;
|
@ -401,7 +401,7 @@ export const AppContextProvider = ({
|
||||
}
|
||||
setBadRequest('');
|
||||
|
||||
let requestBody = {};
|
||||
const requestBody = {};
|
||||
if (action == 'login' || action == 'refresh') {
|
||||
requestBody.token_sha256 = sha256(newToken ?? oldRobot.token);
|
||||
} else if (action == 'generate' && newToken != null) {
|
||||
@ -459,7 +459,7 @@ export const AppContextProvider = ({
|
||||
shannonEntropy: data.token_shannon_entropy,
|
||||
pubKey: data.public_key,
|
||||
encPrivKey: data.encrypted_private_key,
|
||||
copiedToken: data.found ? true : false,
|
||||
copiedToken: !!data.found,
|
||||
};
|
||||
setRobot(newRobot);
|
||||
garage.updateRobot(newRobot, targetSlot);
|
||||
|
@ -16,8 +16,9 @@ class Garage {
|
||||
} else {
|
||||
this.slots = [emptySlot];
|
||||
}
|
||||
this.setGarage = initialState?.setGarage || (() => {});
|
||||
this.setGarage = initialState?.setGarage != null || (() => {});
|
||||
}
|
||||
|
||||
slots: Slot[] = [emptySlot];
|
||||
setGarage: (state: Garage) => void = () => {};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
class Robot {
|
||||
constructor(garageRobot?: Robot) {
|
||||
if (garageRobot) {
|
||||
if (garageRobot != null) {
|
||||
this.token = garageRobot?.token ?? undefined;
|
||||
this.pubKey = garageRobot?.pubKey ?? undefined;
|
||||
this.encPrivKey = garageRobot?.encPrivKey ?? undefined;
|
||||
|
@ -51,7 +51,7 @@ class BaseSettings {
|
||||
public coordinator: Coordinator | undefined = undefined;
|
||||
public host?: string;
|
||||
public unsafeClient: boolean = false;
|
||||
public hostedClient: boolean = false;
|
||||
public selfhostedClient: boolean = false;
|
||||
}
|
||||
|
||||
export default BaseSettings;
|
||||
|
@ -46,16 +46,12 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.alertUnsafe {
|
||||
.unsafeAlert {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.hideAlertButton {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
/* No arrows on numeric inputs */
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
|
Loading…
Reference in New Issue
Block a user