diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..5c03475abb --- /dev/null +++ b/.eslintignore @@ -0,0 +1,16 @@ +**/*.scss +**/*.html +**/*.json +**/*.png +**/*.svg +**/*.ttf +**/*.secret +**/*.md +.DS_Store + +node_modules + +dist/* +prod/* + +yarn.lock diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..8ba97ec4ad --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +@@ -1,11 +0,0 @@ +**/*.png +**/*.svg +**/*.ttf +**/*.secret +**/*.md +.DS_Store + +node_modules + +dist/* +prod/* + +yarn.lock diff --git a/package.json b/package.json index f64e08cbe2..e10148acf5 100644 --- a/package.json +++ b/package.json @@ -30,11 +30,18 @@ "lint-fix": "lerna run lint-fix", "ci": "yarn install --frozen-lockfile && yarn build && yarn test", "ci-lint": "yarn install --frozen-lockfile && yarn lint-test", - "ci-publish": "yarn clean && yarn install --frozen-lockfile && lerna run build --ignore @keplr/extension && lerna publish from-git --yes" + "ci-publish": "yarn clean && yarn install --frozen-lockfile && lerna run build --ignore @keplr/extension && lerna publish from-git --yes", + "pre-commit": "lint-staged" }, "pre-commit": [ - "lint-test" + "pre-commit" ], + "lint-staged": { + "*": [ + "eslint", + "prettier --check" + ] + }, "keywords": [], "author": "chainapsis", "license": "Apache-2.0", @@ -51,6 +58,7 @@ "eslint-plugin-react-hooks": "^2.0.1", "eslint-plugin-unicorn": "^24.0.0", "lerna": "^3.22.1", + "lint-staged": "^10.5.4", "pre-commit": "^1.2.2", "prettier": "^2.2.1", "ts-loader": "^8.0.14", diff --git a/packages/mobile/package.json b/packages/mobile/package.json index a9df6318c6..0aef540147 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -24,6 +24,7 @@ "@keplr-wallet/router": "0.8.0", "@keplr-wallet/stores": "0.8.2-rc.0", "@keplr-wallet/types": "0.8.2-rc.0", + "@keplr-wallet/unit": "0.8.2-rc.0", "@react-native-async-storage/async-storage": "^1.14.1", "@react-native-community/masked-view": "^0.1.10", "@react-native-picker/picker": "^1.12.0", diff --git a/packages/mobile/src/app.tsx b/packages/mobile/src/app.tsx index ad71b2045c..0edad202d7 100644 --- a/packages/mobile/src/app.tsx +++ b/packages/mobile/src/app.tsx @@ -2,12 +2,20 @@ import React, { FunctionComponent } from "react"; import { StoreProvider } from "./stores"; import { AppNavigation } from "./navigation"; import { GlobalThemeProvider } from "./global-theme"; +import { + NotificationProvider, + NotificationStoreProvider, +} from "./components/notification"; export const App: FunctionComponent = () => { return ( - + + + + + ); diff --git a/packages/mobile/src/components/address/index.tsx b/packages/mobile/src/components/address/index.tsx index dc5b9e90c8..f9d82d50e6 100644 --- a/packages/mobile/src/components/address/index.tsx +++ b/packages/mobile/src/components/address/index.tsx @@ -3,6 +3,7 @@ import React, { FunctionComponent } from "react"; import { Text } from "react-native-elements"; import { View } from "react-native"; import { Bech32Address } from "@keplr-wallet/cosmos"; +import { bcGray, br3, bw1, caption1, px4, sf } from "../../styles"; export interface AddressProps { maxCharacters: number; @@ -14,16 +15,10 @@ export const Address: FunctionComponent = ({ address, }) => { return ( - - {Bech32Address.shortenAddress(address, maxCharacters)} + + + {Bech32Address.shortenAddress(address, maxCharacters)} + ); }; diff --git a/packages/mobile/src/components/buttons/default-button.tsx b/packages/mobile/src/components/buttons/default-button.tsx index 902512cf4f..6b51b26924 100644 --- a/packages/mobile/src/components/buttons/default-button.tsx +++ b/packages/mobile/src/components/buttons/default-button.tsx @@ -6,11 +6,12 @@ import { GestureResponderEvent, } from "react-native"; import { Button } from "react-native-elements"; +import { bw1, flex1, br1, px4, sf, buttonFont1, py3 } from "../../styles"; type DefalutButtonProps = { - containerStyle?: StyleProp; - buttonStyle?: StyleProp; - titleStyle?: StyleProp; + containerStyle?: StyleProp[]; + buttonStyle?: StyleProp[]; + titleStyle?: StyleProp[]; disabled?: boolean; loading?: boolean; title: string; @@ -18,9 +19,9 @@ type DefalutButtonProps = { }; export const DefaultButton: FunctionComponent = ({ - containerStyle, - buttonStyle, - titleStyle, + containerStyle = [], + buttonStyle = [], + titleStyle = [], title, disabled, loading, @@ -28,21 +29,9 @@ export const DefaultButton: FunctionComponent = ({ }) => { return ( +// +// ); +// }); + +// // eslint-disable-next-line @typescript-eslint/ban-types +// export const UnknownMsgView: FunctionComponent<{ msg: object }> = ({ msg }) => { +// const prettyMsg = useMemo(() => { +// try { +// return yaml.dump(msg); +// } catch (e) { +// console.log(e); +// return "Failed to decode the msg"; +// } +// }, [msg]); + +// return ( +//
+//
{prettyMsg}
+//
+// ); +// }; + +function clearDecimals(dec: string): string { + if (!dec.includes(".")) { + return dec; + } + + for (let i = dec.length - 1; i >= 0; i--) { + if (dec[i] === "0") { + dec = dec.slice(0, dec.length - 1); + } else { + break; + } + } + if (dec.length > 0 && dec[dec.length - 1] === ".") { + dec = dec.slice(0, dec.length - 1); + } + + return dec; +} diff --git a/packages/mobile/src/modals/transaction-details.tsx b/packages/mobile/src/modals/transaction-details.tsx new file mode 100644 index 0000000000..f61fdb68d5 --- /dev/null +++ b/packages/mobile/src/modals/transaction-details.tsx @@ -0,0 +1,133 @@ +import React, { FunctionComponent } from "react"; + +import { observer } from "mobx-react-lite"; +import { useStore } from "../stores"; + +import { + IFeeConfig, + IGasConfig, + IMemoConfig, + SignDocHelper, +} from "@keplr-wallet/hooks"; +import { renderAminoMessage } from "./amino"; +import { renderDirectMessage } from "./direct"; +import { ScrollView, View } from "react-native"; +import { Text } from "react-native-elements"; +import { + body3, + flex1, + flexDirectionRow, + sf, + h6, + mb3, + p3, + subtitle1, + subtitle2, + mb2, + cardStyle, + fcGrey1, + justifyContentAround, + bbw1, + bcGray, + px2, +} from "../styles"; +import Icon from "react-native-vector-icons/Feather"; + +export const TransactionDetails: FunctionComponent<{ + signDocHelper: SignDocHelper; + memoConfig: IMemoConfig; + feeConfig: IFeeConfig; + gasConfig: IGasConfig; + disableInputs?: boolean; +}> = observer( + ({ signDocHelper, memoConfig, feeConfig, gasConfig, disableInputs }) => { + const { chainStore, priceStore, accountStore } = useStore(); + + const mode = signDocHelper.signDocWrapper + ? signDocHelper.signDocWrapper.mode + : "none"; + const msgs = signDocHelper.signDocWrapper + ? signDocHelper.signDocWrapper.mode === "amino" + ? signDocHelper.signDocWrapper.aminoSignDoc.msgs + : signDocHelper.signDocWrapper.protoSignDoc.txMsgs + : []; + + const renderedMsgs = (() => { + if (mode === "amino") { + return (msgs as any[]).map((msg, i) => { + const msgContent = renderAminoMessage( + accountStore.getAccount(chainStore.current.chainId).msgOpts, + msg, + chainStore.current.currencies + ); + return ( + + + + ); + }); + } else if (mode === "direct") { + return (msgs as any[]).map((msg, i) => { + const msgContent = renderDirectMessage( + msg, + chainStore.current.currencies + ); + return ( + + + + ); + }); + } else { + return null; + } + })(); + + return ( + + Messages + + {renderedMsgs} + + + Memo + + {memoConfig.memo ? memoConfig.memo : "(No memo)"} + + + + Fee + + {feeConfig.fee.maxDecimals(6).trim(true).toString()} + + + + ); + } +); + +const Msg: FunctionComponent<{ + icon?: string; + title: string; + content: string; +}> = ({ icon = "question", title, content }) => { + return ( + + + + + + {title} + {content} + + + ); +}; diff --git a/packages/mobile/src/navigation.tsx b/packages/mobile/src/navigation.tsx index 5c2acfff5b..74d43f4408 100644 --- a/packages/mobile/src/navigation.tsx +++ b/packages/mobile/src/navigation.tsx @@ -1,7 +1,12 @@ -import React, { FunctionComponent } from "react"; +import React, { FunctionComponent, useLayoutEffect, useEffect } from "react"; import { Text, View } from "react-native"; import { KeyRingStatus } from "@keplr-wallet/background"; -import { NavigationContainer } from "@react-navigation/native"; +import { + NavigationContainer, + useNavigation, + useRoute, + getFocusedRouteNameFromRoute, +} from "@react-navigation/native"; import { useStore } from "./stores"; import { observer } from "mobx-react-lite"; import { RegisterScreen } from "./screens/register"; @@ -14,12 +19,16 @@ import { StakeStackScreen } from "./screens/stake"; import { GovernanceStackScreen } from "./screens/governance"; import { createDrawerNavigator } from "@react-navigation/drawer"; import { DrawerContent } from "./components/drawer"; +import { Page } from "./components/page"; +import { alignItemsCenter, flex1, justifyContentCenter, sf } from "./styles"; const SplashScreen: FunctionComponent = () => { return ( - - Loading... - + + + Loading... + + ); }; @@ -27,13 +36,38 @@ const Stack = createStackNavigator(); const Drawer = createDrawerNavigator(); const Tab = createBottomTabNavigator(); +export const MainNavigation: FunctionComponent = () => { + const navigation = useNavigation(); + const route = useRoute(); + useEffect(() => { + const routeName = getFocusedRouteNameFromRoute(route); + + if (routeName === "Home" || routeName === undefined) { + navigation.setOptions({ tabBarVisible: true }); + } else { + navigation.setOptions({ tabBarVisible: false }); + } + }, [navigation, route]); + + return ( + + + + + + + ); +}; + export const MainTabNavigation: FunctionComponent = () => { return ( - - - - + + {/* */} ); }; diff --git a/packages/mobile/src/screens/governance/all-proposals.tsx b/packages/mobile/src/screens/governance/all-proposals.tsx index 9c9081be36..7a41207463 100644 --- a/packages/mobile/src/screens/governance/all-proposals.tsx +++ b/packages/mobile/src/screens/governance/all-proposals.tsx @@ -1,6 +1,6 @@ import React, { FunctionComponent } from "react"; -import { Text, useTheme } from "react-native-elements"; -import { View, FlatList, Platform } from "react-native"; +import { Text } from "react-native-elements"; +import { View, FlatList } from "react-native"; import { RectButton } from "react-native-gesture-handler"; import { parseTime } from "./governance-utils"; import { ObservableQueryProposal } from "@keplr-wallet/stores"; @@ -9,36 +9,30 @@ import { useStore } from "../../stores"; import { StateBadge } from "./state-badge"; import { Governance } from "@keplr-wallet/stores"; import { useNavigation } from "@react-navigation/native"; +import { + alignItemsCenter, + bgcWhite, + caption2, + cardStyle, + fcGrey1, + flexDirectionRow, + h6, + justifyContentBetween, + mb2, + mt2, + p4, + sf, + shadow, +} from "../../styles"; const ProposalSummary: FunctionComponent<{ proposal: ObservableQueryProposal; }> = observer(({ proposal }) => { const navigation = useNavigation(); - const { theme } = useTheme(); - return ( ), - padding: 15, - backgroundColor: "#fff", - opacity: 0.9, - ...Platform.select({ - ios: { - shadowColor: "#000", - shadowOffset: { - width: 0, - height: 1, - }, - shadowOpacity: 0.2, - shadowRadius: 1.41, - }, - android: { - elevation: 2, - }, - }), - }} + style={sf([cardStyle, p4, bgcWhite, shadow])} rippleColor="#AAAAAA" onPress={() => { navigation.navigate("Governance Details", { @@ -48,27 +42,21 @@ const ProposalSummary: FunctionComponent<{ > - {`#${proposal.id}`} + {`#${proposal.id}`} - - {proposal.title} - - + {proposal.title} + {proposal.proposalStatus === Governance.ProposalStatus.DEPOSIT_PERIOD - ? `Deposit End Time: ${parseTime(proposal.raw.deposit_end_time)}` - : `Voting End Time: ${parseTime(proposal.raw.voting_end_time)}`} + ? `Deposit endtime: ${parseTime(proposal.raw.deposit_end_time)}` + : `Voting endtime: ${parseTime(proposal.raw.voting_end_time)}`} diff --git a/packages/mobile/src/screens/governance/governance-details-screeen.tsx b/packages/mobile/src/screens/governance/governance-details-screeen.tsx index 28c1260aca..96bde1a0b5 100644 --- a/packages/mobile/src/screens/governance/governance-details-screeen.tsx +++ b/packages/mobile/src/screens/governance/governance-details-screeen.tsx @@ -4,6 +4,7 @@ import { ScrollView } from "react-native"; import { ProposalDetailsCard } from "./proposal-details-card"; import { FixedPage } from "../../components/page"; import { VotingButton } from "./voting-button"; +import { p2 } from "../../styles"; export const GovernanceDetailsScreeen: FunctionComponent<{ route: { @@ -13,7 +14,7 @@ export const GovernanceDetailsScreeen: FunctionComponent<{ const { proposalId } = route.params; return ( - + diff --git a/packages/mobile/src/screens/governance/proposal-details-card.tsx b/packages/mobile/src/screens/governance/proposal-details-card.tsx index ad6ba3cd00..b06495fff4 100644 --- a/packages/mobile/src/screens/governance/proposal-details-card.tsx +++ b/packages/mobile/src/screens/governance/proposal-details-card.tsx @@ -1,13 +1,26 @@ import React, { FunctionComponent } from "react"; -import { Card, Text, Button } from "react-native-elements"; +import { Card, Text } from "react-native-elements"; import { View } from "react-native"; import { parseTime } from "./governance-utils"; import { StateBadge } from "./state-badge"; -import { BarChart } from "../../components/svg"; import { observer } from "mobx-react-lite"; import { useStore } from "../../stores"; -import { VotingButton } from "./voting-button"; import { Governance } from "@keplr-wallet/stores"; +import { + alignItemsCenter, + caption2, + fAlignLeft, + fAlignRight, + flex1, + flexDirectionRow, + h6, + justifyContentBetween, + mb1, + mb2, + overline, + sf, + subtitle2, +} from "../../styles"; export const ProposalDetailsCard: FunctionComponent<{ proposalId: string; @@ -26,21 +39,17 @@ export const ProposalDetailsCard: FunctionComponent<{ return proposal ? ( - {`#${proposal.id}`} + {`#${proposal.id}`} - - {proposal.title} - + {proposal.title} {/* {proposal.proposalStatus !== Governance.ProposalStatus.DEPOSIT_PERIOD ? ( ) : null} */} - + {proposal.proposalStatus === Governance.ProposalStatus.DEPOSIT_PERIOD ? ( - - - Submit Time + + Submit Time + + {parseTime(proposal.raw.submit_time)} - {parseTime(proposal.raw.submit_time)} - - - Deposit End Time + + Deposit End Time + + {parseTime(proposal.raw.deposit_end_time)} - {parseTime(proposal.raw.deposit_end_time)} ) : ( - - - Voting Start Time + + Voting Start Time + + {parseTime(proposal.raw.voting_start_time)} - {parseTime(proposal.raw.voting_start_time)} - - - Voting End Time + + Voting End Time + + {parseTime(proposal.raw.voting_end_time)} - {parseTime(proposal.raw.voting_end_time)} )} - - Description - - - {proposal.raw.content.value.description} - + Description + {proposal.raw.content.value.description} ) : ( // TO DO Loading - Loading + Loading ); }); diff --git a/packages/mobile/src/screens/governance/state-badge.tsx b/packages/mobile/src/screens/governance/state-badge.tsx index b5b645090e..43851d23e6 100644 --- a/packages/mobile/src/screens/governance/state-badge.tsx +++ b/packages/mobile/src/screens/governance/state-badge.tsx @@ -1,44 +1,45 @@ import React, { FunctionComponent } from "react"; -import { View } from "react-native"; -import { Text, useTheme } from "react-native-elements"; +import { StyleProp, View, ViewProps } from "react-native"; +import { Text, TextProps } from "react-native-elements"; import { Governance } from "@keplr-wallet/stores"; +import { br2, caption2, px3, py1, sf } from "../../styles"; export const StateBadge: FunctionComponent<{ proposalStatus: Governance.ProposalStatus; }> = ({ proposalStatus }) => { const ProposalStatus = Governance.ProposalStatus; - const backgroundColor = (() => { + const backgroundColor: StyleProp = (() => { switch (proposalStatus) { case ProposalStatus.DEPOSIT_PERIOD: - return "#aaedf9"; + return { backgroundColor: "#aaedf9" }; case ProposalStatus.VOTING_PERIOD: - return "#eaecfb"; + return { backgroundColor: "#eaecfb" }; case ProposalStatus.PASSED: - return "#b0eed3"; + return { backgroundColor: "#b0eed3" }; case ProposalStatus.REJECTED: - return "#fdd1da"; + return { backgroundColor: "#fdd1da" }; case ProposalStatus.FAILED: - return "#fdd1da"; + return { backgroundColor: "#fdd1da" }; default: - return "#fdd1da"; + return { backgroundColor: "#fdd1da" }; } })(); - const textColor = (() => { + const fontColor: StyleProp = (() => { switch (proposalStatus) { case ProposalStatus.DEPOSIT_PERIOD: - return "#03acca"; + return { color: "#03acca" }; case ProposalStatus.VOTING_PERIOD: - return "#2643e9"; + return { color: "#2643e9" }; case ProposalStatus.PASSED: - return "#1aae6f"; + return { color: "#1aae6f" }; case ProposalStatus.REJECTED: - return "#f80031"; + return { color: "#f80031" }; case ProposalStatus.FAILED: - return "#f80031"; + return { color: "#f80031" }; default: - return "#f80031"; + return { color: "#f80031" }; } })(); @@ -60,15 +61,8 @@ export const StateBadge: FunctionComponent<{ })(); return ( - - {text} + + {text} ); }; diff --git a/packages/mobile/src/screens/governance/voting-button.tsx b/packages/mobile/src/screens/governance/voting-button.tsx index 3db2af7f75..fe1fe9dfba 100644 --- a/packages/mobile/src/screens/governance/voting-button.tsx +++ b/packages/mobile/src/screens/governance/voting-button.tsx @@ -1,14 +1,30 @@ import React, { FunctionComponent, useEffect, useState } from "react"; -import { Button, Text, useTheme } from "react-native-elements"; +import { Button, Text } from "react-native-elements"; import { observer } from "mobx-react-lite"; -import { View } from "react-native"; +import { StyleProp, View, ViewProps } from "react-native"; import { RectButton } from "react-native-gesture-handler"; import { useStore } from "../../stores"; import { Governance } from "@keplr-wallet/stores"; import { WhiteButton, DefaultButton } from "../../components/buttons"; - -type VoteType = "Yes" | "Abstain" | "No" | "No With Veto"; +import { + alignItemsCenter, + bgcWhite, + justifyContentCenter, + flexDirectionRow, + mr4, + sf, + bgcGray, + px4, + py4, + bbw1, + bcGray, + bgcPrimary, + br2, + buttonFont2, +} from "../../styles"; + +type VoteType = "Yes" | "Abstain" | "No" | "NoWithVeto"; export const VotingButton: FunctionComponent<{ proposalId: string; @@ -88,12 +104,12 @@ export const VotingButton: FunctionComponent<{ } /> ) : ( - + - + = ({ const [options] = useState([ "Yes", "No", - "No With Veto", + "NoWithVeto", "Abstain", ]); @@ -149,41 +165,38 @@ const VoteCheckbox: FunctionComponent<{ active: boolean; optionText: string; }> = ({ active, optionText }) => { - const { theme } = useTheme(); + const color: StyleProp = active ? bgcPrimary : bgcGray; return ( - {optionText} + {optionText} ); }; diff --git a/packages/mobile/src/screens/home/account.tsx b/packages/mobile/src/screens/home/account.tsx index 1c6442f83c..cc0d3e8b98 100644 --- a/packages/mobile/src/screens/home/account.tsx +++ b/packages/mobile/src/screens/home/account.tsx @@ -8,20 +8,29 @@ import { WalletStatus } from "@keplr-wallet/stores"; import Clipboard from "expo-clipboard"; import { RectButton } from "react-native-gesture-handler"; import { Text } from "react-native-elements"; +import { useNotification } from "../../components/notification"; +import { alignItemsCenter, h4, mb2, sf } from "../../styles"; export const AccountView: FunctionComponent = observer(() => { const { accountStore, chainStore } = useStore(); const accountInfo = accountStore.getAccount(chainStore.current.chainId); + const notification = useNotification(); const copyAddress = useCallback(async () => { if (accountInfo.walletStatus === WalletStatus.Loaded) { await Clipboard.setString(accountInfo.bech32Address); + notification.push({ + placement: "top-center", + type: "success", + duration: 1, + content: "copy address", + }); } }, [accountInfo.walletStatus, accountInfo.bech32Address]); return ( - - + + {accountInfo.walletStatus === WalletStatus.Loaded ? accountInfo.name : "Loading..."} diff --git a/packages/mobile/src/screens/home/asset.tsx b/packages/mobile/src/screens/home/asset.tsx index 5ae367d86a..1b0cc0d82f 100644 --- a/packages/mobile/src/screens/home/asset.tsx +++ b/packages/mobile/src/screens/home/asset.tsx @@ -1,10 +1,33 @@ -import React, { FunctionComponent, useMemo } from "react"; +import React, { FunctionComponent } from "react"; import { observer } from "mobx-react-lite"; import { useStore } from "../../stores"; import { View } from "react-native"; -import { Text, Badge, useTheme } from "react-native-elements"; +import { Text, Badge } from "react-native-elements"; import { DoughnutChart } from "../../components/svg"; +import { + fcSecondary, + flex1, + flexDirectionRow, + ml2, + mx2, + sf, + bgcSecondary, + flexDirectionRowReverse, + alignItemsCenter, + fAlignRight, + fcPrimary, + mt4, + relative, + py4, + absolute, + justifyContentCenter, + subtitle2, + h3, + mb1, + subtitle1, + body1, +} from "../../styles"; export const AssetView: FunctionComponent = observer(() => { const { chainStore, accountStore, queriesStore, priceStore } = useStore(); @@ -53,82 +76,54 @@ export const AssetView: FunctionComponent = observer(() => { : parseFloat(stakedSum.toDec().toString()), ]; - const { theme } = useTheme(); - return ( - - + + - Total Balance - + Total Balance + {totalPrice ? totalPrice.toString() : total.shrink(true).maxDecimals(6).toString()} - - - - + + + + Available - - + + {stakable.locale(false).toString()} - - - + + + Staked - + - - + + {stakedSum.locale(false).toString()} diff --git a/packages/mobile/src/screens/home/index.tsx b/packages/mobile/src/screens/home/index.tsx index cf34f777b8..de3f42869e 100644 --- a/packages/mobile/src/screens/home/index.tsx +++ b/packages/mobile/src/screens/home/index.tsx @@ -10,6 +10,7 @@ import { AccountView } from "./account"; import { AssetView } from "./asset"; import { TxButtonView } from "./tx-button"; import { GradientBackground } from "../../components/svg"; +import { DefaultButton } from "../../components/buttons"; const HomeStack = createStackNavigator(); export const HomeStackScreen: FunctionComponent = () => { @@ -45,6 +46,22 @@ const HomeScreen: FunctionComponent = observer(() => { + + { + navigation.navigate("Stake"); + }} + /> + + + { + navigation.navigate("Governance"); + }} + /> + ); }); diff --git a/packages/mobile/src/screens/home/tx-button.tsx b/packages/mobile/src/screens/home/tx-button.tsx index 4d2b9eabf0..ac7dc19a7f 100644 --- a/packages/mobile/src/screens/home/tx-button.tsx +++ b/packages/mobile/src/screens/home/tx-button.tsx @@ -6,6 +6,7 @@ import { View } from "react-native"; import { Dec } from "@keplr-wallet/unit"; import { useNavigation } from "@react-navigation/native"; import { WhiteButton } from "../..//components/buttons"; +import { flexDirectionRow, ml2, mr2 } from "../../styles"; export const TxButtonView: FunctionComponent = observer(() => { const { accountStore, chainStore, queriesStore } = useStore(); @@ -23,21 +24,15 @@ export const TxButtonView: FunctionComponent = observer(() => { undefined; return ( - - {}} - /> + + {}} /> {/* "Disabled" property in button tag will block the mouse enter/leave events. So, tooltip will not work as expected. To solve this problem, don't add "disabled" property to button tag and just add "disabled" class manually. */} { return ( }} + screenOptions={{ + headerBackground: () => , + headerBackTitleVisible: false, + }} > @@ -48,10 +54,15 @@ const SendScreen: FunctionComponent = observer(() => { return ( - + + + Fee -