mirror of
https://github.com/haveno-dex/haveno-ui.git
synced 2024-10-01 07:35:39 -04:00
feat: Account > Node Settings screen
This commit is contained in:
parent
ba4b634aaa
commit
bc6ed842d5
@ -39,6 +39,10 @@ export enum LangKeys {
|
||||
AccountNodeFieldDeamonFlags = "account.nodeSecurity.deamonFlags",
|
||||
AccountNodeFieldPort = "account.nodeSecurity.port",
|
||||
AccountNodeStopDeamon = "account.nodeSecurity.stopDeamon",
|
||||
AccountNodeStartDeamon = "account.nodeSecurity.startDeamon",
|
||||
AccountNodeLocalSaveNotification = "account.nodeSecurity.saveNotification",
|
||||
AccountNodeDeamonStoppedNotif = "account.nodeSecurity.stoppedNotification",
|
||||
AccountNodeDeamonStartedNotif = "account.nodeSecurity.startedNotification",
|
||||
AccountSettingsAddNode = "account.settings.addNewNode",
|
||||
AccountSettingsCurrent = "account.settings.current",
|
||||
AccountSecurityFieldPassword = "account.security.field.password",
|
||||
|
@ -43,6 +43,11 @@ const LangPackEN: { [key in LangKeys]: string } = {
|
||||
[LangKeys.AccountNodeFieldPort]: "Port",
|
||||
[LangKeys.AccountNodeFieldDeamonFlags]: "Deamon startup flags",
|
||||
[LangKeys.AccountNodeStopDeamon]: "Stop deamon",
|
||||
[LangKeys.AccountNodeStartDeamon]: "Start deamon",
|
||||
[LangKeys.AccountNodeLocalSaveNotification]:
|
||||
"Local node settings updated successfully",
|
||||
[LangKeys.AccountNodeDeamonStoppedNotif]: "Deamon stopped successfully",
|
||||
[LangKeys.AccountNodeDeamonStartedNotif]: "Deamon started successfully",
|
||||
[LangKeys.AccountSettingsAddNode]: "Add a new node",
|
||||
[LangKeys.AccountSettingsCurrent]: "Current",
|
||||
[LangKeys.AccountSecurityFieldPassword]: "Update account password",
|
||||
|
@ -44,6 +44,11 @@ const LangPackES: { [key in LangKeys]: string } = {
|
||||
[LangKeys.AccountNodeFieldPort]: "Puerto",
|
||||
[LangKeys.AccountNodeFieldDeamonFlags]: "Indicadores de inicio de daemon",
|
||||
[LangKeys.AccountNodeStopDeamon]: "Detener demonio",
|
||||
[LangKeys.AccountNodeStartDeamon]: "Comienzo demonio",
|
||||
[LangKeys.AccountNodeLocalSaveNotification]:
|
||||
"La configuración del nodo local se actualizó correctamente.",
|
||||
[LangKeys.AccountNodeDeamonStoppedNotif]: "Daemon se detuvo con éxito",
|
||||
[LangKeys.AccountNodeDeamonStartedNotif]: "Daemon se inició con éxito",
|
||||
[LangKeys.AccountSettingsAddNode]: "Agregar un nuevo nodo",
|
||||
[LangKeys.AccountSettingsCurrent]: "Actual",
|
||||
[LangKeys.AccountSecurityFieldPassword]: "Clave",
|
||||
|
@ -18,6 +18,10 @@ export enum QueryKeys {
|
||||
HavenoVersion = "Haveno.Version",
|
||||
Balances = "Haveno.Balances",
|
||||
PaymentAccounts = "Haveno.PaymentAccounts",
|
||||
MoneroNodeSettings = "Haveno.MoneroNodeSettings",
|
||||
MoneroNodeIsRunning = "Haveno.MoneroNodeIsRunning",
|
||||
MoneroRemoteNodes = "Haveno.MoneroRemoteNodes",
|
||||
|
||||
SyncStatus = "Haveno.SyncStatus",
|
||||
|
||||
StorageAccountInfo = "Storage.AccountInfo",
|
||||
|
27
packages/renderer/src/hooks/haveno/useIsMoneroNodeRunning.ts
Normal file
27
packages/renderer/src/hooks/haveno/useIsMoneroNodeRunning.ts
Normal file
@ -0,0 +1,27 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { useQuery } from "react-query";
|
||||
import { QueryKeys } from "@constants/query-keys";
|
||||
import { useHavenoClient } from "./useHavenoClient";
|
||||
|
||||
export function useIsMoneroNodeRunning() {
|
||||
const client = useHavenoClient();
|
||||
|
||||
return useQuery<boolean, Error>(QueryKeys.MoneroNodeIsRunning, () =>
|
||||
client.isMoneroNodeRunning()
|
||||
);
|
||||
}
|
31
packages/renderer/src/hooks/haveno/useMoneroNodeSettings.ts
Normal file
31
packages/renderer/src/hooks/haveno/useMoneroNodeSettings.ts
Normal file
@ -0,0 +1,31 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { QueryKeys } from "@constants/query-keys";
|
||||
import type { MoneroNodeSettings } from "haveno-ts";
|
||||
import { useQuery } from "react-query";
|
||||
import { useHavenoClient } from "./useHavenoClient";
|
||||
|
||||
export function useMoneroNodeSettings() {
|
||||
const client = useHavenoClient();
|
||||
|
||||
return useQuery<MoneroNodeSettings | undefined, Error>(
|
||||
QueryKeys.MoneroNodeSettings,
|
||||
async () => {
|
||||
return client.getMoneroNodeSettings();
|
||||
}
|
||||
);
|
||||
}
|
39
packages/renderer/src/hooks/haveno/useMoneroRemoteNodes.ts
Normal file
39
packages/renderer/src/hooks/haveno/useMoneroRemoteNodes.ts
Normal file
@ -0,0 +1,39 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { useQuery } from "react-query";
|
||||
import { QueryKeys } from "@constants/query-keys";
|
||||
// import { useHavenoClient } from "./useHavenoClient";
|
||||
|
||||
interface MoneroRemoteNodes {
|
||||
title: string;
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
export function useMoneroRemoteNodes() {
|
||||
// const client = useHavenoClient();
|
||||
|
||||
return useQuery<MoneroRemoteNodes[], Error>(
|
||||
QueryKeys.MoneroRemoteNodes,
|
||||
async () => {
|
||||
return Promise.resolve([
|
||||
{ title: "node.moneroworldcom:18089", isActive: true },
|
||||
{ title: "node.xmr.pt:18081", isActive: true },
|
||||
{ title: "node.monero.net:18081", isActive: true },
|
||||
]);
|
||||
}
|
||||
);
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { QueryKeys } from "@constants/query-keys";
|
||||
import { useHavenoClient } from "./useHavenoClient";
|
||||
|
||||
interface SetMeneroNodeSettingsVariables {
|
||||
blockchainPath?: string;
|
||||
bootstrapUrl?: string;
|
||||
startupFlags?: Array<string>;
|
||||
}
|
||||
|
||||
export function useSetMoneroNodeSettings() {
|
||||
const queryClient = useQueryClient();
|
||||
const client = useHavenoClient();
|
||||
|
||||
return useMutation(
|
||||
async (data: SetMeneroNodeSettingsVariables) => {
|
||||
const nodeSettings = await client.getMoneroNodeSettings();
|
||||
|
||||
data.blockchainPath &&
|
||||
nodeSettings?.setBlockchainPath(data.blockchainPath);
|
||||
data.startupFlags && nodeSettings?.setStartupFlagsList(data.startupFlags);
|
||||
data.bootstrapUrl && nodeSettings?.setBootstrapUrl(data.bootstrapUrl);
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(QueryKeys.MoneroNodeSettings);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
34
packages/renderer/src/hooks/haveno/useStartMoneroNode.ts
Normal file
34
packages/renderer/src/hooks/haveno/useStartMoneroNode.ts
Normal file
@ -0,0 +1,34 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { QueryKeys } from "@constants/query-keys";
|
||||
import type { MoneroNodeSettings } from "haveno-ts";
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { useHavenoClient } from "./useHavenoClient";
|
||||
|
||||
export function useStartMoneroNode() {
|
||||
const client = useHavenoClient();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<void, Error, MoneroNodeSettings>(
|
||||
(data: MoneroNodeSettings) => client.startMoneroNode(data),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(QueryKeys.MoneroNodeIsRunning);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
30
packages/renderer/src/hooks/haveno/useStopMoneroNode.ts
Normal file
30
packages/renderer/src/hooks/haveno/useStopMoneroNode.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { QueryKeys } from "@constants/query-keys";
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { useHavenoClient } from "./useHavenoClient";
|
||||
|
||||
export function useStopMoneroNode() {
|
||||
const queryClient = useQueryClient();
|
||||
const client = useHavenoClient();
|
||||
|
||||
return useMutation(() => client.stopMoneroNode(), {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(QueryKeys.MoneroNodeIsRunning);
|
||||
},
|
||||
});
|
||||
}
|
@ -14,28 +14,70 @@
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { Box, Stack, Grid, createStyles } from "@mantine/core";
|
||||
import { useForm } from "@mantine/form";
|
||||
import { Box, Stack, Grid, Group } from "@mantine/core";
|
||||
import { joiResolver, useForm } from "@mantine/form";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { showNotification } from "@mantine/notifications";
|
||||
import { Button } from "@atoms/Buttons";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { LangKeys } from "@constants/lang";
|
||||
import { TextInput } from "@atoms/TextInput";
|
||||
import { useMoneroNodeSettings } from "@hooks/haveno/useMoneroNodeSettings";
|
||||
import { useSetMoneroNodeSettings } from "@hooks/haveno/useSetMoneroNodeSettings";
|
||||
import { NodeLocalStopDeamon } from "./NodeLocalStopDeamon";
|
||||
import type { NodeLocalFormValues } from "./_hooks";
|
||||
import { useNodeLocalFormValidation } from "./_hooks";
|
||||
import { transformSettingsRequestToForm } from "./_utils";
|
||||
|
||||
export function NodeLocalForm() {
|
||||
const form = useForm({
|
||||
const { data: nodeSettings } = useMoneroNodeSettings();
|
||||
const { mutateAsync: updateNodeSettings } = useSetMoneroNodeSettings();
|
||||
const intl = useIntl();
|
||||
|
||||
const validation = useNodeLocalFormValidation();
|
||||
|
||||
const form = useForm<NodeLocalFormValues>({
|
||||
initialValues: {
|
||||
blockchainLocation: "",
|
||||
startupFlags: "",
|
||||
deamonAddress: "",
|
||||
port: "",
|
||||
...(nodeSettings
|
||||
? transformSettingsRequestToForm(nodeSettings.toObject())
|
||||
: {}),
|
||||
},
|
||||
validate: joiResolver(validation),
|
||||
});
|
||||
|
||||
const handleFormSubmit = (values: NodeLocalFormValues) => {
|
||||
updateNodeSettings({
|
||||
blockchainPath: values.blockchainLocation,
|
||||
startupFlags: values.startupFlags.split(", "),
|
||||
bootstrapUrl: `${values.deamonAddress}:${values.port}`,
|
||||
})
|
||||
.then(() => {
|
||||
showNotification({
|
||||
color: "green",
|
||||
message: intl.formatMessage({
|
||||
id: LangKeys.AccountNodeLocalSaveNotification,
|
||||
defaultMessage: "Local node settings updated successfully",
|
||||
}),
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.dir(err);
|
||||
showNotification({
|
||||
color: "red",
|
||||
message: err.message,
|
||||
title: "Something went wrong",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<NodeLocalStopDeamon />
|
||||
|
||||
<form onSubmit={form.onSubmit((values) => console.log(values))}>
|
||||
<form onSubmit={form.onSubmit(handleFormSubmit)}>
|
||||
<Stack spacing="lg">
|
||||
<TextInput
|
||||
id="blockchainLocation"
|
||||
@ -48,7 +90,7 @@ export function NodeLocalForm() {
|
||||
{...form.getInputProps("blockchainLocation")}
|
||||
/>
|
||||
<TextInput
|
||||
id="deamonFlags"
|
||||
id="startupFlags"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id={LangKeys.AccountNodeFieldDeamonFlags}
|
||||
@ -67,6 +109,7 @@ export function NodeLocalForm() {
|
||||
defaultMessage="Deamon Address"
|
||||
/>
|
||||
}
|
||||
required
|
||||
{...form.getInputProps("deamonAddress")}
|
||||
/>
|
||||
</Grid.Col>
|
||||
@ -79,33 +122,19 @@ export function NodeLocalForm() {
|
||||
defaultMessage="Port"
|
||||
/>
|
||||
}
|
||||
required
|
||||
{...form.getInputProps("port")}
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
<Group position="right" mt="md">
|
||||
<Button size="md" type="submit">
|
||||
<FormattedMessage id={LangKeys.Save} defaultMessage="Save" />
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function NodeLocalStopDeamon() {
|
||||
const { classes } = useStyles();
|
||||
|
||||
return (
|
||||
<div className={classes.actions}>
|
||||
<Button flavor="neutral">
|
||||
<FormattedMessage
|
||||
id={LangKeys.AccountNodeStopDeamon}
|
||||
defaultMessage="Stop deamon"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
actions: {
|
||||
marginBottom: theme.spacing.xl,
|
||||
},
|
||||
}));
|
||||
|
@ -0,0 +1,112 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { createStyles } from "@mantine/core";
|
||||
import { showNotification } from "@mantine/notifications";
|
||||
import { Button } from "@atoms/Buttons";
|
||||
import { LangKeys } from "@constants/lang";
|
||||
import { useMoneroNodeSettings } from "@hooks/haveno/useMoneroNodeSettings";
|
||||
import { useStopMoneroNode } from "@hooks/haveno/useStopMoneroNode";
|
||||
import { useIsMoneroNodeRunning } from "@hooks/haveno/useIsMoneroNodeRunning";
|
||||
import { useStartMoneroNode } from "@hooks/haveno/useStartMoneroNode";
|
||||
|
||||
export function NodeLocalStopDeamon() {
|
||||
const { classes } = useStyles();
|
||||
const intl = useIntl();
|
||||
|
||||
const { mutateAsync: stopMoneroNode } = useStopMoneroNode();
|
||||
const { data: isMoneroNodeRunning } = useIsMoneroNodeRunning();
|
||||
const { mutateAsync: startMoneroNode } = useStartMoneroNode();
|
||||
const { isLoading: isNodeSettingsLoading, data: nodeSettings } =
|
||||
useMoneroNodeSettings();
|
||||
|
||||
// handle the stop button click.
|
||||
const handleStopBtnClick = () => {
|
||||
stopMoneroNode()
|
||||
.then(() => {
|
||||
showNotification({
|
||||
color: "green",
|
||||
message: intl.formatMessage({
|
||||
id: LangKeys.AccountNodeDeamonStoppedNotif,
|
||||
defaultMessage: "Deamon stopped successfully",
|
||||
}),
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.dir(err);
|
||||
showNotification({
|
||||
color: "red",
|
||||
message: err.message,
|
||||
title: "Something went wrong",
|
||||
});
|
||||
});
|
||||
};
|
||||
// Handle the start button click.
|
||||
const handleStartBtnClick = () => {
|
||||
if (!nodeSettings) {
|
||||
return;
|
||||
}
|
||||
startMoneroNode(nodeSettings)
|
||||
.then(() => {
|
||||
showNotification({
|
||||
color: "green",
|
||||
message: intl.formatMessage({
|
||||
id: LangKeys.AccountNodeDeamonStartedNotif,
|
||||
defaultMessage: "Deamon started successfully",
|
||||
}),
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.dir(err);
|
||||
showNotification({
|
||||
color: "red",
|
||||
message: err.message,
|
||||
title: "Something went wrong",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classes.actions}>
|
||||
{isMoneroNodeRunning ? (
|
||||
<Button flavor="neutral" onClick={handleStopBtnClick}>
|
||||
<FormattedMessage
|
||||
id={LangKeys.AccountNodeStopDeamon}
|
||||
defaultMessage="Stop deamon"
|
||||
/>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
flavor="neutral"
|
||||
onClick={handleStartBtnClick}
|
||||
disabled={Boolean(isNodeSettingsLoading || !nodeSettings)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id={LangKeys.AccountNodeStopDeamon}
|
||||
defaultMessage="Start deamon"
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
actions: {
|
||||
marginBottom: theme.spacing.xl,
|
||||
},
|
||||
}));
|
@ -15,23 +15,26 @@
|
||||
// =============================================================================
|
||||
|
||||
import { Stack, createStyles, Group } from "@mantine/core";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { Button } from "@atoms/Buttons";
|
||||
import { NodeStatus, NodeStatusType } from "@atoms/NodeStatus";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { LangKeys } from "@constants/lang";
|
||||
import { useMoneroRemoteNodes } from "@hooks/haveno/useMoneroRemoteNodes";
|
||||
|
||||
export function NodeRemoteStatus() {
|
||||
const { data: remoteNodes } = useMoneroRemoteNodes();
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<NodeStatus
|
||||
title="node.moneroworldcom:18089"
|
||||
status={NodeStatusType.Active}
|
||||
/>
|
||||
<NodeStatus title="node.xmr.pt:18081" status={NodeStatusType.Inactive} />
|
||||
<NodeStatus
|
||||
title="node.monero.net:18081"
|
||||
status={NodeStatusType.Active}
|
||||
/>
|
||||
{remoteNodes?.map((node) => (
|
||||
<NodeStatus
|
||||
key={node.title}
|
||||
title={node.title}
|
||||
status={
|
||||
node.isActive ? NodeStatusType.Active : NodeStatusType.Inactive
|
||||
}
|
||||
/>
|
||||
))}
|
||||
<AddNewNodeButton />
|
||||
|
||||
<Group position="right" mt="sm">
|
||||
|
@ -0,0 +1,52 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import { BodyText } from "@atoms/Typography";
|
||||
import { useMoneroNodeSettings } from "@hooks/haveno/useMoneroNodeSettings";
|
||||
import { useIsMoneroNodeRunning } from "@hooks/haveno/useIsMoneroNodeRunning";
|
||||
import { useMoneroRemoteNodes } from "@hooks/haveno/useMoneroRemoteNodes";
|
||||
|
||||
interface NodeSettingsBootProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function LocalNodeSettingsBoot({ children }: NodeSettingsBootProps) {
|
||||
const { isLoading: isNodeSettingsLoading } = useMoneroNodeSettings();
|
||||
const { isLoading: isMoneroNodeIsLoading } = useIsMoneroNodeRunning();
|
||||
|
||||
return isNodeSettingsLoading || isMoneroNodeIsLoading ? (
|
||||
<BodyText>Loading settings...</BodyText>
|
||||
) : (
|
||||
<>{children}</>
|
||||
);
|
||||
}
|
||||
|
||||
interface RemoteNodeSettingsBootProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function RemoteNodeSettingsBoot({
|
||||
children,
|
||||
}: RemoteNodeSettingsBootProps) {
|
||||
const { isLoading: isMoneroRemoteLoading } = useMoneroRemoteNodes();
|
||||
|
||||
return isMoneroRemoteLoading ? (
|
||||
<BodyText>Loading settings...</BodyText>
|
||||
) : (
|
||||
<>{children}</>
|
||||
);
|
||||
}
|
@ -22,6 +22,10 @@ import { ReactComponent as CloudIcon } from "@assets/setting-cloud.svg";
|
||||
import { ReactComponent as ServerIcon } from "@assets/setting-server.svg";
|
||||
import { NodeLocalForm } from "./NodeLocalForm";
|
||||
import { NodeRemoteStatus } from "./NodeRemoteStatus";
|
||||
import {
|
||||
LocalNodeSettingsBoot,
|
||||
RemoteNodeSettingsBoot,
|
||||
} from "./NodeSettingsBoot";
|
||||
|
||||
export function NodeSettingsSwitch() {
|
||||
const { classes } = useStyles();
|
||||
@ -43,7 +47,9 @@ export function NodeSettingsSwitch() {
|
||||
}
|
||||
icon={<ServerIcon width={32} height={62} />}
|
||||
>
|
||||
<NodeLocalForm />
|
||||
<LocalNodeSettingsBoot>
|
||||
<NodeLocalForm />
|
||||
</LocalNodeSettingsBoot>
|
||||
</NodeConnectSwitch.Method>
|
||||
|
||||
<NodeConnectSwitch.Method
|
||||
@ -56,7 +62,9 @@ export function NodeSettingsSwitch() {
|
||||
}
|
||||
icon={<CloudIcon width={58} height={54} />}
|
||||
>
|
||||
<NodeRemoteStatus />
|
||||
<RemoteNodeSettingsBoot>
|
||||
<NodeRemoteStatus />
|
||||
</RemoteNodeSettingsBoot>
|
||||
</NodeConnectSwitch.Method>
|
||||
</NodeConnectSwitch>
|
||||
);
|
||||
|
33
packages/renderer/src/pages/Account/NodeSettings/_hooks.ts
Normal file
33
packages/renderer/src/pages/Account/NodeSettings/_hooks.ts
Normal file
@ -0,0 +1,33 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import * as Joi from "joi";
|
||||
|
||||
export interface NodeLocalFormValues {
|
||||
blockchainLocation: string;
|
||||
startupFlags: string;
|
||||
deamonAddress: string;
|
||||
port: string;
|
||||
}
|
||||
|
||||
export function useNodeLocalFormValidation() {
|
||||
return Joi.object<NodeLocalFormValues>({
|
||||
blockchainLocation: Joi.string().empty("").uri({ relativeOnly: true }),
|
||||
startupFlags: Joi.string().empty(""),
|
||||
deamonAddress: Joi.string().uri({ allowRelative: false }),
|
||||
port: Joi.number().port(),
|
||||
});
|
||||
}
|
55
packages/renderer/src/pages/Account/NodeSettings/_utils.ts
Normal file
55
packages/renderer/src/pages/Account/NodeSettings/_utils.ts
Normal file
@ -0,0 +1,55 @@
|
||||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
|
||||
import type { MoneroNodeSettings } from "haveno-ts";
|
||||
import type { NodeLocalFormValues } from "./_hooks";
|
||||
|
||||
/**
|
||||
* Transformes the settings request values to form.
|
||||
* @param {MoneroNodeSettings.AsObject} nodeSettings
|
||||
* @returns {NodeLocalFormValues}
|
||||
*/
|
||||
export function transformSettingsRequestToForm(
|
||||
nodeSettings: MoneroNodeSettings.AsObject
|
||||
): NodeLocalFormValues {
|
||||
return {
|
||||
blockchainLocation: nodeSettings?.blockchainPath || "",
|
||||
startupFlags: nodeSettings?.startupFlagsList.join(", ") || "",
|
||||
deamonAddress: transfromBootstrapUrl(nodeSettings?.bootstrapUrl || ""),
|
||||
port: transformPort(nodeSettings?.bootstrapUrl || ""),
|
||||
};
|
||||
}
|
||||
|
||||
function transformPort(urlAsString: string) {
|
||||
try {
|
||||
const url = new URL(urlAsString);
|
||||
return url.port;
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function transfromBootstrapUrl(urlAsString: string) {
|
||||
try {
|
||||
const url = new URL(urlAsString);
|
||||
|
||||
// Remove the port from url.
|
||||
url.port = "";
|
||||
return url.href;
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user