Skip to content

Commit

Permalink
feat: link to Core Webs Halliday flow from Bridge (ava-labs#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
meeh0w authored Jan 7, 2025
1 parent 64cac62 commit 8cce5d2
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/background/services/featureFlags/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export enum FeatureGates {
BLOCKAID_DAPP_SCAN_WARNING = 'blockaid-dapp-scan-warning',
BLOCKAID_TRANSACTION_SCAN = 'blockaid-transaction-scan',
BLOCKAID_JSONRPC_SCAN = 'blockaid-jsonrpc-scan',
HALLIDAY_BRIDGE_BANNER = 'halliday-bridge-banner',
}

// Posthog API does not return disabled flags on their `/decide` api endpoint
Expand Down Expand Up @@ -94,6 +95,7 @@ export const DISABLED_FLAG_VALUES: FeatureFlags = {
[FeatureGates.BLOCKAID_DAPP_SCAN_WARNING]: false,
[FeatureGates.BLOCKAID_TRANSACTION_SCAN]: false,
[FeatureGates.BLOCKAID_JSONRPC_SCAN]: false,
[FeatureGates.HALLIDAY_BRIDGE_BANNER]: false,
};

// Default flags are used when posthog is not available
Expand Down Expand Up @@ -143,6 +145,7 @@ export const DEFAULT_FLAGS: FeatureFlags = {
[FeatureGates.BLOCKAID_DAPP_SCAN_WARNING]: true,
[FeatureGates.BLOCKAID_TRANSACTION_SCAN]: true,
[FeatureGates.BLOCKAID_JSONRPC_SCAN]: true,
[FeatureGates.HALLIDAY_BRIDGE_BANNER]: true,
};

export enum FeatureFlagEvents {
Expand Down
92 changes: 92 additions & 0 deletions src/components/common/HallidayBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
Card,
CardActionArea,
Grow,
IconButton,
Link,
Stack,
Typography,
XIcon,
} from '@avalabs/core-k2-components';

import { getCoreWebUrl } from '@src/utils/getCoreWebUrl';
import { useDismissedBanners } from '@src/hooks/useDismissedBanners';
import { useFeatureFlagContext } from '@src/contexts/FeatureFlagsProvider';
import { FeatureGates } from '@src/background/services/featureFlags/models';

const HALLIDAY_BANNER_ID = 'halliday-e2d6f109-2175-4303-9321-17b010781371';

export const HallidayBanner = () => {
const { t } = useTranslation();

const [isOpen, setIsOpen] = useState(false);
const { isDismissed, dismiss } = useDismissedBanners();
const { isFlagEnabled } = useFeatureFlagContext();

useEffect(() => {
if (!isFlagEnabled(FeatureGates.HALLIDAY_BRIDGE_BANNER)) {
setIsOpen(false);
return;
}

let isMounted = true;

isDismissed(HALLIDAY_BANNER_ID).then((isHallidayDismissed) => {
if (!isMounted) {
return;
}

setIsOpen(!isHallidayDismissed);
});

return () => {
isMounted = false;
};
}, [isDismissed, isFlagEnabled]);

return (
<Grow in={isOpen} unmountOnExit mountOnEnter>
<Card sx={{ mx: 2, mb: 2, position: 'relative' }}>
<IconButton
size="small"
sx={{ position: 'absolute', top: 4, right: 4, zIndex: 9999 }}
onClick={() => {
setIsOpen(false);
dismiss(HALLIDAY_BANNER_ID);
}}
>
<XIcon size={20} />
</IconButton>
<CardActionArea
component={Link}
href={`${getCoreWebUrl()}/bridge?useHalliday=1`}
rel="noopener noreferrer"
target="_blank"
>
<Stack sx={{ gap: 1, py: 1, px: 2 }}>
<Stack sx={{ flexDirection: 'row', gap: 1, alignItems: 'center' }}>
<img
src="/images/halliday-icon.png"
style={{ height: 24 }}
alt="Halliday Logo"
/>
<Typography variant="button" sx={{ fontSize: 'body2.fontSize' }}>
{t('Bridge using Halliday')}
</Typography>
</Stack>
<Typography
variant="caption"
sx={{ color: 'text.secondary', lineHeight: 1.5 }}
>
{t(
'Buy and bridge USD and other currencies directly to L1s using Halliday.',
)}
</Typography>
</Stack>
</CardActionArea>
</Card>
</Grow>
);
};
6 changes: 5 additions & 1 deletion src/contexts/FeatureFlagsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import { ExtensionRequest } from '@src/background/connections/extensionConnectio

const FeatureFlagsContext = createContext<{
featureFlags: Record<FeatureGates, boolean>;
}>({} as any);
isFlagEnabled: (flagName: string) => boolean;
}>({
isFlagEnabled: () => false,
} as any);

export function FeatureFlagsContextProvider({ children }: { children: any }) {
const { events, request } = useConnectionContext();
Expand Down Expand Up @@ -47,6 +50,7 @@ export function FeatureFlagsContextProvider({ children }: { children: any }) {
return (
<FeatureFlagsContext.Provider
value={{
isFlagEnabled: (flagName) => featureFlags[flagName],
featureFlags,
}}
>
Expand Down
25 changes: 25 additions & 0 deletions src/hooks/useDismissedBanners.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useLocalStorage } from './useLocalStorage';

const DISMISSED_BANNERS_STORAGE_KEY = 'dismissed-banners';

export const useDismissedBanners = () => {
const { get, set } = useLocalStorage();

return {
async isDismissed(bannerId: string) {
const dismissedBanners = await get(DISMISSED_BANNERS_STORAGE_KEY);

return dismissedBanners && Array.isArray(dismissedBanners)
? dismissedBanners.includes(bannerId)
: false;
},
async dismiss(bannerId: string) {
const alreadyDismissedBanners = await get(DISMISSED_BANNERS_STORAGE_KEY);
const newDismissedBanners = alreadyDismissedBanners
? [...alreadyDismissedBanners, bannerId]
: [bannerId];

return set(DISMISSED_BANNERS_STORAGE_KEY, newDismissedBanners);
},
};
};
14 changes: 14 additions & 0 deletions src/hooks/useLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { storage } from 'webextension-polyfill';

export const useLocalStorage = () => {
return {
async get(key: string) {
const stored = await storage.local.get(key);

return stored[key];
},
async set(key: string, value: any) {
return storage.local.set({ [key]: value });
},
};
};
Binary file added src/images/halliday-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/localization/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,13 @@
"Bridge in progress. <br/> Click for details.": "Bridge in progress. <br/> Click for details.",
"Bridge initialization failed": "Bridge initialization failed",
"Bridge not available": "Bridge not available",
"Bridge using Halliday": "Bridge using Halliday",
"Bridging from Avalanche to Bitcoin takes approximately . Please see\n the <FaqLink>FAQ</FaqLink> for additional info.": "Bridging from Avalanche to Bitcoin takes approximately . Please see\n the <FaqLink>FAQ</FaqLink> for additional info.",
"Bridging this token pair utilizes Avalanche Interchain Messaging. <faqLink>Bridge FAQs</faqLink>": "Bridging this token pair utilizes Avalanche Interchain Messaging. <faqLink>Bridge FAQs</faqLink>",
"Bridging...": "Bridging...",
"Browse Files": "Browse Files",
"Buy": "Buy",
"Buy and bridge USD and other currencies directly to L1s using Halliday.": "Buy and bridge USD and other currencies directly to L1s using Halliday.",
"C-Chain": "C-Chain",
"Camera Access": "Camera Access",
"Canadian Dollar": "Canadian Dollar",
Expand Down
2 changes: 2 additions & 0 deletions src/pages/Bridge/Bridge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { isBitcoinNetwork } from '@src/background/services/network/utils/isBitco
import { useLiveBalance } from '@src/hooks/useLiveBalance';
import { NetworkWithCaipId } from '@src/background/services/network/models';
import { useNetworkFeeContext } from '@src/contexts/NetworkFeeProvider';
import { HallidayBanner } from '@src/components/common/HallidayBanner';

import { useBridge } from './hooks/useBridge';
import { BridgeForm } from './components/BridgeForm';
Expand Down Expand Up @@ -325,6 +326,7 @@ export function Bridge() {
>
{t('Bridge')}
</PageTitle>
<HallidayBanner />
{isReady && networkFee ? (
<BridgeForm {...formProps} networkFee={networkFee} />
) : (
Expand Down

0 comments on commit 8cce5d2

Please sign in to comment.