option to remember invoice type choice

This commit is contained in:
Paul Miller
2023-09-22 17:41:49 -05:00
parent 8555f3a1f3
commit c0d540518f
7 changed files with 73 additions and 24 deletions

View File

@@ -328,11 +328,11 @@ export function ModalCloseButton() {
);
}
export const SIMPLE_OVERLAY = "fixed inset-0 z-50 bg-black/20 backdrop-blur-md";
export const SIMPLE_OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-lg";
export const SIMPLE_DIALOG_POSITIONER =
"fixed inset-0 z-50 flex items-center justify-center";
export const SIMPLE_DIALOG_CONTENT =
"max-w-[500px] w-[90vw] max-h-[100dvh] overflow-y-scroll disable-scrollbars mx-4 p-4 bg-neutral-800/80 backdrop-blur-md shadow-xl rounded-xl border border-white/10";
"max-w-[500px] w-[90vw] max-h-[100dvh] overflow-y-scroll disable-scrollbars mx-4 p-4 bg-neutral-800/90 rounded-xl border border-white/10";
export const SimpleDialog: ParentComponent<{
title: string;

View File

@@ -1,5 +1,7 @@
import { RadioGroup } from "@kobalte/core";
import { For, Show } from "solid-js";
import { createSignal, For, Show } from "solid-js";
import { timeout } from "~/utils";
type Choices = {
value: string;
@@ -10,18 +12,31 @@ type Choices = {
// TODO: how could would it be if we could just pass the estimated fees in here?
export function StyledRadioGroup(props: {
value: string;
initialValue: string;
choices: Choices;
onValueChange: (value: string) => void;
small?: boolean;
accent?: "red" | "white";
vertical?: boolean;
delayOnChange?: boolean;
}) {
const [value, setValue] = createSignal(props.initialValue);
async function onChange(value: string) {
setValue(value);
// This is so if the modal is going to be closed after value change, it will show the choice briefly first
if (props.delayOnChange) {
await timeout(200);
props.onValueChange(value);
} else {
props.onValueChange(value);
}
}
return (
// TODO: rewrite this with CVA, props are bad for tailwind
<RadioGroup.Root
value={props.value}
onChange={props.onValueChange}
value={value()}
onChange={onChange}
class={"w-full gap-4"}
classList={{
"flex flex-col": props.vertical,
@@ -36,7 +51,7 @@ export function StyledRadioGroup(props: {
{(choice) => (
<RadioGroup.Item
value={choice.value}
class={`rounded bg-white/10 outline outline-black/50 ui-checked:bg-neutral-950 ui-checked:outline-2 ui-checked:outline-m-blue`}
class={`rounded-lg bg-m-grey-700 ui-checked:outline`}
classList={{
"ui-checked:outline-m-red": props.accent === "red",
"ui-checked:outline-white":
@@ -45,19 +60,28 @@ export function StyledRadioGroup(props: {
}}
disabled={choice.disabled}
>
<div class={props.small ? "px-2 py-2" : "px-4 py-3"}>
<div
class={"flex items-center gap-2 p-4"}
classList={{ "px-2 py-2": props.small }}
>
<RadioGroup.ItemInput />
<RadioGroup.ItemControl>
<RadioGroup.ItemIndicator />
<RadioGroup.ItemControl
class="flex aspect-square h-6 w-6 items-center justify-center rounded-full border"
classList={{
hidden: !props.vertical
}}
>
<RadioGroup.ItemIndicator class="h-3 w-3 rounded-full bg-white" />
</RadioGroup.ItemControl>
<RadioGroup.ItemLabel class="text-neutral-400 ui-checked:text-white">
<RadioGroup.ItemLabel>
<div class="block">
<div
class={"font-semibold"}
classList={{
"text-base": props.small,
"text-lg": !props.small
"text-md": !props.small,
"text-sm": !props.vertical
}}
class={`font-semibold max-sm:text-sm`}
>
{choice.label}
</div>

View File

@@ -89,7 +89,8 @@ export default {
onchain: "On-chain",
lightning: "Lightning",
unified: "Unified"
}
},
remember_choice: "Remember my choice next time"
},
send: {
sending: "Sending...",

View File

@@ -24,6 +24,7 @@ import {
BackLink,
Button,
Card,
Checkbox,
DefaultMain,
ExternalLink,
Fee,
@@ -110,7 +111,7 @@ function FeeWarning(props: { fee: bigint; flavor: ReceiveFlavor }) {
}
export default function Receive() {
const [state, _actions] = useMegaStore();
const [state, actions] = useMegaStore();
const navigate = useNavigate();
const i18n = useI18n();
@@ -132,8 +133,10 @@ export default function Receive() {
const [paymentTx, setPaymentTx] = createSignal<OnChainTx>();
const [paymentInvoice, setPaymentInvoice] = createSignal<MutinyInvoice>();
// The flavor of the receive
const [flavor, setFlavor] = createSignal<ReceiveFlavor>("unified");
// The flavor of the receive (defaults to unified)
const [flavor, setFlavor] = createSignal<ReceiveFlavor>(
state.preferredInvoiceType
);
// loading state for the continue button
const [loading, setLoading] = createSignal(false);
@@ -156,6 +159,8 @@ export default function Receive() {
}
];
const [rememberChoice, setRememberChoice] = createSignal(false);
const receiveString = createMemo(() => {
if (unified() && receiveState() === "show") {
if (flavor() === "unified") {
@@ -326,6 +331,9 @@ export default function Receive() {
function selectFlavor(flavor: string) {
setFlavor(flavor as ReceiveFlavor);
if (rememberChoice()) {
actions.setPreferredInvoiceType(flavor as ReceiveFlavor);
}
setMethodChooserOpen(false);
}
@@ -434,11 +442,19 @@ export default function Receive() {
}
>
<StyledRadioGroup
value={flavor()}
initialValue={flavor()}
onValueChange={selectFlavor}
choices={RECEIVE_FLAVORS}
accent="white"
vertical
delayOnChange
/>
<Checkbox
label={i18n.t(
"receive.remember_choice"
)}
checked={rememberChoice()}
onChange={setRememberChoice}
/>
</SimpleDialog>
</Show>

View File

@@ -473,7 +473,7 @@ export default function Redshift() {
</NiceP>
<StyledRadioGroup
accent="red"
value={shiftType()}
initialValue={shiftType()}
onValueChange={(newValue) =>
setShiftType(
newValue as ShiftOption

View File

@@ -102,7 +102,7 @@ export function MethodChooser(props: {
<Match when={props.both}>
<StyledRadioGroup
accent="white"
value={props.source}
initialValue={props.source}
onValueChange={props.setSource}
choices={methods()}
/>
@@ -110,7 +110,7 @@ export function MethodChooser(props: {
<Match when={props.source === "lightning"}>
<StyledRadioGroup
accent="white"
value={props.source}
initialValue={props.source}
onValueChange={props.setSource}
choices={[methods()[0]]}
/>
@@ -118,7 +118,7 @@ export function MethodChooser(props: {
<Match when={props.source === "onchain"}>
<StyledRadioGroup
accent="white"
value={props.source}
initialValue={props.source}
onValueChange={props.setSource}
choices={[methods()[1]]}
/>

View File

@@ -55,6 +55,7 @@ export type MegaStore = [
settings?: MutinyWalletSettingStrings;
safe_mode?: boolean;
npub?: string;
preferredInvoiceType: "unified" | "lightning" | "onchain";
},
{
setup(password?: string): Promise<void>;
@@ -67,6 +68,9 @@ export type MegaStore = [
fetchPrice(fiat: Currency): Promise<number>;
saveFiat(fiat: Currency): void;
saveNpub(npub: string): void;
setPreferredInvoiceType(
type: "unified" | "lightning" | "onchain"
): void;
}
];
@@ -98,7 +102,8 @@ export const Provider: ParentComponent = (props) => {
load_stage: "fresh" as LoadStage,
settings: undefined as MutinyWalletSettingStrings | undefined,
safe_mode: searchParams.safe_mode === "true",
npub: localStorage.getItem("npub") || undefined
npub: localStorage.getItem("npub") || undefined,
preferredInvoiceType: "unified" as "unified" | "lightning" | "onchain"
});
const actions = {
@@ -306,6 +311,9 @@ export const Provider: ParentComponent = (props) => {
saveNpub(npub: string) {
localStorage.setItem("npub", npub);
setState({ npub });
},
setPreferredInvoiceType(type: "unified" | "lightning" | "onchain") {
setState({ preferredInvoiceType: type });
}
};