Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/three-fans-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": patch
---

Add Last Used badge in Connect UI to highlight the last used sign-in method
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { AuthArgsType } from "../../../../../wallets/in-app/core/authentication/types.js";
import { LAST_USED_WALLET_ID } from "../../../../../wallets/manager/index.js";
import type { WalletId } from "../../../../../wallets/wallet-types.js";
import { LAST_AUTH_PROVIDER_STORAGE_KEY } from "../../../../core/utils/storage.js";

export function getLastUsedWalletId() {
try {
if (typeof window !== "undefined" && window.localStorage) {
return window.localStorage.getItem(
LAST_USED_WALLET_ID,
) as WalletId | null;
}
} catch {
// ignore
}
return null;
}

Check warning on line 17 in packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts#L15-L17

Added lines #L15 - L17 were not covered by tests

export function getLastUsedSocialAuth() {
try {
if (typeof window !== "undefined" && window.localStorage) {
return window.localStorage.getItem(LAST_AUTH_PROVIDER_STORAGE_KEY) as
| (AuthArgsType["strategy"] & string)
| null;
}
} catch {
// ignore
}
return null;
}

Check warning on line 30 in packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts#L28-L30

Added lines #L28 - L30 were not covered by tests
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ export const WalletButtonEl = /* @__PURE__ */ StyledButton((_) => {
'&[data-active="true"]': {
backgroundColor: theme.colors.tertiaryBg,
},

alignItems: "center",
borderRadius: radius.md,
boxSizing: "border-box",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";
import { ChevronLeftIcon } from "@radix-ui/react-icons";
import { useEffect, useRef, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import type { Chain } from "../../../../chains/types.js";
import type { ThirdwebClient } from "../../../../client/client.js";
import type { InjectedSupportedWalletIds } from "../../../../wallets/__generated__/wallet-ids.js";
Expand All @@ -19,6 +19,7 @@
import { useSetSelectionData } from "../../providers/wallet-ui-states-provider.js";
import { sortWallets } from "../../utils/sortWallets.js";
import InAppWalletSelectionUI from "../../wallets/in-app/InAppWalletSelectionUI.js";
import { LAST_USED_BADGE_VERTICAL_RESERVED_SPACE } from "../components/badge.js";
import {
Container,
Line,
Expand All @@ -38,6 +39,7 @@
import type { ConnectLocale } from "./locale/types.js";
import { SmartConnectUI } from "./Modal/SmartWalletConnectUI.js";
import { useScreenContext } from "./Modal/screen.js";
import { getLastUsedWalletId } from "./Modal/storage.js";
import { TOS } from "./Modal/TOS.js";
import { PoweredByThirdweb } from "./PoweredByTW.js";
import { WalletButtonEl, WalletEntryButton } from "./WalletEntryButton.js";
Expand Down Expand Up @@ -136,6 +138,7 @@
const [approvedTOS, setApprovedTOS] = useState(false);

const installedWallets = getInstalledWallets();
const lastUsedWalletId = useMemo(() => getLastUsedWalletId(), []);

Check warning on line 141 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L141

Added line #L141 was not covered by tests
const propsWallets = props.wallets;
let _wallets: Wallet[] = [...propsWallets];

Expand Down Expand Up @@ -219,6 +222,11 @@
const connectAWallet = (
<WalletTypeRowButton
className="tw-select-connect-a-wallet-button"
lastUsedBadge={
!!lastUsedWalletId &&
lastUsedWalletId !== "inApp" &&
!lastUsedWalletId.startsWith("ecosystem.")

Check warning on line 228 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L225-L228

Added lines #L225 - L228 were not covered by tests
}
client={props.client}
disabled={props.meta.requireApproval && !approvedTOS}
icon={OutlineWalletIcon}
Expand Down Expand Up @@ -497,7 +505,7 @@
>
{/* Header */}
{showHeader && (
<Container p="lg">
<Container px="lg" pt="lg" pb="xs">

Check warning on line 508 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L508

Added line #L508 was not covered by tests
{isWalletGroupExpanded ? (
<ModalHeader
onBack={() => {
Expand All @@ -514,41 +522,42 @@
{/* Body */}
<Container
expand
px="md"
scrollY
style={
!showHeader
? {
paddingTop: spacing.lg,
paddingTop: spacing.md,

Check warning on line 529 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L529

Added line #L529 was not covered by tests
}
: {
paddingTop: "2px",
}
}
>
{!showHeader && isWalletGroupExpanded && (
<Container
center="y"
flex="row"
style={{
padding: spacing.sm,
paddingTop: 0,
}}
>
<IconButton
onClick={() => {
setIsWalletGroupExpanded(false);
}}
<Container px="md">
<Container
center="y"
flex="row"

Check warning on line 540 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L537-L540

Added lines #L537 - L540 were not covered by tests
style={{
gap: spacing.xxs,
paddingBlock: spacing.xxs,
paddingRight: spacing.xs,
transform: `translateX(-${spacing.xs})`,
padding: spacing.sm,
paddingTop: 0,

Check warning on line 543 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L542-L543

Added lines #L542 - L543 were not covered by tests
}}
>
<ChevronLeftIcon height={iconSize.sm} width={iconSize.sm} />
{props.connectLocale.goBackButton}
</IconButton>
<IconButton
onClick={() => {
setIsWalletGroupExpanded(false);
}}
style={{
gap: spacing.xxs,
paddingBlock: spacing.xxs,
paddingRight: spacing.xs,
transform: `translateX(-${spacing.xs})`,
}}

Check warning on line 555 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L546-L555

Added lines #L546 - L555 were not covered by tests
>
<ChevronLeftIcon height={iconSize.sm} width={iconSize.sm} />
{props.connectLocale.goBackButton}
</IconButton>
</Container>

Check warning on line 560 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L557-L560

Added lines #L557 - L560 were not covered by tests
</Container>
)}

Expand Down Expand Up @@ -602,11 +611,16 @@
const wallets = sortWallets(props.wallets, props.recommendedWallets);
const { screen } = useScreenContext();
const setSelectionData = useSetSelectionData();

const lastUsedWalletId = useMemo(() => getLastUsedWalletId(), []);

Check warning on line 615 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L615

Added line #L615 was not covered by tests

return (
<WalletList
style={{
maxHeight: "370px",
minHeight: "100%",
paddingTop:
props.size === "wide" ? 0 : LAST_USED_BADGE_VERTICAL_RESERVED_SPACE,

Check warning on line 623 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L622-L623

Added lines #L622 - L623 were not covered by tests
}}
>
{wallets.map((wallet) => {
Expand Down Expand Up @@ -634,7 +648,7 @@
) : (
<WalletEntryButton
className="tw-wallet-select-wallet-button"
badge={undefined}
badge={lastUsedWalletId === wallet.id ? "Last used" : undefined}

Check warning on line 651 in packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx#L651

Added line #L651 was not covered by tests
client={props.client}
connectLocale={props.connectLocale}
isActive={isActive}
Expand Down Expand Up @@ -730,7 +744,7 @@
margin: "-2px",
marginBottom: 0,
// to show the box-shadow of inputs that overflows
padding: "2px",
paddingInline: spacing.md,
paddingBottom: spacing.lg,
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ThirdwebClient } from "../../../../client/client.js";
import { iconSize, spacing } from "../../../core/design-system/index.js";
import { Text } from "../../ui/components/text.js";
import { LastUsedBadge } from "../components/badge.js";
import { Container } from "../components/basic.js";
import { Button } from "../components/buttons.js";
import type { IconFC } from "./icons/types.js";
Expand All @@ -12,6 +13,7 @@ type WalletTypeRowProps = {
icon: IconFC;
disabled?: boolean;
className?: string;
lastUsedBadge: boolean;
};

export function WalletTypeRowButton(props: WalletTypeRowProps) {
Expand All @@ -27,9 +29,11 @@ export function WalletTypeRowButton(props: WalletTypeRowProps) {
display: "flex",
justifyContent: "flex-start",
padding: spacing.sm,
position: "relative",
}}
variant="outline"
>
{props.lastUsedBadge && <LastUsedBadge />}
<Container center="y" color="accentText" flex="row" gap="sm">
<props.icon size={iconSize.md} />
<Text color="primaryText">{props.title}</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
</Text>
<Spacer y="xl" />
<InputSelectionUI
lastUsedBadge={false}

Check warning on line 156 in packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx#L156

Added line #L156 was not covered by tests
disabled={
loading || !!errorConnecting || !walletConnectClient
}
Expand Down
49 changes: 49 additions & 0 deletions packages/thirdweb/src/react/web/ui/components/badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { radius, spacing } from "../../../core/design-system/index.js";
import { Container } from "./basic.js";
import { Text } from "./text.js";

function Badge(props: { text: string }) {
return (
<Container
bg="modalBg"
color="secondaryText"
borderColor="borderColor"
flex="row"
center="y"
style={{
borderRadius: radius.full,
padding: `${spacing["3xs"]} ${spacing.xs}`,
borderWidth: "1px",
borderStyle: "solid",
}}

Check warning on line 18 in packages/thirdweb/src/react/web/ui/components/badge.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/components/badge.tsx#L5-L18

Added lines #L5 - L18 were not covered by tests
>
<Text
style={{
fontSize: 10,
whiteSpace: "nowrap",
}}

Check warning on line 24 in packages/thirdweb/src/react/web/ui/components/badge.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/components/badge.tsx#L20-L24

Added lines #L20 - L24 were not covered by tests
>
{props.text}
</Text>
</Container>

Check warning on line 28 in packages/thirdweb/src/react/web/ui/components/badge.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/components/badge.tsx#L26-L28

Added lines #L26 - L28 were not covered by tests
);
}

Check warning on line 30 in packages/thirdweb/src/react/web/ui/components/badge.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/components/badge.tsx#L30

Added line #L30 was not covered by tests

export function LastUsedBadge() {
return (
<div
style={{
position: "absolute",
top: -10,
right: -10,
zIndex: 1,
pointerEvents: "none",
cursor: "default",
}}

Check warning on line 42 in packages/thirdweb/src/react/web/ui/components/badge.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/components/badge.tsx#L33-L42

Added lines #L33 - L42 were not covered by tests
>
<Badge text="Last used" />
</div>

Check warning on line 45 in packages/thirdweb/src/react/web/ui/components/badge.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/components/badge.tsx#L44-L45

Added lines #L44 - L45 were not covered by tests
);
}

Check warning on line 47 in packages/thirdweb/src/react/web/ui/components/badge.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/components/badge.tsx#L47

Added line #L47 was not covered by tests

export const LAST_USED_BADGE_VERTICAL_RESERVED_SPACE = 12;
12 changes: 12 additions & 0 deletions packages/thirdweb/src/react/web/utils/sortWallets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getInstalledWalletProviders } from "../../../wallets/injected/mipdStore.js";
import type { WalletId } from "../../../wallets/wallet-types.js";
import { getLastUsedWalletId } from "../ui/ConnectWallet/Modal/storage.js";

/**
*
Expand All @@ -10,6 +11,7 @@
recommendedWallets?: { id: WalletId }[],
): T[] {
const providers = getInstalledWalletProviders();
const lastUsedWalletId = getLastUsedWalletId();

Check warning on line 14 in packages/thirdweb/src/react/web/utils/sortWallets.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/utils/sortWallets.ts#L14

Added line #L14 was not covered by tests
return (
wallets
// show the installed wallets first
Expand Down Expand Up @@ -38,6 +40,16 @@
}
return 0;
})
// show the last used wallet even before recommended wallets
.sort((a, b) => {
if (a.id === lastUsedWalletId) {
return -1;
}
if (b.id === lastUsedWalletId) {
return 1;
}
return 0;
})

Check warning on line 52 in packages/thirdweb/src/react/web/utils/sortWallets.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/utils/sortWallets.ts#L44-L52

Added lines #L44 - L52 were not covered by tests
// show in-app wallets first
.sort((a, b) => {
const aIsInApp = a.id === "inApp" || a.id === "embedded";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe("InputSelectionUI", () => {

render(
<InputSelectionUI
lastUsedBadge={false}
defaultSmsCountryCode="CA"
format="phone"
name=""
Expand All @@ -31,6 +32,7 @@ describe("InputSelectionUI", () => {
it('should initialize countryCodeInfo with "US +1" if defaultSmsCountryCode is not provided', () => {
render(
<InputSelectionUI
lastUsedBadge={false}
format="phone"
name=""
onSelect={vi.fn()}
Expand All @@ -49,6 +51,7 @@ describe("InputSelectionUI", () => {

render(
<InputSelectionUI
lastUsedBadge={false}
allowedSmsCountryCodes={["IN", "BR"]}
format="phone"
name=""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
radius,
spacing,
} from "../../../core/design-system/index.js";
import { LastUsedBadge } from "../../ui/components/badge.js";
import { IconButton } from "../../ui/components/buttons.js";
import { Input, InputContainer } from "../../ui/components/formElements.js";
import { Spacer } from "../../ui/components/Spacer.js";
Expand All @@ -26,6 +27,7 @@ export function InputSelectionUI(props: {
disabled?: boolean;
defaultSmsCountryCode?: SupportedSmsCountry;
allowedSmsCountryCodes?: SupportedSmsCountry[];
lastUsedBadge: boolean;
}) {
const [countryCodeInfo, setCountryCodeInfo] = useState(
props.defaultSmsCountryCode
Expand Down Expand Up @@ -72,6 +74,8 @@ export function InputSelectionUI(props: {
position: "relative",
}}
>
{props.lastUsedBadge && <LastUsedBadge />}

{props.format === "phone" && (
<CountrySelector
allowedCountryCodes={props.allowedSmsCountryCodes}
Expand Down
Loading
Loading