Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(mfi-v2-ui): lendbox keyboard nav #1080

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,16 @@ const BorrowLend = (
{...combinedProps}
requestedLendType={ActionType.Deposit}
onCloseDialog={actionBoxProps.isDialog ? actionBoxProps.dialogProps?.onClose : undefined}
searchMode={shouldBeHidden}
searchMode={combinedProps.searchMode}
shouldBeHidden={shouldBeHidden}
setShouldBeHidden={setShouldBeHidden}
/>
<LendBox
{...combinedProps}
requestedLendType={ActionType.Borrow}
onCloseDialog={actionBoxProps.isDialog ? actionBoxProps.dialogProps?.onClose : undefined}
searchMode={shouldBeHidden}
searchMode={combinedProps.searchMode}
shouldBeHidden={shouldBeHidden}
setShouldBeHidden={setShouldBeHidden}
/>
</ActionBoxNavigator>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from "react";

import { ActionType, ExtendedBankInfo, ValidatorStakeGroup } from "@mrgnlabs/marginfi-v2-ui-state";
import { formatAmount } from "@mrgnlabs/mrgn-utils";
import { ActionType, ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
import { formatAmount, useIsMobile } from "@mrgnlabs/mrgn-utils";
import { tokenPriceFormatter, WSOL_MINT } from "@mrgnlabs/mrgn-common";

import { Input } from "~/components/ui/input";
import { LendingAction, BankSelect } from "./components";
import { OracleSetup } from "@mrgnlabs/marginfi-client-v2";

type ActionInputProps = {
amountRaw: string;
Expand Down Expand Up @@ -51,6 +50,7 @@ export const ActionInput = ({
setSelectedBank,
}: ActionInputProps) => {
const amountInputRef = React.useRef<HTMLInputElement>(null);
const isMobile = useIsMobile();

const numberFormater = React.useMemo(() => new Intl.NumberFormat("en-US", { maximumFractionDigits: 10 }), []);

Expand Down Expand Up @@ -88,6 +88,12 @@ export const ActionInput = ({
}
}, [banks, selectedBank, isDepositingStakedCollat]);

React.useEffect(() => {
if (selectedBank && !isMobile) {
amountInputRef.current?.focus();
}
}, [selectedBank, isMobile]);

return (
<div className="rounded-lg p-2.5 bg-mfi-action-box-background-dark">
<div className="flex justify-center gap-1 items-center font-medium text-3xl">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import React from "react";
import Link from "next/link";

import { WalletContextState } from "@solana/wallet-adapter-react";
import { IconInfoCircle, IconSettings } from "@tabler/icons-react";

import {
ActiveBankInfo,
ExtendedBankInfo,
ActionType,
TokenAccountMap,
AccountSummary,
computeAccountSummary,
DEFAULT_ACCOUNT_SUMMARY,
Expand All @@ -26,6 +24,7 @@ import {
MultiStepToastHandle,
PreviousTxn,
usePrevious,
useIsMobile,
} from "@mrgnlabs/mrgn-utils";

import { ActionBoxContentWrapper, ActionButton, ActionSettingsButton } from "~/components/action-box-v2/components";
Expand Down Expand Up @@ -67,6 +66,7 @@ export type LendBoxProps = {

searchMode?: boolean;
onCloseDialog?: () => void;
shouldBeHidden?: boolean;
setShouldBeHidden?: (hidden: boolean) => void;

onComplete?: (previousTxn: PreviousTxn) => void;
Expand Down Expand Up @@ -95,6 +95,7 @@ export const LendBox = ({
stakeAccounts,
setDisplaySettings,
onCloseDialog,
shouldBeHidden = false,
searchMode = false,
setShouldBeHidden,
}: LendBoxProps) => {
Expand Down Expand Up @@ -142,39 +143,39 @@ export const LendBox = ({

const hasRefreshed = React.useRef(false);
const _prevSelectedBank = usePrevious(selectedBank);
const _prevSearchMode = usePrevious(searchMode);
const _prevShouldBeHidden = usePrevious(shouldBeHidden);

/**
* Handles visibility and state refresh logic when `searchMode` is enabled.
* Handles visibility and state refresh logic when `shouldBeHidden` is enabled.
* - If no bank is selected, hide the component.
* - If a bank is selected, show the component.
* - If `searchMode` is first enabled and a bank was already selected, refresh the state.
* - If `shouldBeHidden` is first enabled and a bank was already selected, refresh the state.
*/
React.useEffect(() => {
if (!searchMode) return;
if (!shouldBeHidden) return;

if (!selectedBank) {
setShouldBeHidden?.(true);
} else {
setShouldBeHidden?.(false);
}

// Refresh state when searchMode is enabled and a bank was initially selected
// Refresh state when shouldBeHidden is enabled and a bank was initially selected
if (!hasRefreshed.current && _prevSelectedBank === undefined && selectedBank) {
refreshState();
hasRefreshed.current = true;
}
}, [searchMode, selectedBank, _prevSelectedBank, setShouldBeHidden, refreshState]);
}, [shouldBeHidden, selectedBank, _prevSelectedBank, setShouldBeHidden, refreshState]);

/**
* Resets `hasRefreshed` when `searchMode` changes from `false` → `true`.
* This ensures `refreshState()` can run again when toggling `searchMode` on.
* Resets `hasRefreshed` when `shouldBeHidden` changes from `false` → `true`.
* This ensures `refreshState()` can run again when toggling `shouldBeHidden` on.
*/
React.useEffect(() => {
if (_prevSearchMode === false && searchMode === true) {
if (_prevShouldBeHidden === false && shouldBeHidden === true) {
hasRefreshed.current = false;
}
}, [searchMode, _prevSearchMode]);
}, [shouldBeHidden, _prevShouldBeHidden]);

const [isTransactionExecuting, setIsTransactionExecuting] = React.useState(false);
const [isSimulating, setIsSimulating] = React.useState<{
Expand Down Expand Up @@ -229,6 +230,8 @@ export const LendBox = ({
const [lstDialogCallback, setLSTDialogCallback] = React.useState<(() => void) | null>(null);
const [additionalActionMessages, setAdditionalActionMessages] = React.useState<ActionMessageType[]>([]);

const isMobile = useIsMobile();

// Cleanup the store when the wallet disconnects
React.useEffect(() => {
if (!connected) {
Expand Down Expand Up @@ -590,6 +593,35 @@ export const LendBox = ({
}
}, [marginfiClient, banks, refreshSelectedBanks]);

React.useEffect(() => {
const handleKeyPress = async (event: KeyboardEvent) => {
if (isMobile || event.key !== "Enter" || isLoading || !connected || searchMode) {
return;
}

const isActionEnabled = !additionalActionMessages
.concat(actionMessages)
.filter((value) => value.isEnabled === false).length;

if (isActionEnabled) {
showCloseBalance ? await handleCloseBalance() : await handleLendingAction();
}
};

document.addEventListener("keypress", handleKeyPress);
return () => document.removeEventListener("keypress", handleKeyPress);
}, [
isLoading,
connected,
additionalActionMessages,
actionMessages,
showCloseBalance,
handleCloseBalance,
handleLendingAction,
isMobile,
searchMode,
]);

return (
<ActionBoxContentWrapper>
<div className="mb-4">
Expand All @@ -608,9 +640,9 @@ export const LendBox = ({
showTokenSelectionGroups={showTokenSelectionGroups}
setAmountRaw={setAmountRaw}
setSelectedBank={setSelectedBank}
searchMode={searchMode}
searchMode={shouldBeHidden}
onCloseDialog={() => {
searchMode && onCloseDialog?.();
shouldBeHidden && onCloseDialog?.();
}}
/>
</div>
Expand Down