mirror of
https://github.com/apotdevin/thunderhub.git
synced 2024-11-19 09:50:03 +01:00
chore: 🔧 remove qr login
This commit is contained in:
parent
d6f9e51ed0
commit
47ee9c0127
37
package-lock.json
generated
37
package-lock.json
generated
@ -16465,11 +16465,6 @@
|
|||||||
"verror": "1.10.0"
|
"verror": "1.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jsqr": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-zCTP6Qd/WwjrpuHFkJuXc5opRdKprUr7eI7+JCCtcetThJt45qptu82MWQ+eET+FtDrMo7+BYjo3iD0XIq1L9Q=="
|
|
||||||
},
|
|
||||||
"jsx-ast-utils": {
|
"jsx-ast-utils": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.3.0.tgz",
|
||||||
@ -20339,16 +20334,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
"react-qr-reader": {
|
|
||||||
"version": "2.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-qr-reader/-/react-qr-reader-2.2.1.tgz",
|
|
||||||
"integrity": "sha512-EL5JEj53u2yAOgtpAKAVBzD/SiKWn0Bl7AZy6ZrSf1lub7xHwtaXe6XSx36Wbhl1VMGmvmrwYMRwO1aSCT2fwA==",
|
|
||||||
"requires": {
|
|
||||||
"jsqr": "^1.2.0",
|
|
||||||
"prop-types": "^15.7.2",
|
|
||||||
"webrtc-adapter": "^7.2.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react-refresh": {
|
"react-refresh": {
|
||||||
"version": "0.8.3",
|
"version": "0.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
|
||||||
@ -21179,14 +21164,6 @@
|
|||||||
"integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
|
"integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"rtcpeerconnection-shim": {
|
|
||||||
"version": "1.2.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
|
|
||||||
"integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==",
|
|
||||||
"requires": {
|
|
||||||
"sdp": "^2.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"run-async": {
|
"run-async": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||||
@ -21326,11 +21303,6 @@
|
|||||||
"integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==",
|
"integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"sdp": {
|
|
||||||
"version": "2.12.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
|
|
||||||
"integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw=="
|
|
||||||
},
|
|
||||||
"secp256k1": {
|
"secp256k1": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.1.tgz",
|
||||||
@ -24177,15 +24149,6 @@
|
|||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webrtc-adapter": {
|
|
||||||
"version": "7.6.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.6.1.tgz",
|
|
||||||
"integrity": "sha512-orgybuYN6971dRWL/fdvo36Ro8zUvfXovEoaTXuKIuGySOZRCqmtSJ4oEYuNpi4C6NzkJrF1Nwf+N1VyOttkcg==",
|
|
||||||
"requires": {
|
|
||||||
"rtcpeerconnection-shim": "^1.2.15",
|
|
||||||
"sdp": "^2.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"websocket": {
|
"websocket": {
|
||||||
"version": "1.0.31",
|
"version": "1.0.31",
|
||||||
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz",
|
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz",
|
||||||
|
@ -70,7 +70,6 @@
|
|||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-feather": "^2.0.8",
|
"react-feather": "^2.0.8",
|
||||||
"react-intersection-observer": "^8.26.2",
|
"react-intersection-observer": "^8.26.2",
|
||||||
"react-qr-reader": "^2.2.1",
|
|
||||||
"react-spinners": "^0.8.3",
|
"react-spinners": "^0.8.3",
|
||||||
"react-spring": "^8.0.27",
|
"react-spring": "^8.0.27",
|
||||||
"react-toastify": "^6.0.5",
|
"react-toastify": "^6.0.5",
|
||||||
|
@ -9,6 +9,7 @@ import { GridWrapper } from 'src/components/gridWrapper/GridWrapper';
|
|||||||
import { withApollo } from 'config/client';
|
import { withApollo } from 'config/client';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { useStatusState } from 'src/context/StatusContext';
|
import { useStatusState } from 'src/context/StatusContext';
|
||||||
|
import { ChannelFeeType } from 'src/graphql/types';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardWithTitle,
|
CardWithTitle,
|
||||||
@ -159,7 +160,7 @@ const FeesView = () => {
|
|||||||
<CardWithTitle>
|
<CardWithTitle>
|
||||||
<SubTitle>Channel Details</SubTitle>
|
<SubTitle>Channel Details</SubTitle>
|
||||||
<Card mobileCardPadding={'0'} mobileNoBackground={true}>
|
<Card mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||||
{data.getChannelFees.map((channel, index: number) => (
|
{data.getChannelFees.map((channel: ChannelFeeType, index: number) => (
|
||||||
<FeeCard
|
<FeeCard
|
||||||
channel={channel}
|
channel={channel}
|
||||||
index={index + 1}
|
index={index + 1}
|
||||||
|
@ -7,7 +7,6 @@ import { InterfaceSettings } from '../src/views/settings/Interface';
|
|||||||
import { AccountSettings } from '../src/views/settings/Account';
|
import { AccountSettings } from '../src/views/settings/Account';
|
||||||
import { DangerView } from '../src/views/settings/Danger';
|
import { DangerView } from '../src/views/settings/Danger';
|
||||||
import { CurrentSettings } from '../src/views/settings/Current';
|
import { CurrentSettings } from '../src/views/settings/Current';
|
||||||
import { SyncSettings } from '../src/views/settings/Sync';
|
|
||||||
import { ChatSettings } from '../src/views/settings/Chat';
|
import { ChatSettings } from '../src/views/settings/Chat';
|
||||||
import { PrivacySettings } from '../src/views/settings/Privacy';
|
import { PrivacySettings } from '../src/views/settings/Privacy';
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ const SettingsView = () => {
|
|||||||
<InterfaceSettings />
|
<InterfaceSettings />
|
||||||
<PrivacySettings />
|
<PrivacySettings />
|
||||||
<ChatSettings />
|
<ChatSettings />
|
||||||
<SyncSettings />
|
|
||||||
<CurrentSettings />
|
<CurrentSettings />
|
||||||
<AccountSettings />
|
<AccountSettings />
|
||||||
<DangerView />
|
<DangerView />
|
||||||
|
@ -24,13 +24,6 @@ const PasswordInput = dynamic(() => import('./views/Password'), {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const QRLogin = dynamic(() => import('./views/QRLogin'), {
|
|
||||||
ssr: false,
|
|
||||||
loading: function Loading() {
|
|
||||||
return <LoadingCard noCard={true} />;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
type AuthProps = {
|
type AuthProps = {
|
||||||
type: string;
|
type: string;
|
||||||
status: string;
|
status: string;
|
||||||
@ -55,41 +48,16 @@ export const Auth = ({ type, status, callback, setStatus }: AuthProps) => {
|
|||||||
|
|
||||||
const [adminChecked, setAdminChecked] = useState(false);
|
const [adminChecked, setAdminChecked] = useState(false);
|
||||||
|
|
||||||
const quickSave = ({
|
|
||||||
name = 'Unknown',
|
|
||||||
host,
|
|
||||||
admin,
|
|
||||||
viewOnly,
|
|
||||||
cert,
|
|
||||||
}: {
|
|
||||||
name?: string;
|
|
||||||
host?: string;
|
|
||||||
admin?: string;
|
|
||||||
viewOnly?: string;
|
|
||||||
cert?: string;
|
|
||||||
}) => {
|
|
||||||
dispatch({ type: 'disconnected' });
|
|
||||||
dispatchChat({ type: 'disconnected' });
|
|
||||||
dispatchAccount({
|
|
||||||
type: 'addAccountAndSave',
|
|
||||||
accountToAdd: { name, host, admin, viewOnly, cert },
|
|
||||||
});
|
|
||||||
|
|
||||||
push(appendBasePath('/'));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSet = ({
|
const handleSet = ({
|
||||||
host,
|
host,
|
||||||
admin,
|
admin,
|
||||||
viewOnly,
|
viewOnly,
|
||||||
cert,
|
cert,
|
||||||
skipCheck,
|
|
||||||
}: {
|
}: {
|
||||||
host?: string;
|
host?: string;
|
||||||
admin?: string;
|
admin?: string;
|
||||||
viewOnly?: string;
|
viewOnly?: string;
|
||||||
cert?: string;
|
cert?: string;
|
||||||
skipCheck?: boolean;
|
|
||||||
}) => {
|
}) => {
|
||||||
const id = getAccountId(
|
const id = getAccountId(
|
||||||
host ?? '',
|
host ?? '',
|
||||||
@ -108,8 +76,6 @@ export const Auth = ({ type, status, callback, setStatus }: AuthProps) => {
|
|||||||
toast.error('A host url is needed to connect.');
|
toast.error('A host url is needed to connect.');
|
||||||
} else if (!admin && !viewOnly) {
|
} else if (!admin && !viewOnly) {
|
||||||
toast.error('View-Only or Admin macaroon are needed to connect.');
|
toast.error('View-Only or Admin macaroon are needed to connect.');
|
||||||
} else if (skipCheck) {
|
|
||||||
quickSave({ name, cert, admin, viewOnly, host });
|
|
||||||
} else {
|
} else {
|
||||||
host && setHost(host);
|
host && setHost(host);
|
||||||
admin && setAdmin(admin);
|
admin && setAdmin(admin);
|
||||||
@ -164,8 +130,6 @@ export const Auth = ({ type, status, callback, setStatus }: AuthProps) => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'login':
|
case 'login':
|
||||||
return <LoginForm handleSet={handleSet} />;
|
return <LoginForm handleSet={handleSet} />;
|
||||||
case 'qrcode':
|
|
||||||
return <QRLogin handleSet={handleSet} />;
|
|
||||||
case 'connect':
|
case 'connect':
|
||||||
return <ConnectLoginForm handleSet={handleSet} />;
|
return <ConnectLoginForm handleSet={handleSet} />;
|
||||||
default:
|
default:
|
||||||
|
@ -1,154 +0,0 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
|
||||||
import QrReader from 'react-qr-reader';
|
|
||||||
import { toast } from 'react-toastify';
|
|
||||||
import sortBy from 'lodash.sortby';
|
|
||||||
import Modal from '../../modal/ReactModal';
|
|
||||||
import { getQRConfig } from '../../../utils/auth';
|
|
||||||
import { Line, QRTextWrapper } from '../Auth.styled';
|
|
||||||
import { LoadingBar } from '../../loadingBar/LoadingBar';
|
|
||||||
import { SubTitle } from '../../generic/Styled';
|
|
||||||
import { ColorButton } from '../../buttons/colorButton/ColorButton';
|
|
||||||
|
|
||||||
type QRLoginProps = {
|
|
||||||
handleSet: ({
|
|
||||||
name,
|
|
||||||
host,
|
|
||||||
admin,
|
|
||||||
viewOnly,
|
|
||||||
cert,
|
|
||||||
skipCheck,
|
|
||||||
}: {
|
|
||||||
name?: string;
|
|
||||||
host?: string;
|
|
||||||
admin?: string;
|
|
||||||
viewOnly?: string;
|
|
||||||
cert?: string;
|
|
||||||
skipCheck?: boolean;
|
|
||||||
}) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const QRLogin = ({ handleSet }: QRLoginProps) => {
|
|
||||||
const [qrData, setQrData] = useState<any>([]);
|
|
||||||
const [modalOpen, setModalOpen] = useState(true);
|
|
||||||
const [modalClosed, setModalClosed] = useState('none');
|
|
||||||
|
|
||||||
const [total, setTotal] = useState(0);
|
|
||||||
const [missing, setMissing] = useState<number[]>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (qrData.length >= total && total !== 0) {
|
|
||||||
setModalOpen(false);
|
|
||||||
|
|
||||||
const sorted = sortBy(qrData, 'index');
|
|
||||||
const strings = sorted.map((code: { auth: string }) => code.auth);
|
|
||||||
const completeString = strings.join('');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { name, cert, admin, viewOnly, host } = getQRConfig(
|
|
||||||
completeString
|
|
||||||
);
|
|
||||||
|
|
||||||
handleSet({
|
|
||||||
name,
|
|
||||||
host,
|
|
||||||
admin,
|
|
||||||
viewOnly,
|
|
||||||
cert,
|
|
||||||
skipCheck: true,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
toast.error('Error reading QR codes.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [qrData, handleSet, total]);
|
|
||||||
|
|
||||||
const handleScan = (data: string | null) => {
|
|
||||||
if (data) {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(data);
|
|
||||||
!total && setTotal(parsed.total);
|
|
||||||
!missing && setMissing([...Array(parsed.total).keys()]);
|
|
||||||
|
|
||||||
if (missing && missing.length >= 0 && missing.includes(parsed.index)) {
|
|
||||||
const remaining = missing.filter((value: number) => {
|
|
||||||
const currentNumber = Number(parsed.index);
|
|
||||||
return value !== currentNumber;
|
|
||||||
});
|
|
||||||
const data = [...qrData, parsed];
|
|
||||||
setQrData(data);
|
|
||||||
setMissing(remaining);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
setModalOpen(false);
|
|
||||||
toast.error('Error reading QR codes.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleError = () => {
|
|
||||||
setModalOpen(false);
|
|
||||||
setModalClosed('error');
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
setModalClosed('forced');
|
|
||||||
setModalOpen(false);
|
|
||||||
setMissing(undefined);
|
|
||||||
setTotal(0);
|
|
||||||
setQrData([]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderInfo = () => {
|
|
||||||
switch (modalClosed) {
|
|
||||||
case 'forced':
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<QRTextWrapper>
|
|
||||||
<SubTitle>No information read from QR Codes.</SubTitle>
|
|
||||||
</QRTextWrapper>
|
|
||||||
<ColorButton
|
|
||||||
fullWidth={true}
|
|
||||||
onClick={() => {
|
|
||||||
setModalClosed('none');
|
|
||||||
setModalOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Try Again
|
|
||||||
</ColorButton>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
case 'error':
|
|
||||||
return (
|
|
||||||
<QRTextWrapper>
|
|
||||||
<SubTitle>
|
|
||||||
Make sure you have a camara available and that you have given
|
|
||||||
ThunderHub the correct permissions to use it.
|
|
||||||
</SubTitle>
|
|
||||||
</QRTextWrapper>
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{renderInfo()}
|
|
||||||
<Modal isOpen={modalOpen} closeCallback={handleClose}>
|
|
||||||
<Line>
|
|
||||||
<LoadingBar
|
|
||||||
percent={missing ? 100 * ((total - missing.length) / total) : 0}
|
|
||||||
/>
|
|
||||||
</Line>
|
|
||||||
<QrReader
|
|
||||||
delay={500}
|
|
||||||
onError={handleError}
|
|
||||||
onScan={handleScan}
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default QRLogin;
|
|
@ -44,7 +44,7 @@ export const Channels: React.FC = () => {
|
|||||||
|
|
||||||
const { capacity, channel_count } = partner_node_info?.node || {};
|
const { capacity, channel_count } = partner_node_info?.node || {};
|
||||||
const { base_fee_mtokens, fee_rate } =
|
const { base_fee_mtokens, fee_rate } =
|
||||||
partner_fee_info?.channel?.policies?.[0] || {};
|
partner_fee_info?.channel?.partner_node_policies || {};
|
||||||
|
|
||||||
const partner = Number(capacity) || 0;
|
const partner = Number(capacity) || 0;
|
||||||
const channels = Number(channel_count) || 0;
|
const channels = Number(channel_count) || 0;
|
||||||
|
@ -70,11 +70,13 @@ export const ForwardCard = ({
|
|||||||
<ColumnLine>
|
<ColumnLine>
|
||||||
{renderLine(
|
{renderLine(
|
||||||
'Incoming:',
|
'Incoming:',
|
||||||
incoming_channel_info?.channel?.policies?.[0]?.node?.node?.alias
|
incoming_channel_info?.channel?.partner_node_policies?.node
|
||||||
|
?.node?.alias
|
||||||
)}
|
)}
|
||||||
{renderLine(
|
{renderLine(
|
||||||
'Outgoing:',
|
'Outgoing:',
|
||||||
outgoing_channel_info?.channel?.policies?.[0]?.node?.node?.alias
|
outgoing_channel_info?.channel?.partner_node_policies?.node
|
||||||
|
?.node?.alias
|
||||||
)}
|
)}
|
||||||
</ColumnLine>
|
</ColumnLine>
|
||||||
</ResponsiveSingle>
|
</ResponsiveSingle>
|
||||||
|
@ -83,15 +83,6 @@ export const LoginBox = () => {
|
|||||||
>
|
>
|
||||||
BTCPayServer
|
BTCPayServer
|
||||||
</SingleButton>
|
</SingleButton>
|
||||||
<SingleButton
|
|
||||||
selected={isType === 'qrcode'}
|
|
||||||
onClick={() => {
|
|
||||||
setHelp(false);
|
|
||||||
setIsType('qrcode');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
QR Code
|
|
||||||
</SingleButton>
|
|
||||||
</MultiButton>
|
</MultiButton>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -75,12 +75,6 @@ export const AccountSettings = () => {
|
|||||||
>
|
>
|
||||||
BTCPayServer Info
|
BTCPayServer Info
|
||||||
</SingleButton>
|
</SingleButton>
|
||||||
<SingleButton
|
|
||||||
selected={isType === 'qrcode'}
|
|
||||||
onClick={() => setIsType('qrcode')}
|
|
||||||
>
|
|
||||||
QR Code
|
|
||||||
</SingleButton>
|
|
||||||
</MultiButton>
|
</MultiButton>
|
||||||
</SingleLine>
|
</SingleLine>
|
||||||
);
|
);
|
||||||
|
@ -1,178 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import { X } from 'react-feather';
|
|
||||||
import QRCode from 'qrcode.react';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import { useAccountState, CLIENT_ACCOUNT } from 'src/context/AccountContext';
|
|
||||||
import {
|
|
||||||
CardWithTitle,
|
|
||||||
SubTitle,
|
|
||||||
Card,
|
|
||||||
Sub4Title,
|
|
||||||
Separation,
|
|
||||||
} from '../../components/generic/Styled';
|
|
||||||
import { SettingsLine } from '../../../pages/settings';
|
|
||||||
import {
|
|
||||||
MultiButton,
|
|
||||||
SingleButton,
|
|
||||||
} from '../../components/buttons/multiButton/MultiButton';
|
|
||||||
import { ColorButton } from '../../components/buttons/colorButton/ColorButton';
|
|
||||||
import { useInterval } from '../../hooks/UseInterval';
|
|
||||||
import Modal from '../../components/modal/ReactModal';
|
|
||||||
import { themeColors } from '../../styles/Themes';
|
|
||||||
|
|
||||||
const QRWrapper = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const SyncSettings = () => {
|
|
||||||
const { account } = useAccountState();
|
|
||||||
|
|
||||||
const getValue = () => {
|
|
||||||
switch (true) {
|
|
||||||
case account?.type === CLIENT_ACCOUNT && !!account.viewOnly:
|
|
||||||
return 'viewOnly';
|
|
||||||
default:
|
|
||||||
return 'adminOnly';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const [state, setState] = useState('none');
|
|
||||||
const [type, setType] = useState(getValue());
|
|
||||||
|
|
||||||
if (!account || account.type !== CLIENT_ACCOUNT) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { viewOnly, admin, host, cert, name } = account;
|
|
||||||
|
|
||||||
const getObject = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'complete':
|
|
||||||
return { viewOnly, admin };
|
|
||||||
case 'adminOnly':
|
|
||||||
return { admin };
|
|
||||||
default:
|
|
||||||
return { viewOnly };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderSettings = () => (
|
|
||||||
<>
|
|
||||||
<Separation />
|
|
||||||
<SettingsLine>
|
|
||||||
<Sub4Title>Sync Type</Sub4Title>
|
|
||||||
<MultiButton>
|
|
||||||
{viewOnly && (
|
|
||||||
<SingleButton
|
|
||||||
selected={type === 'viewOnly'}
|
|
||||||
onClick={() => setType('viewOnly')}
|
|
||||||
>
|
|
||||||
View-Only
|
|
||||||
</SingleButton>
|
|
||||||
)}
|
|
||||||
{admin && (
|
|
||||||
<SingleButton
|
|
||||||
selected={type === 'adminOnly'}
|
|
||||||
onClick={() => setType('adminOnly')}
|
|
||||||
>
|
|
||||||
Admin-Only
|
|
||||||
</SingleButton>
|
|
||||||
)}
|
|
||||||
{viewOnly && admin && (
|
|
||||||
<SingleButton
|
|
||||||
selected={type === 'complete'}
|
|
||||||
onClick={() => setType('complete')}
|
|
||||||
>
|
|
||||||
Admin and View
|
|
||||||
</SingleButton>
|
|
||||||
)}
|
|
||||||
</MultiButton>
|
|
||||||
</SettingsLine>
|
|
||||||
<SettingsLine>
|
|
||||||
<ColorButton
|
|
||||||
withMargin={'16px 0 0'}
|
|
||||||
fullWidth={true}
|
|
||||||
onClick={() => setState('finish')}
|
|
||||||
>
|
|
||||||
Generate QR
|
|
||||||
</ColorButton>
|
|
||||||
</SettingsLine>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderQRCode = () => {
|
|
||||||
const connection = JSON.stringify({
|
|
||||||
name,
|
|
||||||
host,
|
|
||||||
cert,
|
|
||||||
...getObject(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
isOpen={true}
|
|
||||||
noMinWidth={true}
|
|
||||||
closeCallback={() => setState('none')}
|
|
||||||
>
|
|
||||||
<QRWrapper>
|
|
||||||
<SubTitle subtitleColor={themeColors.black}>
|
|
||||||
Scan with ThunderHub
|
|
||||||
</SubTitle>
|
|
||||||
<QRLoop connection={connection} />
|
|
||||||
</QRWrapper>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CardWithTitle>
|
|
||||||
<SubTitle>Sync</SubTitle>
|
|
||||||
<Card>
|
|
||||||
<SettingsLine>
|
|
||||||
<Sub4Title>Sync account to another device</Sub4Title>
|
|
||||||
<ColorButton
|
|
||||||
onClick={() =>
|
|
||||||
setState((prev: string) =>
|
|
||||||
prev !== 'none' ? 'none' : 'generate'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{state !== 'none' ? <X size={18} /> : 'Sync'}
|
|
||||||
</ColorButton>
|
|
||||||
</SettingsLine>
|
|
||||||
{state === 'generate' && renderSettings()}
|
|
||||||
{state === 'finish' && renderQRCode()}
|
|
||||||
</Card>
|
|
||||||
</CardWithTitle>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const QRLoop = ({ connection }: { connection: string }) => {
|
|
||||||
const textArray = connection.match(/.{1,100}/g) ?? [];
|
|
||||||
const length = textArray.length;
|
|
||||||
|
|
||||||
const objectArray = textArray.map((value: string, index: number) =>
|
|
||||||
JSON.stringify({
|
|
||||||
index,
|
|
||||||
total: length,
|
|
||||||
auth: value,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const [count, setCount] = useState(0);
|
|
||||||
|
|
||||||
useInterval(() => {
|
|
||||||
setCount((prev: number) => {
|
|
||||||
if (prev < length - 1) {
|
|
||||||
return prev + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
return <QRCode value={objectArray[count]} renderAs={'svg'} size={200} />;
|
|
||||||
};
|
|
@ -5,7 +5,6 @@ import { InterfaceSettings } from './Interface';
|
|||||||
import { AccountSettings } from './Account';
|
import { AccountSettings } from './Account';
|
||||||
import { DangerView } from './Danger';
|
import { DangerView } from './Danger';
|
||||||
import { CurrentSettings } from './Current';
|
import { CurrentSettings } from './Current';
|
||||||
import { SyncSettings } from './Sync';
|
|
||||||
|
|
||||||
export const ButtonRow = styled.div`
|
export const ButtonRow = styled.div`
|
||||||
width: auto;
|
width: auto;
|
||||||
@ -20,7 +19,6 @@ const SettingsView = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<InterfaceSettings />
|
<InterfaceSettings />
|
||||||
<SyncSettings />
|
|
||||||
<CurrentSettings />
|
<CurrentSettings />
|
||||||
<AccountSettings />
|
<AccountSettings />
|
||||||
<DangerView />
|
<DangerView />
|
||||||
|
Loading…
Reference in New Issue
Block a user