From 242cd8466755420ff8890741ebebdf91acf3dfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Paczy=C5=84ski?= Date: Thu, 14 Dec 2023 09:55:28 +0100 Subject: [PATCH 1/6] Create reusable `SharedAvatar` component --- .../Shared/SharedAccountItemSummary.tsx | 25 ++++++------- ui/components/Shared/SharedAddressAvatar.tsx | 23 +++++------- ui/components/Shared/SharedAvatar.tsx | 36 +++++++++++++++++++ .../SharedCurrentAccountInformation.tsx | 18 ++++------ 4 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 ui/components/Shared/SharedAvatar.tsx diff --git a/ui/components/Shared/SharedAccountItemSummary.tsx b/ui/components/Shared/SharedAccountItemSummary.tsx index ce174e7770..6ec6d36e9b 100644 --- a/ui/components/Shared/SharedAccountItemSummary.tsx +++ b/ui/components/Shared/SharedAccountItemSummary.tsx @@ -4,6 +4,17 @@ import { AccountTotal } from "@tallyho/tally-background/redux-slices/selectors" import { useTranslation } from "react-i18next" import SharedLoadingSpinner from "./SharedLoadingSpinner" +import SharedAvatar from "./SharedAvatar" + +function Avatar({ avatarURL }: { avatarURL?: string }) { + return ( + + ) +} interface Props { isSelected?: boolean @@ -33,10 +44,10 @@ export default function SharedAccountItemSummary(props: Props): ReactElement {
{isSelected ? (
-
+
) : ( -
+ )}
@@ -91,16 +102,6 @@ export default function SharedAccountItemSummary(props: Props): ReactElement { padding: 5px 0; overflow: hidden; } - .avatar { - background: url("${avatarURL ?? "./images/avatar@2x.png"}") center - no-repeat; - background-color: var(--green-40); - background-size: cover; - width: 48px; - height: 48px; - border-radius: 12px; - flex-shrink: 0; - } .avatar_selected_outline { width: 52px; height: 52px; diff --git a/ui/components/Shared/SharedAddressAvatar.tsx b/ui/components/Shared/SharedAddressAvatar.tsx index 0db8c4200d..08780964d6 100644 --- a/ui/components/Shared/SharedAddressAvatar.tsx +++ b/ui/components/Shared/SharedAddressAvatar.tsx @@ -1,4 +1,5 @@ import React, { ReactElement } from "react" +import SharedAvatar from "./SharedAvatar" /* @TODO Switch to using our own resolution service, especially @@ -12,20 +13,12 @@ export default function SharedAddressAvatar({ url?: string }): ReactElement { return ( -
- -
+ ) } diff --git a/ui/components/Shared/SharedAvatar.tsx b/ui/components/Shared/SharedAvatar.tsx new file mode 100644 index 0000000000..99fe9e50ba --- /dev/null +++ b/ui/components/Shared/SharedAvatar.tsx @@ -0,0 +1,36 @@ +import React, { CSSProperties } from "react" + +type SharedAvatarProps = { + width: string + background?: string + borderRadius?: string + avatarURL?: string + backupAvatar: string + style?: CSSProperties +} + +export default function SharedAvatar({ + width, + background = "var(--green-40)", + borderRadius = "12px", + avatarURL, + backupAvatar, + style, +}: SharedAvatarProps) { + return ( + <> +
+ + + ) +} diff --git a/ui/components/Shared/SharedCurrentAccountInformation.tsx b/ui/components/Shared/SharedCurrentAccountInformation.tsx index 1b3ec8ff6a..70070e4047 100644 --- a/ui/components/Shared/SharedCurrentAccountInformation.tsx +++ b/ui/components/Shared/SharedCurrentAccountInformation.tsx @@ -2,6 +2,7 @@ import React, { ReactElement } from "react" import classNames from "classnames" import SharedIcon from "./SharedIcon" import { useAreInternalSignersUnlocked } from "../../hooks/signing-hooks" +import SharedAvatar from "./SharedAvatar" type Props = { shortenedAddress: string @@ -25,7 +26,12 @@ export default function SharedCurrentAccountInformation({ {name ?? shortenedAddress} -
+ {showLockStatus && (
Date: Thu, 14 Dec 2023 11:30:57 +0100 Subject: [PATCH 2/6] Move avatar type fetching to redux --- background/main.ts | 10 +++++++- background/redux-slices/accounts.ts | 9 ++++--- .../selectors/accountsSelectors.ts | 8 +++++-- .../Shared/SharedAccountItemSummary.tsx | 13 +++++++--- ui/components/Shared/SharedAddressAvatar.tsx | 13 ++++++---- ui/components/Shared/SharedAvatar.tsx | 24 +++++++++++++++++-- .../SharedCurrentAccountInformation.tsx | 3 +++ .../SharedCurrentAccountInformation.test.tsx | 5 ++++ .../SigningNetworkAccountInfoTopBar.tsx | 4 +++- .../TopMenu/TopMenuProfileButton.tsx | 3 ++- 10 files changed, 75 insertions(+), 17 deletions(-) diff --git a/background/main.ts b/background/main.ts index be26f8c40d..15da403ba4 100644 --- a/background/main.ts +++ b/background/main.ts @@ -1059,11 +1059,19 @@ export default class Main extends BaseService { this.store.dispatch(updateAccountName({ ...addressOnNetwork, name })) }, ) + this.nameService.emitter.on( "resolvedAvatar", async ({ from: { addressOnNetwork }, resolved: { avatar } }) => { + const fileTypeResponse = await fetch(avatar, { method: "HEAD" }) + const avatarType = fileTypeResponse.headers.get("Content-Type") + this.store.dispatch( - updateENSAvatar({ ...addressOnNetwork, avatar: avatar.toString() }), + updateENSAvatar({ + ...addressOnNetwork, + avatar: avatar.toString(), + avatarType: avatarType ?? undefined, + }), ) }, ) diff --git a/background/redux-slices/accounts.ts b/background/redux-slices/accounts.ts index 80bb2533d1..f4bef2a822 100644 --- a/background/redux-slices/accounts.ts +++ b/background/redux-slices/accounts.ts @@ -66,6 +66,7 @@ export type AccountData = { ens: { name?: DomainName avatarURL?: URI + avatarType?: string } defaultName: string defaultAvatar: string @@ -386,8 +387,10 @@ const accountSlice = createSlice({ updateENSAvatar: ( immerState, { - payload: { address, network, avatar }, - }: { payload: AddressOnNetwork & { avatar: URI } }, + payload: { address, network, avatar, avatarType }, + }: { + payload: AddressOnNetwork & { avatar: URI; avatarType?: string } + }, ) => { const normalizedAddress = normalizeEVMAddress(address) @@ -412,7 +415,7 @@ const accountSlice = createSlice({ immerState.accountsData.evm[network.chainID][normalizedAddress] = { ...baseAccountData, - ens: { ...baseAccountData.ens, avatarURL: avatar }, + ens: { ...baseAccountData.ens, avatarURL: avatar, avatarType }, } }, /** diff --git a/background/redux-slices/selectors/accountsSelectors.ts b/background/redux-slices/selectors/accountsSelectors.ts index 282e907e79..d3d46fbc78 100644 --- a/background/redux-slices/selectors/accountsSelectors.ts +++ b/background/redux-slices/selectors/accountsSelectors.ts @@ -336,6 +336,7 @@ export type AccountTotal = AddressOnNetwork & { accountSigner: AccountSigner name?: string avatarURL?: string + avatarType?: string localizedTotalMainCurrencyAmount?: string } @@ -458,6 +459,8 @@ function getNetworkAccountTotalsByCategory( } } + const { name, avatarURL, avatarType } = accountData.ens + return { address, network, @@ -466,8 +469,9 @@ function getNetworkAccountTotalsByCategory( signerId, path, accountSigner, - name: accountData.ens.name ?? accountData.defaultName, - avatarURL: accountData.ens.avatarURL ?? accountData.defaultAvatar, + name: name ?? accountData.defaultName, + avatarURL: avatarURL ?? accountData.defaultAvatar, + avatarType, localizedTotalMainCurrencyAmount: formatCurrencyAmount( mainCurrencySymbol, getTotalBalance(accountData.balances, prices, mainCurrencySymbol), diff --git a/ui/components/Shared/SharedAccountItemSummary.tsx b/ui/components/Shared/SharedAccountItemSummary.tsx index 6ec6d36e9b..bd5e811bf8 100644 --- a/ui/components/Shared/SharedAccountItemSummary.tsx +++ b/ui/components/Shared/SharedAccountItemSummary.tsx @@ -6,10 +6,16 @@ import { useTranslation } from "react-i18next" import SharedLoadingSpinner from "./SharedLoadingSpinner" import SharedAvatar from "./SharedAvatar" -function Avatar({ avatarURL }: { avatarURL?: string }) { +type AvatarProps = { + avatarURL?: string + avatarType?: string +} + +function Avatar({ avatarURL, avatarType }: AvatarProps) { return ( @@ -31,6 +37,7 @@ export default function SharedAccountItemSummary(props: Props): ReactElement { shortenedAddress, name, avatarURL, + avatarType, localizedTotalMainCurrencyAmount, } = accountTotal @@ -44,10 +51,10 @@ export default function SharedAccountItemSummary(props: Props): ReactElement {
{isSelected ? (
- +
) : ( - + )}
diff --git a/ui/components/Shared/SharedAddressAvatar.tsx b/ui/components/Shared/SharedAddressAvatar.tsx index 08780964d6..37b7ea89ed 100644 --- a/ui/components/Shared/SharedAddressAvatar.tsx +++ b/ui/components/Shared/SharedAddressAvatar.tsx @@ -1,6 +1,12 @@ import React, { ReactElement } from "react" import SharedAvatar from "./SharedAvatar" +type SharedAddressAvatarProps = { + address: string + url?: string + avatarType?: string +} + /* @TODO Switch to using our own resolution service, especially once we upgrade our service to support whatever else Effigy can do. @@ -8,15 +14,14 @@ once we upgrade our service to support whatever else Effigy can do. export default function SharedAddressAvatar({ address, url, -}: { - address: string - url?: string -}): ReactElement { + avatarType, +}: SharedAddressAvatarProps): ReactElement { return ( diff --git a/ui/components/Shared/SharedAvatar.tsx b/ui/components/Shared/SharedAvatar.tsx index 99fe9e50ba..2dff4f94d8 100644 --- a/ui/components/Shared/SharedAvatar.tsx +++ b/ui/components/Shared/SharedAvatar.tsx @@ -5,6 +5,7 @@ type SharedAvatarProps = { background?: string borderRadius?: string avatarURL?: string + avatarType?: string backupAvatar: string style?: CSSProperties } @@ -14,22 +15,41 @@ export default function SharedAvatar({ background = "var(--green-40)", borderRadius = "12px", avatarURL, + avatarType, backupAvatar, style, }: SharedAvatarProps) { return ( <> -
+ {avatarType === "video/mp4" ? ( +
+
+ ) : ( +
+ )} ) diff --git a/ui/components/Shared/SharedCurrentAccountInformation.tsx b/ui/components/Shared/SharedCurrentAccountInformation.tsx index 70070e4047..1349c0ff91 100644 --- a/ui/components/Shared/SharedCurrentAccountInformation.tsx +++ b/ui/components/Shared/SharedCurrentAccountInformation.tsx @@ -8,6 +8,7 @@ type Props = { shortenedAddress: string name: string | undefined avatarURL: string | undefined + avatarType: string | undefined showHoverStyle: boolean showLockStatus?: boolean } @@ -16,6 +17,7 @@ export default function SharedCurrentAccountInformation({ shortenedAddress, name, avatarURL, + avatarType, showHoverStyle, showLockStatus, }: Props): ReactElement { @@ -28,6 +30,7 @@ export default function SharedCurrentAccountInformation({ { name={name} shortenedAddress="" avatarURL={undefined} + avatarType={undefined} />, ) @@ -28,6 +29,7 @@ describe("SharedCurrentAccountInformation", () => { name={undefined} shortenedAddress={shortenedAddress} avatarURL={undefined} + avatarType={undefined} />, ) @@ -40,6 +42,7 @@ describe("SharedCurrentAccountInformation", () => { name={name} shortenedAddress="" avatarURL={undefined} + avatarType={undefined} showLockStatus={false} />, ) @@ -54,6 +57,7 @@ describe("SharedCurrentAccountInformation", () => { name={name} shortenedAddress="" avatarURL={undefined} + avatarType={undefined} showLockStatus />, ) @@ -70,6 +74,7 @@ describe("SharedCurrentAccountInformation", () => { name={name} shortenedAddress="" avatarURL={undefined} + avatarType={undefined} showLockStatus />, { diff --git a/ui/components/Signing/SigningNetworkAccountInfoTopBar.tsx b/ui/components/Signing/SigningNetworkAccountInfoTopBar.tsx index 2f3a0f25df..aaf1d54be9 100644 --- a/ui/components/Signing/SigningNetworkAccountInfoTopBar.tsx +++ b/ui/components/Signing/SigningNetworkAccountInfoTopBar.tsx @@ -12,7 +12,8 @@ export default function SigningNetworkAccountInfoTopBar({ accountTotal, }: Props): ReactElement { const { t } = useTranslation() - const { network, shortenedAddress, name, avatarURL } = accountTotal + const { network, shortenedAddress, name, avatarURL, avatarType } = + accountTotal return (
@@ -29,6 +30,7 @@ export default function SigningNetworkAccountInfoTopBar({ shortenedAddress={shortenedAddress} name={name} avatarURL={avatarURL} + avatarType={avatarType} />