Skip to content

Commit

Permalink
Browser: homepage empty state, search logic fixes (#5737)
Browse files Browse the repository at this point in the history
  • Loading branch information
christianbaroni authored and ibrahimtaveras00 committed May 16, 2024
1 parent ff3f8c0 commit 480cdfb
Show file tree
Hide file tree
Showing 9 changed files with 280 additions and 155 deletions.
8 changes: 5 additions & 3 deletions src/components/DappBrowser/DappBrowserShadows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Box, globalColors, useColorMode } from '@/design-system';
import { IS_IOS } from '@/env';
import { StyleSheet } from 'react-native';

export const BrowserButtonShadows = ({ children }: { children: React.ReactNode }) => {
export const BrowserButtonShadows = ({ children, lightShadows }: { children: React.ReactNode; lightShadows?: boolean }) => {
const { isDarkMode } = useColorMode();

if (!IS_IOS) return <>{children}</>;
Expand All @@ -14,15 +14,17 @@ export const BrowserButtonShadows = ({ children }: { children: React.ReactNode }
style={{
shadowColor: globalColors.grey100,
shadowOffset: { width: 0, height: 8 },
shadowOpacity: isDarkMode ? 0.3 : 0.1,
// eslint-disable-next-line no-nested-ternary
shadowOpacity: isDarkMode ? 0.3 : lightShadows ? 0.06 : 0.08,
shadowRadius: 12,
}}
>
<Box
style={{
shadowColor: globalColors.grey100,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: isDarkMode ? 0.2 : 0.04,
// eslint-disable-next-line no-nested-ternary
shadowOpacity: isDarkMode ? 0.2 : lightShadows ? 0.02 : 0.04,
shadowRadius: 3,
}}
>
Expand Down
158 changes: 114 additions & 44 deletions src/components/DappBrowser/Homepage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import React, { useCallback, useMemo } from 'react';
import { ButtonPressAnimation } from '@/components/animations';
import { Bleed, Box, ColorModeProvider, Cover, Inline, Inset, Stack, Text, TextIcon, globalColors, useColorMode } from '@/design-system';
import {
Bleed,
Box,
ColorModeProvider,
Cover,
Inline,
Inset,
Stack,
Text,
TextIcon,
globalColors,
useBackgroundColor,
useColorMode,
} from '@/design-system';
import { ScrollView, StyleSheet, View } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { BlurView } from '@react-native-community/blur';
Expand All @@ -10,8 +23,6 @@ import { IS_ANDROID, IS_IOS } from '@/env';
import { THICK_BORDER_WIDTH } from '@/__swaps__/screens/Swap/constants';
import { opacity } from '@/__swaps__/utils/swaps';
import { useFavoriteDappsStore } from '@/state/favoriteDapps';
// import { FadeMask } from '@/__swaps__/screens/Swap/components/FadeMask';
// import MaskedView from '@react-native-masked-view/masked-view';
import { Site, useBrowserHistoryStore } from '@/state/browserHistory';
import { getDappHost } from './handleProviderRequest';
import { uniqBy } from 'lodash';
Expand All @@ -21,6 +32,7 @@ import { WEBVIEW_HEIGHT } from './Dimensions';
import { useDapps } from '@/resources/metadata/dapps';
import haptics from '@/utils/haptics';
import * as i18n from '@/languages';
import { getNameFromFormattedUrl } from './utils';

const HORIZONTAL_PAGE_INSET = 24;
const MAX_RECENTS_TO_DISPLAY = 6;
Expand Down Expand Up @@ -101,49 +113,49 @@ const Favorites = ({ goToUrl }: { goToUrl: (url: string) => void }) => {
const favoriteDapps = useFavoriteDappsStore(state => state.favoriteDapps);

return (
favoriteDapps.length > 0 && (
<Stack space="20px">
<Inline alignVertical="center" space="6px">
<Text color="yellow" size="15pt" align="center" weight="heavy">
􀋃
</Text>
<Text color="label" size="20pt" weight="heavy">
{i18n.t(i18n.l.dapp_browser.homepage.favorites)}
</Text>
</Inline>
<Box flexDirection="row" flexWrap="wrap" gap={LOGO_PADDING} width={{ custom: DEVICE_WIDTH - HORIZONTAL_PAGE_INSET * 2 }}>
{favoriteDapps.map(dapp => (
<Logo goToUrl={goToUrl} key={`${dapp.url}-${dapp.name}`} site={dapp} />
))}
</Box>
</Stack>
)
<Stack space="20px">
<Inline alignVertical="center" space="6px">
<Text color="yellow" size="15pt" align="center" weight="heavy">
􀋃
</Text>
<Text color="label" size="20pt" weight="heavy">
{i18n.t(i18n.l.dapp_browser.homepage.favorites)}
</Text>
</Inline>
<Box flexDirection="row" flexWrap="wrap" gap={LOGO_PADDING} width={{ custom: DEVICE_WIDTH - HORIZONTAL_PAGE_INSET * 2 }}>
{favoriteDapps.length > 0
? favoriteDapps.map(dapp => <Logo goToUrl={goToUrl} key={`${dapp.url}-${dapp.name}`} site={dapp} />)
: Array(4)
.fill(null)
.map((_, index) => <PlaceholderLogo key={index} />)}
</Box>
</Stack>
);
};

const Recents = ({ goToUrl }: { goToUrl: (url: string) => void }) => {
const recents = useBrowserHistoryStore(state => uniqBy(state.recents, 'url').slice(0, MAX_RECENTS_TO_DISPLAY));

return (
recents.length > 0 && (
<Stack space="20px">
<Inline alignVertical="center" space="6px">
<Text color="blue" size="15pt" align="center" weight="heavy">
􀐫
</Text>
<Text color="label" size="20pt" weight="heavy">
{i18n.t(i18n.l.dapp_browser.homepage.recents)}
</Text>
<Stack space="20px">
<Inline alignVertical="center" space="6px">
<Text color="blue" size="15pt" align="center" weight="heavy">
􀐫
</Text>
<Text color="label" size="20pt" weight="heavy">
{i18n.t(i18n.l.dapp_browser.homepage.recents)}
</Text>
</Inline>
<Box width={{ custom: DEVICE_WIDTH }}>
<Inline space={{ custom: CARD_PADDING }}>
{recents.length > 0
? recents.map(site => <Card key={site.url} site={site} showMenuButton goToUrl={goToUrl} />)
: Array(2)
.fill(null)
.map((_, index) => <PlaceholderCard key={index} />)}
</Inline>
<Box width={{ custom: DEVICE_WIDTH }}>
<Inline space={{ custom: CARD_PADDING }}>
{recents.map(site => (
<Card key={site.url} site={site} showMenuButton goToUrl={goToUrl} />
))}
</Inline>
</Box>
</Stack>
)
</Box>
</Stack>
);
};

Expand All @@ -169,7 +181,7 @@ const Card = React.memo(function Card({
if (isFavorite) {
removeFavorite(url);
} else {
addFavorite(site);
addFavorite({ ...site, name: getNameFromFormattedUrl(site.url, true) });
}
}
}, [addFavorite, isFavorite, removeFavorite, site]);
Expand Down Expand Up @@ -343,6 +355,44 @@ const Card = React.memo(function Card({
);
});

export const PlaceholderCard = React.memo(function PlaceholderCard() {
const { isDarkMode } = useColorMode();

const fillTertiary = useBackgroundColor('fillTertiary');
const cardOpacity = isDarkMode ? 0.6 : 0.5;

return (
<View style={{ width: CARD_WIDTH }}>
<Box
as={LinearGradient}
colors={[opacity(fillTertiary, (isDarkMode ? 0.08 : 0.05) * cardOpacity), opacity(fillTertiary, 0)]}
end={{ x: 0.5, y: 1 }}
locations={[0, 1]}
start={{ x: 0.5, y: 0 }}
width={{ custom: CARD_WIDTH }}
height={{ custom: CARD_HEIGHT }}
style={{ borderRadius: 24 }}
/>
{IS_IOS && (
<Box
borderRadius={24}
height="full"
position="absolute"
style={{
borderColor: isDarkMode ? opacity(globalColors.white100, 0.04) : opacity(globalColors.grey100, 0.02),
borderWidth: THICK_BORDER_WIDTH,
opacity: cardOpacity,
overflow: 'hidden',
pointerEvents: 'none',
}}
width="full"
/>
)}
<Box />
</View>
);
});

export const Logo = React.memo(function Logo({ goToUrl, site }: { goToUrl: (url: string) => void; site: Omit<Site, 'timestamp'> }) {
const { isDarkMode } = useColorMode();

Expand Down Expand Up @@ -391,23 +441,43 @@ export const Logo = React.memo(function Logo({ goToUrl, site }: { goToUrl: (url:
)}
</Box>
<Bleed bottom="10px" horizontal="8px">
{/* <MaskedView
maskElement={<FadeMask fadeEdgeInset={0} fadeWidth={12} side="right" />}
style={{ width: LOGO_SIZE + LOGO_LABEL_SPILLOVER * 2 }}
> */}
<Box width={{ custom: LOGO_SIZE + LOGO_LABEL_SPILLOVER * 2 }}>
<Text size="13pt" numberOfLines={1} weight="bold" color="labelSecondary" align="center" style={{ paddingVertical: 10 }}>
{site.name}
</Text>
</Box>
{/* </MaskedView> */}
</Bleed>
</Stack>
</ButtonPressAnimation>
</View>
);
});

export const PlaceholderLogo = React.memo(function PlaceholderLogo() {
const { isDarkMode } = useColorMode();
const borderRadius = IS_ANDROID ? LOGO_BORDER_RADIUS / 2 : LOGO_BORDER_RADIUS;

return (
<View style={{ opacity: isDarkMode ? 0.6 : 0.5, width: LOGO_SIZE }}>
<Box width={{ custom: LOGO_SIZE }} height={{ custom: LOGO_SIZE }} background="fillTertiary" style={{ borderRadius }} />
{IS_IOS && (
<Box
borderRadius={borderRadius}
height="full"
position="absolute"
style={{
borderColor: isDarkMode ? opacity(globalColors.white100, 0.04) : opacity(globalColors.grey100, 0.02),
borderWidth: THICK_BORDER_WIDTH,
overflow: 'hidden',
pointerEvents: 'none',
}}
width="full"
/>
)}
</View>
);
});

const styles = StyleSheet.create({
cardContainer: {
backgroundColor: globalColors.white100,
Expand Down
4 changes: 3 additions & 1 deletion src/components/DappBrowser/TabViewToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ type BaseButtonProps = {
iconColor?: TextColor;
iconSize?: TextSize;
iconWeight?: TextWeight;
lightShadows?: boolean;
onPress?: () => void;
onPressWorklet?: () => void;
paddingHorizontal?: BoxProps['paddingHorizontal'];
Expand All @@ -112,6 +113,7 @@ const BaseButton = ({
iconColor = 'labelSecondary',
iconSize = 'icon 17px',
iconWeight = 'heavy',
lightShadows = true,
onPress,
onPressWorklet,
paddingHorizontal = '16px',
Expand All @@ -127,7 +129,7 @@ const BaseButton = ({
const buttonColor = IS_IOS ? buttonColorIOS : buttonColorAndroid;

return (
<BrowserButtonShadows>
<BrowserButtonShadows lightShadows={lightShadows}>
<Bleed space="8px">
<HybridWorkletButton onPress={onPress} onPressWorklet={onPressWorklet} scaleTo={scaleTo} style={{ padding: 8 }}>
<Box
Expand Down
66 changes: 26 additions & 40 deletions src/components/DappBrowser/search/results/SearchResult.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { StyleSheet } from 'react-native';
import { Source } from 'react-native-fast-image';
import Animated, { DerivedValue, SharedValue, useAnimatedProps, useAnimatedStyle, useDerivedValue } from 'react-native-reanimated';
import Animated, { SharedValue, useAnimatedProps, useAnimatedStyle, useDerivedValue } from 'react-native-reanimated';
import GoogleSearchIcon from '@/assets/googleSearchIcon.png';
import { AnimatedFasterImage } from '@/components/AnimatedComponents/AnimatedFasterImage';
import { ButtonPressAnimation } from '@/components/animations';
Expand Down Expand Up @@ -96,13 +96,7 @@ export const SearchResult = ({ index, goToUrl }: { index: number; goToUrl: (url:

const searchText = i18n.t(i18n.l.dapp_browser.search.search);

export const GoogleSearchResult = ({
goToUrl,
shouldShowGoogleSearch,
}: {
goToUrl: (url: string) => void;
shouldShowGoogleSearch: DerivedValue<boolean>;
}) => {
export const GoogleSearchResult = ({ goToUrl }: { goToUrl: (url: string) => void }) => {
const { searchQuery } = useSearchContext();
const { width: deviceWidth } = useDimensions();

Expand All @@ -113,39 +107,31 @@ export const GoogleSearchResult = ({
[goToUrl, searchQuery]
);

const animatedStyle = useAnimatedStyle(() => {
return {
display: shouldShowGoogleSearch?.value ? 'flex' : 'none',
};
});

return (
<Animated.View style={animatedStyle}>
<Box as={ButtonPressAnimation} padding="8px" borderRadius={18} scaleTo={0.95} onPress={onPress}>
<Inline space="12px" alignVertical="center" wrap={false}>
<Box
alignItems="center"
justifyContent="center"
style={{ backgroundColor: globalColors.white100 }}
width={{ custom: 40 }}
height={{ custom: 40 }}
borderRadius={10}
>
<ImgixImage source={GoogleSearchIcon as Source} style={{ width: 30, height: 30 }} size={30} />
</Box>
<Box width={{ custom: deviceWidth - 100 }}>
<Stack space="10px">
<AnimatedText size="17pt" weight="bold" color="label" numberOfLines={1}>
{animatedText}
</AnimatedText>
<Text size="13pt" weight="bold" color="labelTertiary">
Google
</Text>
</Stack>
</Box>
</Inline>
</Box>
</Animated.View>
<Box as={ButtonPressAnimation} padding="8px" borderRadius={18} scaleTo={0.95} onPress={onPress}>
<Inline space="12px" alignVertical="center" wrap={false}>
<Box
alignItems="center"
justifyContent="center"
style={{ backgroundColor: globalColors.white100 }}
width={{ custom: 40 }}
height={{ custom: 40 }}
borderRadius={10}
>
<ImgixImage source={GoogleSearchIcon as Source} style={{ width: 30, height: 30 }} size={30} />
</Box>
<Box width={{ custom: deviceWidth - 100 }}>
<Stack space="10px">
<AnimatedText size="17pt" weight="bold" color="label" numberOfLines={1}>
{animatedText}
</AnimatedText>
<Text size="13pt" weight="bold" color="labelTertiary">
Google
</Text>
</Stack>
</Box>
</Inline>
</Box>
);
};

Expand Down
Loading

0 comments on commit 480cdfb

Please sign in to comment.