Skip to content

Commit 81b0358

Browse files
authored
fix bonk logo, add local url and base64 fallbacks to blob conversion (#32)
1 parent e255cba commit 81b0358

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed

src/icons/logo-short.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ export const LogoShortIcon: React.FC<{ id?: string; width?: number; height?: num
2121
return (
2222
<div
2323
id={id}
24-
className="ml-1 flex h-auto w-full flex-row items-start justify-center overflow-hidden object-center"
24+
className="flex h-auto w-full flex-row items-start justify-center overflow-hidden object-center"
2525
>
2626
<img
2727
src={logoSrc}
2828
alt="Bonk"
2929
width={width}
3030
height={height}
31-
className="h-full w-auto object-contain"
31+
className="h-full object-contain"
3232
/>
3333
</div>
3434
);

src/views/dialogs/SharePNLAnalyticsDialog.tsx

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import { useMemo } from 'react';
1+
import { useEffect, useMemo, useState } from 'react';
22

33
import { BonsaiHelpers } from '@/bonsai/ontology';
44
import { useToBlob } from '@hugocxl/react-to-image';
55
import styled from 'styled-components';
66
import tw from 'twin.macro';
77

88
import { AnalyticsEvents } from '@/constants/analytics';
9+
import { ASSET_ICON_MAP } from '@/constants/assets';
910
import { ButtonAction } from '@/constants/buttons';
1011
import { DialogProps, SharePNLAnalyticsDialogProps } from '@/constants/dialogs';
1112
import { STRING_KEYS } from '@/constants/localization';
1213
import { IndexerPositionSide } from '@/types/indexer/indexerApiGen';
1314

15+
import { useCustomNotification } from '@/hooks/useCustomNotification';
1416
import { useAppSelectorWithArgs } from '@/hooks/useParameterizedSelector';
1517
import { useStringGetter } from '@/hooks/useStringGetter';
1618

@@ -38,8 +40,14 @@ const copyBlobToClipboard = async (blob: Blob | null) => {
3840
return;
3941
}
4042

41-
const item = new ClipboardItem({ 'image/png': blob });
42-
await navigator.clipboard.write([item]);
43+
try {
44+
const item = new ClipboardItem({ 'image/png': blob });
45+
await navigator.clipboard.write([item]);
46+
} catch (error) {
47+
// eslint-disable-next-line no-console
48+
console.error('Failed to copy blob. ', error);
49+
throw error;
50+
}
4351
};
4452

4553
export const SharePNLAnalyticsDialog = ({
@@ -56,12 +64,27 @@ export const SharePNLAnalyticsDialog = ({
5664
const stringGetter = useStringGetter();
5765
const dispatch = useAppDispatch();
5866
const logoUrl = useAppSelectorWithArgs(BonsaiHelpers.assets.selectAssetLogo, assetId);
59-
6067
const symbol = getDisplayableAssetFromBaseAsset(assetId);
68+
const notify = useCustomNotification();
69+
const [isCopied, setIsCopied] = useState(false);
6170

6271
const [{ isLoading: isCopying }, convert, ref] = useToBlob<HTMLDivElement>({
6372
quality: 1.0,
64-
onSuccess: copyBlobToClipboard,
73+
onSuccess: async (blob) => {
74+
await copyBlobToClipboard(blob);
75+
setIsCopied(true);
76+
setTimeout(() => setIsCopied(false), 2000);
77+
},
78+
onError: (error) => {
79+
// eslint-disable-next-line no-console
80+
console.error('Failed to copy blob. ', error);
81+
notify({
82+
title: stringGetter({ key: STRING_KEYS.ERROR }),
83+
body: stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG }),
84+
slotTitleLeft: <Icon iconName={IconName.Warning} tw="text-color-warning" />,
85+
toastDuration: 5000,
86+
});
87+
},
6588
});
6689

6790
const [{ isLoading: isSharing }, convertShare, refShare] = useToBlob<HTMLDivElement>({
@@ -98,6 +121,36 @@ export const SharePNLAnalyticsDialog = ({
98121

99122
const [assetLeft, assetRight] = marketId.split('-');
100123

124+
const [logoBase64, setLogoBase64] = useState<string | null>(null);
125+
126+
const localLogoUrl = useMemo(() => {
127+
if (assetId && Object.prototype.hasOwnProperty.call(ASSET_ICON_MAP, assetId)) {
128+
return ASSET_ICON_MAP[assetId as keyof typeof ASSET_ICON_MAP];
129+
}
130+
return logoUrl;
131+
}, [logoUrl, assetId]);
132+
133+
useEffect(() => {
134+
if (!logoUrl) return;
135+
136+
const img = new Image();
137+
img.crossOrigin = 'anonymous';
138+
img.src = logoUrl;
139+
img.onload = () => {
140+
const canvas = document.createElement('canvas');
141+
canvas.width = img.width || 26;
142+
canvas.height = img.height || 26;
143+
const ctx = canvas.getContext('2d');
144+
ctx?.drawImage(img, 0, 0, canvas.width, canvas.height);
145+
setLogoBase64(canvas.toDataURL('image/png'));
146+
};
147+
img.onerror = () => {
148+
// eslint-disable-next-line no-console
149+
console.error('Failed to load asset image. ', logoUrl);
150+
setLogoBase64(null);
151+
};
152+
}, [logoUrl]);
153+
101154
return (
102155
<Dialog isOpen setIsOpen={setIsOpen} title={stringGetter({ key: STRING_KEYS.SHARE_ACTIVITY })}>
103156
<$ShareableCard
@@ -110,7 +163,11 @@ export const SharePNLAnalyticsDialog = ({
110163
>
111164
<div tw="flexColumn h-full">
112165
<div tw="row mb-0.75 gap-0.5">
113-
<AssetIcon logoUrl={logoUrl} symbol={assetId} tw="[--asset-icon-size:1.625rem]" />
166+
<AssetIcon
167+
logoUrl={logoBase64 ?? localLogoUrl}
168+
symbol={assetId}
169+
tw="[--asset-icon-size:1.625rem]"
170+
/>
114171

115172
<span>
116173
<span tw="text-color-text-2 font-base-bold">{assetLeft}</span>/{assetRight}
@@ -126,7 +183,7 @@ export const SharePNLAnalyticsDialog = ({
126183
showSign={ShowSign.Both}
127184
/>
128185
<div className="mt-auto flex h-auto max-h-[3rem] w-full justify-center">
129-
<LogoShortIcon tw="h-auto w-full" />
186+
<LogoShortIcon tw="h-auto w-auto object-scale-down" />
130187
</div>
131188
</div>
132189

@@ -176,7 +233,7 @@ export const SharePNLAnalyticsDialog = ({
176233
<div tw="flex gap-1">
177234
<$Action
178235
action={ButtonAction.Secondary}
179-
slotLeft={<Icon iconName={IconName.Copy} />}
236+
slotLeft={<Icon iconName={isCopied ? IconName.Check : IconName.Copy} />}
180237
onClick={() => {
181238
track(AnalyticsEvents.SharePnlCopied({ asset: assetId }));
182239
convert();
@@ -185,7 +242,7 @@ export const SharePNLAnalyticsDialog = ({
185242
isLoading: isCopying,
186243
}}
187244
>
188-
{stringGetter({ key: STRING_KEYS.COPY })}
245+
{stringGetter({ key: isCopied ? STRING_KEYS.COPIED : STRING_KEYS.COPY })}
189246
</$Action>
190247
<$Action
191248
action={ButtonAction.Primary}

0 commit comments

Comments
 (0)