Skip to content

Commit

Permalink
pick a federation on setup
Browse files Browse the repository at this point in the history
  • Loading branch information
futurepaul committed Apr 12, 2024
1 parent 936f66f commit 11e0b86
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 73 deletions.
10 changes: 7 additions & 3 deletions e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ export async function loadHome(page: Page) {

await page.locator("button:has-text('Skip for now')").click();

await page.getByText("Pick a Federation").waitFor();

await page.locator("button:has-text('Skip for now')").click();

await page.locator(`button:has-text('Confirm')`).click();

// Should have a balance up top now
await page.locator(`text=0 sats`).first();
// Status light should be ready
await page.locator(`title="READY"`).first();
await page.locator(`text=0 sats`).first().waitFor();
}

export async function visitSettings(page: Page) {
Expand Down
14 changes: 10 additions & 4 deletions public/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -551,13 +551,14 @@
"remove": "Remove",
"expires": "Expires",
"federation_id": "Federation ID",
"description": "Mutiny has experimental support for the Fedimint protocol. Store funds in a federation at your own risk!",
"learn_more": "Learn more about Fedimint.",
"description": "Federations are bitcoin-based networks that make it cheaper, quicker, and easier to use bitcoin.",
"learn_more": "Learn more",
"discover": "Discover Federations",
"manual": "Invite Code",
"created_at": "Created At",
"recommended_by": "Recommended By",
"already_in_fed": "You're already in a federation!"
"already_in_fed": "You're already in a federation!",
"descriptionpart2": "Each one is ran by a group of different inviduals or companies. Discover one that you or your friends might trust below."
},
"gift": {
"give_sats_link": "Give sats as a gift",
Expand Down Expand Up @@ -743,13 +744,18 @@
},
"setup": {
"new_profile": {
"description": "Mutiny makes payments social."
"description": "Mutiny makes payments social.",
"title": "Create your profile"
},
"skip": "Skip for now",
"import_profile": "Import existing nostr profile",
"import": {
"title": "Import nostr profile",
"description": "Login with an existing nostr account."
},
"federation": {
"pick": "Pick a federation",
"skip_confirm": "You'll need to pay chain and channel fees to use Mutiny, and miss out on advanced features such as lightning address. You can change your mind later in the settings."
}
}
}
4 changes: 2 additions & 2 deletions public/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,8 @@
"remove": "Eliminar",
"expires": "Expira",
"federation_id": "ID federación",
"description": "Mutiny tiene soporte experimental para el protocolo Fedimint. ¡Almacene fondos en una federación bajo su propio riesgo!",
"learn_more": "Aprenda más sobre Fedimint.",
"description": "",
"learn_more": "Aprenda más",
"created_at": "Creado En",
"recommended_by": "Recomendado por"
},
Expand Down
8 changes: 6 additions & 2 deletions src/components/ImportNsecForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { createSignal, Show } from "solid-js";
import { Button, InfoBox, SimpleInput } from "~/components";
import { useMegaStore } from "~/state/megaStore";

export function ImportNsecForm() {
export function ImportNsecForm(props: { setup?: boolean }) {
const [state, _actions] = useMegaStore();
const navigate = useNavigate();
const [nsec, setNsec] = createSignal("");
Expand All @@ -29,7 +29,11 @@ export function ImportNsecForm() {
undefined
);
console.log("Changed to new npub: ", new_npub);
navigate("/");
if (props.setup) {
navigate("/addfederation");
} else {
navigate("/");
}
} catch (e) {
console.error(e);
setError("Invalid nsec");
Expand Down
4 changes: 3 additions & 1 deletion src/components/layout/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ export const Button: ParentComponent<ButtonProps> = (props) => {
<button
{...attrs}
disabled={props.disabled || props.loading}
class="rounded-xl p-3 font-semibold transition active:-mb-[2px] active:mt-[2px] disabled:bg-neutral-400/10 disabled:text-white/20 disabled:shadow-inner-button-disabled"
class="rounded-xl p-3 font-semibold transition active:-mb-[2px] active:mt-[2px] "
classList={{
"disabled:bg-neutral-400/10 disabled:text-white/20 disabled:shadow-inner-button-disabled":
local.intent !== "text",
"bg-white text-black": local.intent === "active",
"bg-m-grey-800 text-white shadow-inner-button text-shadow-button":
!local.intent || local.intent === "inactive",
Expand Down
9 changes: 8 additions & 1 deletion src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ import {
Servers,
Settings
} from "~/routes/settings";
import { ImportProfile, NewProfile, Setup, SetupRestore } from "~/routes/setup";
import {
AddFederation,
ImportProfile,
NewProfile,
Setup,
SetupRestore
} from "~/routes/setup";
import { Provider as MegaStoreProvider, useMegaStore } from "~/state/megaStore";

function GlobalListeners() {
Expand Down Expand Up @@ -159,6 +165,7 @@ export function Router() {
<Route path="/" component={Main} />
<Route path="/setup" component={Setup} />
<Route path="/setup/restore" component={SetupRestore} />
<Route path="/addfederation" component={AddFederation} />
<Route path="/newprofile" component={NewProfile} />
<Route path="/editprofile" component={EditProfile} />
<Route path="/importprofile" component={ImportProfile} />
Expand Down
138 changes: 81 additions & 57 deletions src/routes/settings/ManageFederations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
SubmitHandler
} from "@modular-forms/solid";
import { FederationBalance, TagItem } from "@mutinywallet/mutiny-wasm";
import { A, useSearchParams } from "@solidjs/router";
import { A, useNavigate, useSearchParams } from "@solidjs/router";
import { BadgeCheck, Scan } from "lucide-solid";
import {
createResource,
Expand All @@ -26,12 +26,13 @@ import {
Button,
ConfirmDialog,
DefaultMain,
ExternalLink,
FancyCard,
InfoBox,
KeyValue,
LabelCircle,
LargeHeader,
LoadingSpinner,
LoadingShimmer,
MediumHeader,
MiniStringShower,
MutinyWalletGuard,
Expand Down Expand Up @@ -81,9 +82,13 @@ type RefetchType = (
| null
| undefined;

function AddFederationForm(props: { refetch?: RefetchType }) {
export function AddFederationForm(props: {
refetch?: RefetchType;
setup?: boolean;
}) {
const i18n = useI18n();
const [state, actions] = useMegaStore();
const navigate = useNavigate();
const [error, setError] = createSignal<Error>();
const [success, setSuccess] = createSignal("");

Expand Down Expand Up @@ -162,6 +167,9 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
await props.refetch();
}
reset(feedbackForm);
if (props.setup) {
navigate("/");
}
} catch (e) {
console.error("Error submitting federation:", e);
setError(eify(e));
Expand All @@ -171,56 +179,61 @@ function AddFederationForm(props: { refetch?: RefetchType }) {

return (
<>
<MediumHeader>
{i18n.t("settings.manage_federations.manual")}
</MediumHeader>
<Form onSubmit={handleSubmit}>
<VStack>
<Field
name="federation_code"
validate={[
required(
i18n.t(
"settings.manage_federations.federation_code_required"
<Show when={!props.setup}>
<MediumHeader>
{i18n.t("settings.manage_federations.manual")}
</MediumHeader>
<Form onSubmit={handleSubmit}>
<VStack>
<Field
name="federation_code"
validate={[
required(
i18n.t(
"settings.manage_federations.federation_code_required"
)
)
)
]}
>
{(field, props) => (
<TextField
{...props}
{...field}
error={field.error}
placeholder="fed11..."
required
/>
)}
</Field>
<Button
loading={feedbackForm.submitting}
disabled={feedbackForm.invalid || !feedbackForm.dirty}
intent="blue"
type="submit"
>
{i18n.t("settings.manage_federations.add")}
</Button>
<Show when={error()}>
<InfoBox accent="red">{error()?.message}</InfoBox>
</Show>
<Show when={success()}>
<InfoBox accent="green">{success()}</InfoBox>
</Show>
</VStack>
</Form>
<MediumHeader>
{i18n.t("settings.manage_federations.discover")}
</MediumHeader>
]}
>
{(field, props) => (
<TextField
{...props}
{...field}
error={field.error}
placeholder="fed11..."
required
/>
)}
</Field>
<Button
loading={feedbackForm.submitting}
disabled={
feedbackForm.invalid || !feedbackForm.dirty
}
intent="blue"
type="submit"
>
{i18n.t("settings.manage_federations.add")}
</Button>
<Show when={error()}>
<InfoBox accent="red">{error()?.message}</InfoBox>
</Show>
<Show when={success()}>
<InfoBox accent="green">{success()}</InfoBox>
</Show>
</VStack>
</Form>
<MediumHeader>
{i18n.t("settings.manage_federations.discover")}
</MediumHeader>
</Show>

<Suspense>
<Switch>
<Match when={federations.loading}>
<div class="flex flex-col items-center justify-center">
<LoadingSpinner wide />
</div>
<FancyCard>
<LoadingShimmer />
</FancyCard>
</Match>
<Match when={federations.latest}>
<For each={federations()}>
Expand All @@ -247,13 +260,17 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
</Show>
</div>
</div>
<KeyValue
key={i18n.t(
"settings.manage_federations.federation_id"
)}
>
<MiniStringShower text={fed.id} />
</KeyValue>
<Show when={!props.setup}>
<KeyValue
key={i18n.t(
"settings.manage_federations.federation_id"
)}
>
<MiniStringShower
text={fed.id}
/>
</KeyValue>
</Show>
<Show when={fed.created_at}>
<KeyValue
key={i18n.t(
Expand Down Expand Up @@ -517,13 +534,20 @@ export function ManageFederations() {
</A>{" "}
</Show>
</div>
{/* <BackLink href="/settings" title={i18n.t("settings.header")} /> */}
<LargeHeader>
{i18n.t("settings.manage_federations.title")}
</LargeHeader>
<NiceP>
{i18n.t("settings.manage_federations.description")}{" "}
</NiceP>
<NiceP>
{i18n.t("settings.manage_federations.descriptionpart2")}{" "}
</NiceP>
<NiceP>
<ExternalLink href="https://fedimint.org/docs/intro">
{i18n.t("settings.manage_federations.learn_more")}
</ExternalLink>
</NiceP>
<Suspense>
<Show when={!state.federations?.length}>
<AddFederationForm refetch={refetch} />
Expand Down
65 changes: 65 additions & 0 deletions src/routes/setup/AddFederation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useNavigate } from "@solidjs/router";
import { createSignal, Suspense } from "solid-js";

import {
Button,
ConfirmDialog,
DefaultMain,
ExternalLink,
MutinyWalletGuard,
VStack
} from "~/components";
import { useI18n } from "~/i18n/context";

import { AddFederationForm } from "../settings";

export function AddFederation() {
const i18n = useI18n();
const navigate = useNavigate();

const [confirmOpen, setConfirmOpen] = createSignal(false);

async function handleSkip() {
navigate("/");
}

return (
<MutinyWalletGuard>
<DefaultMain>
<div class="mx-auto flex max-w-[20rem] flex-col items-center gap-4 py-4">
<h1 class="text-3xl font-semibold">
{i18n.t("setup.federation.pick")}
</h1>
<p class="text-pretty text-center text-xl font-light text-neutral-200">
{i18n.t("settings.manage_federations.description")}
</p>
<p class="text-pretty text-center text-xl font-light text-neutral-200">
{i18n.t("settings.manage_federations.descriptionpart2")}
</p>

<Button onClick={() => setConfirmOpen(true)} intent="text">
{i18n.t("setup.skip")}
</Button>
<ConfirmDialog
open={confirmOpen()}
loading={false}
onConfirm={handleSkip}
onCancel={() => setConfirmOpen(false)}
>
{i18n.t("setup.federation.skip_confirm")}
</ConfirmDialog>
<VStack>
<Suspense>
<AddFederationForm setup />
</Suspense>
</VStack>
<p class="text-pretty text-center text-xl font-light text-neutral-200">
<ExternalLink href="https://fedimint.org/docs/intro">
{i18n.t("settings.manage_federations.learn_more")}
</ExternalLink>
</p>
</div>
</DefaultMain>
</MutinyWalletGuard>
);
}
Loading

0 comments on commit 11e0b86

Please sign in to comment.