diff --git a/package.json b/package.json index 51091a5ad..3a167068f 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ ] }, "dependencies": { + "@7i7o/arsvgies": "^1.1.0", "@arconnect/components": "^0.2.6", "@arconnect/keystone-sdk": "^0.0.5", "@arconnect/warp-dre": "^0.0.1", diff --git a/src/components/Recipient.tsx b/src/components/Recipient.tsx index ced01456f..3ef35cfd1 100644 --- a/src/components/Recipient.tsx +++ b/src/components/Recipient.tsx @@ -9,6 +9,7 @@ import { searchArNSName } from "~lib/arns"; import { useToasts } from "@arconnect/components"; import { formatAddress, isAddressFormat } from "~utils/format"; import { ExtensionStorage } from "~utils/storage"; +import Squircle from "./Squircle"; export type Contact = { name: string; @@ -17,6 +18,7 @@ export type Contact = { notes: string; ArNSAddress: string; avatarId: string; + avatar: string; }; export const generateProfileIcon = (name) => { @@ -183,7 +185,7 @@ export default function Recipient({ onClick, onClose }: RecipientProps) { }} > {contact.profileIcon ? ( - + ) : ( {generateProfileIcon(contact?.name || contact.address)} @@ -253,16 +255,15 @@ const ContactItem = styled.div` } `; -export const ProfilePicture = styled.img<{ size?: string }>` - width: ${(props) => (props.size ? props.size : "34px")}; - height: ${(props) => (props.size ? props.size : "34px")}; - border-radius: 50%; +export const ProfilePicture = styled(Squircle)<{ size?: string }>` + width: ${(props) => (props.size ? props.size : "2rem")}; + height: ${(props) => (props.size ? props.size : "2rem")}; margin-right: 10px; `; -export const AutoContactPic = styled.div<{ size?: string }>` - width: ${(props) => (props.size ? props.size : "34px")}; - height: ${(props) => (props.size ? props.size : "34px")}; +export const AutoContactPic = styled(Squircle)<{ size?: string }>` + width: ${(props) => (props.size ? props.size : "2rem")}; + height: ${(props) => (props.size ? props.size : "2rem")}; display: flex; background-color: #ab9aff26; align-items: center; diff --git a/src/components/dashboard/list/WalletListItem.tsx b/src/components/dashboard/list/WalletListItem.tsx index d461b4a44..460a56d16 100644 --- a/src/components/dashboard/list/WalletListItem.tsx +++ b/src/components/dashboard/list/WalletListItem.tsx @@ -7,7 +7,6 @@ import type { StoredWallet } from "~wallets"; import HardwareWalletIcon from "~components/hardware/HardwareWalletIcon"; import keystoneLogo from "url:/assets/hardware/keystone.png"; import BaseElement, { SettingIcon } from "./BaseElement"; -import { svgie } from "~utils/svgies"; export default function WalletListItem({ wallet, @@ -20,11 +19,6 @@ export default function WalletListItem({ // format address const formattedAddress = useMemo(() => formatAddress(address, 8), [address]); - const svgieAvatar = useMemo( - () => svgie(address, { asDataURI: true }), - [address] - ); - // allow dragging with the drag icon const dragControls = useDragControls(); @@ -40,11 +34,11 @@ export default function WalletListItem({ title={name} description={formattedAddress} active={active} - img={avatar || svgieAvatar} + img={avatar || wallet?.avatar} dragControls={dragControls} {...props} > - {!avatar && !svgieAvatar && } + {!avatar && !wallet?.avatar && } {wallet.type === "hardware" && wallet.api === "keystone" && ( )} diff --git a/src/components/dashboard/subsettings/AddContact.tsx b/src/components/dashboard/subsettings/AddContact.tsx index 2f4b0ab32..344813cb7 100644 --- a/src/components/dashboard/subsettings/AddContact.tsx +++ b/src/components/dashboard/subsettings/AddContact.tsx @@ -33,6 +33,7 @@ import styled from "styled-components"; import { useLocation } from "wouter"; import copy from "copy-to-clipboard"; import { gql } from "~gateways/api"; +import { arSvgie } from "@7i7o/arsvgies"; export default function AddContact() { // contacts @@ -60,7 +61,8 @@ export default function AddContact() { profileIcon: "", notes: "", ArNSAddress: "", - avatarId: "" + avatarId: "", + avatar: "" }); useEffect(() => { @@ -128,10 +130,24 @@ export default function AddContact() { const handleInputChange = (e) => { const { name, value } = e.target; - setContact({ - ...contact, - [name]: value - }); + if (name !== "address") { + setContact({ + ...contact, + [name]: value + }); + } else { + if (!value || value.length !== 43) { + setContact({ + ...contact, + [name]: value, + avatar: "" + }); + } else { + arSvgie(value, { asDataURI: true }).then((avatar) => + setContact({ ...contact, [name]: value, avatar }) + ); + } + } }; async function fetchArnsAddresses(ownerAddress) { @@ -200,7 +216,8 @@ export default function AddContact() { profileIcon: contact.profileIcon, notes: contact.notes, ArNSAddress: contact.ArNSAddress, - avatarId: contact.avatarId + avatarId: contact.avatarId, + avatar: contact.avatar }; try { @@ -213,7 +230,8 @@ export default function AddContact() { profileIcon: "", notes: "", ArNSAddress: "", - avatarId: "" + avatarId: "", + avatar: "" }); setLocation(`/contacts/${contact.address}`); @@ -232,7 +250,8 @@ export default function AddContact() { profileIcon: "", notes: "", ArNSAddress: "", - avatarId: "" + avatarId: "", + avatar: "" }); removeContactModal.setOpen(false); @@ -257,7 +276,10 @@ export default function AddContact() { {contact.avatarId && contact.profileIcon && ( )} - {!contact.avatarId && !contact.profileIcon && ( + {!contact.profileIcon && contact.avatar && ( + + )} + {!contact.avatarId && !contact.profileIcon && !contact.avatar && ( {generateProfileIcon(contact.name, contact.address)} diff --git a/src/components/dashboard/subsettings/ContactSettings.tsx b/src/components/dashboard/subsettings/ContactSettings.tsx index 33409c20a..12afbcd02 100644 --- a/src/components/dashboard/subsettings/ContactSettings.tsx +++ b/src/components/dashboard/subsettings/ContactSettings.tsx @@ -11,7 +11,7 @@ import { useToasts } from "@arconnect/components"; import { CheckIcon, CopyIcon } from "@iconicicons/react"; -import { useState, useEffect, type MouseEventHandler, useMemo } from "react"; +import { useState, useEffect, type MouseEventHandler } from "react"; import { useStorage } from "@plasmohq/storage/hook"; import { ExtensionStorage } from "~utils/storage"; import styled from "styled-components"; @@ -22,7 +22,8 @@ import { uploadUserAvatar, getUserAvatar } from "~lib/avatar"; import { getAllArNSNames } from "~lib/arns"; import copy from "copy-to-clipboard"; import { EventType, trackEvent } from "~utils/analytics"; -import { svgie } from "~utils/svgies"; +import Squircle from "~components/Squircle"; +import { arSvgie } from "@7i7o/arsvgies"; export default function ContactSettings({ address }: Props) { // contacts @@ -43,7 +44,8 @@ export default function ContactSettings({ address }: Props) { profileIcon: "", notes: "", ArNSAddress: "", - avatarId: "" + avatarId: "", + avatar: "" }); const [contactIndex, setContactIndex] = useState(-1); const [arnsResults, setArnsResults] = useState([]); @@ -51,13 +53,6 @@ export default function ContactSettings({ address }: Props) { const [copied, setCopied] = useState(false); const [originalContact, setOriginalContact] = useState(null); - const svgieAvatar = useMemo(() => { - if (!contact.address || contact.avatarId) { - return ""; - } - return svgie(contact.address, { asDataURI: true }); - }, [contact.address, contact.avatarId]); - useEffect(() => { const loadedContact = storedContacts.find((c) => c.address === address); if (loadedContact) { @@ -71,7 +66,8 @@ export default function ContactSettings({ address }: Props) { profileIcon: "", notes: "", ArNSAddress: "", - avatarId: "" + avatarId: "", + avatar: "" }); setContactIndex(-1); } @@ -88,12 +84,30 @@ export default function ContactSettings({ address }: Props) { const handleInputChange = (e) => { const { name, value } = e.target; - setContact({ - ...contact, - [name]: value - }); + if (name !== "address") { + setContact({ + ...contact, + [name]: value + }); + } else { + if (!value || value.length !== 43) { + setContact({ + ...contact, + [name]: value, + avatar: "" + }); + } else { + arSvgie(value, { asDataURI: true }).then((avatar) => + setContact({ ...contact, [name]: value, avatar }) + ); + } + } }; + useEffect(() => { + console.log(`Changed Address: ${contact.address}`); + }, [contact.address]); + const saveContact = async () => { // check if the address has been changed to a different one that's already in use const addressChanged = @@ -293,7 +307,7 @@ export default function ContactSettings({ address }: Props) { {browser.i18n.getMessage("contact_avatar")} {contact.avatarId && !avatarLoading ? ( - + ) : ( avatarLoading && contact.avatarId && ( @@ -302,10 +316,10 @@ export default function ContactSettings({ address }: Props) { ) )} - {!contact.profileIcon && svgieAvatar && ( - + {!contact.profileIcon && contact.avatar && ( + )} - {!contact.profileIcon && !svgieAvatar && ( + {!contact.profileIcon && !contact.avatar && ( {generateProfileIcon(contact.name, contact.address)} @@ -550,10 +564,9 @@ export const AutoContactPic = styled.div` background-color: #ab9aff26; `; -export const ContactPic = styled.img` +export const ContactPic = styled(Squircle)` width: 100px; height: 100px; - border-radius: 100%; margin-bottom: 10px; `; diff --git a/src/components/dashboard/subsettings/WalletSettings.tsx b/src/components/dashboard/subsettings/WalletSettings.tsx index a859ca0ec..899bbd16e 100644 --- a/src/components/dashboard/subsettings/WalletSettings.tsx +++ b/src/components/dashboard/subsettings/WalletSettings.tsx @@ -29,6 +29,7 @@ import browser from "webextension-polyfill"; import styled from "styled-components"; import copy from "copy-to-clipboard"; import { formatAddress } from "~utils/format"; +import Squircle from "~components/Squircle"; export default function WalletSettings({ address }: Props) { // wallets @@ -219,6 +220,11 @@ export default function WalletSettings({ address }: Props) { + + + + +