Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new onboarding #2989

Merged
merged 14 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions src/app/components/ConnectorForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function ConnectorForm({
)}
{image && (
<>
<div className="w-full mb-6">
<div className="w-96 mb-6">
<img
src={image}
alt="Screenshot"
Expand All @@ -56,7 +56,7 @@ function ConnectorForm({

return (
<form onSubmit={onSubmit}>
<div className="max-w-xl mx-auto mt-6 relative bg-white dark:bg-surface-02dp p-7 shadow rounded-lg">
<div className="max-w-xl mx-auto mt-6 relative bg-white dark:bg-surface-02dp p-10 rounded-2xl border border-gray-200 darK:border-neutral-700">
pavanjoshi914 marked this conversation as resolved.
Show resolved Hide resolved
<div className="flex items-center mb-4">
{logo && <img src={logo} className="w-16 mr-4 rounded-lg" />}
{/*
Expand All @@ -70,28 +70,27 @@ function ConnectorForm({
title
)}
</div>
{media}
{description && (
<div className="text-gray-500 dark:text-white whitespace-pre-line">
<div className="text-gray-700 dark:text-white whitespace-pre-line mb-8">
pavanjoshi914 marked this conversation as resolved.
Show resolved Hide resolved
{typeof description === "string" ? (
<p className="mb-6">{description}</p>
) : (
description
)}
</div>
)}
{media}
<div>{children}</div>
</div>

<div className="my-6 flex justify-center">
<Button
type="submit"
label={submitLabel}
loading={submitLoading}
disabled={submitDisabled}
primary
className="w-64"
/>
<div className="mt-8 flex justify-center">
<Button
type="submit"
label={submitLabel}
loading={submitLoading}
disabled={submitDisabled}
primary
className="w-64"
/>
</div>
</div>
</form>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/ConnectorPath/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Props = {

function ConnectorPath({ title, icon, description, content, actions }: Props) {
return (
<div className="flex flex-col p-10 border border-neutral-200 dark:border-neutral-700 rounded-2xl bg-white dark:bg-surface-02dp">
<div className="flex flex-col p-10 border border-gray-200 dark:border-neutral-700 rounded-2xl bg-white dark:bg-surface-02dp">
<div className="flex flex-col sm:flex-row items-center mb-4 space-x-3">
{icon}
<h1 className="text-xl font-bold dark:text-white text-center">
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/LinkButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ type Props = {
export default function LinkButton({ to, title, logo }: Props) {
return (
<Link to={to}>
<div className="p-10 h-72 border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-surface-02dp text-center overflow-hidden rounded-lg hover:bg-gray-50 dark:hover:bg-neutral-800 transition duration-200 flex flex-col justify-center space-y-4">
<div className="p-10 h-72 border border-gray-200 dark:border-neutral-700 bg-white dark:bg-surface-02dp text-center overflow-hidden rounded-lg hover:bg-gray-50 dark:hover:bg-neutral-800 transition duration-200 flex flex-col justify-center space-y-4">
<div>
<img src={logo} alt="logo" className="inline rounded-3xl w-32" />
<img src={logo} alt="logo" className="inline rounded-3xl w-32 mb-6" />
</div>
<div>
<span className="block dark:text-white text-lg font-medium">
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/PasswordForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default function PasswordForm<

return (
<>
<div className="w-full">
<div className="w-full mt-8">
<TextField
autoFocus={autoFocus}
id="password"
Expand Down
27 changes: 19 additions & 8 deletions src/app/router/connectorRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import ChooseConnector from "@screens/connectors/ChooseConnector";
import ConnectBtcpay from "@screens/connectors/ConnectBtcpay";
import ConnectCitadel from "@screens/connectors/ConnectCitadel";
import ConnectEclair from "@screens/connectors/ConnectEclair";
import ConnectGaloy, { galoyUrls } from "@screens/connectors/ConnectGaloy";
Expand All @@ -14,6 +13,8 @@ import ConnectUmbrel from "@screens/connectors/ConnectUmbrel";
import { Route } from "react-router-dom";
import i18n from "~/i18n/i18nConfig";

import ConnectBtcpayCommando from "~/app/screens/connectors/ConnectBtcpayCommando";
import ConnectBtcpayLND from "~/app/screens/connectors/ConnectBtcpayLND";
import ConnectNWC from "~/app/screens/connectors/ConnectNWC";
import ConnectVoltage from "~/app/screens/connectors/ConnectVoltage";
import ConnectCommando from "../screens/connectors/ConnectCommando";
Expand Down Expand Up @@ -81,6 +82,18 @@ const connectorMap: { [key: string]: ConnectorRoute } = {
title: i18n.t("translation:choose_connector.umbrel_lightning_node.title"),
logo: lightning_node,
},
"btcpay-lnd": {
path: "lnd",
element: <ConnectBtcpayLND />,
title: i18n.t("translation:choose_connector.lnd.title"),
logo: lnd,
},
"btcpay-commando": {
path: "commando",
element: <ConnectBtcpayCommando />,
title: i18n.t("translation:choose_connector.commando.title"),
logo: core_ln,
},
"raspiblitz-lnd": {
path: "lnd",
element: <ConnectRaspiBlitz />,
Expand Down Expand Up @@ -153,12 +166,6 @@ const connectorMap: { [key: string]: ConnectorRoute } = {
title: i18n.t("translation:choose_connector.bitcoin_jungle.title"),
logo: galoyBitcoinJungle,
},
btcpay: {
path: "btcpay",
element: <ConnectBtcpay />,
title: i18n.t("translation:choose_connector.btcpay.title"),
logo: btcpay,
},
voltage: {
path: "voltage",
element: <ConnectVoltage />,
Expand Down Expand Up @@ -203,6 +210,10 @@ const distributionMap: { [key: string]: { logo: string; children: Route[] } } =
connectorMap["lnbits"],
],
},
btcpay: {
logo: btcpay,
children: [connectorMap["btcpay-lnd"], connectorMap["btcpay-commando"]],
},
umbrel: {
logo: umbrel,
children: [
Expand Down Expand Up @@ -250,7 +261,7 @@ function getConnectorRoutes(): ConnectorRoute[] {
connectorMap["lnbits"],
connectorMap["lnd-hub-go"],
connectorMap["eclair"],
connectorMap["btcpay"],
getDistribution("btcpay"),
connectorMap["voltage"],
connectorMap[galoyPaths.blink],
connectorMap[galoyPaths.bitcoinJungle],
Expand Down
53 changes: 30 additions & 23 deletions src/app/screens/Onboard/SetPassword/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Button from "@components/Button";
import PasswordForm from "@components/PasswordForm";
import {
PopiconsCircleExclamationLine,
PopiconsLockOpenLine,
} from "@popicons/react";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
Expand Down Expand Up @@ -33,48 +37,51 @@ export default function SetPassword() {
}

const unlockScreenshot = (
<img
src="assets/images/unlock_passcode.png"
alt="Unlock screen"
className="h-44"
/>
<img src="assets/images/unlock_passcode.png" alt="Unlock screen" />
);

return (
<form onSubmit={handleSubmit}>
<div className="max-w-xl shadow-lg rounded-xl mx-auto relative lg:flex lg:space-x-8 bg-white dark:bg-surface-02dp pt-10 pb-10 px-10">
<div className="max-w-xl rounded-2xl mx-auto relative lg:flex lg:space-x-8 bg-white dark:bg-surface-02dp pt-10 pb-10 px-10 border border-gray-200 dark:border-gray-700">
<div>
<h1 className="text-2xl font-bold dark:text-white max-sm:text-center">
<h1 className="text-2xl font-bold dark:text-white text-center">
{t("title")}
</h1>

<p className="text-gray-500 my-5 dark:text-gray-400">
{t("description")}
</p>
<div className="w-full flex justify-center short:hidden my-5">
<div className="w-full flex justify-center my-8 short:hidden">
{unlockScreenshot}
</div>

<div className="flex flex-row text-gray-500 my-4 dark:text-gray-400">
<PopiconsLockOpenLine className="w-6 h-6 mr-2"></PopiconsLockOpenLine>
{t("description1")}
</div>
<div className="flex flex-row text-gray-500 my-4 dark:text-gray-400">
<PopiconsCircleExclamationLine className="w-6 h-6 mr-2"></PopiconsCircleExclamationLine>
{t("description2")}
</div>

<div>
<PasswordForm
i18nKeyPrefix="welcome.set_password"
formData={formData}
setFormData={setFormData}
/>
</div>
<div className="mt-8 flex justify-center">
<Button
label={tCommon("actions.next")}
type="submit"
primary
disabled={
!formData.password ||
formData.password !== formData.passwordConfirmation
}
className="w-64"
/>
</div>
</div>
</div>
<div className="my-8 flex justify-center">
<Button
label={tCommon("actions.next")}
type="submit"
primary
disabled={
!formData.password ||
formData.password !== formData.passwordConfirmation
}
className="w-64"
/>
</div>
</form>
);
}
2 changes: 1 addition & 1 deletion src/app/screens/connectors/ChooseConnector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function ChooseConnector({
{connectorRoutes.map(({ path, title, logo }) => (
<div
key={path}
className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4 px-2"
className="w-full sm:w-1/2 md:w-1/3 lg:w-1/5 mb-4 px-2"
>
<LinkButton to={path} title={title} logo={logo} />
</div>
Expand Down
144 changes: 144 additions & 0 deletions src/app/screens/connectors/ConnectBtcpayCommando/index.tsx
pavanjoshi914 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import CompanionDownloadInfo from "@components/CompanionDownloadInfo";
import ConnectorForm from "@components/ConnectorForm";
import TextField from "@components/form/TextField";
import ConnectionErrorToast from "@components/toasts/ConnectionErrorToast";
import fetchAdapter from "@vespaiach/axios-fetch-adapter";
import axios from "axios";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import toast from "~/app/components/Toast";
import msg from "~/common/lib/msg";

import logo from "/static/assets/icons/btcpay.svg";

const initialFormData = {
url: "",
macaroon: "",
name: "",
};

export default function ConnectBtcpayCommando() {
const navigate = useNavigate();
const { t } = useTranslation("translation", {
keyPrefix: "choose_connector.btcpay_commando",
});
const [formData, setFormData] = useState(initialFormData);
const [loading, setLoading] = useState(false);
const [hasTorSupport, setHasTorSupport] = useState(false);

function getConfigUrl(data: string) {
const configUrl = data.trim().replace("config=", "");
try {
return new URL(configUrl);
} catch (e) {
return null;
}
}
async function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
const configUrl = getConfigUrl(event.target.value);
if (!configUrl) {
return;
}
const host = configUrl.host;
try {
const response = await axios.get<{
configurations: [{ uri: string; adminMacaroon: string }];
}>(configUrl.toString(), { adapter: fetchAdapter });

if (response.data.configurations[0].uri) {
setFormData({
url: response.data.configurations[0].uri,
macaroon: response.data.configurations[0].adminMacaroon,
name: host,
});
}
} catch (e) {
console.error(e);
toast.error(t("errors.connection_failed"));
}
}

function getConnectorType() {
if (formData.url.match(/\.onion/i) && !hasTorSupport) {
return "nativelnd";
}
// default to LND
return "lnd";
}

async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
setLoading(true);
const { url, macaroon, name } = formData;
const account = {
name: name || "LND",
config: {
macaroon,
url,
},
connector: getConnectorType(),
};

try {
let validation;
// TODO: for native connectors we currently skip the validation because it is too slow (booting up Tor etc.)
if (account.connector === "nativelnd") {
validation = { valid: true, error: "" };
} else {
validation = await msg.request("validateAccount", account);
}

if (validation.valid) {
const addResult = await msg.request("addAccount", account);
if (addResult.accountId) {
await msg.request("selectAccount", {
id: addResult.accountId,
});
navigate("/test-connection");
}
} else {
toast.error(
<ConnectionErrorToast message={validation.error as string} />
);
}
} catch (e) {
console.error(e);
let message = "";
if (e instanceof Error) {
message += `${e.message}`;
}
toast.error(<ConnectionErrorToast message={message} />);
}
setLoading(false);
}

return (
<ConnectorForm
title={t("page.title")}
description={t("page.instructions")}
logo={logo}
submitLoading={loading}
submitDisabled={formData.url === "" || formData.macaroon === ""}
onSubmit={handleSubmit}
>
<TextField
id="btcpay-config"
label={t("config.label")}
placeholder={t("config.placeholder")}
onChange={handleChange}
required
autoFocus={true}
/>
{formData.url.match(/\.onion/i) && (
<div className="mt-6">
<CompanionDownloadInfo
hasTorCallback={(hasTor: boolean) => {
setHasTorSupport(hasTor);
}}
/>
</div>
)}
</ConnectorForm>
);
}
Loading
Loading