diff --git a/.eslintrc.js b/.eslintrc.js
index db7e98ee..cd62c780 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,7 +1,6 @@
module.exports = {
root: true,
- extends: '@react-native-community',
+ extends: ['@react-native-community', 'plugin:jest/recommended'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
};
-
diff --git a/.prettierrc.js b/.prettierrc.js
index dc65c364..2e6bc15c 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -4,6 +4,6 @@ module.exports = {
singleQuote: true,
trailingComma: 'all',
bracketSpacing: true,
- semi: false
+ semi: true
};
diff --git a/__tests__/Test.test.tsx b/__tests__/Test.test.tsx
index 6ce3b6bd..bdad1211 100644
--- a/__tests__/Test.test.tsx
+++ b/__tests__/Test.test.tsx
@@ -1,43 +1,13 @@
-import * as React from 'react';
-import * as ReactNative from 'react-native';
+import React from 'react';
import renderer from 'react-test-renderer';
import Test from '../src/components/Test';
-import App from '../App';
-
-import { ButtonIcon } from '../src/components/ButtonIcon';
-import IconOptions from 'src/assets/icons/icon-options.svg';
-
-import { shallow, mount } from 'enzyme'
-import 'jest-enzyme'
-import 'jest-styled-components'
-
-
-// const button = {
-// type: 'options',
-// onPress: () => {},
-// iconImage: IconOptions,
-// accessibilityLabel: 'More Options'
-// }
-
-
-// it('icon button renders', () => {
-// const { type, iconImage, accessibilityLabel, onPress } = button;
-// const component =
-//
-// const tree = renderer.create(component).toJSON()
-// expect(tree).toMatchSnapshot()
-// });
+import 'jest-enzyme';
+import 'jest-styled-components';
it('Test component renders', () => {
- const component =
- const tree = renderer.create(component).toJSON()
- expect(tree).toMatchSnapshot()
-});
\ No newline at end of file
+ const component = ;
+ const tree = renderer.create(component).toJSON();
+ expect(tree).toMatchSnapshot();
+});
diff --git a/__tests__/__snapshots__/Test.test.tsx.snap b/__tests__/__snapshots__/Test.test.tsx.snap
index c904124d..367329e6 100644
--- a/__tests__/__snapshots__/Test.test.tsx.snap
+++ b/__tests__/__snapshots__/Test.test.tsx.snap
@@ -1,15 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Test component renders 1`] = `
-
- Testing, testing, 1, 2, 3
-
+
+ Testing, testing, 1, 2, 3
+
+
`;
diff --git a/commitlint.config.js b/commitlint.config.js
index 4c335439..84dcb122 100644
--- a/commitlint.config.js
+++ b/commitlint.config.js
@@ -1,3 +1,3 @@
module.exports = {
- extends: ['@commitlint/config-conventional']
-};
\ No newline at end of file
+ extends: ['@commitlint/config-conventional'],
+};
diff --git a/declarations.d.ts b/declarations.d.ts
index 64d4b422..1eae33fe 100644
--- a/declarations.d.ts
+++ b/declarations.d.ts
@@ -1,5 +1,6 @@
declare module '*.svg' {
- import { SvgProps } from 'react-native-svg'
- const content: React.FC
- export default content
+ import React from 'react';
+ import { SvgProps } from 'react-native-svg';
+ const content: React.FC;
+ export default content;
}
diff --git a/index.js b/index.js
index 127e8994..200879b7 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,4 @@
-import 'react-native-get-random-values'
+import 'react-native-get-random-values';
import { AppRegistry } from 'react-native';
import App from './src/App';
diff --git a/jest.config.js b/jest.config.js
index 62af9be5..8b81c84f 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,20 +1,20 @@
module.exports = {
- preset: 'react-native',
- moduleNameMapper: {
- '^@/(.*)$': '/$1',
- },
- moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
- testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
- testPathIgnorePatterns: ['\\.snap$', '/node_modules/'],
- transformIgnorePatterns: ['node_modules/?!(static-container)'],
- cacheDirectory: '.jest/cache',
- globals: {
- 'ts-jest': {
- isolatedModules: true,
- },
- },
- clearMocks: true,
- // setupFiles: ["/jest.setup.js"],
- setupFilesAfterEnv: ['./jest.setup.js'],
- collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/node_modules/**'],
-};
\ No newline at end of file
+ preset: 'react-native',
+ moduleNameMapper: {
+ '^@/(.*)$': '/$1',
+ },
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
+ testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
+ testPathIgnorePatterns: ['\\.snap$', '/node_modules/'],
+ transformIgnorePatterns: ['node_modules/?!(static-container)'],
+ cacheDirectory: '.jest/cache',
+ globals: {
+ 'ts-jest': {
+ isolatedModules: true,
+ },
+ },
+ clearMocks: true,
+ // setupFiles: ["/jest.setup.js"],
+ setupFilesAfterEnv: ['./jest.setup.js'],
+ collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/node_modules/**'],
+};
diff --git a/jest.setup.js b/jest.setup.js
index af7ce866..1e2fd8a1 100644
--- a/jest.setup.js
+++ b/jest.setup.js
@@ -16,4 +16,4 @@ jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
// React Native Share
jest.mock('react-native-share', () => ({
default: jest.fn(),
-}));
\ No newline at end of file
+}));
diff --git a/metro.config.js b/metro.config.js
index f5608b4e..fdc5964c 100644
--- a/metro.config.js
+++ b/metro.config.js
@@ -1,4 +1,4 @@
-const { getDefaultConfig } = require('metro-config')
+const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
@@ -9,8 +9,8 @@ module.exports = (async () => {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
},
resolver: {
- assetExts: assetExts.filter(ext => ext !== 'svg'),
+ assetExts: assetExts.filter((ext) => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg'],
},
- }
-})()
+ };
+})();
diff --git a/package.json b/package.json
index 1504e313..668eda9b 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"enzyme": "^3.11.0",
"eslint": "^7.22.0",
+ "eslint-plugin-jest": "^24.3.6",
"husky": "^6.0.0",
"jest": "^27.0.4",
"jest-enzyme": "^7.1.2",
diff --git a/react-test.ts b/react-test.ts
deleted file mode 100644
index 1bfe1e1e..00000000
--- a/react-test.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View, Text } from 'react-native';
-
-export const Test = () => {
- return (
-
- Hello humans
-
- )
-}
\ No newline at end of file
diff --git a/rn-cli.config.js b/rn-cli.config.js
index 35e2ad70..f42e993c 100644
--- a/rn-cli.config.js
+++ b/rn-cli.config.js
@@ -1,8 +1,8 @@
module.exports = {
- getTransformModulePath() {
- return require.resolve('react-native-typescript-transformer');
- },
- getSourceExts() {
- return ['ts', 'tsx'];
- }
-};
\ No newline at end of file
+ getTransformModulePath() {
+ return require.resolve('react-native-typescript-transformer');
+ },
+ getSourceExts() {
+ return ['ts', 'tsx'];
+ },
+};
diff --git a/src/@types/bookmarks.d.ts b/src/@types/bookmarks.d.ts
index 9afeb373..03c135ea 100644
--- a/src/@types/bookmarks.d.ts
+++ b/src/@types/bookmarks.d.ts
@@ -1,7 +1,7 @@
export type Bookmark = {
- "displayName": String
- "description": String
- "protocol": "http" | "https" | "ipfs" | "hyper" | "dat"
- "location": String
- "tags": String[]
-}
\ No newline at end of file
+ displayName: String;
+ description: String;
+ protocol: 'http' | 'https' | 'ipfs' | 'hyper' | 'dat';
+ location: String;
+ tags: String[];
+};
diff --git a/src/@types/env.d.ts b/src/@types/env.d.ts
index d93e5d0f..ebdc6924 100644
--- a/src/@types/env.d.ts
+++ b/src/@types/env.d.ts
@@ -4,4 +4,4 @@ export type EnvType = {
ETH_WALLET_ADDRESS: String;
ETH_WALLET_SECRET_SEED_PHRASE: String;
ETH_WALLET_SECRET_PRIVATE_KEY: String;
-}
\ No newline at end of file
+};
diff --git a/src/@types/styled.d.ts b/src/@types/styled.d.ts
index d366b81b..3b636f60 100644
--- a/src/@types/styled.d.ts
+++ b/src/@types/styled.d.ts
@@ -1,21 +1,21 @@
-import 'styled-components/native'
+import 'styled-components/native';
declare module 'styled-components/native' {
- export interface DefaultTheme {
- colors: {
- scheme: string
- text: string
- background: string
- debug: string
- },
- ui: {
- background: string
- foreground: string
- icon: string
- },
- addressBar: {
- background: string
- color: string
- }
- }
-}
\ No newline at end of file
+ export interface DefaultTheme {
+ colors: {
+ scheme: string;
+ text: string;
+ background: string;
+ debug: string;
+ };
+ ui: {
+ background: string;
+ foreground: string;
+ icon: string;
+ };
+ addressBar: {
+ background: string;
+ color: string;
+ };
+ }
+}
diff --git a/src/App.tsx b/src/App.tsx
index 5dcda281..27999e72 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,24 +1,22 @@
-import React from 'react'
-import { Provider } from 'react-redux'
-import { ThemeProvider } from 'styled-components/native'
+import React from 'react';
+import { RecoilRoot } from 'recoil';
+import { ThemeProvider } from 'styled-components/native';
-import store from 'src/store/index'
+import AppNavigator from 'src/AppNavigator';
-import AppNavigator from 'src/AppNavigator'
+import lightTheme from 'src/themes/light';
+import darkTheme from 'src/themes/dark';
-import lightTheme from 'src/themes/light'
-import darkTheme from 'src/themes/dark'
-
-import { isDarkMode } from 'src/utils/appearance'
+import { IsDarkMode } from 'src/utils/appearance';
export default function App() {
return (
<>
-
-
+
+
-
+
>
- )
+ );
}
diff --git a/src/AppNavigator.tsx b/src/AppNavigator.tsx
index 21213a2a..e17144bd 100644
--- a/src/AppNavigator.tsx
+++ b/src/AppNavigator.tsx
@@ -1,75 +1,43 @@
-import React, { useEffect } from 'react'
-import { useSelector, useDispatch } from 'react-redux'
+import React, { useEffect } from 'react';
+import { useSetRecoilState } from 'recoil';
-import { NavigationContainer } from '@react-navigation/native'
-import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'
+import { NavigationContainer } from '@react-navigation/native';
+import {
+ createStackNavigator,
+ TransitionPresets,
+} from '@react-navigation/stack';
-import { useTheme } from 'styled-components/native'
+import { env } from 'environments/.env.development';
-import { env } from 'environments/.env.development'
+import { ethereumState } from 'src/store/atoms';
-import { AppState } from 'src/store/reducers'
-import {
- ETH_WALLET_ADDRESS,
- ETH_WALLET_BALANCE,
- ETH_WALLET_HEX,
- ETH_WALLET_ENS
-} from 'src/store/ethereum.reducer'
+import { Ethereum } from 'src/protocols/ethereum';
-import { Ethereum } from 'src/protocols/ethereum'
-
-import Browser from 'src/views/Browser'
-import Settings from 'src/views/Settings'
-import { ethers } from 'ethers'
-
-
-const Stack = createStackNavigator()
+import Browser from 'src/views/Browser';
+import Settings from 'src/views/Settings';
+const Stack = createStackNavigator();
export default function AppNavigator() {
-
- const theme = useTheme()
-
- const ethereumState = useSelector((state: AppState) => state.ethereum)
- const dispatch = useDispatch()
+ const setEthereumState = useSetRecoilState(ethereumState);
useEffect(() => {
-
- const wallet = new Ethereum()
- wallet.walletPrivateKey = `${env.ETH_WALLET_SECRET_PRIVATE_KEY}`
- wallet.walletAddress = `${(env.ETH_WALLET_ADDRESS).toLowerCase()}`
-
- // Store users wallet address
- dispatch({
- type: ETH_WALLET_ADDRESS,
- ethWalletAddress: wallet.walletAddress
- });
-
-
- (async() => {
-
- // Set hex and ENS wallet addresses
- dispatch({
- type: ETH_WALLET_ENS,
- ethWalletEns: wallet.isAddressHex() ?
- await wallet.getEnsFromAddress() :
- wallet.walletAddress
- });
- dispatch({
- type: ETH_WALLET_HEX,
- ethWalletHex: wallet.isAddressENS() ?
- await wallet.getAddressFromEns() :
- wallet.walletAddress
- });
-
- dispatch({
- type: ETH_WALLET_BALANCE,
- ethWalletBalance: await wallet.getBalance()
- });
-
+ const wallet = new Ethereum();
+ wallet.walletPrivateKey = `${env.ETH_WALLET_SECRET_PRIVATE_KEY}`;
+ wallet.walletAddress = `${env.ETH_WALLET_ADDRESS.toLowerCase()}`;
+ (async () => {
+ setEthereumState({
+ ethWalletAddress: wallet.walletAddress,
+ ethWalletHex: wallet.isAddressENS()
+ ? await wallet.getAddressFromEns()
+ : wallet.walletAddress,
+ ethWalletEns: wallet.isAddressHex()
+ ? await wallet.getEnsFromAddress()
+ : wallet.walletAddress,
+ ethWalletBalance: await wallet.getBalance(),
+ });
})();
- }, []);
-
+ }, [setEthereumState]);
return (
@@ -77,17 +45,16 @@ export default function AppNavigator() {
initialRouteName="Browser"
screenOptions={{
cardStyle: {
- backgroundColor: 'transparent'
+ backgroundColor: 'transparent',
},
cardOverlayEnabled: true,
cardShadowEnabled: true,
gestureEnabled: true,
- animationEnabled: true,
+ animationEnabled: true,
...TransitionPresets.ModalPresentationIOS,
}}
mode="modal"
- headerMode="screen"
- >
+ headerMode="screen">
- )
-}
\ No newline at end of file
+ );
+}
diff --git a/src/components/BrowserWebView.tsx b/src/components/BrowserWebView.tsx
index 43669ec7..d33903f4 100644
--- a/src/components/BrowserWebView.tsx
+++ b/src/components/BrowserWebView.tsx
@@ -1,19 +1,10 @@
-import React, { useRef, useEffect, useState } from 'react'
-import { WebView } from 'react-native-webview'
-import { useSelector, useDispatch } from 'react-redux'
-import styled from 'styled-components/native'
-
-import { AppState } from 'src/store/reducers'
-import {
- WEBVIEW_REF,
- WEBVIEW_STATE,
- URL_INPUT
-} from 'src/store/navigation.reducer'
-
-
+import React, { useRef, useEffect, useState } from 'react';
+import { useRecoilState } from 'recoil';
+import { WebView } from 'react-native-webview';
+import { navigationState } from 'src/store/atoms';
+import styled from 'styled-components/native';
export default function BrowserWebView() {
-
const config = {
detectorTypes: 'all',
allowStorage: true,
@@ -21,26 +12,30 @@ export default function BrowserWebView() {
allowCookies: true,
allowLocation: true,
allowCaching: true,
- defaultSearchEngine: 'duck'
- }
+ defaultSearchEngine: 'duck',
+ };
- const webViewRef = useRef(null)
+ const webViewRef = useRef(null);
-
- const navigation = useSelector((state: AppState) => state.navigation)
- const dispatch = useDispatch()
+ const [refreshing, setRefreshing] = useState(false);
- const [ refreshing, setRefreshing ] = useState(false)
+ const [navState, setNavState] = useRecoilState(navigationState);
useEffect(() => {
- dispatch({ type: WEBVIEW_REF, webViewRef });
- }, []);
+ setNavState((previous) => {
+ return {
+ ...previous,
+ webViewRef: webViewRef,
+ };
+ });
+ }, [setNavState]);
const webViewReload = () => {
setRefreshing(true);
- navigation.webViewRef.current.reload();
- }
-
+ if (navState.webViewRef) {
+ navState.webViewRef.current?.reload();
+ }
+ };
return (
<>
@@ -48,31 +43,36 @@ export default function BrowserWebView() {
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
refreshControl={
-
+
}>
{ }}
- onNavigationStateChange={(navState: { url: string }) => {
- console.log('onNavigationStateChange', navState)
- dispatch({ type: URL_INPUT, urlInput: navState.url })
- dispatch({ type: WEBVIEW_STATE, webViewState: navState })
+ source={{ uri: navState.urlCurrent }}
+ onLoadStart={() => {}}
+ onNavigationStateChange={(currentNavState) => {
+ console.log('onNavigationStateChange', currentNavState);
+ setNavState((previous) => {
+ return {
+ ...previous,
+ urlInput: currentNavState.url,
+ webViewState: currentNavState,
+ };
+ });
}}
onLoadEnd={() => {
- setRefreshing(false)
+ setRefreshing(false);
}}
onContentProcessDidTerminate={(syntheticEvent) => {
- const { nativeEvent } = syntheticEvent
- console.warn('Content process terminated, reloading', nativeEvent)
- // TODO - Show message in UI that the webview crashed
- webViewReload()
+ const { nativeEvent } = syntheticEvent;
+ console.warn(
+ 'Content process terminated, reloading',
+ nativeEvent,
+ );
+ // TODO - Show message in UI that the webview crashed
+ webViewReload();
}}
startInLoadingState
domStorageEnabled={config.allowStorage}
@@ -85,29 +85,23 @@ export default function BrowserWebView() {
>
- )
+ );
}
-
-
const ScrollView = styled.ScrollView.attrs(() => ({
contentContainerStyle: {
flex: 1,
- }
+ },
}))`
/* Note: experiment with dynamic container heights
/*margin-top: 46px;*/
/*margin-bottom: 134px;*/
-`
+`;
-const RefreshControl = styled.RefreshControl``
+const RefreshControl = styled.RefreshControl``;
const SafeAreaView = styled.SafeAreaView`
flex: 1;
-`
-
-const WebViewContainer = styled(WebView)``
+`;
-const Text = styled.Text`
- color: ${props => props.theme.colors.text};
-`
+const WebViewContainer = styled(WebView)``;
diff --git a/src/components/ButtonIcon.tsx b/src/components/ButtonIcon.tsx
index 3be82720..d83afcf1 100644
--- a/src/components/ButtonIcon.tsx
+++ b/src/components/ButtonIcon.tsx
@@ -1,57 +1,45 @@
-import React from 'react'
+import React from 'react';
import { GestureResponderEvent } from 'react-native';
import { SvgProps } from 'react-native-svg';
-import styled, { useTheme } from 'styled-components/native'
-
+import styled, { useTheme } from 'styled-components/native';
interface IconProps {
- type: string
-};
+ type: string;
+}
interface ButtonIconProps {
- type: string
- onPress: (event: GestureResponderEvent) => void
- iconImage: React.FC
- accessibilityLabel: string
-};
-
+ type: string;
+ onPress: (event: GestureResponderEvent) => void;
+ iconImage: React.FC;
+ accessibilityLabel: string;
+}
export const ButtonIcon = ({
- type, onPress, iconImage, accessibilityLabel
+ type,
+ onPress,
+ iconImage,
+ accessibilityLabel,
}: ButtonIconProps) => {
- const theme = useTheme()
- const IconImage = iconImage
- return (
-
-
-
- );
+ const theme = useTheme();
+ const IconImage = iconImage;
+ return (
+
+
+
+ );
};
+const iconSize = 32;
-const iconSize = 32
-
-const View = styled.View`
- margin-left: 16px;
- margin-right: 16px;
- padding-top: 8px;
- padding-bottom: 8px;
- flex-direction: row;
- justify-content: space-between;
-`
const Icon = styled.Pressable.attrs({
- hitSlop: 10
+ hitSlop: 10,
})`
height: ${iconSize}px;
padding-top: 0;
padding-right: 10px;
padding-bottom: 0;
padding-left: 10px;
- ${({ type }: IconProps) => type === 'tabs' && ``}
- ${({ type }: IconProps) => type === 'reload' && ``}
- ${({ type }: IconProps) => type === 'options' && ``}
-`
+ ${({ type }: IconProps) => type === 'tabs' && ''}
+ ${({ type }: IconProps) => type === 'reload' && ''}
+ ${({ type }: IconProps) => type === 'options' && ''}
+`;
diff --git a/src/components/Navigation/NavigationButtons.tsx b/src/components/Navigation/NavigationButtons.tsx
index e6c934ee..daa63dc0 100644
--- a/src/components/Navigation/NavigationButtons.tsx
+++ b/src/components/Navigation/NavigationButtons.tsx
@@ -1,105 +1,82 @@
-import React, { useContext } from 'react'
-import { SafeAreaView } from 'react-native'
-import { useSelector, useDispatch } from 'react-redux'
-import { useNavigation } from '@react-navigation/native'
-import styled, { useTheme } from 'styled-components/native'
+import React from 'react';
+import { SafeAreaView } from 'react-native';
+import { useRecoilState } from 'recoil';
+import { useNavigation } from '@react-navigation/native';
+import styled from 'styled-components/native';
-import { AppState } from 'src/store/reducers'
-
-
-import IconArrowLeft from 'src/assets/icons/icon-arrow-left.svg'
-import IconArrowRight from 'src/assets/icons/icon-arrow-right.svg'
-import IconOptions from 'src/assets/icons/icon-options.svg'
-import IconRefresh from 'src/assets/icons/icon-refresh.svg'
-import IconTabs from 'src/assets/icons/icon-tabs.svg'
-
-import { ButtonIcon } from 'src/components/ButtonIcon'
-
-
-interface IconProps {
- type: string
-}
+import { navigationState } from 'src/store/atoms';
+import IconArrowLeft from 'src/assets/icons/icon-arrow-left.svg';
+import IconArrowRight from 'src/assets/icons/icon-arrow-right.svg';
+import IconOptions from 'src/assets/icons/icon-options.svg';
+import IconRefresh from 'src/assets/icons/icon-refresh.svg';
+import IconTabs from 'src/assets/icons/icon-tabs.svg';
+import { ButtonIcon } from 'src/components/ButtonIcon';
const NavigationButtons = () => {
-
- const theme = useTheme()
-
- const screenNavigation = useNavigation()
-
- const navigation = useSelector((state: AppState) => state.navigation)
- const dispatch = useDispatch()
-
- const webViewReload = () => navigation.webViewRef.current.reload()
- // TODO - Make backward/forward inactive based on history
- const webViewGoBack = () => navigation.webViewRef.current.goBack()
- const webViewGoForward = () => navigation.webViewRef.current.goForward()
- const viewSettings = () => screenNavigation.navigate('Settings')
-
-
- const navigationButtons = [
- {
- type: 'back',
- onPress: () => webViewGoBack(),
- iconImage: IconArrowLeft,
- accessibilityLabel: 'Go back'
- },
- {
- type: 'forward',
- onPress: () => webViewGoForward(),
- iconImage: IconArrowRight,
- accessibilityLabel: 'Go forward'
- },
- {
- type: 'tabs',
- onPress: () => { },
- iconImage: IconTabs,
- accessibilityLabel: 'List opened web-site tabs'
- },
- {
- type: 'reload',
- onPress: () => webViewReload(),
- iconImage: IconRefresh,
- accessibilityLabel: 'Reload web-page'
- },
- {
- type: 'options',
- onPress: () => viewSettings(),
- iconImage: IconOptions,
- accessibilityLabel: 'More Options'
- }
- ];
-
-
-
-
- return (
-
-
-
- {
- navigationButtons.map((button) => {
- const { type, iconImage, accessibilityLabel, onPress } = button;
- return (
-
- )
- })
- }
-
-
-
- )
-}
-
-
-const iconSize = 32
+ const screenNavigation = useNavigation();
+
+ const [navState] = useRecoilState(navigationState);
+
+ const webViewReload = () => navState.webViewRef?.current?.reload();
+ const webViewGoBack = () => navState.webViewRef?.current?.goBack();
+ const webViewGoForward = () => navState.webViewRef?.current?.goForward();
+
+ const viewSettings = () => screenNavigation.navigate('Settings');
+
+ const navigationButtons = [
+ {
+ type: 'back',
+ onPress: () => webViewGoBack(),
+ iconImage: IconArrowLeft,
+ accessibilityLabel: 'Go back',
+ },
+ {
+ type: 'forward',
+ onPress: () => webViewGoForward(),
+ iconImage: IconArrowRight,
+ accessibilityLabel: 'Go forward',
+ },
+ {
+ type: 'tabs',
+ onPress: () => {},
+ iconImage: IconTabs,
+ accessibilityLabel: 'List opened web-site tabs',
+ },
+ {
+ type: 'reload',
+ onPress: () => webViewReload(),
+ iconImage: IconRefresh,
+ accessibilityLabel: 'Reload web-page',
+ },
+ {
+ type: 'options',
+ onPress: () => viewSettings(),
+ iconImage: IconOptions,
+ accessibilityLabel: 'More Options',
+ },
+ ];
+
+ return (
+
+
+ {navigationButtons.map((button) => {
+ const { type, iconImage, accessibilityLabel, onPress } = button;
+ return (
+
+ );
+ })}
+
+
+ );
+};
const View = styled.View`
margin-left: 16px;
@@ -108,20 +85,6 @@ const View = styled.View`
padding-bottom: 8px;
flex-direction: row;
justify-content: space-between;
-`
-const Icon = styled.Pressable.attrs({
- hitSlop: 10
-})`
- height: ${iconSize}px;
- padding-top: 0;
- padding-right: 10px;
- padding-bottom: 0;
- padding-left: 10px;
- ${({ type }: IconProps) => type === 'tabs' && ``}
- ${({ type }: IconProps) => type === 'reload' && ``}
- ${({ type }: IconProps) => type === 'options' && ``}
-`
-
-
+`;
-export default NavigationButtons
\ No newline at end of file
+export default NavigationButtons;
diff --git a/src/components/Navigation/NavigationComboInput.tsx b/src/components/Navigation/NavigationComboInput.tsx
index cb8878eb..02799feb 100644
--- a/src/components/Navigation/NavigationComboInput.tsx
+++ b/src/components/Navigation/NavigationComboInput.tsx
@@ -1,59 +1,65 @@
-import React, { useState, useContext } from 'react'
-import { useSelector, useDispatch } from 'react-redux'
-import styled, { useTheme } from 'styled-components/native'
-
-import Share from 'react-native-share'
-
-import { AppState } from 'src/store/reducers'
-import { URL_INPUT, URL_CURRENT } from 'src/store/navigation.reducer'
-
-import { isDarkMode } from 'src/utils/appearance'
-import { upgradeUrl } from 'src/utils/url'
-
-import { ButtonIcon } from 'src/components/ButtonIcon'
-import IconShare from 'src/assets/icons/icon-share.svg'
+import React, { useState } from 'react';
+import styled, { useTheme } from 'styled-components/native';
+import Share from 'react-native-share';
+import { IsDarkMode } from 'src/utils/appearance';
+import { upgradeUrl } from 'src/utils/url';
+import IconShare from 'src/assets/icons/icon-share.svg';
+import { useRecoilState } from 'recoil';
+import { navigationState } from 'src/store/atoms';
const AddressTextInput = () => {
+ const theme = useTheme();
- const theme = useTheme()
-
- const navigation = useSelector((state: AppState) => state.navigation)
- const dispatch = useDispatch()
+ const [navState, setNavState] = useRecoilState(navigationState);
- const [shareVisible, shareVisibility] = useState(true)
+ const [shareVisible, shareVisibility] = useState(true);
const shareCurrentUri = () => {
const shareOptions = {
title: 'Share',
- message: `Sharing: ${navigation.webViewState.title}`,
- url: navigation.webViewState.url
- }
+ message: `Sharing: ${navState.webViewState?.title}`,
+ url: navState.webViewState?.url,
+ };
Share.open(shareOptions)
- .then((resp) => { console.log('Share successful', resp) })
- .catch((err) => { console.log('Share error', err) })
- }
+ .then((resp) => {
+ console.log('Share successful', resp);
+ })
+ .catch((err) => {
+ console.log('Share error', err);
+ });
+ };
return (
{
- dispatch({ type: URL_INPUT, urlInput: url })
+ setNavState((previous) => {
+ return {
+ ...previous,
+ urlInput: url,
+ };
+ });
}}
onSubmitEditing={(event) => {
- const urlCurrent = upgradeUrl(event.nativeEvent.text)
- dispatch({ type: URL_INPUT, urlInput: urlCurrent })
- dispatch({ type: URL_CURRENT, urlCurrent: urlCurrent })
+ const urlCurrent = upgradeUrl(event.nativeEvent.text);
+ setNavState((previous) => {
+ return {
+ ...previous,
+ urlInput: urlCurrent,
+ urlCurrent: urlCurrent,
+ };
+ });
}}
onFocus={() => {
- shareVisibility(false)
+ shareVisibility(false);
}}
- onBlur={(event) => {
+ onBlur={() => {
// TODO - Re-instate previous URL on before onSubmitEditing
- shareVisibility(true)
+ shareVisibility(true);
}}
autoCapitalize="none"
autoCompleteType="off"
@@ -61,23 +67,20 @@ const AddressTextInput = () => {
returnKeyType="go"
blurOnSubmit={true}
clearButtonMode="while-editing"
- keyboardAppearance={isDarkMode() ? 'dark' : 'light'}
+ keyboardAppearance={IsDarkMode() ? 'dark' : 'light'}
// TODO - Change keyboard type to search if URL not detected
- keyboardType="web-search"
+ keyboardType="web-search"
selectTextOnFocus={true}
textContentType="URL"
/>
- {
- shareVisible &&
+ {shareVisible && (
- }
+ )}
- )
-}
-
-
+ );
+};
const AddressBar = styled.View`
margin-left: 10px;
@@ -85,16 +88,16 @@ const AddressBar = styled.View`
margin-top: 10px;
margin-bottom: 10px;
border-radius: 6px;
- background-color: ${props => props.theme.addressBar.background};
-`
+ background-color: ${(props) => props.theme.addressBar.background};
+`;
const URLSearchInput = styled.TextInput`
font-size: 18px;
text-align: left;
padding: 10px;
- color: ${props => props.theme.addressBar.color};
-`
+ color: ${(props) => props.theme.addressBar.color};
+`;
const Icon = styled.Pressable.attrs({
- hitSlop: 10
+ hitSlop: 10,
})`
/*border: 1px solid rgba(255,0,0,.5);*/
right: -8px;
@@ -104,9 +107,7 @@ const Icon = styled.Pressable.attrs({
margin-right: 8px;
padding-bottom: 7.5px;
margin-left: 8px;
- color: ${props => props.theme.addressBar.color};
-`
-
-
+ color: ${(props) => props.theme.addressBar.color};
+`;
-export default AddressTextInput
\ No newline at end of file
+export default AddressTextInput;
diff --git a/src/components/Navigation/index.tsx b/src/components/Navigation/index.tsx
index ad8b57d8..d9ec0fbe 100644
--- a/src/components/Navigation/index.tsx
+++ b/src/components/Navigation/index.tsx
@@ -1,8 +1,7 @@
-import React from 'react'
-
-import NavigationTextInput from 'src/components/Navigation/NavigationComboInput'
-import NavigationButtons from 'src/components/Navigation/NavigationButtons'
+import React from 'react';
+import NavigationTextInput from 'src/components/Navigation/NavigationComboInput';
+import NavigationButtons from 'src/components/Navigation/NavigationButtons';
export default function Navigation() {
return (
@@ -10,5 +9,5 @@ export default function Navigation() {
>
- )
-}
\ No newline at end of file
+ );
+}
diff --git a/src/components/Test.tsx b/src/components/Test.tsx
index 738bc45d..bfb135ea 100644
--- a/src/components/Test.tsx
+++ b/src/components/Test.tsx
@@ -1,17 +1,17 @@
-import React from 'react'
-import styled from 'styled-components/native'
+import React from 'react';
+import styled from 'styled-components/native';
export default function Test() {
return (
Testing, testing, 1, 2, 3
- )
+ );
}
const TestView = styled.View`
background-color: rgba(255, 0, 0, 0.25);
-`
+`;
const Text = styled.Text`
color: red;
-`
+`;
diff --git a/src/data/bookmarks.data.ts b/src/data/bookmarks.data.ts
index 0dc0791a..3062958b 100644
--- a/src/data/bookmarks.data.ts
+++ b/src/data/bookmarks.data.ts
@@ -1,41 +1,41 @@
-import type { Bookmark } from 'src/@types/bookmarks'
+import type { Bookmark } from 'src/@types/bookmarks';
-
-export const Bookmarks:Bookmark[] = [
+export const Bookmarks: Bookmark[] = [
{
- "displayName": "Foundation",
- "description": "Foundation is a platform that aims to build a new creative economy.",
- "protocol": "http",
- "location": "https://foundation.app/",
- "tags": ["ethereum", "nft", "art"]
+ displayName: 'Foundation',
+ description:
+ 'Foundation is a platform that aims to build a new creative economy.',
+ protocol: 'http',
+ location: 'https://foundation.app/',
+ tags: ['ethereum', 'nft', 'art'],
},
{
- "displayName": "Catalog",
- "description": "Catalog is a record press, an auction house, and an open music library.",
- "protocol": "http",
- "location": "https://beta.catalog.works/leslie",
- "tags": ["ethereum", "nft", "music"]
+ displayName: 'Catalog',
+ description:
+ 'Catalog is a record press, an auction house, and an open music library.',
+ protocol: 'http',
+ location: 'https://beta.catalog.works/leslie',
+ tags: ['ethereum', 'nft', 'music'],
},
{
- "displayName": "Mirror",
- "description": "Writing as usual. Publishing like never before.",
- "protocol": "http",
- "location": "https://mirror.xyz/",
- "tags": ["ethereum", "nft", "writing"]
+ displayName: 'Mirror',
+ description: 'Writing as usual. Publishing like never before.',
+ protocol: 'http',
+ location: 'https://mirror.xyz/',
+ tags: ['ethereum', 'nft', 'writing'],
},
{
- "displayName": "Mirror",
- "description": "Writing as usual. Publishing like never before.",
- "protocol": "http",
- "location": "https://web3summit.com/",
- "tags": ["ethereum", "nft", "writing"]
+ displayName: 'Mirror',
+ description: 'Writing as usual. Publishing like never before.',
+ protocol: 'http',
+ location: 'https://web3summit.com/',
+ tags: ['ethereum', 'nft', 'writing'],
},
{
- "displayName": "Mirror",
- "description": "Writing as usual. Publishing like never before.",
- "protocol": "ipfs",
- "location": "bafybeidyka6iguedudto3vablngbhyttw32apjk6mo474zfnhlgbivl7me",
- "tags": ["ethereum", "nft", "writing"]
+ displayName: 'Mirror',
+ description: 'Writing as usual. Publishing like never before.',
+ protocol: 'ipfs',
+ location: 'bafybeidyka6iguedudto3vablngbhyttw32apjk6mo474zfnhlgbivl7me',
+ tags: ['ethereum', 'nft', 'writing'],
},
-
-]
\ No newline at end of file
+];
diff --git a/src/protocols/ethereum/index.ts b/src/protocols/ethereum/index.ts
index 8a261c09..f2e4dee9 100644
--- a/src/protocols/ethereum/index.ts
+++ b/src/protocols/ethereum/index.ts
@@ -1,35 +1,28 @@
// import 'react-native-get-random-values'
-import '@ethersproject/shims'
-import { ethers } from 'ethers'
-import type { BigNumber, Wallet } from 'ethers'
-
-import { env } from 'environments/.env.development'
-
-
-
-const provider =
- new ethers.providers.FallbackProvider([
- new ethers.providers.EtherscanProvider(
- `${env.ETHERSCAN_NETWORK}`,
- `${env.ETHERSCAN_API_KEY}`
- ),
- ]);
-
+import '@ethersproject/shims';
+import { ethers } from 'ethers';
+import type { BigNumber, Wallet } from 'ethers';
+import { env } from 'environments/.env.development';
+const provider = new ethers.providers.FallbackProvider([
+ new ethers.providers.EtherscanProvider(
+ `${env.ETHERSCAN_NETWORK}`,
+ `${env.ETHERSCAN_API_KEY}`,
+ ),
+]);
export class Ethereum {
-
- walletPrivateKey: string;
+ walletPrivateKey: string;
walletJSON: string;
walletPassword: string;
walletAddress: string;
constructor(
- walletPrivateKey = '',
- walletJSON = '',
+ walletPrivateKey = '',
+ walletJSON = '',
walletPassword = '',
- walletAddress = '',
+ walletAddress = '',
) {
this.walletPrivateKey = walletPrivateKey;
this.walletJSON = walletJSON;
@@ -41,43 +34,45 @@ export class Ethereum {
public isAddressENS() {
const { walletAddress } = this;
return !ethers.utils.isAddress(walletAddress) &&
- /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/
- .test(walletAddress) ? true : false;
+ /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.test(
+ walletAddress,
+ )
+ ? true
+ : false;
}
-
public isAddressHex() {
const { walletAddress } = this;
- if (ethers.utils.isAddress(walletAddress))
- return true;
- };
-
+ if (ethers.utils.isAddress(walletAddress)) {
+ return true;
+ }
+ }
public async getEnsFromAddress(): Promise {
const { walletAddress } = this;
- if (!ethers.utils.isAddress(walletAddress))
- return 'Not a valid address'
+ if (!ethers.utils.isAddress(walletAddress)) {
+ return 'Not a valid address';
+ }
return await provider
.lookupAddress(walletAddress)
- .then(result => {
- const address = result === null ?
- `${walletAddress.substr(0,6)}...${walletAddress.slice(-4)}` :
- result;
- return address
+ .then((result) => {
+ const address =
+ result === null
+ ? `${walletAddress.substr(0, 6)}...${walletAddress.slice(-4)}`
+ : result;
+ return address;
})
- .catch(err => `Error: Address doesn't exist. ${err}`);
- };
-
+ .catch((err) => `Error: Address doesn't exist. ${err}`);
+ }
public async getAddressFromEns(): Promise {
const { walletAddress } = this;
return provider
.resolveName(walletAddress)
- .then(result => result)
- .catch(err => `Error: ${err}`)
+ .then((result) => result)
+ .catch((err) => `Error: ${err}`);
}
-
/**
* TODO
* - Show small amounts
@@ -89,27 +84,24 @@ export class Ethereum {
return await provider
.getBalance(walletAddress)
.then((result) => {
- const balanceRemainder:BigNumber = result.mod(1e14);
+ const balanceRemainder: BigNumber = result.mod(1e14);
const balanceFormatted = ethers.utils.formatEther(
- result.sub(balanceRemainder)
+ result.sub(balanceRemainder),
);
return balanceFormatted;
})
.catch((err) => {
console.error('Error:', err);
- return 'Unknown'
+ return 'Unknown';
});
- };
-
+ }
public async walletFromMnemonic(): Promise