Add copy to generate address
This commit is contained in:
@@ -47,6 +47,8 @@ interface QRCodeProps {
|
|||||||
dialogTitle?: string;
|
dialogTitle?: string;
|
||||||
/** Whether to display the raw encoded value as copyable text above the QR code. */
|
/** Whether to display the raw encoded value as copyable text above the QR code. */
|
||||||
showValue?: boolean;
|
showValue?: boolean;
|
||||||
|
/** Optional subtitle to display below the QR code. */
|
||||||
|
subtitle?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,6 +157,7 @@ export function QRCode({
|
|||||||
dialog = false,
|
dialog = false,
|
||||||
dialogTitle = 'QR Code',
|
dialogTitle = 'QR Code',
|
||||||
showValue = false,
|
showValue = false,
|
||||||
|
subtitle = null,
|
||||||
}: QRCodeProps): React.ReactElement {
|
}: QRCodeProps): React.ReactElement {
|
||||||
const { rows, moduleCount } = useMemo(() => {
|
const { rows, moduleCount } = useMemo(() => {
|
||||||
const matrix = generateMatrix(value);
|
const matrix = generateMatrix(value);
|
||||||
@@ -190,6 +193,7 @@ export function QRCode({
|
|||||||
return (
|
return (
|
||||||
<DialogWrapper title={dialogTitle} borderColor={colors.primary} width={dialogWidth}>
|
<DialogWrapper title={dialogTitle} borderColor={colors.primary} width={dialogWidth}>
|
||||||
{qrContent}
|
{qrContent}
|
||||||
|
{subtitle}
|
||||||
</DialogWrapper>
|
</DialogWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
type HistoryDisplayRow,
|
type HistoryDisplayRow,
|
||||||
type HistoryColorName,
|
type HistoryColorName,
|
||||||
} from '../../utils/history-utils.js';
|
} from '../../utils/history-utils.js';
|
||||||
|
import { copyToClipboard } from '../utils/clipboard.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map history color name to theme color.
|
* Map history color name to theme color.
|
||||||
@@ -75,7 +76,10 @@ type HistoryListItem = ListItemData<HistoryDisplayRow>;
|
|||||||
function QRDialogOverlay({ address, onClose }: { address: string; onClose: () => void }): React.ReactElement {
|
function QRDialogOverlay({ address, onClose }: { address: string; onClose: () => void }): React.ReactElement {
|
||||||
useInputLayer('qr-dialog');
|
useInputLayer('qr-dialog');
|
||||||
|
|
||||||
useLayeredInput('qr-dialog', (_input, key) => {
|
useLayeredInput('qr-dialog', (input, key) => {
|
||||||
|
if (input === 'c' || input === 'C') {
|
||||||
|
copyToClipboard(address);
|
||||||
|
}
|
||||||
if (key.escape || key.return) {
|
if (key.escape || key.return) {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
@@ -93,10 +97,13 @@ function QRDialogOverlay({ address, onClose }: { address: string; onClose: () =>
|
|||||||
dialog
|
dialog
|
||||||
dialogTitle="Receive Address"
|
dialogTitle="Receive Address"
|
||||||
showValue
|
showValue
|
||||||
|
subtitle={
|
||||||
|
<Box flexDirection="column" justifyContent="center" marginTop={1}>
|
||||||
|
<Text color={colors.textMuted}>Press C to copy to clipboard</Text>
|
||||||
|
<Text color={colors.textMuted}>Press Enter or Esc to close</Text>
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Box justifyContent="center" marginTop={1}>
|
|
||||||
<Text color={colors.textMuted}>Press Enter or Esc to close</Text>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export interface SelectableUtxoLike {
|
|||||||
selected: boolean;
|
selected: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move to engine
|
||||||
export const hasMissingRequirements = (missingRequirements: {
|
export const hasMissingRequirements = (missingRequirements: {
|
||||||
variables?: string[];
|
variables?: string[];
|
||||||
inputs?: string[];
|
inputs?: string[];
|
||||||
@@ -32,6 +33,7 @@ export const isInvitationRequirementsComplete = async (
|
|||||||
return !hasMissingRequirements(missingRequirements);
|
return !hasMissingRequirements(missingRequirements);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Move to engine in templates.ts
|
||||||
export const resolveActionRoles = (
|
export const resolveActionRoles = (
|
||||||
template: XOTemplate | undefined,
|
template: XOTemplate | undefined,
|
||||||
actionIdentifier: string | undefined,
|
actionIdentifier: string | undefined,
|
||||||
@@ -51,6 +53,7 @@ export const resolveActionRoles = (
|
|||||||
return [...new Set(roleIds)];
|
return [...new Set(roleIds)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Move to engine
|
||||||
export const roleRequiresInputs = (
|
export const roleRequiresInputs = (
|
||||||
template: XOTemplate | undefined,
|
template: XOTemplate | undefined,
|
||||||
actionIdentifier: string | undefined,
|
actionIdentifier: string | undefined,
|
||||||
@@ -75,6 +78,7 @@ export const roleRequiresInputs = (
|
|||||||
return (roleInputs?.length ?? 0) > 0;
|
return (roleInputs?.length ?? 0) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const getTransactionOutputIdentifier = (
|
export const getTransactionOutputIdentifier = (
|
||||||
output: XOTemplateTransactionOutput,
|
output: XOTemplateTransactionOutput,
|
||||||
): string | undefined => {
|
): string | undefined => {
|
||||||
@@ -121,6 +125,7 @@ export const tryCashAddressToLockingBytecodeHex = (
|
|||||||
return binToHex(result.bytecode);
|
return binToHex(result.bytecode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Replace with libauth compiler in the engine
|
||||||
export const resolveProvidedLockingBytecodeHex = (
|
export const resolveProvidedLockingBytecodeHex = (
|
||||||
template: XOTemplate,
|
template: XOTemplate,
|
||||||
outputIdentifier: string,
|
outputIdentifier: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user