Skip to content

Commit

Permalink
feat: handle unverified assets activation
Browse files Browse the repository at this point in the history
  • Loading branch information
JoseRFelix committed Dec 20, 2024
1 parent 9263375 commit a53e313
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 15 deletions.
28 changes: 27 additions & 1 deletion packages/mobile/app/settings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Stack } from "expo-router";
import { router } from "expo-router";
import React from "react";
import { ScrollView, View } from "react-native";
import { ScrollView, Switch, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { useShallow } from "zustand/react/shallow";

import { RouteHeader } from "~/components/route-header";
import { SettingsGroup } from "~/components/settings/settings-group";
import { SettingsItem } from "~/components/settings/settings-item";
import { Text } from "~/components/ui/text";
import { Colors } from "~/constants/theme-colors";
import { useSettingsStore } from "~/stores/settings";

export default function SettingsScreen() {
return (
Expand Down Expand Up @@ -82,10 +85,33 @@ export default function SettingsScreen() {
title="Face ID"
onPress={() => router.push("/settings/face-id")}
/>
<PreviewAssetsToggle />
{/* <SettingsItem title="Recovery phrase" onPress={() => {}} />
<SettingsItem title="iCloud backup" onPress={() => {}} /> */}
</SettingsGroup>
</ScrollView>
</SafeAreaView>
);
}

const PreviewAssetsToggle: React.FC = () => {
const { showUnverifiedAssets, setShowUnverifiedAssets } = useSettingsStore(
useShallow((state) => ({
showUnverifiedAssets: state.showUnverifiedAssets,
setShowUnverifiedAssets: state.setShowUnverifiedAssets,
}))
);

return (
<SettingsItem
title="Show unverified assets"
rightElement={
<Switch
value={showUnverifiedAssets}
onValueChange={setShowUnverifiedAssets}
trackColor={{ true: Colors.wosmongton["500"] }}
/>
}
/>
);
};
108 changes: 108 additions & 0 deletions packages/mobile/components/modals/unverified-asset-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {
BottomSheetBackdrop,
BottomSheetBackdropProps,
BottomSheetModal,
BottomSheetView,
} from "@gorhom/bottom-sheet";
import { forwardRef, useCallback } from "react";
import { StyleSheet } from "react-native";

import { AssetImage } from "~/components/ui/asset-image";
import { Button } from "~/components/ui/button";
import { Text } from "~/components/ui/text";
import { Colors } from "~/constants/theme-colors";

interface UnverifiedAssetModalProps {
onActivate: () => void;
assetSymbol: string;
assetImageUrl?: string;
}

export const UnverifiedAssetModal = forwardRef<
BottomSheetModal,
UnverifiedAssetModalProps
>(({ onActivate, assetSymbol, assetImageUrl }, ref) => {
return (
<BottomSheetModal
ref={ref}
enablePanDownToClose
// enableDynamicSizing={false}
// snapPoints={["50%"]}
backdropComponent={useCallback(
(props: BottomSheetBackdropProps) => (
<BottomSheetBackdrop
{...props}
appearsOnIndex={0}
disappearsOnIndex={-1}
/>
),
[]
)}
backgroundStyle={styles.bottomSheetBackground}
handleIndicatorStyle={styles.indicator}
>
<BottomSheetView style={styles.container}>
{assetImageUrl && (
<AssetImage uri={assetImageUrl} style={styles.assetIcon} />
)}
<Text type="title" style={styles.title}>
Activate unverified assets
</Text>
<Text type="subtitle" style={styles.description}>
{assetSymbol} is an unverified token. Do you wish to activate it? Be
sure to research thoroughly before trading.
</Text>
<Text type="caption" style={styles.note}>
You can always deactivate this setting in the settings modal.
</Text>
<Button
title="Activate"
variant="primary"
onPress={onActivate}
buttonStyle={styles.button}
/>
</BottomSheetView>
</BottomSheetModal>
);
});

const styles = StyleSheet.create({
container: {
alignItems: "center",
paddingHorizontal: 24,
paddingTop: 5,
paddingBottom: 42,
flex: 1,
},
bottomSheetBackground: {
backgroundColor: Colors.osmoverse[900],
},
indicator: {
backgroundColor: Colors.osmoverse[400],
},
assetIcon: {
width: 48,
height: 48,
borderRadius: 24,
marginBottom: 16,
},
title: {
fontSize: 24,
marginBottom: 16,
textAlign: "center",
},
description: {
color: Colors.osmoverse[200],
textAlign: "center",
marginBottom: 12,
},
note: {
color: Colors.osmoverse[300],
textAlign: "center",
marginBottom: 24,
},
button: {
width: "100%",
paddingVertical: 16,
},
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { BottomSheetModal } from "@gorhom/bottom-sheet";
import { Dec } from "@osmosis-labs/unit";
import { formatPretty } from "@osmosis-labs/utils";
import { FlashList } from "@shopify/flash-list";
import { Link } from "expo-router";
import { useMemo, useState } from "react";
import { useMemo, useRef, useState } from "react";
import {
ActivityIndicator,
Image,
Expand All @@ -11,11 +12,15 @@ import {
View,
} from "react-native";
import { SvgUri } from "react-native-svg";
import { useShallow } from "zustand/react/shallow";

import { UnverifiedAssetModal } from "~/components/modals/unverified-asset-modal";
import { SubscriptDecimal } from "~/components/subscript-decimal";
import { Button } from "~/components/ui/button";
import { Text } from "~/components/ui/text";
import { Colors } from "~/constants/theme-colors";
import { useCosmosWallet } from "~/hooks/use-cosmos-wallet";
import { useSettingsStore } from "~/stores/settings";
import { getChangeColor } from "~/utils/price";
import { api, RouterOutputs } from "~/utils/trpc";

Expand All @@ -24,6 +29,11 @@ const itemSize = 70;
export const PortfolioAssetBalancesTable = () => {
const { address } = useCosmosWallet();
const [searchQuery, setSearchQuery] = useState("");
const { showUnverifiedAssets } = useSettingsStore(
useShallow((state) => ({
showUnverifiedAssets: state.showUnverifiedAssets,
}))
);

const {
data: assetPagesData,
Expand All @@ -37,6 +47,10 @@ export const PortfolioAssetBalancesTable = () => {
userOsmoAddress: address!,
limit: 50,
...(searchQuery && { search: { query: searchQuery } }),
sort: {
keyPath: "usdValue",
direction: "desc",
},
},
{
enabled: Boolean(address),
Expand Down Expand Up @@ -89,6 +103,62 @@ const AssetItem = ({
}: {
asset: RouterOutputs["local"]["assets"]["getUserBridgeAssets"]["items"][number];
}) => {
const unverifiedAssetModalRef = useRef<BottomSheetModal>(null);
const { showUnverifiedAssets, setShowUnverifiedAssets } = useSettingsStore(
useShallow((state) => ({
showUnverifiedAssets: state.showUnverifiedAssets,
setShowUnverifiedAssets: state.setShowUnverifiedAssets,
}))
);

const isUnverified = !asset.isVerified;

if (isUnverified && !showUnverifiedAssets) {
return (
<View style={styles.assetItem}>
<View style={[styles.assetLeft, { opacity: 0.5 }]}>
{asset.coinImageUrl?.endsWith(".svg") ? (
<SvgUri
uri={asset.coinImageUrl}
width={40}
height={40}
style={styles.assetIcon}
/>
) : (
<Image
source={{ uri: asset.coinImageUrl }}
style={styles.assetIcon}
/>
)}
<View>
<Text style={styles.assetName}>{asset.coinName}</Text>
{asset.amount && (
<Text type="caption" style={{ color: Colors.osmoverse[400] }}>
{formatPretty(asset.amount, { maxDecimals: 8 })}
</Text>
)}
</View>
</View>
<Button
title="Activate"
variant="primary"
onPress={() => {
unverifiedAssetModalRef.current?.present();
}}
/>

<UnverifiedAssetModal
ref={unverifiedAssetModalRef}
onActivate={() => {
setShowUnverifiedAssets(true);
}}
assetSymbol={asset.coinDenom}
assetImageUrl={asset.coinImageUrl}
/>
</View>
);
}

return (
<Link
href={{
Expand Down
1 change: 0 additions & 1 deletion packages/mobile/components/ui/asset-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@ const styles = StyleSheet.create({
width: 40,
height: 40,
borderRadius: 20,
marginRight: 12,
},
});
22 changes: 22 additions & 0 deletions packages/mobile/stores/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";

import { mmkvStorage } from "~/utils/mmkv";

interface SettingsState {
showUnverifiedAssets: boolean;
setShowUnverifiedAssets: (show: boolean) => void;
}

export const useSettingsStore = create<SettingsState>()(
persist(
(set) => ({
showUnverifiedAssets: false,
setShowUnverifiedAssets: (show) => set({ showUnverifiedAssets: show }),
}),
{
name: "settings-store",
storage: createJSONStorage(() => mmkvStorage),
}
)
);
22 changes: 11 additions & 11 deletions packages/trpc/src/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,21 +370,22 @@ export const assetsRouter = createTRPCRouter({
),
getUserBridgeAssets: publicProcedure
.input(
GetInfiniteAssetsInputSchema.merge(UserOsmoAddressSchema).merge(
z.object({
sort: createSortSchema([
"currentPrice",
"priceChange24h",
"usdValue",
] as const).optional(),
})
)
GetInfiniteAssetsInputSchema.omit({ onlyVerified: true })
.merge(UserOsmoAddressSchema)
.merge(
z.object({
sort: createSortSchema([
"currentPrice",
"priceChange24h",
"usdValue",
] as const).optional(),
})
)
)
.query(
({
input: {
search,
onlyVerified,
userOsmoAddress,
sort: sortInput,
categories,
Expand Down Expand Up @@ -446,7 +447,6 @@ export const assetsRouter = createTRPCRouter({
},
cacheKey: JSON.stringify({
search,
onlyVerified,
userOsmoAddress,
sort: sortInput,
categories,
Expand Down
1 change: 0 additions & 1 deletion packages/web/components/table/portfolio-asset-balances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ export const PortfolioAssetBalancesTable: FunctionComponent<{
userOsmoAddress: account?.address,
limit: 50,
search: searchQuery,
onlyVerified: !searchQuery && showUnverifiedAssets === false,
includePreview: showPreviewAssets,
sort,
},
Expand Down

0 comments on commit a53e313

Please sign in to comment.