diff --git a/App.tsx b/App.tsx index 8ad2f17ef1..f6627b706c 100644 --- a/App.tsx +++ b/App.tsx @@ -19,7 +19,6 @@ import { Navigator } from "./packages/components/navigation/Navigator"; import { DropdownsContextProvider } from "./packages/context/DropdownsProvider"; import { FeedbacksContextProvider } from "./packages/context/FeedbacksProvider"; import { SearchBarContextProvider } from "./packages/context/SearchBarProvider"; -import { SidebarContextProvider } from "./packages/context/SidebarProvider"; import { TNSMetaDataListContextProvider } from "./packages/context/TNSMetaDataListProvider"; import { TNSContextProvider } from "./packages/context/TNSProvider"; import { TransactionModalsProvider } from "./packages/context/TransactionModalsProvider"; @@ -62,10 +61,8 @@ export default function App() { - - - - + + diff --git a/packages/components/inputs/SearchNSInputContainer.tsx b/packages/components/inputs/SearchNSInputContainer.tsx new file mode 100644 index 0000000000..2b5d54fce9 --- /dev/null +++ b/packages/components/inputs/SearchNSInputContainer.tsx @@ -0,0 +1,50 @@ +import React, { FC } from "react"; +import { StyleProp, View, ViewStyle } from "react-native"; + +import { useNameSearch } from "../../hooks/search/useNameSearch"; +import { useSelectedNetworkId } from "../../hooks/useSelectedNetwork"; +import { layout } from "../../utils/style/layout"; +import { AvatarWithName } from "../user/AvatarWithName"; + +// Used as a wrapper on a TextInput or something like. It allows to search a name in TNS and returns the address. +export const SearchNSInputContainer: FC<{ + searchText: string; + onPressName: (userId: string) => void; + style?: StyleProp; +}> = ({ searchText, onPressName, style, children }) => { + const selectedNetworkId = useSelectedNetworkId(); + const { names } = useNameSearch({ + networkId: selectedNetworkId, + input: searchText, + limit: 12, + }); + const hasNames = !!names.length; + + return ( + <> + {children} + {hasNames && ( + + {names.map((n) => ( + onPressName(userId)} + style={{ marginRight: layout.padding_x1 }} + /> + ))} + + )} + + ); +}; diff --git a/packages/components/modals/SendModal.tsx b/packages/components/modals/SendModal.tsx index 308c6715d6..cc25114e29 100644 --- a/packages/components/modals/SendModal.tsx +++ b/packages/components/modals/SendModal.tsx @@ -36,6 +36,7 @@ import { SVG } from "../SVG"; import { MaxButton } from "../buttons/MaxButton"; import { PrimaryButton } from "../buttons/PrimaryButton"; import { DAOSelector } from "../dao/DAOSelector"; +import { SearchNSInputContainer } from "../inputs/SearchNSInputContainer"; import { TextInputCustom } from "../inputs/TextInputCustom"; import { SpacerColumn, SpacerRow } from "../spacer"; @@ -64,7 +65,7 @@ export const SendModal: React.FC = ({ }) => { const { setToastError, setToastSuccess } = useFeedbacks(); const selectedWallet = useSelectedWallet(); - const { control, setValue, handleSubmit } = useForm(); + const { control, setValue, handleSubmit, watch } = useForm(); const [selectedDAOId, setSelectedDAOId] = useState(""); const makeProposal = useDAOMakeProposal(selectedDAOId); const [, daoAddress] = parseUserId(selectedDAOId); @@ -206,19 +207,27 @@ export const SendModal: React.FC = ({ > - - height={48} - width={320} - control={control} - variant="labelOutside" - label="Receiver" - name="toAddress" - rules={{ required: true }} - placeHolder={`Enter a ${ - getNetwork(networkId)?.displayName || networkId - } address`} - defaultValue="" - /> + { + const [, userAddress] = parseUserId(userId); + setValue("toAddress", userAddress); + }} + searchText={watch("toAddress")} + > + + height={48} + width={320} + control={control} + variant="labelOutside" + label="Receiver" + name="toAddress" + rules={{ required: true }} + placeHolder={`Enter a ${ + getNetwork(networkId)?.displayName || networkId + } name or address`} + defaultValue="" + /> + diff --git a/packages/components/navigation/BuyTokens.tsx b/packages/components/navigation/BuyTokens.tsx index 148198d39f..1757316e6c 100644 --- a/packages/components/navigation/BuyTokens.tsx +++ b/packages/components/navigation/BuyTokens.tsx @@ -1,20 +1,22 @@ import React from "react"; -import { Linking, TouchableOpacity } from "react-native"; +import { Linking, TextStyle, TouchableOpacity } from "react-native"; import { CreditCardIcon } from "react-native-heroicons/outline"; import { primaryColor } from "../../utils/style/colors"; -import { fontBold16 } from "../../utils/style/fonts"; import { layout } from "../../utils/style/layout"; import { BrandText } from "../BrandText"; -export const BuyTokens: React.FC = () => { +export const BuyTokens: React.FC<{ + flexDirection: "row" | "column"; + textStyle: TextStyle; +}> = ({ flexDirection, textStyle }) => { return ( { Linking.openURL("https://frontier.osmosis.zone/?from=OSMO&to=TORI"); @@ -22,9 +24,9 @@ export const BuyTokens: React.FC = () => { > - Buy Tokens + Buy Tokens ); }; diff --git a/packages/components/navigation/Sidebar.tsx b/packages/components/navigation/Sidebar.tsx index f42757ecfd..7d9b90bad4 100644 --- a/packages/components/navigation/Sidebar.tsx +++ b/packages/components/navigation/Sidebar.tsx @@ -22,6 +22,7 @@ import useSelectedWallet from "../../hooks/useSelectedWallet"; import { NetworkKind } from "../../networks"; import { useAppNavigation } from "../../utils/navigation"; import { neutral17, neutral33 } from "../../utils/style/colors"; +import { fontBold16, fontBold9 } from "../../utils/style/fonts"; import { smallSidebarWidth, fullSidebarWidth, @@ -146,7 +147,10 @@ export const Sidebar: React.FC = () => { /> - + {selectedNetworkKind === NetworkKind.Cosmos && diff --git a/packages/components/user/AvatarWithName.tsx b/packages/components/user/AvatarWithName.tsx index 3b585d5292..f2a83d4ca8 100644 --- a/packages/components/user/AvatarWithName.tsx +++ b/packages/components/user/AvatarWithName.tsx @@ -18,7 +18,7 @@ export const AvatarWithName: React.FC< userId: string | undefined; } ) & { - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; } > = (props) => { @@ -31,7 +31,7 @@ export const AvatarWithName: React.FC< export const AvatarWithNameFromName: React.FC<{ networkId: string | undefined; name: string | undefined; - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; }> = ({ networkId, name, style, onPress }) => { const { nameOwner } = useNSNameOwner(networkId, name); @@ -47,7 +47,7 @@ export const AvatarWithNameFromName: React.FC<{ export const AvatarWithNameFromUserId: React.FC<{ userId: string | undefined; - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; }> = ({ userId, style, onPress }) => { const { primaryAlias } = useNSPrimaryAlias(userId); @@ -64,7 +64,7 @@ export const AvatarWithNameFromUserId: React.FC<{ export const AvatarWithNameView: React.FC<{ name: string | undefined; userId: string | undefined; - style: StyleProp; + style?: StyleProp; onPress: (userId: string) => void; }> = ({ name, userId, style, onPress }) => { const [, userAddress] = parseUserId(userId); diff --git a/packages/context/SidebarProvider.tsx b/packages/context/SidebarProvider.tsx index 0f65d75cd7..fe56dffa4d 100644 --- a/packages/context/SidebarProvider.tsx +++ b/packages/context/SidebarProvider.tsx @@ -1,47 +1,33 @@ -import React, { - createContext, - useContext, - useState, - useEffect, - useMemo, -} from "react"; -import { useWindowDimensions } from "react-native"; +import { useEffect, useMemo } from "react"; import { useSelector } from "react-redux"; +import { useIsMobile } from "../hooks/useIsMobile"; import { getValuesFromId, SEPARATOR } from "../screens/DAppStore/query/util"; import { selectAvailableApps, selectCheckedApps, setSelectedApps, } from "../store/slices/dapps-store"; +import { + selectSidebarExpanded, + setSidebarExpanded, +} from "../store/slices/settings"; import { useAppDispatch } from "../store/store"; import { SIDEBAR_LIST } from "../utils/sidebar"; -interface DefaultValue { - isSidebarExpanded: boolean; - toggleSidebar: () => void; - dynamicSidebar: { [p: string]: any }; -} - -const defaultValue: DefaultValue = { - isSidebarExpanded: false, - toggleSidebar: () => {}, - dynamicSidebar: {}, -}; - -const SidebarContext = createContext(defaultValue); - -const MOBILE_WIDTH = 768; - -export const SidebarContextProvider: React.FC = ({ children }) => { - // The entered isSidebarExpanded - const [isSidebarExpanded, setIsSidebarExpanded] = useState( - defaultValue.isSidebarExpanded - ); - +export const useSidebar = () => { + const isSidebarExpanded = useSelector(selectSidebarExpanded); const selectedApps = useSelector(selectCheckedApps); const availableApps = useSelector(selectAvailableApps); const dispatch = useAppDispatch(); + // on mobile sidebar is not expanded on load + const isMobile = useIsMobile(); + useEffect(() => { + if (isMobile) { + dispatch(setSidebarExpanded(false)); + } + }, [dispatch, isMobile]); + useEffect(() => { if (selectedApps.length === 0 && Object.values(availableApps).length > 0) { dispatch( @@ -87,27 +73,14 @@ export const SidebarContextProvider: React.FC = ({ children }) => { return dynamicAppsSelection; }, [availableApps, selectedApps]); - const { width: windowWidth } = useWindowDimensions(); - useEffect(() => { - setIsSidebarExpanded( - windowWidth >= MOBILE_WIDTH ? defaultValue.isSidebarExpanded : false - ); - }, [windowWidth]); - - const toggleSidebar = () => setIsSidebarExpanded(!isSidebarExpanded); + const toggleSidebar = () => { + dispatch(setSidebarExpanded(!isSidebarExpanded)); + }; - return ( - - {children} - - ); + return { + isSidebarExpanded, + toggleSidebar, + dynamicSidebar, + }; }; - -export const useSidebar = () => useContext(SidebarContext); diff --git a/packages/store/slices/settings.ts b/packages/store/slices/settings.ts index 2b72c1c1a1..745bf48d4a 100644 --- a/packages/store/slices/settings.ts +++ b/packages/store/slices/settings.ts @@ -10,6 +10,7 @@ interface Settings { isAdenaConnected: boolean; alreadyVisited: boolean; areTestnetsEnabled: boolean; + sideBarExpanded: boolean; } const initialState: Settings = { @@ -20,6 +21,7 @@ const initialState: Settings = { isAdenaConnected: false, alreadyVisited: false, areTestnetsEnabled: false, + sideBarExpanded: true, }; export const selectSelectedNetworkId = (state: RootState) => @@ -37,6 +39,9 @@ export const selectIsAdenaConnected = (state: RootState) => export const selectAreTestnetsEnabled = (state: RootState) => state.settings.areTestnetsEnabled; +export const selectSidebarExpanded = (state: RootState) => + state.settings.sideBarExpanded; + export const selectNFTStorageAPI = (state: RootState) => state.settings.NFTStorageAPI; @@ -59,6 +64,9 @@ const settingsSlice = createSlice({ setAreTestnetsEnabled: (state, action: PayloadAction) => { state.areTestnetsEnabled = action.payload; }, + setSidebarExpanded: (state, action: PayloadAction) => { + state.sideBarExpanded = action.payload; + }, setNFTStorageAPI: (state, action: PayloadAction) => { state.NFTStorageAPI = action.payload; }, @@ -71,6 +79,7 @@ export const { setIsKeplrConnected, setIsAdenaConnected, setAreTestnetsEnabled, + setSidebarExpanded, setNFTStorageAPI, } = settingsSlice.actions;