mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2025-12-19 07:14:22 +01:00
format project with plugins
This commit is contained in:
@@ -1,24 +1,25 @@
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import {
|
||||
createEffect,
|
||||
createResource,
|
||||
createSignal,
|
||||
For,
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
createEffect,
|
||||
createResource,
|
||||
createSignal
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { A } from "solid-start";
|
||||
import { createDeepSignal } from "~/utils/deepSignal";
|
||||
|
||||
import {
|
||||
NiceP,
|
||||
DetailsIdModal,
|
||||
LoadingShimmer,
|
||||
ActivityItem,
|
||||
HackActivityType
|
||||
DetailsIdModal,
|
||||
HackActivityType,
|
||||
LoadingShimmer,
|
||||
NiceP
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { createDeepSignal } from "~/utils/deepSignal";
|
||||
|
||||
export const THREE_COLUMNS =
|
||||
"grid grid-cols-[auto,1fr,auto] gap-4 py-2 px-2 border-b border-neutral-800 last:border-b-0";
|
||||
@@ -117,7 +118,7 @@ export function CombinedActivity(props: { limit?: number }) {
|
||||
</Show>
|
||||
<Switch>
|
||||
<Match when={activity.latest.length === 0}>
|
||||
<div class="w-full text-center pb-4">
|
||||
<div class="w-full pb-4 text-center">
|
||||
<NiceP>
|
||||
{i18n.t(
|
||||
"activity.receive_some_sats_to_get_started"
|
||||
@@ -151,7 +152,7 @@ export function CombinedActivity(props: { limit?: number }) {
|
||||
<Show when={props.limit && activity.latest.length > 0}>
|
||||
<A
|
||||
href="/activity"
|
||||
class="text-m-red active:text-m-red/80 font-semibold no-underline self-center"
|
||||
class="self-center font-semibold text-m-red no-underline active:text-m-red/80"
|
||||
>
|
||||
{i18n.t("activity.view_all")}
|
||||
</A>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Match, ParentComponent, Switch, createResource } from "solid-js";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { createResource, Match, ParentComponent, Switch } from "solid-js";
|
||||
|
||||
import bolt from "~/assets/icons/bolt.svg";
|
||||
import chain from "~/assets/icons/chain.svg";
|
||||
import off from "~/assets/icons/download-channel.svg";
|
||||
import shuffle from "~/assets/icons/shuffle.svg";
|
||||
import on from "~/assets/icons/upload-channel.svg";
|
||||
import off from "~/assets/icons/download-channel.svg";
|
||||
import { timeAgo } from "~/utils/prettyPrintTime";
|
||||
|
||||
import { generateGradient } from "~/utils/gradientHash";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { AmountFiat, AmountSats } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { generateGradient } from "~/utils/gradientHash";
|
||||
import { timeAgo } from "~/utils/prettyPrintTime";
|
||||
|
||||
export const ActivityAmount: ParentComponent<{
|
||||
amount: string;
|
||||
@@ -69,7 +69,7 @@ function LabelCircle(props: {
|
||||
|
||||
return (
|
||||
<div
|
||||
class="flex-none h-[3rem] w-[3rem] rounded-full bg-neutral-700 flex items-center justify-center text-3xl uppercase border-t border-b border-t-white/50 border-b-white/10"
|
||||
class="flex h-[3rem] w-[3rem] flex-none items-center justify-center rounded-full border-b border-t border-b-white/10 border-t-white/50 bg-neutral-700 text-3xl uppercase"
|
||||
style={{ background: bg() }}
|
||||
>
|
||||
<Switch>
|
||||
@@ -110,10 +110,10 @@ export function ActivityItem(props: {
|
||||
return (
|
||||
<div
|
||||
onClick={() => props.onClick && props.onClick()}
|
||||
class="grid grid-cols-[auto_minmax(0,_1fr)_minmax(0,_max-content)] pb-4 gap-4 border-b border-neutral-800 last:border-b-0"
|
||||
class="grid grid-cols-[auto_minmax(0,_1fr)_minmax(0,_max-content)] gap-4 border-b border-neutral-800 pb-4 last:border-b-0"
|
||||
classList={{ "cursor-pointer": !!props.onClick }}
|
||||
>
|
||||
<div class="flex gap-2 md:gap-4 items-center">
|
||||
<div class="flex items-center gap-2 md:gap-4">
|
||||
<div class="">
|
||||
<Switch>
|
||||
<Match when={props.kind === "Lightning"}>
|
||||
@@ -154,12 +154,12 @@ export function ActivityItem(props: {
|
||||
</span>{" "}
|
||||
</Match>
|
||||
<Match when={firstContact()?.name}>
|
||||
<span class="text-base font-semibold truncate">
|
||||
<span class="truncate text-base font-semibold">
|
||||
{firstContact()?.name}
|
||||
</span>
|
||||
</Match>
|
||||
<Match when={props.labels.length > 0}>
|
||||
<span class="text-base font-semibold truncate">
|
||||
<span class="truncate text-base font-semibold">
|
||||
{props.labels[0]}
|
||||
</span>
|
||||
</Match>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Show } from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { satsToUsd } from "~/utils/conversions";
|
||||
|
||||
import bolt from "~/assets/icons/bolt.svg";
|
||||
import chain from "~/assets/icons/chain.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { satsToUsd } from "~/utils/conversions";
|
||||
|
||||
function prettyPrintAmount(n?: number | bigint): string {
|
||||
if (!n || n.valueOf() === 0) {
|
||||
@@ -20,14 +21,14 @@ export function AmountSats(props: {
|
||||
}) {
|
||||
const i18n = useI18n();
|
||||
return (
|
||||
<div class="flex gap-2 items-center">
|
||||
<div class="flex items-center gap-2">
|
||||
<Show when={props.icon === "lightning"}>
|
||||
<img src={bolt} alt="lightning" class="h-[18px]" />
|
||||
</Show>
|
||||
<Show when={props.icon === "chain"}>
|
||||
<img src={chain} alt="chain" class="h-[18px]" />
|
||||
</Show>
|
||||
<h1 class="font-light text-right">
|
||||
<h1 class="text-right font-light">
|
||||
<Show when={props.icon === "plus"}>
|
||||
<span>+</span>
|
||||
</Show>
|
||||
@@ -37,7 +38,7 @@ export function AmountSats(props: {
|
||||
{props.loading ? "..." : prettyPrintAmount(props.amountSats)}
|
||||
|
||||
<span
|
||||
class="font-light text-base"
|
||||
class="text-base font-light"
|
||||
classList={{
|
||||
"text-sm": props.denominationSize === "sm",
|
||||
"text-lg": props.denominationSize === "lg",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Match, ParentComponent, Show, Switch, createMemo } from "solid-js";
|
||||
import { Card, VStack, AmountEditable } from "~/components";
|
||||
import { createMemo, Match, ParentComponent, Show, Switch } from "solid-js";
|
||||
|
||||
import { AmountEditable, Card, VStack } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { satsToUsd } from "~/utils/conversions";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
const noop = () => {
|
||||
// do nothing
|
||||
@@ -11,7 +12,7 @@ const noop = () => {
|
||||
const KeyValue: ParentComponent<{ key: string; gray?: boolean }> = (props) => {
|
||||
return (
|
||||
<div
|
||||
class="flex justify-between items-center"
|
||||
class="flex items-center justify-between"
|
||||
classList={{ "text-neutral-400": props.gray }}
|
||||
>
|
||||
<div class="font-semibold uppercase">{props.key}</div>
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import {
|
||||
For,
|
||||
ParentComponent,
|
||||
Show,
|
||||
createResource,
|
||||
createSignal,
|
||||
onMount,
|
||||
For,
|
||||
Match,
|
||||
onCleanup,
|
||||
Switch,
|
||||
Match
|
||||
onMount,
|
||||
ParentComponent,
|
||||
Show,
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { Button, InlineAmount, InfoBox, FeesModal } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { satsToUsd, usdToSats } from "~/utils/conversions";
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import pencil from "~/assets/icons/pencil.svg";
|
||||
import currencySwap from "~/assets/icons/currency-swap.svg";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useNavigate } from "solid-start";
|
||||
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import currencySwap from "~/assets/icons/currency-swap.svg";
|
||||
import pencil from "~/assets/icons/pencil.svg";
|
||||
import { Button, FeesModal, InfoBox, InlineAmount } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { satsToUsd, usdToSats } from "~/utils/conversions";
|
||||
|
||||
function fiatInputSanitizer(input: string): string {
|
||||
// Make sure only numbers and a single decimal point are allowed
|
||||
const numeric = input.replace(/[^0-9.]/g, "").replace(/(\..*)\./g, "$1");
|
||||
@@ -90,7 +91,7 @@ function SingleDigitButton(props: {
|
||||
fallback={<div />}
|
||||
>
|
||||
<button
|
||||
class="disabled:opacity-50 flex justify-center items-center p-2 rounded-lg md:hover:bg-white/10 active:bg-m-blue text-white text-4xl font-semi font-inter"
|
||||
class="font-semi font-inter flex items-center justify-center rounded-lg p-2 text-4xl text-white active:bg-m-blue disabled:opacity-50 md:hover:bg-white/10"
|
||||
onMouseDown={onHold}
|
||||
onMouseUp={endHold}
|
||||
onMouseLeave={endHold}
|
||||
@@ -108,7 +109,7 @@ function BigScalingText(props: { text: string; fiat: boolean }) {
|
||||
|
||||
return (
|
||||
<h1
|
||||
class="font-light px-2 text-center transition-transform ease-out duration-300 text-4xl"
|
||||
class="px-2 text-center text-4xl font-light transition-transform duration-300 ease-out"
|
||||
classList={{
|
||||
"scale-90": chars() >= 11,
|
||||
"scale-95": chars() === 10,
|
||||
@@ -136,7 +137,7 @@ function SmallSubtleAmount(props: { text: string; fiat: boolean }) {
|
||||
{props.fiat ? i18n.t("common.usd") : i18n.t("common.sats")}
|
||||
</span>
|
||||
<img
|
||||
class={"pl-[4px] pb-[4px] hover:cursor-pointer"}
|
||||
class={"pb-[4px] pl-[4px] hover:cursor-pointer"}
|
||||
src={currencySwap}
|
||||
height={24}
|
||||
width={24}
|
||||
@@ -438,7 +439,7 @@ export const AmountEditable: ParentComponent<{
|
||||
<Dialog.Root open={isOpen()}>
|
||||
<button
|
||||
onClick={() => setIsOpen(true)}
|
||||
class="px-4 py-2 rounded-xl border-2 border-m-blue flex gap-2 items-center"
|
||||
class="flex items-center gap-2 rounded-xl border-2 border-m-blue px-4 py-2"
|
||||
>
|
||||
<Show
|
||||
when={localSats() !== "0"}
|
||||
@@ -461,10 +462,10 @@ export const AmountEditable: ParentComponent<{
|
||||
onEscapeKeyDown={handleClose}
|
||||
>
|
||||
{/* TODO: figure out how to submit on enter */}
|
||||
<div class="w-full flex justify-end">
|
||||
<div class="flex w-full justify-end">
|
||||
<button
|
||||
onClick={handleClose}
|
||||
class="hover:bg-white/10 rounded-lg active:bg-m-blue w-8 h-8"
|
||||
class="h-8 w-8 rounded-lg hover:bg-white/10 active:bg-m-blue"
|
||||
>
|
||||
<img src={close} alt="Close" />
|
||||
</button>
|
||||
@@ -472,7 +473,7 @@ export const AmountEditable: ParentComponent<{
|
||||
{/* <form onSubmit={handleSubmit} class="text-black"> */}
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
class="opacity-0 absolute -z-10"
|
||||
class="absolute -z-10 opacity-0"
|
||||
>
|
||||
<input
|
||||
ref={(el) => (satsInputRef = el)}
|
||||
@@ -492,10 +493,10 @@ export const AmountEditable: ParentComponent<{
|
||||
/>
|
||||
</form>
|
||||
|
||||
<div class="flex flex-col flex-1 justify-around gap-2 max-w-[400px] mx-auto w-full">
|
||||
<div class="mx-auto flex w-full max-w-[400px] flex-1 flex-col justify-around gap-2">
|
||||
<div class="flex justify-center">
|
||||
<div
|
||||
class="p-4 flex flex-col gap-4 w-max items-center justify-center"
|
||||
class="flex w-max flex-col items-center justify-center gap-4 p-4"
|
||||
onClick={toggle}
|
||||
>
|
||||
<BigScalingText
|
||||
@@ -530,7 +531,7 @@ export const AmountEditable: ParentComponent<{
|
||||
</InfoBox>
|
||||
</Match>
|
||||
</Switch>
|
||||
<div class="flex justify-center gap-4 my-2">
|
||||
<div class="my-2 flex justify-center gap-4">
|
||||
<For
|
||||
each={
|
||||
mode() === "fiat"
|
||||
@@ -544,7 +545,7 @@ export const AmountEditable: ParentComponent<{
|
||||
setFixedAmount(amount.amount);
|
||||
focus();
|
||||
}}
|
||||
class="py-2 px-4 rounded-lg bg-white/10"
|
||||
class="rounded-lg bg-white/10 px-4 py-2"
|
||||
>
|
||||
{amount.label}
|
||||
</button>
|
||||
@@ -558,13 +559,13 @@ export const AmountEditable: ParentComponent<{
|
||||
);
|
||||
focus();
|
||||
}}
|
||||
class="py-2 px-4 rounded-lg bg-white/10"
|
||||
class="rounded-lg bg-white/10 px-4 py-2"
|
||||
>
|
||||
{i18n.t("receive.amount_editable.max")}
|
||||
</button>
|
||||
</Show>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 w-full flex-none">
|
||||
<div class="grid w-full flex-none grid-cols-3">
|
||||
<For each={CHARACTERS}>
|
||||
{(character) => (
|
||||
<SingleDigitButton
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
import {
|
||||
DefaultMain,
|
||||
SafeArea,
|
||||
VStack,
|
||||
Card,
|
||||
LoadingShimmer,
|
||||
BalanceBox,
|
||||
ReloadPrompt,
|
||||
NavBar,
|
||||
OnboardWarning,
|
||||
CombinedActivity,
|
||||
BetaWarningModal,
|
||||
PendingNwc,
|
||||
DecryptDialog,
|
||||
LoadingIndicator
|
||||
} from "~/components";
|
||||
import { A } from "solid-start";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Match, Show, Suspense, Switch } from "solid-js";
|
||||
import { A } from "solid-start";
|
||||
|
||||
import settings from "~/assets/icons/settings.svg";
|
||||
import pixelLogo from "~/assets/mutiny-pixel-logo.png";
|
||||
import plusLogo from "~/assets/mutiny-plus-logo.png";
|
||||
import { FeedbackLink } from "~/routes/Feedback";
|
||||
import {
|
||||
BalanceBox,
|
||||
BetaWarningModal,
|
||||
Card,
|
||||
CombinedActivity,
|
||||
DecryptDialog,
|
||||
DefaultMain,
|
||||
LoadingIndicator,
|
||||
LoadingShimmer,
|
||||
NavBar,
|
||||
OnboardWarning,
|
||||
PendingNwc,
|
||||
ReloadPrompt,
|
||||
SafeArea,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { FeedbackLink } from "~/routes/Feedback";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export function App() {
|
||||
const i18n = useI18n();
|
||||
@@ -31,7 +32,7 @@ export function App() {
|
||||
<SafeArea>
|
||||
<DefaultMain>
|
||||
<LoadingIndicator />
|
||||
<header class="w-full flex justify-between items-center mt-4 mb-2">
|
||||
<header class="mb-2 mt-4 flex w-full items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<Switch>
|
||||
<Match when={state.mutiny_plus}>
|
||||
@@ -57,13 +58,13 @@ export function App() {
|
||||
state.mutiny_wallet?.get_network() !== "bitcoin"
|
||||
}
|
||||
>
|
||||
<div class="box-border px-2 py-1 -my-1 text-white-400 bg-neutral-800 rounded text-xs uppercase w-fit">
|
||||
<div class="text-white-400 -my-1 box-border w-fit rounded bg-neutral-800 px-2 py-1 text-xs uppercase">
|
||||
{state.mutiny_wallet?.get_network()}
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
<A
|
||||
class="md:hidden p-2 hover:bg-white/5 rounded-lg active:bg-m-blue"
|
||||
class="rounded-lg p-2 hover:bg-white/5 active:bg-m-blue md:hidden"
|
||||
href="/settings"
|
||||
>
|
||||
<img src={settings} alt="Settings" class="h-6 w-6" />
|
||||
@@ -92,7 +93,7 @@ export function App() {
|
||||
</Suspense>
|
||||
</VStack>
|
||||
</Card>
|
||||
<div class="self-center mt-4">
|
||||
<div class="mt-4 self-center">
|
||||
<FeedbackLink />
|
||||
</div>
|
||||
</DefaultMain>
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
import { Match, Show, Switch } from "solid-js";
|
||||
import { A, useNavigate } from "solid-start";
|
||||
|
||||
import shuffle from "~/assets/icons/shuffle.svg";
|
||||
import {
|
||||
AmountFiat,
|
||||
AmountSats,
|
||||
Button,
|
||||
FancyCard,
|
||||
Indicator,
|
||||
AmountSats,
|
||||
AmountFiat,
|
||||
InfoBox
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { A, useNavigate } from "solid-start";
|
||||
import shuffle from "~/assets/icons/shuffle.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export function LoadingShimmer() {
|
||||
return (
|
||||
<div class="flex flex-col gap-2 animate-pulse">
|
||||
<div class="flex animate-pulse flex-col gap-2">
|
||||
<h1 class="text-4xl font-light">
|
||||
<div class="w-[12rem] rounded bg-neutral-700 h-[2.5rem]" />
|
||||
<div class="h-[2.5rem] w-[12rem] rounded bg-neutral-700" />
|
||||
</h1>
|
||||
<h2 class="text-xl font-light text-white/70">
|
||||
<div class="w-[8rem] rounded bg-neutral-700 h-[1.75rem]" />
|
||||
<div class="h-[1.75rem] w-[8rem] rounded bg-neutral-700" />
|
||||
</h2>
|
||||
</div>
|
||||
);
|
||||
@@ -99,7 +100,7 @@ export function BalanceBox(props: { loading?: boolean }) {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end gap-1 justify-between">
|
||||
<div class="flex flex-col items-end justify-between gap-1">
|
||||
<Show when={state.balance?.unconfirmed != 0n}>
|
||||
<Indicator>
|
||||
{i18n.t("common.pending")}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { ParentComponent, createSignal } from "solid-js";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { createSignal, ParentComponent } from "solid-js";
|
||||
|
||||
import {
|
||||
DIALOG_CONTENT,
|
||||
DIALOG_POSITIONER,
|
||||
OVERLAY,
|
||||
ModalCloseButton,
|
||||
OVERLAY,
|
||||
SmallHeader
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
|
||||
export function BetaWarningModal() {
|
||||
const i18n = useI18n();
|
||||
@@ -57,7 +58,7 @@ export const WarningModal: ParentComponent<{
|
||||
<Dialog.Overlay class={OVERLAY} />
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
<Dialog.Title class="flex justify-between mb-2 items-center">
|
||||
<Dialog.Title class="mb-2 flex items-center justify-between">
|
||||
<SmallHeader>{props.title}</SmallHeader>
|
||||
<Dialog.CloseButton>
|
||||
<ModalCloseButton />
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { Match, Switch, createSignal } from "solid-js";
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import { SubmitHandler } from "@modular-forms/solid";
|
||||
import { createSignal, Match, Switch } from "solid-js";
|
||||
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import {
|
||||
ContactFormValues,
|
||||
ContactForm,
|
||||
ContactFormValues,
|
||||
SmallHeader,
|
||||
TinyButton
|
||||
} from "~/components";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
|
||||
export function ContactEditor(props: {
|
||||
createContact: (contact: ContactFormValues) => void;
|
||||
@@ -34,7 +35,7 @@ export function ContactEditor(props: {
|
||||
onClick={() => setIsOpen(true)}
|
||||
class="flex flex-col items-center gap-2"
|
||||
>
|
||||
<div class="bg-neutral-500 flex-none h-16 w-16 rounded-full flex items-center justify-center text-4xl uppercase ">
|
||||
<div class="flex h-16 w-16 flex-none items-center justify-center rounded-full bg-neutral-500 text-4xl uppercase ">
|
||||
<span class="leading-[4rem]">+</span>
|
||||
</div>
|
||||
<SmallHeader class="overflow-ellipsis">
|
||||
@@ -54,11 +55,11 @@ export function ContactEditor(props: {
|
||||
class={DIALOG_CONTENT}
|
||||
onEscapeKeyDown={() => setIsOpen(false)}
|
||||
>
|
||||
<div class="w-full flex justify-end">
|
||||
<div class="flex w-full justify-end">
|
||||
<button
|
||||
tabindex="-1"
|
||||
onClick={() => setIsOpen(false)}
|
||||
class="hover:bg-white/10 rounded-lg active:bg-m-blue"
|
||||
class="rounded-lg hover:bg-white/10 active:bg-m-blue"
|
||||
>
|
||||
<img src={close} alt="Close" />
|
||||
</button>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { SubmitHandler, createForm, required } from "@modular-forms/solid";
|
||||
import { createForm, required, SubmitHandler } from "@modular-forms/solid";
|
||||
|
||||
import {
|
||||
Button,
|
||||
ContactFormValues,
|
||||
LargeHeader,
|
||||
VStack,
|
||||
TextField,
|
||||
ContactFormValues
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -22,7 +23,7 @@ export function ContactForm(props: {
|
||||
return (
|
||||
<Form
|
||||
onSubmit={props.handleSubmit}
|
||||
class="flex flex-col flex-1 justify-around gap-4 max-w-[400px] mx-auto w-full"
|
||||
class="mx-auto flex w-full max-w-[400px] flex-1 flex-col justify-around gap-4"
|
||||
>
|
||||
<div>
|
||||
<LargeHeader>{props.title}</LargeHeader>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import { Match, Switch, createSignal } from "solid-js";
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { SubmitHandler } from "@modular-forms/solid";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { createSignal, Match, Switch } from "solid-js";
|
||||
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
NiceP,
|
||||
SmallHeader,
|
||||
ContactForm,
|
||||
showToast
|
||||
NiceP,
|
||||
showToast,
|
||||
SmallHeader
|
||||
} from "~/components";
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import { SubmitHandler } from "@modular-forms/solid";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
|
||||
export type ContactFormValues = {
|
||||
name: string;
|
||||
@@ -42,15 +43,15 @@ export function ContactViewer(props: {
|
||||
<Dialog.Root open={isOpen()}>
|
||||
<button
|
||||
onClick={() => setIsOpen(true)}
|
||||
class="flex flex-col items-center gap-2 w-16 flex-shrink-0 overflow-x-hidden"
|
||||
class="flex w-16 flex-shrink-0 flex-col items-center gap-2 overflow-x-hidden"
|
||||
>
|
||||
<div
|
||||
class="flex-none h-16 w-16 rounded-full flex items-center justify-center text-4xl uppercase border-t border-b border-t-white/50 border-b-white/10"
|
||||
class="flex h-16 w-16 flex-none items-center justify-center rounded-full border-b border-t border-b-white/10 border-t-white/50 text-4xl uppercase"
|
||||
style={{ background: props.gradient }}
|
||||
>
|
||||
{props.contact.name[0]}
|
||||
</div>
|
||||
<SmallHeader class="overflow-ellipsis w-16 text-center overflow-hidden h-4">
|
||||
<SmallHeader class="h-4 w-16 overflow-hidden overflow-ellipsis text-center">
|
||||
{props.contact.name}
|
||||
</SmallHeader>
|
||||
</button>
|
||||
@@ -63,14 +64,14 @@ export function ContactViewer(props: {
|
||||
setIsEditing(false);
|
||||
}}
|
||||
>
|
||||
<div class="w-full flex justify-end">
|
||||
<div class="flex w-full justify-end">
|
||||
<button
|
||||
tabindex="-1"
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
setIsEditing(false);
|
||||
}}
|
||||
class="hover:bg-white/10 rounded-lg active:bg-m-blue"
|
||||
class="rounded-lg hover:bg-white/10 active:bg-m-blue"
|
||||
>
|
||||
<img src={close} alt="Close" />
|
||||
</button>
|
||||
@@ -85,17 +86,17 @@ export function ContactViewer(props: {
|
||||
/>
|
||||
</Match>
|
||||
<Match when={!isEditing()}>
|
||||
<div class="flex flex-col flex-1 justify-around items-center gap-4 max-w-[400px] mx-auto w-full">
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="mx-auto flex w-full max-w-[400px] flex-1 flex-col items-center justify-around gap-4">
|
||||
<div class="flex w-full flex-col items-center">
|
||||
<div
|
||||
class="flex-none h-32 w-32 rounded-full flex items-center justify-center text-8xl uppercase border-t border-b border-t-white/50 border-b-white/10"
|
||||
class="flex h-32 w-32 flex-none items-center justify-center rounded-full border-b border-t border-b-white/10 border-t-white/50 text-8xl uppercase"
|
||||
style={{
|
||||
background: props.gradient
|
||||
}}
|
||||
>
|
||||
{props.contact.name[0]}
|
||||
</div>
|
||||
<h1 class="text-2xl font-semibold uppercase mt-2 mb-4">
|
||||
<h1 class="mb-4 mt-2 text-2xl font-semibold uppercase">
|
||||
{props.contact.name}
|
||||
</h1>
|
||||
<Card
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Show } from "solid-js";
|
||||
import { QRCodeSVG } from "solid-qr-code";
|
||||
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
|
||||
@@ -9,17 +10,17 @@ export function CopyableQR(props: { value: string }) {
|
||||
return (
|
||||
<div
|
||||
id="qr"
|
||||
class="w-full bg-white rounded-xl relative"
|
||||
class="relative w-full rounded-xl bg-white"
|
||||
onClick={() => copy(props.value)}
|
||||
>
|
||||
<Show when={copied()}>
|
||||
<div class="absolute w-full h-full bg-neutral-900/60 z-50 rounded-xl flex flex-col items-center justify-center transition-all">
|
||||
<div class="absolute z-50 flex h-full w-full flex-col items-center justify-center rounded-xl bg-neutral-900/60 transition-all">
|
||||
<p class="text-xl font-bold">{i18n.t("common.copied")}</p>
|
||||
</div>
|
||||
</Show>
|
||||
<QRCodeSVG
|
||||
value={props.value}
|
||||
class="w-full h-full p-8 max-h-[400px]"
|
||||
class="h-full max-h-[400px] w-full p-8"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { Button, SimpleDialog, TextField, InfoBox } from "~/components";
|
||||
import { createSignal, Show } from "solid-js";
|
||||
import { A } from "solid-start";
|
||||
|
||||
import { Button, InfoBox, SimpleDialog, TextField } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import { A } from "solid-start";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export function DecryptDialog() {
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { createSignal } from "solid-js";
|
||||
import { ConfirmDialog, Button, showToast } from "~/components";
|
||||
|
||||
import { Button, ConfirmDialog, showToast } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { MutinyChannel, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import {
|
||||
createEffect,
|
||||
createMemo,
|
||||
createResource,
|
||||
For,
|
||||
Match,
|
||||
ParentComponent,
|
||||
Show,
|
||||
Suspense,
|
||||
Switch,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createResource
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import {
|
||||
InfoBox,
|
||||
Hr,
|
||||
ModalCloseButton,
|
||||
TinyButton,
|
||||
VStack,
|
||||
ActivityAmount,
|
||||
HackActivityType,
|
||||
CopyButton,
|
||||
TruncateMiddle,
|
||||
AmountSmall
|
||||
} from "~/components";
|
||||
import { MutinyChannel, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||
|
||||
import bolt from "~/assets/icons/bolt-black.svg";
|
||||
import chain from "~/assets/icons/chain-black.svg";
|
||||
import copyIcon from "~/assets/icons/copy.svg";
|
||||
import shuffle from "~/assets/icons/shuffle-black.svg";
|
||||
|
||||
import { prettyPrintTime } from "~/utils/prettyPrintTime";
|
||||
import {
|
||||
ActivityAmount,
|
||||
AmountSmall,
|
||||
CopyButton,
|
||||
HackActivityType,
|
||||
Hr,
|
||||
InfoBox,
|
||||
ModalCloseButton,
|
||||
TinyButton,
|
||||
TruncateMiddle,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { prettyPrintTime } from "~/utils/prettyPrintTime";
|
||||
import { MutinyTagItem, tagToMutinyTag } from "~/utils/tags";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
interface ChannelClosure {
|
||||
channel_id: string;
|
||||
@@ -74,10 +73,10 @@ function LightningHeader(props: {
|
||||
|
||||
return (
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="p-4 bg-neutral-100 rounded-full">
|
||||
<img src={bolt} alt="lightning bolt" class="w-8 h-8" />
|
||||
<div class="rounded-full bg-neutral-100 p-4">
|
||||
<img src={bolt} alt="lightning bolt" class="h-8 w-8" />
|
||||
</div>
|
||||
<h1 class="uppercase font-semibold">
|
||||
<h1 class="font-semibold uppercase">
|
||||
{props.info.inbound
|
||||
? i18n.t("modals.transaction_details.lightning_receive")
|
||||
: i18n.t("modals.transaction_details.lightning_send")}
|
||||
@@ -126,7 +125,7 @@ function OnchainHeader(props: {
|
||||
|
||||
return (
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="p-4 bg-neutral-100 rounded-full">
|
||||
<div class="rounded-full bg-neutral-100 p-4">
|
||||
<Switch>
|
||||
<Match
|
||||
when={
|
||||
@@ -134,14 +133,14 @@ function OnchainHeader(props: {
|
||||
props.kind === "ChannelClose"
|
||||
}
|
||||
>
|
||||
<img src={shuffle} alt="swap" class="w-8 h-8" />
|
||||
<img src={shuffle} alt="swap" class="h-8 w-8" />
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<img src={chain} alt="blockchain" class="w-8 h-8" />
|
||||
<img src={chain} alt="blockchain" class="h-8 w-8" />
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
<h1 class="uppercase font-semibold">
|
||||
<h1 class="font-semibold uppercase">
|
||||
{props.kind === "ChannelOpen"
|
||||
? i18n.t("modals.transaction_details.channel_open")
|
||||
: props.kind === "ChannelClose"
|
||||
@@ -176,8 +175,8 @@ function OnchainHeader(props: {
|
||||
|
||||
export const KeyValue: ParentComponent<{ key: string }> = (props) => {
|
||||
return (
|
||||
<li class="flex justify-between items-center gap-4">
|
||||
<span class="uppercase font-semibold whitespace-nowrap text-sm">
|
||||
<li class="flex items-center justify-between gap-4">
|
||||
<span class="whitespace-nowrap text-sm font-semibold uppercase">
|
||||
{props.key}
|
||||
</span>
|
||||
<span class="font-light">{props.children}</span>
|
||||
@@ -189,7 +188,7 @@ export function MiniStringShower(props: { text: string }) {
|
||||
const [copy, copied] = useCopy({ copiedTimeout: 1000 });
|
||||
|
||||
return (
|
||||
<div class="w-full grid gap-1 grid-cols-[minmax(0,_1fr)_auto]">
|
||||
<div class="grid w-full grid-cols-[minmax(0,_1fr)_auto] gap-1">
|
||||
<TruncateMiddle text={props.text} />
|
||||
{/* <pre class="truncate text-neutral-300 font-light">{props.text}</pre> */}
|
||||
<button
|
||||
@@ -197,7 +196,7 @@ export function MiniStringShower(props: { text: string }) {
|
||||
classList={{ "bg-m-green rounded": copied() }}
|
||||
onClick={() => copy(props.text)}
|
||||
>
|
||||
<img src={copyIcon} alt="copy" class="w-4 h-4" />
|
||||
<img src={copyIcon} alt="copy" class="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
@@ -224,7 +223,7 @@ function LightningDetails(props: { info: MutinyInvoice }) {
|
||||
<KeyValue
|
||||
key={i18n.t("modals.transaction_details.description")}
|
||||
>
|
||||
<span class="text-neutral-300 truncate">
|
||||
<span class="truncate text-neutral-300">
|
||||
{props.info.description}
|
||||
</span>
|
||||
</KeyValue>
|
||||
@@ -268,8 +267,8 @@ function OnchainDetails(props: { info: OnChainTx; kind?: HackActivityType }) {
|
||||
await (state.mutiny_wallet?.list_channels() as Promise<
|
||||
MutinyChannel[]
|
||||
>);
|
||||
const channel = channels.find((channel) =>
|
||||
channel.outpoint?.startsWith(props.info.txid)
|
||||
const channel = channels.find(
|
||||
(channel) => channel.outpoint?.startsWith(props.info.txid)
|
||||
);
|
||||
return channel;
|
||||
} catch (e) {
|
||||
@@ -375,7 +374,7 @@ function ChannelCloseDetails(props: { info: ChannelClosure }) {
|
||||
</KeyValue>
|
||||
</Show>
|
||||
<KeyValue key={i18n.t("modals.transaction_details.reason")}>
|
||||
<p class="text-neutral-300 text-right">
|
||||
<p class="text-right text-neutral-300">
|
||||
{props.info.reason ?? ""}
|
||||
</p>
|
||||
</KeyValue>
|
||||
@@ -458,7 +457,7 @@ export function DetailsIdModal(props: {
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
<Suspense>
|
||||
<div class="flex justify-between mb-2">
|
||||
<div class="mb-2 flex justify-between">
|
||||
<div />
|
||||
<Dialog.CloseButton>
|
||||
<ModalCloseButton />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { ParentComponent } from "solid-js";
|
||||
|
||||
import { Button, SmallHeader } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -22,7 +23,7 @@ export const ConfirmDialog: ParentComponent<{
|
||||
<Dialog.Overlay class={OVERLAY} />
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
<div class="flex justify-between mb-2">
|
||||
<div class="mb-2 flex justify-between">
|
||||
<Dialog.Title>
|
||||
<SmallHeader>
|
||||
{i18n.t(
|
||||
@@ -33,7 +34,7 @@ export const ConfirmDialog: ParentComponent<{
|
||||
</div>
|
||||
<Dialog.Description class="flex flex-col gap-4">
|
||||
{props.children}
|
||||
<div class="flex gap-4 w-full justify-end">
|
||||
<div class="flex w-full justify-end gap-4">
|
||||
<Button onClick={props.onCancel}>
|
||||
{i18n.t("modals.confirm_dialog.cancel")}
|
||||
</Button>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { A, Title } from "solid-start";
|
||||
|
||||
import {
|
||||
Button,
|
||||
DefaultMain,
|
||||
@@ -7,7 +9,6 @@ import {
|
||||
SafeArea,
|
||||
SmallHeader
|
||||
} from "~/components/layout";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export function ErrorDisplay(props: { error: Error }) {
|
||||
@@ -20,7 +21,7 @@ export function ErrorDisplay(props: { error: Error }) {
|
||||
<SmallHeader>
|
||||
{i18n.t("error.general.never_should_happen")}
|
||||
</SmallHeader>
|
||||
<p class="bg-white/10 rounded-xl p-4 font-mono">
|
||||
<p class="rounded-xl bg-white/10 p-4 font-mono">
|
||||
<span class="font-bold">{props.error.name}</span>:{" "}
|
||||
{props.error.message}
|
||||
</p>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { AmountFiat, AmountSats, FeesModal } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export function Fee(props: { amountSats?: bigint | number }) {
|
||||
const i18n = useI18n();
|
||||
|
||||
return (
|
||||
<div class="flex gap-3">
|
||||
<p class="text-m-grey-400 text-sm">{i18n.t("common.fee")}</p>
|
||||
<p class="text-sm text-m-grey-400">{i18n.t("common.fee")}</p>
|
||||
<div class="flex gap-1">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-right text-sm">
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { ParentComponent, Show, createResource } from "solid-js";
|
||||
import { I18nContext } from "~/i18n/context";
|
||||
import i18next from "i18next";
|
||||
import { createResource, ParentComponent, Show } from "solid-js";
|
||||
|
||||
import i18nConfig from "~/i18n/config";
|
||||
import { I18nContext } from "~/i18n/context";
|
||||
|
||||
export const I18nProvider: ParentComponent = (props) => {
|
||||
const [i18nConfigured] = createResource(async () => {
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { createFileUploader } from "@solid-primitives/upload";
|
||||
import { createSignal, Show } from "solid-js";
|
||||
|
||||
import {
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
InfoBox,
|
||||
InnerCard,
|
||||
NiceP,
|
||||
SimpleDialog,
|
||||
VStack,
|
||||
ConfirmDialog,
|
||||
showToast,
|
||||
InfoBox,
|
||||
TextField
|
||||
SimpleDialog,
|
||||
TextField,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import eify from "~/utils/eify";
|
||||
import { downloadTextFile } from "~/utils/download";
|
||||
import { createFileUploader } from "@solid-primitives/upload";
|
||||
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { downloadTextFile } from "~/utils/download";
|
||||
import eify from "~/utils/eify";
|
||||
|
||||
export function ImportExport(props: { emergency?: boolean }) {
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ParentComponent } from "solid-js";
|
||||
|
||||
import info from "~/assets/icons/info.svg";
|
||||
|
||||
export const InfoBox: ParentComponent<{
|
||||
@@ -6,7 +7,7 @@ export const InfoBox: ParentComponent<{
|
||||
}> = (props) => {
|
||||
return (
|
||||
<div
|
||||
class="grid grid-cols-[auto_minmax(0,_1fr)] rounded-xl px-4 py-2 md:p-4 gap-4 bg-neutral-950/50 border"
|
||||
class="grid grid-cols-[auto_minmax(0,_1fr)] gap-4 rounded-xl border bg-neutral-950/50 px-4 py-2 md:p-4"
|
||||
classList={{
|
||||
"border-m-red": props.accent === "red",
|
||||
"border-m-blue bg-m-blue/10": props.accent === "blue",
|
||||
@@ -15,7 +16,7 @@ export const InfoBox: ParentComponent<{
|
||||
}}
|
||||
>
|
||||
<div class="self-center">
|
||||
<img src={info} alt="info" class="w-8 h-8" />
|
||||
<img src={info} alt="info" class="h-8 w-8" />
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<p class="text-sm font-light">{props.children}</p>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import { Match, Show, Switch } from "solid-js";
|
||||
import { QRCodeSVG } from "solid-qr-code";
|
||||
import { ReceiveFlavor } from "~/routes/Receive";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import { AmountSats, AmountFiat, TruncateMiddle } from "~/components";
|
||||
|
||||
import boltBlack from "~/assets/icons/bolt-black.svg";
|
||||
import chainBlack from "~/assets/icons/chain-black.svg";
|
||||
import copyBlack from "~/assets/icons/copy-black.svg";
|
||||
import shareBlack from "~/assets/icons/share-black.svg";
|
||||
import chainBlack from "~/assets/icons/chain-black.svg";
|
||||
import boltBlack from "~/assets/icons/bolt-black.svg";
|
||||
import { AmountFiat, AmountSats, TruncateMiddle } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { ReceiveFlavor } from "~/routes/Receive";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
|
||||
function KindIndicator(props: { kind: ReceiveFlavor }) {
|
||||
const i18n = useI18n();
|
||||
return (
|
||||
<div class="text-black flex flex-col items-end">
|
||||
<div class="flex flex-col items-end text-black">
|
||||
<Switch>
|
||||
<Match when={props.kind === "onchain"}>
|
||||
<h3 class="font-semibold">
|
||||
@@ -68,16 +69,16 @@ export function IntegratedQr(props: {
|
||||
return (
|
||||
<div
|
||||
id="qr"
|
||||
class="w-full bg-white rounded-xl relative flex flex-col items-center px-4"
|
||||
class="relative flex w-full flex-col items-center rounded-xl bg-white px-4"
|
||||
onClick={() => copy(props.value)}
|
||||
>
|
||||
<Show when={copied()}>
|
||||
<div class="absolute w-full h-full bg-neutral-900/60 z-50 rounded-xl flex flex-col items-center justify-center transition-all">
|
||||
<div class="absolute z-50 flex h-full w-full flex-col items-center justify-center rounded-xl bg-neutral-900/60 transition-all">
|
||||
<p class="text-xl font-bold">{i18n.t("common.copied")}</p>
|
||||
</div>
|
||||
</Show>
|
||||
<div
|
||||
class="w-full flex items-center py-4 max-w-[256px]"
|
||||
class="flex w-full max-w-[256px] items-center py-4"
|
||||
classList={{
|
||||
"justify-between": props.kind !== "onchain",
|
||||
"justify-end": props.kind === "onchain"
|
||||
@@ -88,7 +89,7 @@ export function IntegratedQr(props: {
|
||||
<div class="text-black">
|
||||
<AmountSats amountSats={Number(props.amountSats)} />
|
||||
</div>
|
||||
<div class="text-black text-sm">
|
||||
<div class="text-sm text-black">
|
||||
<AmountFiat amountSats={Number(props.amountSats)} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -98,10 +99,10 @@ export function IntegratedQr(props: {
|
||||
|
||||
<QRCodeSVG
|
||||
value={props.value}
|
||||
class="w-full h-full max-h-[256px]"
|
||||
class="h-full max-h-[256px] w-full"
|
||||
/>
|
||||
<div
|
||||
class="w-full grid gap-1 py-4 max-w-[256px] "
|
||||
class="grid w-full max-w-[256px] gap-1 py-4 "
|
||||
classList={{
|
||||
"grid-cols-[2rem_minmax(0,1fr)_2rem]": !!navigator.share,
|
||||
"grid-cols-[minmax(0,1fr)_2rem]": !navigator.share
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { JSX, createMemo } from "solid-js";
|
||||
import { createMemo, JSX } from "solid-js";
|
||||
|
||||
import {
|
||||
ModalCloseButton,
|
||||
SmallHeader,
|
||||
CopyButton,
|
||||
DIALOG_CONTENT,
|
||||
DIALOG_POSITIONER,
|
||||
ModalCloseButton,
|
||||
OVERLAY,
|
||||
CopyButton
|
||||
SmallHeader
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -29,7 +30,7 @@ export function JsonModal(props: {
|
||||
<Dialog.Overlay class={OVERLAY} />
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
<div class="flex justify-between mb-2 items-center">
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<Dialog.Title>
|
||||
<SmallHeader>{props.title}</SmallHeader>
|
||||
</Dialog.Title>
|
||||
@@ -37,8 +38,8 @@ export function JsonModal(props: {
|
||||
<ModalCloseButton />
|
||||
</Dialog.CloseButton>
|
||||
</div>
|
||||
<Dialog.Description class="flex flex-col gap-4 items-center">
|
||||
<div class="bg-white/5 rounded-xl max-h-[50vh] overflow-y-scroll disable-scrollbars p-4">
|
||||
<Dialog.Description class="flex flex-col items-center gap-4">
|
||||
<div class="max-h-[50vh] overflow-y-scroll rounded-xl bg-white/5 p-4 disable-scrollbars">
|
||||
<pre class="whitespace-pre-wrap break-all">
|
||||
{json()}
|
||||
</pre>
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Collapsible, TextField } from "@kobalte/core";
|
||||
import { MutinyChannel, MutinyPeer } from "@mutinywallet/mutiny-wasm";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import {
|
||||
createResource,
|
||||
createSignal,
|
||||
For,
|
||||
Match,
|
||||
Show,
|
||||
Suspense,
|
||||
Switch,
|
||||
createResource,
|
||||
createSignal
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { MutinyChannel, MutinyPeer } from "@mutinywallet/mutiny-wasm";
|
||||
import { Collapsible, TextField } from "@kobalte/core";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import eify from "~/utils/eify";
|
||||
|
||||
import {
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
Hr,
|
||||
Button,
|
||||
InnerCard,
|
||||
VStack,
|
||||
showToast,
|
||||
MiniStringShower,
|
||||
ResetRouter,
|
||||
Restart,
|
||||
ResyncOnchain,
|
||||
ResetRouter,
|
||||
MiniStringShower
|
||||
showToast,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
|
||||
// TODO: hopefully I don't have to maintain this type forever but I don't know how to pass it around otherwise
|
||||
type RefetchPeersType = (
|
||||
@@ -57,7 +58,7 @@ function PeerItem(props: { peer: MutinyPeer }) {
|
||||
return (
|
||||
<Collapsible.Root>
|
||||
<Collapsible.Trigger class="w-full">
|
||||
<h2 class="truncate text-start text-lg font-mono bg-neutral-200 text-black rounded px-4 py-2">
|
||||
<h2 class="truncate rounded bg-neutral-200 px-4 py-2 text-start font-mono text-lg text-black">
|
||||
{">"}{" "}
|
||||
{props.peer.alias ? props.peer.alias : props.peer.pubkey}
|
||||
</h2>
|
||||
@@ -157,7 +158,7 @@ function ConnectPeer(props: { refetchPeers: RefetchPeersType }) {
|
||||
{i18n.t("settings.admin.kitchen_sink.connect_peer")}
|
||||
</TextField.Label>
|
||||
<TextField.Input
|
||||
class="w-full p-2 rounded-lg text-black"
|
||||
class="w-full rounded-lg p-2 text-black"
|
||||
placeholder="028241..."
|
||||
/>
|
||||
<TextField.ErrorMessage class="text-red-500">
|
||||
@@ -207,7 +208,7 @@ function ChannelItem(props: { channel: MutinyChannel; network?: Network }) {
|
||||
return (
|
||||
<Collapsible.Root>
|
||||
<Collapsible.Trigger class="w-full">
|
||||
<h2 class="truncate text-start text-lg font-mono bg-neutral-200 text-black rounded px-4 py-2">
|
||||
<h2 class="truncate rounded bg-neutral-200 px-4 py-2 text-start font-mono text-lg text-black">
|
||||
{">"} {props.channel.peer}
|
||||
</h2>
|
||||
</Collapsible.Trigger>
|
||||
@@ -386,7 +387,7 @@ function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) {
|
||||
<TextField.Label class="text-sm font-semibold uppercase">
|
||||
{i18n.t("settings.admin.kitchen_sink.pubkey")}
|
||||
</TextField.Label>
|
||||
<TextField.Input class="w-full p-2 rounded-lg text-black" />
|
||||
<TextField.Input class="w-full rounded-lg p-2 text-black" />
|
||||
</TextField.Root>
|
||||
<TextField.Root
|
||||
value={amount()}
|
||||
@@ -398,7 +399,7 @@ function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) {
|
||||
</TextField.Label>
|
||||
<TextField.Input
|
||||
type="number"
|
||||
class="w-full p-2 rounded-lg text-black"
|
||||
class="w-full rounded-lg p-2 text-black"
|
||||
/>
|
||||
</TextField.Root>
|
||||
<Button layout="small" type="submit">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Progress } from "@kobalte/core";
|
||||
import { Show } from "solid-js";
|
||||
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
@@ -29,11 +30,11 @@ export function LoadingBar(props: { value: number; max: number }) {
|
||||
getValueLabel={({ value }) =>
|
||||
i18n.t("modals.loading.loading", { stage: valueToStage(value) })
|
||||
}
|
||||
class="w-full flex flex-col gap-2"
|
||||
class="flex w-full flex-col gap-2"
|
||||
>
|
||||
<Progress.ValueLabel class="text-sm text-m-grey-400" />
|
||||
<Progress.Track class="h-6 bg-white/10 rounded">
|
||||
<Progress.Fill class="bg-m-blue rounded h-full w-[var(--kb-progress-fill-width)] transition-[width]" />
|
||||
<Progress.Track class="h-6 rounded bg-white/10">
|
||||
<Progress.Fill class="h-full w-[var(--kb-progress-fill-width)] rounded bg-m-blue transition-[width]" />
|
||||
</Progress.Track>
|
||||
</Progress.Root>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
|
||||
import { Button, InnerCard, NiceP, VStack } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { downloadTextFile } from "~/utils/download";
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { ParentComponent, createSignal, JSXElement } from "solid-js";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { createSignal, JSXElement, ParentComponent } from "solid-js";
|
||||
|
||||
import help from "~/assets/icons/help.svg";
|
||||
import {
|
||||
DIALOG_CONTENT,
|
||||
DIALOG_POSITIONER,
|
||||
OVERLAY,
|
||||
ModalCloseButton,
|
||||
OVERLAY,
|
||||
SmallHeader
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import help from "~/assets/icons/help.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export function FeesModal(props: { icon?: boolean }) {
|
||||
@@ -18,7 +19,7 @@ export function FeesModal(props: { icon?: boolean }) {
|
||||
title={i18n.t("modals.more_info.whats_with_the_fees")}
|
||||
linkText={
|
||||
props.icon ? (
|
||||
<img src={help} alt="help" class="w-4 h-4 cursor-pointer" />
|
||||
<img src={help} alt="help" class="h-4 w-4 cursor-pointer" />
|
||||
) : (
|
||||
i18n.t("common.why")
|
||||
)
|
||||
@@ -44,7 +45,7 @@ export const MoreInfoModal: ParentComponent<{
|
||||
return (
|
||||
<Dialog.Root open={open()} onOpenChange={setOpen}>
|
||||
<Dialog.Trigger>
|
||||
<button class="underline decoration-light-text hover:decoration-white font-semibold">
|
||||
<button class="font-semibold underline decoration-light-text hover:decoration-white">
|
||||
{props.linkText}
|
||||
</button>
|
||||
</Dialog.Trigger>
|
||||
@@ -52,7 +53,7 @@ export const MoreInfoModal: ParentComponent<{
|
||||
<Dialog.Overlay class={OVERLAY} />
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
<Dialog.Title class="flex justify-between mb-2 items-center">
|
||||
<Dialog.Title class="mb-2 flex items-center justify-between">
|
||||
<SmallHeader>{props.title}</SmallHeader>
|
||||
<Dialog.CloseButton>
|
||||
<ModalCloseButton />
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import mutiny_m from "~/assets/icons/m.svg";
|
||||
import airplane from "~/assets/icons/airplane.svg";
|
||||
import settings from "~/assets/icons/settings.svg";
|
||||
import receive from "~/assets/icons/big-receive.svg";
|
||||
import redshift from "~/assets/icons/rs.svg";
|
||||
import userClock from "~/assets/icons/user-clock.svg";
|
||||
|
||||
import { A } from "solid-start";
|
||||
|
||||
import airplane from "~/assets/icons/airplane.svg";
|
||||
import receive from "~/assets/icons/big-receive.svg";
|
||||
import mutiny_m from "~/assets/icons/m.svg";
|
||||
import redshift from "~/assets/icons/rs.svg";
|
||||
import settings from "~/assets/icons/settings.svg";
|
||||
import userClock from "~/assets/icons/user-clock.svg";
|
||||
|
||||
type ActiveTab =
|
||||
| "home"
|
||||
| "scan"
|
||||
@@ -41,8 +41,8 @@ function NavBarItem(props: {
|
||||
|
||||
export function NavBar(props: { activeTab: ActiveTab }) {
|
||||
return (
|
||||
<nav class="hidden md:block fixed shadow-none z-40 safe-bottom top-0 bottom-auto left-0 h-full">
|
||||
<ul class="flex flex-col justify-start gap-4 px-4 mt-4">
|
||||
<nav class="fixed bottom-auto left-0 top-0 z-40 hidden h-full shadow-none safe-bottom md:block">
|
||||
<ul class="mt-4 flex flex-col justify-start gap-4 px-4">
|
||||
<NavBarItem
|
||||
href="/"
|
||||
icon={mutiny_m}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Show } from "solid-js";
|
||||
import { ButtonLink, SmallHeader } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
import save from "~/assets/icons/save.svg";
|
||||
import { ButtonLink, SmallHeader } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export function OnboardWarning() {
|
||||
const i18n = useI18n();
|
||||
@@ -11,9 +12,9 @@ export function OnboardWarning() {
|
||||
return (
|
||||
<>
|
||||
<Show when={!state.has_backed_up}>
|
||||
<div class="grid grid-cols-[auto_minmax(0,_1fr)_auto] rounded-xl p-4 gap-4 bg-neutral-950/50">
|
||||
<div class="grid grid-cols-[auto_minmax(0,_1fr)_auto] gap-4 rounded-xl bg-neutral-950/50 p-4">
|
||||
<div class="self-center">
|
||||
<img src={save} alt="backup" class="w-8 h-8" />
|
||||
<img src={save} alt="backup" class="h-8 w-8" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-center">
|
||||
<SmallHeader>
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
||||
import { formatExpiration } from "~/utils/prettyPrintTime";
|
||||
import { Card, VStack, ActivityAmount, InfoBox } from "~/components";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import bolt from "~/assets/icons/bolt.svg";
|
||||
import {
|
||||
createEffect,
|
||||
createResource,
|
||||
createSignal,
|
||||
For,
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
createEffect,
|
||||
createResource,
|
||||
createSignal
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { A } from "solid-start";
|
||||
|
||||
import bolt from "~/assets/icons/bolt.svg";
|
||||
import greenCheck from "~/assets/icons/green-check.svg";
|
||||
import redClose from "~/assets/icons/red-close.svg";
|
||||
import eify from "~/utils/eify";
|
||||
import { A } from "solid-start";
|
||||
import { createDeepSignal } from "~/utils/deepSignal";
|
||||
import { ActivityAmount, Card, InfoBox, VStack } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { createDeepSignal } from "~/utils/deepSignal";
|
||||
import eify from "~/utils/eify";
|
||||
import { formatExpiration } from "~/utils/prettyPrintTime";
|
||||
|
||||
type PendingItem = {
|
||||
id: string;
|
||||
@@ -118,14 +118,14 @@ export function PendingNwc() {
|
||||
</Show>
|
||||
<For each={pendingRequests()}>
|
||||
{(pendingItem) => (
|
||||
<div class="grid grid-cols-[auto_minmax(0,_1fr)_minmax(0,_max-content)_auto] items-center pb-4 gap-4 border-b border-neutral-800 last:border-b-0">
|
||||
<div class="grid grid-cols-[auto_minmax(0,_1fr)_minmax(0,_max-content)_auto] items-center gap-4 border-b border-neutral-800 pb-4 last:border-b-0">
|
||||
<img
|
||||
class="w-[1rem]"
|
||||
src={bolt}
|
||||
alt="onchain"
|
||||
/>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-base font-semibold truncate">
|
||||
<span class="truncate text-base font-semibold">
|
||||
{pendingItem.name_of_connection}
|
||||
</span>
|
||||
<time class="text-sm text-neutral-500">
|
||||
@@ -141,7 +141,7 @@ export function PendingNwc() {
|
||||
price={state.price}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex gap-2 w-[5rem]">
|
||||
<div class="flex w-[5rem] gap-2">
|
||||
<Switch>
|
||||
<Match
|
||||
when={paying() !== pendingItem.id}
|
||||
@@ -182,7 +182,7 @@ export function PendingNwc() {
|
||||
</VStack>
|
||||
<A
|
||||
href="/settings/connections"
|
||||
class="text-m-red active:text-m-red/80 font-semibold no-underline self-center"
|
||||
class="self-center font-semibold text-m-red no-underline active:text-m-red/80"
|
||||
>
|
||||
{i18n.t("settings.connections.pending_nwc.configure_link")}
|
||||
</A>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { onCleanup, onMount } from "solid-js";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import {
|
||||
BarcodeScanner,
|
||||
BarcodeFormat,
|
||||
BarcodeScanner,
|
||||
PermissionStates,
|
||||
ScanResult
|
||||
} from "@mutinywallet/barcode-scanner";
|
||||
import QrScanner from "qr-scanner";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { onCleanup, onMount } from "solid-js";
|
||||
|
||||
export function Scanner(props: { onResult: (result: string) => void }) {
|
||||
let container: HTMLVideoElement | undefined;
|
||||
@@ -80,7 +80,7 @@ export function Scanner(props: { onResult: (result: string) => void }) {
|
||||
<div id="video-container">
|
||||
<video
|
||||
ref={container}
|
||||
class="w-full h-full fixed object-cover bg-transparent"
|
||||
class="fixed h-full w-full bg-transparent object-cover"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Button, InnerCard, NiceP, VStack } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export function ResetRouter() {
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
import { Button, InnerCard, NiceP, VStack } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { For, Match, Switch, createMemo, createSignal } from "solid-js";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import { createMemo, createSignal, For, Match, Switch } from "solid-js";
|
||||
|
||||
import copyIcon from "~/assets/icons/copy.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
|
||||
export function SeedWords(props: {
|
||||
words: string;
|
||||
@@ -25,11 +26,11 @@ export function SeedWords(props: {
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="flex flex-col gap-4 bg-m-red p-4 rounded-xl overflow-hidden">
|
||||
<div class="flex flex-col gap-4 overflow-hidden rounded-xl bg-m-red p-4">
|
||||
<Switch>
|
||||
<Match when={!shouldShow()}>
|
||||
<div
|
||||
class="cursor-pointer flex w-full justify-center"
|
||||
class="flex w-full cursor-pointer justify-center"
|
||||
onClick={toggleShow}
|
||||
>
|
||||
<code class="text-red">
|
||||
@@ -41,17 +42,17 @@ export function SeedWords(props: {
|
||||
<Match when={shouldShow()}>
|
||||
<>
|
||||
<div
|
||||
class="cursor-pointer flex w-full justify-center"
|
||||
class="flex w-full cursor-pointer justify-center"
|
||||
onClick={toggleShow}
|
||||
>
|
||||
<code class="text-red">
|
||||
{i18n.t("settings.backup.seed_words.hide")}
|
||||
</code>
|
||||
</div>
|
||||
<ol class="overflow-hidden columns-2 w-full list-decimal list-inside">
|
||||
<ol class="w-full list-inside list-decimal columns-2 overflow-hidden">
|
||||
<For each={splitWords()}>
|
||||
{(word) => (
|
||||
<li class="font-mono text-left min-w-fit bg">
|
||||
<li class="bg min-w-fit text-left font-mono">
|
||||
{word}
|
||||
</li>
|
||||
)}
|
||||
@@ -60,7 +61,7 @@ export function SeedWords(props: {
|
||||
<div class="flex w-full justify-center">
|
||||
<button
|
||||
onClick={dangerouslyCopy}
|
||||
class="bg-white/10 hover:bg-white/20 p-2 rounded-lg"
|
||||
class="rounded-lg bg-white/10 p-2 hover:bg-white/20"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<span>
|
||||
@@ -75,7 +76,7 @@ export function SeedWords(props: {
|
||||
<img
|
||||
src={copyIcon}
|
||||
alt="copy"
|
||||
class="w-4 h-4"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
import { Title } from "solid-start";
|
||||
import {
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
ImportExport,
|
||||
Logs,
|
||||
DeleteEverything
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { Match, Switch } from "solid-js";
|
||||
import { FeedbackLink } from "~/routes/Feedback";
|
||||
import { Title } from "solid-start";
|
||||
|
||||
import {
|
||||
DefaultMain,
|
||||
DeleteEverything,
|
||||
ImportExport,
|
||||
LargeHeader,
|
||||
Logs,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { FeedbackLink } from "~/routes/Feedback";
|
||||
|
||||
function ErrorFooter() {
|
||||
return (
|
||||
<>
|
||||
<div class="h-full" />
|
||||
<div class="self-center mt-4">
|
||||
<div class="mt-4 self-center">
|
||||
<FeedbackLink setupError={true} />
|
||||
</div>
|
||||
</>
|
||||
@@ -40,7 +41,7 @@ export function SetupErrorDisplay(props: { initialError: Error }) {
|
||||
<LargeHeader>
|
||||
{i18n.t("error.on_boot.loading_failed.header")}
|
||||
</LargeHeader>
|
||||
<p class="bg-white/10 rounded-xl p-4 font-mono">
|
||||
<p class="rounded-xl bg-white/10 p-4 font-mono">
|
||||
<span class="font-bold">{error.name}</span>:{" "}
|
||||
{error.message}
|
||||
</p>
|
||||
@@ -82,7 +83,7 @@ export function SetupErrorDisplay(props: { initialError: Error }) {
|
||||
<LargeHeader>
|
||||
{i18n.t("error.on_boot.existing_tab.title")}
|
||||
</LargeHeader>
|
||||
<p class="bg-white/10 rounded-xl p-4 font-mono">
|
||||
<p class="rounded-xl bg-white/10 p-4 font-mono">
|
||||
<span class="font-bold">{error.name}</span>:{" "}
|
||||
{error.message}
|
||||
</p>
|
||||
@@ -102,7 +103,7 @@ export function SetupErrorDisplay(props: { initialError: Error }) {
|
||||
"error.on_boot.incompatible_browser.header"
|
||||
)}
|
||||
</LargeHeader>
|
||||
<p class="bg-white/10 rounded-xl p-4 font-mono">
|
||||
<p class="rounded-xl bg-white/10 p-4 font-mono">
|
||||
<span class="font-bold">{error.name}</span>:{" "}
|
||||
{error.message}
|
||||
</p>
|
||||
@@ -138,7 +139,7 @@ export function SetupErrorDisplay(props: { initialError: Error }) {
|
||||
<LargeHeader>
|
||||
{i18n.t("error.on_boot.loading_failed.header")}
|
||||
</LargeHeader>
|
||||
<p class="bg-white/10 rounded-xl p-4 font-mono">
|
||||
<p class="rounded-xl bg-white/10 p-4 font-mono">
|
||||
<span class="font-bold">{error.name}</span>:{" "}
|
||||
{error.message}
|
||||
</p>
|
||||
@@ -160,7 +161,7 @@ export function SetupErrorDisplay(props: { initialError: Error }) {
|
||||
</NiceP>
|
||||
<ImportExport emergency />
|
||||
<Logs />
|
||||
<div class="rounded-xl p-4 flex flex-col gap-2 bg-m-red">
|
||||
<div class="flex flex-col gap-2 rounded-xl bg-m-red p-4">
|
||||
<SmallHeader>
|
||||
{i18n.t("settings.danger_zone")}
|
||||
</SmallHeader>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Card, VStack, JsonModal } from "~/components";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import copyIcon from "~/assets/icons/copy.svg";
|
||||
import { createSignal, Show } from "solid-js";
|
||||
|
||||
import copyBlack from "~/assets/icons/copy-black.svg";
|
||||
import shareIcon from "~/assets/icons/share.svg";
|
||||
import shareBlack from "~/assets/icons/share-black.svg";
|
||||
import copyIcon from "~/assets/icons/copy.svg";
|
||||
import eyeIcon from "~/assets/icons/eye.svg";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import shareBlack from "~/assets/icons/share-black.svg";
|
||||
import shareIcon from "~/assets/icons/share.svg";
|
||||
import { Card, JsonModal, VStack } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
|
||||
const STYLE =
|
||||
"px-4 py-2 rounded-xl border-2 border-white flex gap-2 items-center font-semibold hover:text-m-blue transition-colors";
|
||||
@@ -68,7 +69,7 @@ export function StringShower(props: { text: string }) {
|
||||
title={i18n.t("modals.details")}
|
||||
setOpen={setOpen}
|
||||
/>
|
||||
<div class="w-full grid grid-cols-[minmax(0,_1fr)_auto]">
|
||||
<div class="grid w-full grid-cols-[minmax(0,_1fr)_auto]">
|
||||
<TruncateMiddle text={props.text} />
|
||||
<button class="w-[2rem]" onClick={() => setOpen(true)}>
|
||||
<img src={eyeIcon} alt="eye" />
|
||||
@@ -105,7 +106,7 @@ export function ShareCard(props: { text?: string }) {
|
||||
<Card>
|
||||
<StringShower text={props.text ?? ""} />
|
||||
<VStack>
|
||||
<div class="flex gap-4 justify-center">
|
||||
<div class="flex justify-center gap-4">
|
||||
<CopyButton text={props.text ?? ""} />
|
||||
<Show when={navigator.share}>
|
||||
<ShareButton receiveString={props.text ?? ""} />
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { Select, createOptions } from "@thisbeyond/solid-select";
|
||||
import { createOptions, Select } from "@thisbeyond/solid-select";
|
||||
|
||||
import "~/styles/solid-select.css";
|
||||
import { For, Show, createMemo, createSignal, onMount } from "solid-js";
|
||||
|
||||
import { createMemo, createSignal, For, onMount, Show } from "solid-js";
|
||||
|
||||
import { TinyButton } from "~/components";
|
||||
import { MutinyTagItem, sortByLastUsed } from "~/utils/tags";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { MutinyTagItem, sortByLastUsed } from "~/utils/tags";
|
||||
|
||||
const createLabelValue = (label: string): Partial<MutinyTagItem> => {
|
||||
return { name: label, kind: "Contact" };
|
||||
@@ -57,7 +60,7 @@ export function TagEditor(props: {
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="flex flex-col gap-2 flex-shrink flex-1">
|
||||
<div class="flex flex-1 flex-shrink flex-col gap-2">
|
||||
<Select
|
||||
multiple
|
||||
initialValue={props.selectedValues}
|
||||
@@ -65,7 +68,7 @@ export function TagEditor(props: {
|
||||
onChange={onChange}
|
||||
{...selectProps()}
|
||||
/>
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<Show when={availableTags() && availableTags()!.length > 0}>
|
||||
<For each={availableTags()!.slice(0, 3)}>
|
||||
{(tag) => (
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Toast, toaster } from "@kobalte/core";
|
||||
import { Portal } from "solid-js/web";
|
||||
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import { SmallHeader } from "~/components";
|
||||
|
||||
export function Toaster() {
|
||||
return (
|
||||
<Portal>
|
||||
<Toast.Region class="z-[9999] top-0 fixed flex gap-4 w-full justify-center safe-top safe-left safe-right safe-bottom">
|
||||
<Toast.List class="max-w-[100vw] w-[400px] mt-8 flex flex-col gap-4" />
|
||||
<Toast.Region class="fixed top-0 z-[9999] flex w-full justify-center gap-4 safe-top safe-left safe-right safe-bottom">
|
||||
<Toast.List class="mt-8 flex w-[400px] max-w-[100vw] flex-col gap-4" />
|
||||
</Toast.Region>
|
||||
</Portal>
|
||||
);
|
||||
@@ -45,11 +46,11 @@ export function ToastItem(props: {
|
||||
return (
|
||||
<Toast.Root
|
||||
toastId={props.toastId}
|
||||
class={`w-[80vw] max-w-[400px] mx-auto p-4 bg-neutral-900/80 backdrop-blur-md shadow-xl rounded-xl border ${
|
||||
class={`mx-auto w-[80vw] max-w-[400px] rounded-xl border bg-neutral-900/80 p-4 shadow-xl backdrop-blur-md ${
|
||||
props.isError ? "border-m-red/50" : "border-white/10"
|
||||
} `}
|
||||
>
|
||||
<div class="flex gap-4 w-full justify-between items-start">
|
||||
<div class="flex w-full items-start justify-between gap-4">
|
||||
<div class="flex-1">
|
||||
<Toast.Title>
|
||||
<SmallHeader>{props.title}</SmallHeader>
|
||||
@@ -58,7 +59,7 @@ export function ToastItem(props: {
|
||||
<p>{props.description}</p>
|
||||
</Toast.Description>
|
||||
</div>
|
||||
<Toast.CloseButton class="hover:bg-white/10 rounded-lg active:bg-m-blue flex-0 w-8 h-8">
|
||||
<Toast.CloseButton class="flex-0 h-8 w-8 rounded-lg hover:bg-white/10 active:bg-m-blue">
|
||||
<img src={close} alt="Close" />
|
||||
</Toast.CloseButton>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ export function BackButton(props: {
|
||||
return (
|
||||
<button
|
||||
onClick={() => props.onClick()}
|
||||
class="text-m-red active:text-m-red/80 text-xl font-semibold no-underline md:hidden flex items-center"
|
||||
class="flex items-center text-xl font-semibold text-m-red no-underline active:text-m-red/80 md:hidden"
|
||||
classList={{ "md:!flex": props.showOnDesktop }}
|
||||
>
|
||||
<Back />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { A } from "solid-start";
|
||||
|
||||
import { Back } from "~/assets/svg/Back";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -7,7 +8,7 @@ export function BackLink(props: { href?: string; title?: string }) {
|
||||
return (
|
||||
<A
|
||||
href={props.href ? props.href : "/"}
|
||||
class="text-m-red active:text-m-red/80 text-xl font-semibold no-underline md:hidden flex items-center"
|
||||
class="flex items-center text-xl font-semibold text-m-red no-underline active:text-m-red/80 md:hidden"
|
||||
>
|
||||
<Back />
|
||||
{props.title ? props.title : i18n.t("common.home")}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useLocation, useNavigate } from "solid-start";
|
||||
|
||||
import { BackButton } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import { cva, VariantProps } from "class-variance-authority";
|
||||
import { children, JSX, ParentComponent, Show, splitProps } from "solid-js";
|
||||
import { Dynamic } from "solid-js/web";
|
||||
import { A } from "solid-start";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
|
||||
const button = cva(
|
||||
"p-3 rounded-xl font-semibold transition disabled:bg-neutral-400/10 disabled:text-white/20 disabled:shadow-inner-button-disabled",
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
import {
|
||||
Collapsible,
|
||||
Dialog,
|
||||
Checkbox as KCheckbox,
|
||||
Separator
|
||||
} from "@kobalte/core";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import {
|
||||
createResource,
|
||||
createSignal,
|
||||
JSX,
|
||||
Match,
|
||||
ParentComponent,
|
||||
Show,
|
||||
Suspense,
|
||||
Switch,
|
||||
createResource,
|
||||
createSignal
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import {
|
||||
Collapsible,
|
||||
Checkbox as KCheckbox,
|
||||
Dialog,
|
||||
Separator
|
||||
} from "@kobalte/core";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import check from "~/assets/icons/check.svg";
|
||||
import { MutinyTagItem } from "~/utils/tags";
|
||||
import { generateGradient } from "~/utils/gradientHash";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import { A } from "solid-start";
|
||||
|
||||
import check from "~/assets/icons/check.svg";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import down from "~/assets/icons/down.svg";
|
||||
import { LoadingIndicator, DecryptDialog } from "~/components";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import { DecryptDialog, LoadingIndicator } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { generateGradient } from "~/utils/gradientHash";
|
||||
import { MutinyTagItem } from "~/utils/tags";
|
||||
|
||||
export const SmallHeader: ParentComponent<{ class?: string }> = (props) => {
|
||||
return (
|
||||
@@ -38,7 +39,7 @@ export const Card: ParentComponent<{
|
||||
titleElement?: JSX.Element;
|
||||
}> = (props) => {
|
||||
return (
|
||||
<div class="rounded-xl p-4 flex flex-col gap-2 bg-neutral-950/50 w-full">
|
||||
<div class="flex w-full flex-col gap-2 rounded-xl bg-neutral-950/50 p-4">
|
||||
{props.title && <SmallHeader>{props.title}</SmallHeader>}
|
||||
{props.titleElement && props.titleElement}
|
||||
{props.children}
|
||||
@@ -48,7 +49,7 @@ export const Card: ParentComponent<{
|
||||
|
||||
export const InnerCard: ParentComponent<{ title?: string }> = (props) => {
|
||||
return (
|
||||
<div class="rounded-xl p-4 flex flex-col gap-2 border border-white/10 bg-[rgba(255,255,255,0.05)]">
|
||||
<div class="flex flex-col gap-2 rounded-xl border border-white/10 bg-[rgba(255,255,255,0.05)] p-4">
|
||||
{props.title && <SmallHeader>{props.title}</SmallHeader>}
|
||||
{props.children}
|
||||
</div>
|
||||
@@ -61,7 +62,7 @@ export const FancyCard: ParentComponent<{
|
||||
tag?: JSX.Element;
|
||||
}> = (props) => {
|
||||
return (
|
||||
<div class="border border-black/50 rounded-xl border-b-4 p-4 flex flex-col gap-2 bg-m-grey-800 shadow-fancy-card">
|
||||
<div class="flex flex-col gap-2 rounded-xl border border-b-4 border-black/50 bg-m-grey-800 p-4 shadow-fancy-card">
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
@@ -75,7 +76,7 @@ export const SettingsCard: ParentComponent<{
|
||||
<div class="mt-2 pl-4">
|
||||
<SmallHeader>{props.title}</SmallHeader>
|
||||
</div>
|
||||
<div class="rounded-xl py-4 flex flex-col gap-2 bg-m-grey-800 w-full">
|
||||
<div class="flex w-full flex-col gap-2 rounded-xl bg-m-grey-800 py-4">
|
||||
{props.children}
|
||||
</div>
|
||||
</VStack>
|
||||
@@ -89,14 +90,14 @@ export const Collapser: ParentComponent<{
|
||||
}> = (props) => {
|
||||
return (
|
||||
<Collapsible.Root class="collapsible">
|
||||
<Collapsible.Trigger class="flex w-full justify-between py-2 hover:bg-m-grey-750 active:bg-m-grey-900 px-4">
|
||||
<Collapsible.Trigger class="flex w-full justify-between px-4 py-2 hover:bg-m-grey-750 active:bg-m-grey-900">
|
||||
<div class="flex items-center gap-2">
|
||||
<Switch>
|
||||
<Match when={props.activityLight === "on"}>
|
||||
<div class="w-2 h-2 rounded-full bg-m-green" />
|
||||
<div class="h-2 w-2 rounded-full bg-m-green" />
|
||||
</Match>
|
||||
<Match when={props.activityLight === "off"}>
|
||||
<div class="w-2 h-2 rounded-full bg-m-red" />
|
||||
<div class="h-2 w-2 rounded-full bg-m-red" />
|
||||
</Match>
|
||||
</Switch>
|
||||
<span>{props.title}</span>
|
||||
@@ -107,7 +108,7 @@ export const Collapser: ParentComponent<{
|
||||
class="collapsible__trigger-icon"
|
||||
/>
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Content class="p-4 bg-m-grey-900 shadow-inner">
|
||||
<Collapsible.Content class="bg-m-grey-900 p-4 shadow-inner">
|
||||
{props.children}
|
||||
</Collapsible.Content>
|
||||
</Collapsible.Root>
|
||||
@@ -126,7 +127,7 @@ export const SafeArea: ParentComponent = (props) => {
|
||||
|
||||
export const DefaultMain: ParentComponent = (props) => {
|
||||
return (
|
||||
<main class="w-full max-w-[600px] flex flex-col gap-4 mx-auto p-4 h-full">
|
||||
<main class="mx-auto flex h-full w-full max-w-[600px] flex-col gap-4 p-4">
|
||||
{props.children}
|
||||
{/* CSS is hard sometimes */}
|
||||
<div class="py-4" />
|
||||
@@ -143,7 +144,7 @@ export const FullscreenLoader = () => {
|
||||
}, 10000);
|
||||
|
||||
return (
|
||||
<div class="w-full h-[100dvh] flex flex-col gap-4 justify-center items-center">
|
||||
<div class="flex h-[100dvh] w-full flex-col items-center justify-center gap-4">
|
||||
<LoadingSpinner wide />
|
||||
<Show when={waitedTooLong()}>
|
||||
<p class="max-w-[20rem] text-neutral-400">
|
||||
@@ -186,7 +187,7 @@ export const LargeHeader: ParentComponent<{
|
||||
}> = (props) => {
|
||||
return (
|
||||
<header
|
||||
class="w-full flex justify-between items-center mt-4 mb-2"
|
||||
class="mb-2 mt-4 flex w-full items-center justify-between"
|
||||
classList={{
|
||||
"justify-between": !props.centered,
|
||||
"justify-center": props.centered
|
||||
@@ -236,7 +237,7 @@ export const SmallAmount: ParentComponent<{
|
||||
sign?: string;
|
||||
}> = (props) => {
|
||||
return (
|
||||
<h2 class="font-light text-lg">
|
||||
<h2 class="text-lg font-light">
|
||||
{props.sign ? `${props.sign} ` : ""}
|
||||
{props.amount.toLocaleString()} <span class="text-sm">SATS</span>
|
||||
</h2>
|
||||
@@ -248,7 +249,7 @@ export const NiceP: ParentComponent = (props) => {
|
||||
};
|
||||
|
||||
export const TinyText: ParentComponent = (props) => {
|
||||
return <p class="text-neutral-400 text-sm">{props.children}</p>;
|
||||
return <p class="text-sm text-neutral-400">{props.children}</p>;
|
||||
};
|
||||
|
||||
export const TinyButton: ParentComponent<{
|
||||
@@ -267,7 +268,7 @@ export const TinyButton: ParentComponent<{
|
||||
|
||||
return (
|
||||
<button
|
||||
class="py-1 px-2 rounded-lg bg-white/10"
|
||||
class="rounded-lg bg-white/10 px-2 py-1"
|
||||
onClick={() => props.onClick()}
|
||||
style={{ background: bg() }}
|
||||
>
|
||||
@@ -278,7 +279,7 @@ export const TinyButton: ParentComponent<{
|
||||
|
||||
export const Indicator: ParentComponent = (props) => {
|
||||
return (
|
||||
<div class="box-border animate-pulse px-2 py-1 -my-1 bg-white/70 rounded text-xs uppercase text-black">
|
||||
<div class="-my-1 box-border animate-pulse rounded bg-white/70 px-2 py-1 text-xs uppercase text-black">
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
@@ -301,12 +302,12 @@ export function Checkbox(props: {
|
||||
onChange={props.onChange}
|
||||
>
|
||||
<KCheckbox.Input class="" />
|
||||
<KCheckbox.Control class="flex-0 w-8 h-8 rounded-lg border-2 border-white bg-neutral-800 ui-checked:bg-m-red">
|
||||
<KCheckbox.Control class="flex-0 h-8 w-8 rounded-lg border-2 border-white bg-neutral-800 ui-checked:bg-m-red">
|
||||
<KCheckbox.Indicator>
|
||||
<img src={check} class="w-8 h-8" alt="check" />
|
||||
<img src={check} class="h-8 w-8" alt="check" />
|
||||
</KCheckbox.Indicator>
|
||||
</KCheckbox.Control>
|
||||
<KCheckbox.Label class="flex-1 text-xl font-light flex flex-col gap-1">
|
||||
<KCheckbox.Label class="flex flex-1 flex-col gap-1 text-xl font-light">
|
||||
{props.label}
|
||||
<Show when={props.caption}>
|
||||
<TinyText>{props.caption}</TinyText>
|
||||
@@ -318,8 +319,8 @@ export function Checkbox(props: {
|
||||
|
||||
export function ModalCloseButton() {
|
||||
return (
|
||||
<button class="self-center justify-self-center hover:bg-white/10 rounded-lg active:bg-m-blue">
|
||||
<img src={close} alt="Close" class="w-8 h-8" />
|
||||
<button class="self-center justify-self-center rounded-lg hover:bg-white/10 active:bg-m-blue">
|
||||
<img src={close} alt="Close" class="h-8 w-8" />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -344,7 +345,7 @@ export const SimpleDialog: ParentComponent<{
|
||||
<Dialog.Overlay class={SIMPLE_OVERLAY} />
|
||||
<div class={SIMPLE_DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={SIMPLE_DIALOG_CONTENT}>
|
||||
<div class="flex justify-between mb-2 items-center">
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<Dialog.Title>
|
||||
<SmallHeader>{props.title}</SmallHeader>
|
||||
</Dialog.Title>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Progress } from "@kobalte/core";
|
||||
|
||||
import { SmallHeader } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -35,7 +36,7 @@ export function ProgressBar(props: { value: number; max: number }) {
|
||||
"send.progress_bar.sats_sent"
|
||||
)}`
|
||||
}
|
||||
class="w-full flex flex-col gap-2"
|
||||
class="flex w-full flex-col gap-2"
|
||||
>
|
||||
<div class="flex justify-between">
|
||||
<Progress.Label>
|
||||
@@ -43,8 +44,8 @@ export function ProgressBar(props: { value: number; max: number }) {
|
||||
</Progress.Label>
|
||||
<Progress.ValueLabel class="text-sm font-semibold uppercase" />
|
||||
</div>
|
||||
<Progress.Track class="h-6 bg-white/10 rounded">
|
||||
<Progress.Fill class="bg-m-red rounded h-full w-[var(--kb-progress-fill-width)] transition-[width]" />
|
||||
<Progress.Track class="h-6 rounded bg-white/10">
|
||||
<Progress.Fill class="h-full w-[var(--kb-progress-fill-width)] rounded bg-m-red transition-[width]" />
|
||||
</Progress.Track>
|
||||
</Progress.Root>
|
||||
);
|
||||
|
||||
@@ -36,7 +36,7 @@ export function StyledRadioGroup(props: {
|
||||
{(choice) => (
|
||||
<RadioGroup.Item
|
||||
value={choice.value}
|
||||
class={`ui-checked:bg-neutral-950 bg-white/10 rounded outline outline-black/50 ui-checked:outline-m-blue ui-checked:outline-2`}
|
||||
class={`rounded bg-white/10 outline outline-black/50 ui-checked:bg-neutral-950 ui-checked:outline-2 ui-checked:outline-m-blue`}
|
||||
classList={{
|
||||
"ui-checked:outline-m-red": props.accent === "red",
|
||||
"ui-checked:outline-white":
|
||||
@@ -45,12 +45,12 @@ export function StyledRadioGroup(props: {
|
||||
}}
|
||||
disabled={choice.disabled}
|
||||
>
|
||||
<div class={props.small ? "py-2 px-2" : "py-3 px-4"}>
|
||||
<div class={props.small ? "px-2 py-2" : "px-4 py-3"}>
|
||||
<RadioGroup.ItemInput />
|
||||
<RadioGroup.ItemControl>
|
||||
<RadioGroup.ItemIndicator />
|
||||
</RadioGroup.ItemControl>
|
||||
<RadioGroup.ItemLabel class="ui-checked:text-white text-neutral-400">
|
||||
<RadioGroup.ItemLabel class="text-neutral-400 ui-checked:text-white">
|
||||
<div class="block">
|
||||
<div
|
||||
classList={{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { TextField as KTextField } from "@kobalte/core";
|
||||
import { type JSX, Show, splitProps } from "solid-js";
|
||||
import { Show, splitProps, type JSX } from "solid-js";
|
||||
|
||||
import { TinyText } from "~/components";
|
||||
|
||||
export type TextFieldProps = {
|
||||
@@ -41,7 +42,7 @@ export function TextField(props: TextFieldProps) {
|
||||
required={props.required}
|
||||
>
|
||||
<Show when={props.label}>
|
||||
<KTextField.Label class="text-sm uppercase font-semibold">
|
||||
<KTextField.Label class="text-sm font-semibold uppercase">
|
||||
{props.label}
|
||||
</KTextField.Label>
|
||||
</Show>
|
||||
@@ -51,14 +52,14 @@ export function TextField(props: TextFieldProps) {
|
||||
<KTextField.Input
|
||||
{...fieldProps}
|
||||
type={props.type}
|
||||
class="w-full p-2 rounded-lg bg-white/10 placeholder-neutral-400"
|
||||
class="w-full rounded-lg bg-white/10 p-2 placeholder-neutral-400"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<KTextField.TextArea
|
||||
{...fieldProps}
|
||||
autoResize
|
||||
class="w-full p-2 rounded-lg bg-white/10 placeholder-neutral-400"
|
||||
class="w-full rounded-lg bg-white/10 p-2 placeholder-neutral-400"
|
||||
/>
|
||||
</Show>
|
||||
<KTextField.ErrorMessage class="text-m-red">
|
||||
|
||||
@@ -5,7 +5,7 @@ export function MegaCheck() {
|
||||
<img
|
||||
src={megacheck}
|
||||
alt="success"
|
||||
class="w-1/2 mx-auto max-w-[50vh] flex-shrink"
|
||||
class="mx-auto w-1/2 max-w-[50vh] flex-shrink"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ export function MegaEx() {
|
||||
<img
|
||||
src={megaex}
|
||||
alt="fail"
|
||||
class="w-1/2 mx-auto max-w-[30vh] flex-shrink"
|
||||
class="mx-auto w-1/2 max-w-[30vh] flex-shrink"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { JSX } from "solid-js";
|
||||
|
||||
import { Button } from "~/components";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
|
||||
type SuccessModalProps = {
|
||||
open: boolean;
|
||||
@@ -24,10 +25,10 @@ export function SuccessModal(props: SuccessModalProps) {
|
||||
<Dialog.Portal>
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
<Dialog.Description class="flex flex-col items-center justify-center gap-6 h-full w-full max-w-[400px] mx-auto">
|
||||
<Dialog.Description class="mx-auto flex h-full w-full max-w-[400px] flex-col items-center justify-center gap-6">
|
||||
{props.children}
|
||||
</Dialog.Description>
|
||||
<div class="w-full flex max-w-[300px] mx-auto">
|
||||
<div class="mx-auto flex w-full max-w-[300px]">
|
||||
<Button onClick={onNice} intent="inactive">
|
||||
{props.confirmText ??
|
||||
`${i18n.t("common.nice")}`}
|
||||
|
||||
@@ -2,9 +2,10 @@ import { use } from "i18next";
|
||||
// FIXME: this doesn't work when deployed
|
||||
// import HttpApi from 'i18next-http-backend';
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
import en from "~/i18n/en/translations";
|
||||
import pt from "~/i18n/pt/translations";
|
||||
import ko from "~/i18n/ko/translations";
|
||||
import pt from "~/i18n/pt/translations";
|
||||
|
||||
export const resources = {
|
||||
en: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createContext, useContext } from "solid-js";
|
||||
import { i18n } from "i18next";
|
||||
import { createContext, useContext } from "solid-js";
|
||||
|
||||
export const I18nContext = createContext<i18n>();
|
||||
|
||||
|
||||
2
src/i18n/i18next.d.ts
vendored
2
src/i18n/i18next.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { resources, defaultNS } from "~/i18n/config";
|
||||
import { defaultNS, resources } from "~/i18n/config";
|
||||
|
||||
declare module "i18next" {
|
||||
interface CustomTypeOptions {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import initWaila, { PaymentParams } from "@mutinywallet/waila-wasm";
|
||||
|
||||
import { Result } from "~/utils/typescript";
|
||||
|
||||
// Make sure we've initialzied waila before we try to use it
|
||||
|
||||
@@ -12,10 +12,12 @@ import {
|
||||
Scripts,
|
||||
Title
|
||||
} from "solid-start";
|
||||
|
||||
// eslint-disable-next-line
|
||||
import "@mutinywallet/ui/style.css";
|
||||
|
||||
import { ErrorDisplay, I18nProvider, Toaster } from "~/components";
|
||||
import { Provider as MegaStoreProvider } from "~/state/megaStore";
|
||||
import { Toaster, ErrorDisplay, I18nProvider } from "~/components";
|
||||
|
||||
export default function Root() {
|
||||
return (
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
import { For, Show, Suspense, createResource } from "solid-js";
|
||||
import { Tabs } from "@kobalte/core";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { createResource, For, Show, Suspense } from "solid-js";
|
||||
|
||||
import {
|
||||
BackLink,
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack,
|
||||
NavBar,
|
||||
BackLink,
|
||||
CombinedActivity,
|
||||
ContactEditor,
|
||||
ContactFormValues,
|
||||
ContactViewer,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
LoadingShimmer,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
showToast,
|
||||
LoadingShimmer
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { Tabs } from "@kobalte/core";
|
||||
import { gradientsPerContact } from "~/utils/gradientHash";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { gradientsPerContact } from "~/utils/gradientHash";
|
||||
|
||||
function ContactRow() {
|
||||
const i18n = useI18n();
|
||||
@@ -67,7 +68,7 @@ function ContactRow() {
|
||||
<div class="flex gap-4">
|
||||
<ContactEditor list createContact={createContact} />
|
||||
<Show when={contacts()}>
|
||||
<div class="flex gap-4 flex-1 overflow-x-scroll disable-scrollbars">
|
||||
<div class="flex flex-1 gap-4 overflow-x-scroll disable-scrollbars">
|
||||
<For each={contacts()}>
|
||||
{(contact) => (
|
||||
<ContactViewer
|
||||
@@ -97,7 +98,7 @@ export default function Activity() {
|
||||
<LargeHeader>{i18n.t("activity.title")}</LargeHeader>
|
||||
<ContactRow />
|
||||
<Tabs.Root defaultValue="mutiny">
|
||||
<Tabs.List class="relative flex justify-around mt-4 mb-8 gap-1 bg-neutral-950 p-1 rounded-xl">
|
||||
<Tabs.List class="relative mb-8 mt-4 flex justify-around gap-1 rounded-xl bg-neutral-950 p-1">
|
||||
<Tabs.Trigger value="mutiny" class={TAB}>
|
||||
{i18n.t("activity.mutiny")}
|
||||
</Tabs.Trigger>
|
||||
@@ -124,7 +125,7 @@ export default function Activity() {
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="nostr">
|
||||
<VStack>
|
||||
<div class="my-8 flex flex-col items-center gap-4 text-center max-w-[20rem] mx-auto">
|
||||
<div class="mx-auto my-8 flex max-w-[20rem] flex-col items-center gap-4 text-center">
|
||||
<NiceP>
|
||||
{i18n.t("activity.import_contacts")}
|
||||
</NiceP>
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import {
|
||||
SubmitHandler,
|
||||
createForm,
|
||||
email,
|
||||
getValue,
|
||||
required,
|
||||
setValue
|
||||
setValue,
|
||||
SubmitHandler
|
||||
} from "@modular-forms/solid";
|
||||
import { Match, Show, Switch, createSignal } from "solid-js";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { createSignal, Match, Show, Switch } from "solid-js";
|
||||
import { A, useLocation } from "solid-start";
|
||||
|
||||
import feedback from "~/assets/icons/feedback.svg";
|
||||
import { InfoBox, MegaCheck, NavBar } from "~/components";
|
||||
import {
|
||||
BackPop,
|
||||
Button,
|
||||
ButtonLink,
|
||||
Checkbox,
|
||||
@@ -16,16 +21,12 @@ import {
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
VStack,
|
||||
BackPop,
|
||||
StyledRadioGroup,
|
||||
TextField
|
||||
TextField,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import feedback from "~/assets/icons/feedback.svg";
|
||||
import eify from "~/utils/eify";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { InfoBox, MegaCheck, NavBar } from "~/components";
|
||||
import eify from "~/utils/eify";
|
||||
|
||||
const FEEDBACK_API = import.meta.env.VITE_FEEDBACK;
|
||||
|
||||
@@ -34,7 +35,7 @@ export function FeedbackLink(props: { setupError?: boolean }) {
|
||||
const location = useLocation();
|
||||
return (
|
||||
<A
|
||||
class="font-semibold no-underline text-m-grey-350 flex gap-2 items-center"
|
||||
class="flex items-center gap-2 font-semibold text-m-grey-350 no-underline"
|
||||
state={{
|
||||
previous: location.pathname,
|
||||
// If we're coming from an error page we want to know that so we can hide the navbar
|
||||
@@ -303,7 +304,7 @@ export default function Feedback() {
|
||||
|
||||
<Switch>
|
||||
<Match when={submitted()}>
|
||||
<div class="flex flex-col gap-4 items-center h-full">
|
||||
<div class="flex h-full flex-col items-center gap-4">
|
||||
<MegaCheck />
|
||||
<LargeHeader centered>
|
||||
{i18n.t("feedback.received")}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
MutinyBip21RawMaterials,
|
||||
MutinyInvoice
|
||||
} from "@mutinywallet/mutiny-wasm";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import {
|
||||
createEffect,
|
||||
createMemo,
|
||||
@@ -13,42 +14,42 @@ import {
|
||||
Show,
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { objectToSearchParams } from "~/utils/objectToSearchParams";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { useNavigate } from "solid-start";
|
||||
|
||||
import side2side from "~/assets/icons/side-to-side.svg";
|
||||
import {
|
||||
Fee,
|
||||
AmountCard,
|
||||
AmountFiat,
|
||||
AmountSats,
|
||||
BackButton,
|
||||
BackLink,
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
Indicator,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
SimpleDialog,
|
||||
NavBar,
|
||||
AmountSats,
|
||||
AmountFiat,
|
||||
BackLink,
|
||||
TagEditor,
|
||||
StyledRadioGroup,
|
||||
showToast,
|
||||
AmountCard,
|
||||
BackButton,
|
||||
SuccessModal,
|
||||
MegaCheck,
|
||||
InfoBox,
|
||||
Fee,
|
||||
FeesModal,
|
||||
IntegratedQr
|
||||
Indicator,
|
||||
InfoBox,
|
||||
IntegratedQr,
|
||||
LargeHeader,
|
||||
MegaCheck,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
SafeArea,
|
||||
showToast,
|
||||
SimpleDialog,
|
||||
StyledRadioGroup,
|
||||
SuccessModal,
|
||||
TagEditor
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { MutinyTagItem } from "~/utils/tags";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import side2side from "~/assets/icons/side-to-side.svg";
|
||||
import eify from "~/utils/eify";
|
||||
import { matchError } from "~/logic/errorDispatch";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { matchError } from "~/logic/errorDispatch";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { objectToSearchParams } from "~/utils/objectToSearchParams";
|
||||
import { MutinyTagItem } from "~/utils/tags";
|
||||
|
||||
type OnChainTx = {
|
||||
transaction: {
|
||||
@@ -290,9 +291,8 @@ export default function Receive() {
|
||||
try {
|
||||
// Lightning invoice might be blank
|
||||
if (lightning) {
|
||||
const invoice = await state.mutiny_wallet?.get_invoice(
|
||||
lightning
|
||||
);
|
||||
const invoice =
|
||||
await state.mutiny_wallet?.get_invoice(lightning);
|
||||
|
||||
// If the invoice has a fees amount that's probably the LSP fee
|
||||
if (invoice?.fees_paid) {
|
||||
@@ -368,7 +368,7 @@ export default function Receive() {
|
||||
</LargeHeader>
|
||||
<Switch>
|
||||
<Match when={!unified() || receiveState() === "edit"}>
|
||||
<div class="flex flex-col flex-1 gap-8">
|
||||
<div class="flex flex-1 flex-col gap-8">
|
||||
<AmountCard
|
||||
initialOpen={shouldShowAmountEditor()}
|
||||
amountSats={amount() || "0"}
|
||||
@@ -406,19 +406,19 @@ export default function Receive() {
|
||||
amountSats={amount() || "0"}
|
||||
kind={flavor()}
|
||||
/>
|
||||
<p class="text-neutral-400 text-center">
|
||||
<p class="text-center text-neutral-400">
|
||||
{i18n.t("receive.keep_mutiny_open")}
|
||||
</p>
|
||||
{/* Only show method chooser when we have an invoice */}
|
||||
<Show when={bip21Raw()?.invoice}>
|
||||
<button
|
||||
class="font-bold text-m-grey-400 flex gap-2 p-2 items-center mx-auto"
|
||||
class="mx-auto flex items-center gap-2 p-2 font-bold text-m-grey-400"
|
||||
onClick={() => setMethodChooserOpen(true)}
|
||||
>
|
||||
<span>
|
||||
{i18n.t("receive.choose_format")}
|
||||
</span>
|
||||
<img class="w-4 h-4" src={side2side} />
|
||||
<img class="h-4 w-4" src={side2side} />
|
||||
</button>
|
||||
<SimpleDialog
|
||||
title={i18n.t(
|
||||
@@ -451,13 +451,13 @@ export default function Receive() {
|
||||
}}
|
||||
>
|
||||
<MegaCheck />
|
||||
<h1 class="w-full mt-4 mb-2 text-2xl font-semibold text-center md:text-3xl">
|
||||
<h1 class="mb-2 mt-4 w-full text-center text-2xl font-semibold md:text-3xl">
|
||||
{receiveState() === "paid" &&
|
||||
paidState() === "lightning_paid"
|
||||
? i18n.t("receive.payment_received")
|
||||
: i18n.t("receive.payment_initiated")}
|
||||
</h1>
|
||||
<div class="flex flex-col gap-1 items-center">
|
||||
<div class="flex flex-col items-center gap-1">
|
||||
<div class="text-xl">
|
||||
<AmountSats
|
||||
amountSats={
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { MutinyChannel } from "@mutinywallet/mutiny-wasm";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import {
|
||||
createEffect,
|
||||
createMemo,
|
||||
@@ -11,37 +13,36 @@ import {
|
||||
Suspense,
|
||||
Switch
|
||||
} from "solid-js";
|
||||
|
||||
import utxoIcon from "~/assets/icons/coin.svg";
|
||||
import wave from "~/assets/wave.gif";
|
||||
import {
|
||||
CENTER_COLUMN,
|
||||
MISSING_LABEL,
|
||||
REDSHIFT_LABEL,
|
||||
RIGHT_COLUMN,
|
||||
THREE_COLUMNS,
|
||||
AmountSats,
|
||||
BackLink,
|
||||
Button,
|
||||
Card,
|
||||
CENTER_COLUMN,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
MISSING_LABEL,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
NiceP,
|
||||
ProgressBar,
|
||||
REDSHIFT_LABEL,
|
||||
RIGHT_COLUMN,
|
||||
SafeArea,
|
||||
SmallAmount,
|
||||
SmallHeader,
|
||||
VStack,
|
||||
BackLink,
|
||||
StyledRadioGroup,
|
||||
NavBar,
|
||||
Button,
|
||||
ProgressBar,
|
||||
AmountSats
|
||||
THREE_COLUMNS,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import wave from "~/assets/wave.gif";
|
||||
import utxoIcon from "~/assets/icons/coin.svg";
|
||||
import { MutinyChannel } from "@mutinywallet/mutiny-wasm";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { getRedshifted, setRedshifted } from "~/utils/fakeLabels";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
|
||||
type ShiftOption = "utxo" | "lightning";
|
||||
|
||||
@@ -462,7 +463,7 @@ export default function Redshift() {
|
||||
{i18n.t("redshift.title")}{" "}
|
||||
{i18n.t("common.coming_soon")}
|
||||
</LargeHeader>
|
||||
<div class="relative filter grayscale pointer-events-none opacity-75">
|
||||
<div class="pointer-events-none relative opacity-75 grayscale filter">
|
||||
<VStack biggap>
|
||||
{/* <pre>{JSON.stringify(redshiftResource(), null, 2)}</pre> */}
|
||||
<Switch>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { createEffect, createSignal } from "solid-js";
|
||||
import { useNavigate } from "solid-start";
|
||||
import { Button, Scanner as Reader, showToast } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { toParsedParams } from "~/logic/waila";
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { createEffect, createSignal } from "solid-js";
|
||||
import { useNavigate } from "solid-start";
|
||||
|
||||
import { Button, Scanner as Reader, showToast } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { toParsedParams } from "~/logic/waila";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export default function Scanner() {
|
||||
const i18n = useI18n();
|
||||
@@ -63,10 +64,10 @@ export default function Scanner() {
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="safe-top safe-left safe-right safe-bottom h-full">
|
||||
<div class="h-full safe-top safe-left safe-right safe-bottom">
|
||||
<Reader onResult={onResult} />
|
||||
<div class="w-full flex flex-col items-center fixed bottom-[2rem] gap-8 px-8">
|
||||
<div class="w-full max-w-[800px] flex flex-col gap-2">
|
||||
<div class="fixed bottom-[2rem] flex w-full flex-col items-center gap-8 px-8">
|
||||
<div class="flex w-full max-w-[800px] flex-col gap-2">
|
||||
<Button intent="blue" onClick={handlePaste}>
|
||||
{i18n.t("scanner.paste")}
|
||||
</Button>
|
||||
|
||||
@@ -1,53 +1,55 @@
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { Contact, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import {
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
onMount
|
||||
Match,
|
||||
onMount,
|
||||
Show,
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { useNavigate } from "solid-start";
|
||||
|
||||
import { Paste } from "~/assets/svg/Paste";
|
||||
import { Scan } from "~/assets/svg/Scan";
|
||||
import {
|
||||
NavBar,
|
||||
AmountSats,
|
||||
AmountCard,
|
||||
AmountFiat,
|
||||
AmountSats,
|
||||
BackButton,
|
||||
BackLink,
|
||||
Button,
|
||||
ButtonLink,
|
||||
Card,
|
||||
DefaultMain,
|
||||
Fee,
|
||||
HStack,
|
||||
InfoBox,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
VStack,
|
||||
StyledRadioGroup,
|
||||
showToast,
|
||||
MegaCheck,
|
||||
MegaEx,
|
||||
BackLink,
|
||||
TagEditor,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
SafeArea,
|
||||
showToast,
|
||||
SmallHeader,
|
||||
StringShower,
|
||||
AmountCard,
|
||||
BackButton,
|
||||
StyledRadioGroup,
|
||||
SuccessModal,
|
||||
InfoBox,
|
||||
Fee
|
||||
TagEditor,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { Paste } from "~/assets/svg/Paste";
|
||||
import { Scan } from "~/assets/svg/Scan";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { ParsedParams, toParsedParams } from "~/logic/waila";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Contact, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||
import eify from "~/utils/eify";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { useNavigate } from "solid-start";
|
||||
import { MutinyTagItem } from "~/utils/tags";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { ParsedParams, toParsedParams } from "~/logic/waila";
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
|
||||
import { FeedbackLink } from "./Feedback";
|
||||
|
||||
export type SendSource = "lightning" | "onchain";
|
||||
@@ -144,7 +146,7 @@ function DestinationInput(props: {
|
||||
props.setFieldDestination(trim);
|
||||
}}
|
||||
placeholder="bitcoin:..."
|
||||
class="p-2 rounded-lg bg-white/10 placeholder-neutral-400"
|
||||
class="rounded-lg bg-white/10 p-2 placeholder-neutral-400"
|
||||
/>
|
||||
<Button
|
||||
disabled={!props.fieldDestination}
|
||||
@@ -155,13 +157,13 @@ function DestinationInput(props: {
|
||||
</Button>
|
||||
<HStack>
|
||||
<Button onClick={props.handlePaste}>
|
||||
<div class="flex flex-col gap-2 items-center">
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<Paste />
|
||||
<span>{i18n.t("send.paste")}</span>
|
||||
</div>
|
||||
</Button>
|
||||
<ButtonLink href="/scanner">
|
||||
<div class="flex flex-col gap-2 items-center">
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<Scan />
|
||||
<span>{i18n.t("send.scan_qr")}</span>
|
||||
</div>
|
||||
@@ -604,7 +606,7 @@ export default function Send() {
|
||||
<Switch>
|
||||
<Match when={sentDetails()?.failure_reason}>
|
||||
<MegaEx />
|
||||
<h1 class="w-full mt-4 mb-2 text-2xl font-semibold text-center md:text-3xl">
|
||||
<h1 class="mb-2 mt-4 w-full text-center text-2xl font-semibold md:text-3xl">
|
||||
{sentDetails()?.amount
|
||||
? source() === "onchain"
|
||||
? i18n.t("send.payment_initiated")
|
||||
@@ -615,14 +617,14 @@ export default function Send() {
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<MegaCheck />
|
||||
<h1 class="w-full mt-4 mb-2 text-2xl font-semibold text-center md:text-3xl">
|
||||
<h1 class="mb-2 mt-4 w-full text-center text-2xl font-semibold md:text-3xl">
|
||||
{sentDetails()?.amount
|
||||
? source() === "onchain"
|
||||
? i18n.t("send.payment_initiated")
|
||||
: i18n.t("send.payment_sent")
|
||||
: sentDetails()?.failure_reason}
|
||||
</h1>
|
||||
<div class="flex flex-col gap-1 items-center">
|
||||
<div class="flex flex-col items-center gap-1">
|
||||
<div class="text-xl">
|
||||
<AmountSats
|
||||
amountSats={sentDetails()?.amount}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import {
|
||||
AmountCard,
|
||||
Fee,
|
||||
NavBar,
|
||||
OnboardWarning,
|
||||
Button,
|
||||
DefaultMain,
|
||||
ShareCard,
|
||||
Fee,
|
||||
LargeHeader,
|
||||
NavBar,
|
||||
OnboardWarning,
|
||||
SafeArea,
|
||||
ShareCard,
|
||||
VStack
|
||||
} from "~/components";
|
||||
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
import { createForm, required } from "@modular-forms/solid";
|
||||
import { MutinyChannel, MutinyPeer } from "@mutinywallet/mutiny-wasm";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import {
|
||||
createMemo,
|
||||
createResource,
|
||||
createSignal,
|
||||
For,
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
createMemo,
|
||||
createResource,
|
||||
createSignal
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { useNavigate } from "solid-start";
|
||||
|
||||
import {
|
||||
AmountCard,
|
||||
NavBar,
|
||||
showToast,
|
||||
AmountFiat,
|
||||
BackLink,
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
InfoBox,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
BackLink,
|
||||
TextField,
|
||||
VStack,
|
||||
MegaCheck,
|
||||
MegaEx,
|
||||
InfoBox,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
SafeArea,
|
||||
showToast,
|
||||
SuccessModal,
|
||||
AmountFiat
|
||||
TextField,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { MethodChooser, SendSource } from "~/routes/Send";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import { useNavigate } from "solid-start";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
const CHANNEL_FEE_ESTIMATE_ADDRESS =
|
||||
"bc1qf7546vg73ddsjznzq57z3e8jdn6gtw6au576j07kt6d9j7nz8mzsyn6lgf";
|
||||
@@ -282,7 +283,7 @@ export default function Swap() {
|
||||
<Switch>
|
||||
<Match when={channelOpenResult()?.failure_reason}>
|
||||
<MegaEx />
|
||||
<h1 class="w-full mt-4 mb-2 text-2xl font-semibold text-center md:text-3xl">
|
||||
<h1 class="mb-2 mt-4 w-full text-center text-2xl font-semibold md:text-3xl">
|
||||
{channelOpenResult()?.failure_reason
|
||||
? channelOpenResult()?.failure_reason
|
||||
?.message
|
||||
@@ -293,10 +294,10 @@ export default function Swap() {
|
||||
<Match when={channelOpenResult()?.channel}>
|
||||
<MegaCheck />
|
||||
<div class="flex flex-col justify-center">
|
||||
<h1 class="w-full mt-4 mb-2 justify-center text-2xl font-semibold text-center md:text-3xl">
|
||||
<h1 class="mb-2 mt-4 w-full justify-center text-center text-2xl font-semibold md:text-3xl">
|
||||
{i18n.t("swap.initiated")}
|
||||
</h1>
|
||||
<p class="text-xl text-center">
|
||||
<p class="text-center text-xl">
|
||||
{i18n.t("swap.sats_added", {
|
||||
amount: (
|
||||
Number(
|
||||
@@ -310,7 +311,7 @@ export default function Swap() {
|
||||
).toLocaleString()
|
||||
})}
|
||||
</p>
|
||||
<div class="text-sm text-center text-white/70">
|
||||
<div class="text-center text-sm text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={
|
||||
Number(
|
||||
@@ -356,16 +357,16 @@ export default function Swap() {
|
||||
<Show when={!hasLsp()}>
|
||||
<Card>
|
||||
<VStack>
|
||||
<div class="w-full flex flex-col gap-2">
|
||||
<div class="flex w-full flex-col gap-2">
|
||||
<label
|
||||
for="peerselect"
|
||||
class="uppercase font-semibold text-sm"
|
||||
class="text-sm font-semibold uppercase"
|
||||
>
|
||||
{i18n.t("swap.use_existing")}
|
||||
</label>
|
||||
<select
|
||||
name="peerselect"
|
||||
class="bg-black px-4 py-2 rounded truncate w-full"
|
||||
class="w-full truncate rounded bg-black px-4 py-2"
|
||||
onChange={handlePeerSelect}
|
||||
value={selectedPeer()}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Title } from "solid-start";
|
||||
import { HttpStatusCode } from "solid-start/server";
|
||||
|
||||
import { ButtonLink, DefaultMain, LargeHeader, SafeArea } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Switch, Match } from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Match, Switch } from "solid-js";
|
||||
|
||||
import { App, FullscreenLoader, SetupErrorDisplay } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export default function Home() {
|
||||
const [state, _] = useMegaStore();
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import {
|
||||
BackLink,
|
||||
DefaultMain,
|
||||
DeleteEverything,
|
||||
KitchenSink,
|
||||
NavBar,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
VStack,
|
||||
BackLink
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function Admin() {
|
||||
<NiceP>{i18n.t("settings.admin.warning_one")}</NiceP>
|
||||
<NiceP>{i18n.t("settings.admin.warning_two")}</NiceP>
|
||||
<KitchenSink />
|
||||
<div class="rounded-xl p-4 flex flex-col gap-2 bg-m-red overflow-x-hidden">
|
||||
<div class="flex flex-col gap-2 overflow-x-hidden rounded-xl bg-m-red p-4">
|
||||
<SmallHeader>
|
||||
{i18n.t("settings.danger_zone")}
|
||||
</SmallHeader>
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import { createEffect, createSignal, Show } from "solid-js";
|
||||
import { useNavigate } from "solid-start";
|
||||
|
||||
import {
|
||||
BackLink,
|
||||
Button,
|
||||
Checkbox,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack,
|
||||
Checkbox,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SeedWords,
|
||||
BackLink
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useNavigate } from "solid-start";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Show, createEffect, createSignal } from "solid-js";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
function Quiz(props: { setHasCheckedAll: (hasChecked: boolean) => void }) {
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import { Match, Switch, createResource } from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { createResource, Match, Switch } from "solid-js";
|
||||
|
||||
import {
|
||||
AmountSmall,
|
||||
BackLink,
|
||||
Card,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
TinyText,
|
||||
VStack,
|
||||
AmountSmall,
|
||||
BackLink,
|
||||
NavBar
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
function BalanceBar(props: { inbound: number; outbound: number }) {
|
||||
const i18n = useI18n();
|
||||
@@ -26,9 +27,9 @@ function BalanceBar(props: { inbound: number; outbound: number }) {
|
||||
</SmallHeader>
|
||||
<SmallHeader>{i18n.t("settings.channels.inbound")}</SmallHeader>
|
||||
</div>
|
||||
<div class="flex gap-1 w-full">
|
||||
<div class="flex w-full gap-1">
|
||||
<div
|
||||
class="bg-m-green p-2 rounded-l-xl min-w-fit"
|
||||
class="min-w-fit rounded-l-xl bg-m-green p-2"
|
||||
style={{
|
||||
"flex-grow": props.outbound || 1
|
||||
}}
|
||||
@@ -36,7 +37,7 @@ function BalanceBar(props: { inbound: number; outbound: number }) {
|
||||
<AmountSmall amountSats={props.outbound} />
|
||||
</div>
|
||||
<div
|
||||
class="bg-m-blue p-2 rounded-r-xl min-w-fit"
|
||||
class="min-w-fit rounded-r-xl bg-m-blue p-2"
|
||||
style={{
|
||||
"flex-grow": props.inbound || 1
|
||||
}}
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
||||
import { For, Show, createResource, createSignal } from "solid-js";
|
||||
import { createResource, createSignal, For, Show } from "solid-js";
|
||||
import { QRCodeSVG } from "solid-qr-code";
|
||||
|
||||
import {
|
||||
KeyValue,
|
||||
MiniStringShower,
|
||||
InfoBox,
|
||||
NavBar,
|
||||
ShareCard,
|
||||
BackLink,
|
||||
Button,
|
||||
Collapser,
|
||||
DefaultMain,
|
||||
InfoBox,
|
||||
KeyValue,
|
||||
LargeHeader,
|
||||
MiniStringShower,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SettingsCard,
|
||||
ShareCard,
|
||||
SimpleDialog,
|
||||
VStack,
|
||||
BackLink,
|
||||
TextField
|
||||
TextField,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
function Nwc() {
|
||||
const i18n = useI18n();
|
||||
@@ -118,10 +119,10 @@ function Nwc() {
|
||||
/>
|
||||
</KeyValue>
|
||||
|
||||
<div class="w-full bg-white rounded-xl">
|
||||
<div class="w-full rounded-xl bg-white">
|
||||
<QRCodeSVG
|
||||
value={profile.nwc_uri}
|
||||
class="w-full h-full p-8 max-h-[320px]"
|
||||
class="h-full max-h-[320px] w-full p-8"
|
||||
/>
|
||||
</div>
|
||||
<ShareCard text={profile.nwc_uri || ""} />
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
|
||||
import {
|
||||
BackLink,
|
||||
DefaultMain,
|
||||
DeleteEverything,
|
||||
ImportExport,
|
||||
LargeHeader,
|
||||
LoadingIndicator,
|
||||
Logs,
|
||||
NavBar,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
VStack,
|
||||
BackLink
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
function EmergencyStack() {
|
||||
@@ -21,7 +22,7 @@ function EmergencyStack() {
|
||||
<VStack>
|
||||
<ImportExport emergency />
|
||||
<Logs />
|
||||
<div class="rounded-xl p-4 flex flex-col gap-2 bg-m-red overflow-x-hidden">
|
||||
<div class="flex flex-col gap-2 overflow-x-hidden rounded-xl bg-m-red p-4">
|
||||
<SmallHeader>{i18n.t("settings.danger_zone")}</SmallHeader>
|
||||
<DeleteEverything emergency />
|
||||
</div>
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import { createForm } from "@modular-forms/solid";
|
||||
import { createSignal, Show } from "solid-js";
|
||||
|
||||
import {
|
||||
BackLink,
|
||||
Button,
|
||||
ButtonLink,
|
||||
DefaultMain,
|
||||
InfoBox,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack,
|
||||
NavBar,
|
||||
BackLink,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
TextField,
|
||||
InfoBox
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { createForm } from "@modular-forms/solid";
|
||||
import { timeout } from "~/utils/timeout";
|
||||
import eify from "~/utils/eify";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import { timeout } from "~/utils/timeout";
|
||||
|
||||
type EncryptPasswordForm = {
|
||||
existingPassword: string;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { TextField } from "@kobalte/core";
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
import {
|
||||
BackLink,
|
||||
Button,
|
||||
NavBar,
|
||||
DefaultMain,
|
||||
InnerCard,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
BackLink
|
||||
NavBar,
|
||||
SafeArea
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
export default function LnUrlAuth() {
|
||||
const i18n = useI18n();
|
||||
@@ -56,7 +57,7 @@ export default function LnUrlAuth() {
|
||||
{i18n.t("settings.lnurl_auth.title")}
|
||||
</TextField.Label>
|
||||
<TextField.Input
|
||||
class="w-full p-2 rounded-lg text-black"
|
||||
class="w-full rounded-lg p-2 text-black"
|
||||
placeholder="LNURL..."
|
||||
/>
|
||||
<TextField.ErrorMessage class="text-red-500">
|
||||
|
||||
@@ -1,38 +1,39 @@
|
||||
import {
|
||||
createResource,
|
||||
createSignal,
|
||||
Match,
|
||||
Show,
|
||||
Suspense,
|
||||
Switch,
|
||||
createResource,
|
||||
createSignal
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { A } from "solid-start";
|
||||
|
||||
import party from "~/assets/party.gif";
|
||||
import {
|
||||
ConfirmDialog,
|
||||
InfoBox,
|
||||
NavBar,
|
||||
BackLink,
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
DefaultMain,
|
||||
FancyCard,
|
||||
InfoBox,
|
||||
LargeHeader,
|
||||
LoadingShimmer,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
TinyText,
|
||||
VStack,
|
||||
BackLink,
|
||||
LoadingShimmer
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import party from "~/assets/party.gif";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { subscriptionValid } from "~/utils/subscriptions";
|
||||
|
||||
function Perks(props: { alreadySubbed?: boolean }) {
|
||||
const i18n = useI18n();
|
||||
return (
|
||||
<ul class="list-disc ml-8 font-light text-lg">
|
||||
<ul class="ml-8 list-disc text-lg font-light">
|
||||
<Show when={props.alreadySubbed}>
|
||||
<li>{i18n.t("settings.plus.satisfaction")}</li>
|
||||
</Show>
|
||||
@@ -214,7 +215,7 @@ export default function Plus() {
|
||||
<VStack>
|
||||
<Switch>
|
||||
<Match when={state.mutiny_plus}>
|
||||
<img src={party} class="w-1/2 mx-auto" />
|
||||
<img src={party} class="mx-auto w-1/2" />
|
||||
<NiceP>{i18n.t("settings.plus.thanks")}</NiceP>
|
||||
<Perks alreadySubbed />
|
||||
<NiceP>
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { TextField as KTextField } from "@kobalte/core";
|
||||
import {
|
||||
Button,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
VStack,
|
||||
BackLink,
|
||||
NavBar,
|
||||
TextFieldProps,
|
||||
showToast,
|
||||
ConfirmDialog,
|
||||
InfoBox
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { For, Show, createSignal, splitProps } from "solid-js";
|
||||
import pasteIcon from "~/assets/icons/paste.svg";
|
||||
import {
|
||||
SubmitHandler,
|
||||
createForm,
|
||||
custom,
|
||||
required,
|
||||
setValues,
|
||||
SubmitHandler,
|
||||
validate
|
||||
} from "@modular-forms/solid";
|
||||
import { TextField as KTextField } from "@kobalte/core";
|
||||
import eify from "~/utils/eify";
|
||||
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { WORDS_EN } from "~/utils/words";
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { createSignal, For, Show, splitProps } from "solid-js";
|
||||
|
||||
import pasteIcon from "~/assets/icons/paste.svg";
|
||||
import {
|
||||
BackLink,
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
DefaultMain,
|
||||
InfoBox,
|
||||
LargeHeader,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
showToast,
|
||||
TextFieldProps,
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import { WORDS_EN } from "~/utils/words";
|
||||
|
||||
type SeedWordsForm = {
|
||||
words: string[];
|
||||
@@ -67,7 +68,7 @@ export function SeedTextField(props: TextFieldProps) {
|
||||
autocorrect="off"
|
||||
autocomplete="off"
|
||||
type={props.type}
|
||||
class="w-full p-2 rounded-lg border bg-m-grey-750 placeholder-neutral-400"
|
||||
class="w-full rounded-lg border bg-m-grey-750 p-2 placeholder-neutral-400"
|
||||
classList={{
|
||||
"border-m-grey-750": !props.error && !props.value,
|
||||
"border-m-red": !!props.error,
|
||||
@@ -170,16 +171,16 @@ function TwelveWordsEntry() {
|
||||
return (
|
||||
<>
|
||||
<Form onSubmit={onSubmit} class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-4 bg-m-grey-800 p-4 rounded-xl overflow-hidden">
|
||||
<div class="flex flex-col gap-4 overflow-hidden rounded-xl bg-m-grey-800 p-4">
|
||||
<Show when={error()}>
|
||||
<InfoBox accent="red">{error()?.message}</InfoBox>
|
||||
</Show>
|
||||
<ul class="overflow-hidden columns-2 w-full list-none pt-2 pr-2">
|
||||
<ul class="w-full list-none columns-2 overflow-hidden pr-2 pt-2">
|
||||
<FieldArray name="words">
|
||||
{(fieldArray) => (
|
||||
<For each={fieldArray.items}>
|
||||
{(_, index) => (
|
||||
<div class="flex items-center gap-1 mb-2">
|
||||
<div class="mb-2 flex items-center gap-1">
|
||||
<pre class="w-[2rem] text-right">
|
||||
{index() + 1}
|
||||
{"."}
|
||||
@@ -217,7 +218,7 @@ function TwelveWordsEntry() {
|
||||
<div class="flex w-full justify-center">
|
||||
<button
|
||||
onClick={handlePaste}
|
||||
class="bg-white/10 hover:bg-white/20 py-2 px-4 rounded-lg"
|
||||
class="rounded-lg bg-white/10 px-4 py-2 hover:bg-white/20"
|
||||
type="button"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -225,7 +226,7 @@ function TwelveWordsEntry() {
|
||||
<img
|
||||
src={pasteIcon}
|
||||
alt="paste"
|
||||
class="w-4 h-4"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
import { createForm, url } from "@modular-forms/solid";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
|
||||
import {
|
||||
BackLink,
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
NavBar,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
showToast,
|
||||
TextField
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import {
|
||||
MutinyWalletSettingStrings,
|
||||
setSettings
|
||||
} from "~/logic/mutinyWalletSetup";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
TextField,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
showToast,
|
||||
BackLink,
|
||||
NavBar
|
||||
} from "~/components";
|
||||
import eify from "~/utils/eify";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
|
||||
export function SettingsStringsEditor() {
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { For, Show } from "solid-js";
|
||||
import { A } from "solid-start";
|
||||
|
||||
import forward from "~/assets/icons/forward.svg";
|
||||
import {
|
||||
BackLink,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NavBar,
|
||||
SafeArea,
|
||||
SettingsCard,
|
||||
VStack,
|
||||
BackLink,
|
||||
NavBar
|
||||
VStack
|
||||
} from "~/components";
|
||||
import { A } from "solid-start";
|
||||
import { For, Show } from "solid-js";
|
||||
import forward from "~/assets/icons/forward.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
@@ -29,7 +30,7 @@ function SettingsLinkList(props: {
|
||||
{(link) => (
|
||||
<A
|
||||
href={link.href}
|
||||
class="no-underline flex w-full flex-col gap-1 py-2 hover:bg-m-grey-750 active:bg-m-grey-900 px-4"
|
||||
class="flex w-full flex-col gap-1 px-4 py-2 no-underline hover:bg-m-grey-750 active:bg-m-grey-900"
|
||||
classList={{
|
||||
"opacity-50 cursor pointer-events-none grayscale":
|
||||
link.disabled
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
/* @refresh reload */
|
||||
|
||||
// Inspired by https://github.com/solidjs/solid-realworld/blob/main/src/store/index.js
|
||||
import { MutinyBalance, MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import {
|
||||
ParentComponent,
|
||||
createContext,
|
||||
onCleanup,
|
||||
onMount,
|
||||
ParentComponent,
|
||||
useContext
|
||||
} from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { useSearchParams } from "solid-start";
|
||||
|
||||
import { checkBrowserCompatibility } from "~/logic/browserCompatibility";
|
||||
import {
|
||||
MutinyWalletSettingStrings,
|
||||
doubleInitDefense,
|
||||
getSettings,
|
||||
initializeWasm,
|
||||
MutinyWalletSettingStrings,
|
||||
setupMutinyWallet
|
||||
} from "~/logic/mutinyWalletSetup";
|
||||
import { MutinyBalance, MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { MutinyTagItem } from "~/utils/tags";
|
||||
import { checkBrowserCompatibility } from "~/logic/browserCompatibility";
|
||||
import eify from "~/utils/eify";
|
||||
import { ParsedParams } from "~/logic/waila";
|
||||
import eify from "~/utils/eify";
|
||||
import { subscriptionValid } from "~/utils/subscriptions";
|
||||
import { useSearchParams } from "solid-start";
|
||||
import { MutinyTagItem } from "~/utils/tags";
|
||||
|
||||
const MegaStoreContext = createContext<MegaStore>();
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
.solid-select-control[data-disabled="true"] {
|
||||
}
|
||||
.solid-select-control {
|
||||
@apply w-full p-2 rounded-lg bg-white/10 placeholder-neutral-400;
|
||||
@apply w-full rounded-lg bg-white/10 p-2 placeholder-neutral-400;
|
||||
@apply grid leading-6;
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
}
|
||||
.solid-select-control[data-multiple="true"][data-has-value="true"] {
|
||||
@apply flex items-stretch gap-1 flex-wrap;
|
||||
@apply flex flex-wrap items-stretch gap-1;
|
||||
}
|
||||
|
||||
.solid-select-placeholder {
|
||||
@@ -23,16 +23,16 @@
|
||||
@apply col-start-1 row-start-1;
|
||||
}
|
||||
.solid-select-multi-value {
|
||||
@apply flex bg-white/20 rounded items-center px-1;
|
||||
@apply flex items-center rounded bg-white/20 px-1;
|
||||
}
|
||||
|
||||
.solid-select-multi-value-remove {
|
||||
/* TODO: there's gotta be a better way to vertically center this */
|
||||
@apply pl-2 pr-1 leading-3 -mt-2 text-2xl;
|
||||
@apply -mt-2 pl-2 pr-1 text-2xl leading-3;
|
||||
}
|
||||
|
||||
.solid-select-input {
|
||||
@apply bg-transparent caret-transparent flex-grow flex-shrink;
|
||||
@apply flex-shrink flex-grow bg-transparent caret-transparent;
|
||||
outline: 2px solid transparent;
|
||||
@apply col-start-1 row-start-1;
|
||||
}
|
||||
@@ -47,17 +47,17 @@
|
||||
}
|
||||
|
||||
.solid-select-list {
|
||||
@apply max-h-[50vh] min-w-full overflow-y-auto absolute whitespace-nowrap z-10 bg-neutral-950 p-2 rounded-lg;
|
||||
@apply absolute z-10 max-h-[50vh] min-w-full overflow-y-auto whitespace-nowrap rounded-lg bg-neutral-950 p-2;
|
||||
}
|
||||
|
||||
.solid-select-option[data-focused="true"] {
|
||||
}
|
||||
|
||||
.solid-select-option > mark {
|
||||
@apply underline bg-white/10 text-white;
|
||||
@apply bg-white/10 text-white underline;
|
||||
}
|
||||
.solid-select-option {
|
||||
@apply cursor-default select-none p-1 hover:bg-neutral-800 rounded;
|
||||
@apply cursor-default select-none rounded p-1 hover:bg-neutral-800;
|
||||
}
|
||||
.solid-select-option[data-disabled="true"] {
|
||||
@apply pointer-events-none opacity-50;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Thanks you https://soorria.com/snippets/use-copy-solidjs
|
||||
import type { Accessor } from "solid-js";
|
||||
import { createSignal } from "solid-js";
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import type { Accessor } from "solid-js";
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
export type UseCopyProps = {
|
||||
copiedTimeout?: number;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user