style: initial dark mode

This commit is contained in:
Cody Bender 2024-08-09 00:59:27 -04:00
parent 6f174c6e0c
commit 0a6fc415ea
5 changed files with 213 additions and 163 deletions

View File

@ -1,21 +1,19 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Laconic Wallet Web App"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Laconic Wallet Web App" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
@ -24,52 +22,58 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Laconic Wallet</title>
<style>
body {
margin: 0;
padding: 0;
height: 100%;
<title>Laconic Wallet</title>
<style>
#app {
background-color: #0f0f0f;
}
body {
margin: 0;
padding: 0;
height: 100%;
background-color: #0f0f0f;
}
.loader-wrapper {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: grid;
place-items: center;
}
.loader {
border: 16px solid #e3e3e3;
border-top: 16px solid #6750a4;
border-radius: 50%;
width: 140px;
height: 140px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
.loader-wrapper {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: grid;
place-items: center;
100% {
transform: rotate(360deg);
}
.loader {
border: 16px solid #e3e3e3;
border-top: 16px solid #6750a4;
border-radius: 50%;
width: 140px;
height: 140px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<div class="loader-wrapper">
<div class="loader"></div>
</div>
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<div class="loader-wrapper">
<div class="loader"></div>
</div>
<!--
</div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
@ -79,5 +83,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</body>
</html>

View File

@ -21,5 +21,5 @@
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
"background_color": "#0f0f0f"
}

View File

@ -1,43 +1,43 @@
import React, { useCallback, useEffect, useState } from 'react';
import { Button, Snackbar, Text } from 'react-native-paper';
import { TxBody, AuthInfo } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
import React, { useCallback, useEffect, useState } from "react";
import { Button, Snackbar, Surface, Text } from "react-native-paper";
import { TxBody, AuthInfo } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { SignClientTypes } from '@walletconnect/types';
import { useNavigation } from '@react-navigation/native';
import { SignClientTypes } from "@walletconnect/types";
import { useNavigation } from "@react-navigation/native";
import {
createStackNavigator,
StackNavigationProp,
} from '@react-navigation/stack';
import { getSdkError } from '@walletconnect/utils';
import { Web3WalletTypes } from '@walletconnect/web3wallet';
import { formatJsonRpcResult } from '@json-rpc-tools/utils';
} from "@react-navigation/stack";
import { getSdkError } from "@walletconnect/utils";
import { Web3WalletTypes } from "@walletconnect/web3wallet";
import { formatJsonRpcResult } from "@json-rpc-tools/utils";
import PairingModal from './components/PairingModal';
import { useWalletConnect } from './context/WalletConnectContext';
import { useAccounts } from './context/AccountsContext';
import InvalidPath from './screens/InvalidPath';
import SignMessage from './screens/SignMessage';
import HomeScreen from './screens/HomeScreen';
import SignRequest from './screens/SignRequest';
import AddSession from './screens/AddSession';
import WalletConnect from './screens/WalletConnect';
import ApproveTransaction from './screens/ApproveTransaction';
import { StackParamsList } from './types';
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Data';
import { getSignParamsMessage } from './utils/wallet-connect/helpers';
import ApproveTransfer from './screens/ApproveTransfer';
import AddNetwork from './screens/AddNetwork';
import EditNetwork from './screens/EditNetwork';
import { COSMOS, EIP155 } from './utils/constants';
import { useNetworks } from './context/NetworksContext';
import { NETWORK_METHODS } from './utils/wallet-connect/common-data';
import { COSMOS_METHODS } from './utils/wallet-connect/COSMOSData';
import PairingModal from "./components/PairingModal";
import { useWalletConnect } from "./context/WalletConnectContext";
import { useAccounts } from "./context/AccountsContext";
import InvalidPath from "./screens/InvalidPath";
import SignMessage from "./screens/SignMessage";
import HomeScreen from "./screens/HomeScreen";
import SignRequest from "./screens/SignRequest";
import AddSession from "./screens/AddSession";
import WalletConnect from "./screens/WalletConnect";
import ApproveTransaction from "./screens/ApproveTransaction";
import { StackParamsList } from "./types";
import { EIP155_SIGNING_METHODS } from "./utils/wallet-connect/EIP155Data";
import { getSignParamsMessage } from "./utils/wallet-connect/helpers";
import ApproveTransfer from "./screens/ApproveTransfer";
import AddNetwork from "./screens/AddNetwork";
import EditNetwork from "./screens/EditNetwork";
import { COSMOS, EIP155 } from "./utils/constants";
import { useNetworks } from "./context/NetworksContext";
import { NETWORK_METHODS } from "./utils/wallet-connect/common-data";
import { COSMOS_METHODS } from "./utils/wallet-connect/COSMOSData";
import styles from "./styles/stylesheet";
const Stack = createStackNavigator<StackParamsList>();
const App = (): React.JSX.Element => {
const navigation =
useNavigation<StackNavigationProp<StackParamsList>>();
const navigation = useNavigation<StackNavigationProp<StackParamsList>>();
const { web3wallet, setActiveSessions } = useWalletConnect();
const { accounts, setCurrentIndex } = useAccounts();
@ -45,16 +45,16 @@ const App = (): React.JSX.Element => {
const [modalVisible, setModalVisible] = useState(false);
const [toastVisible, setToastVisible] = useState(false);
const [currentProposal, setCurrentProposal] = useState<
SignClientTypes.EventArguments['session_proposal'] | undefined
SignClientTypes.EventArguments["session_proposal"] | undefined
>();
const onSessionProposal = useCallback(
async (proposal: SignClientTypes.EventArguments['session_proposal']) => {
async (proposal: SignClientTypes.EventArguments["session_proposal"]) => {
if (!accounts.length || !accounts.length) {
const { id } = proposal;
await web3wallet!.rejectSession({
id,
reason: getSdkError('UNSUPPORTED_ACCOUNTS'),
reason: getSdkError("UNSUPPORTED_ACCOUNTS"),
});
return;
}
@ -74,10 +74,11 @@ const App = (): React.JSX.Element => {
switch (request.method) {
case NETWORK_METHODS.GET_NETWORKS:
const currentNetworkId = networksData.find(
networkData => networkData.networkId === selectedNetwork!.networkId,
(networkData) =>
networkData.networkId === selectedNetwork!.networkId,
)?.networkId;
const networkNamesData = networksData.map(networkData => {
const networkNamesData = networksData.map((networkData) => {
return {
id: networkData.networkId,
name: networkData.networkName,
@ -98,13 +99,13 @@ const App = (): React.JSX.Element => {
case NETWORK_METHODS.CHANGE_NETWORK:
const networkNameData = request.params[0];
const network = networksData.find(
networkData => networkData.networkId === networkNameData.id,
(networkData) => networkData.networkId === networkNameData.id,
);
setCurrentIndex(0);
setSelectedNetwork(network);
const response = formatJsonRpcResult(id, {
response: 'true',
response: "true",
});
await web3wallet!.respondSessionRequest({
@ -114,7 +115,7 @@ const App = (): React.JSX.Element => {
break;
case EIP155_SIGNING_METHODS.ETH_SEND_TRANSACTION:
navigation.navigate('ApproveTransfer', {
navigation.navigate("ApproveTransfer", {
transaction: request.params[0],
requestEvent,
requestSessionData,
@ -122,7 +123,7 @@ const App = (): React.JSX.Element => {
break;
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
navigation.navigate('SignRequest', {
navigation.navigate("SignRequest", {
namespace: EIP155,
address: request.params[1],
message: getSignParamsMessage(request.params),
@ -136,19 +137,19 @@ const App = (): React.JSX.Element => {
txbody: TxBody.toJSON(
TxBody.decode(
Uint8Array.from(
Buffer.from(request.params.signDoc.bodyBytes, 'hex'),
Buffer.from(request.params.signDoc.bodyBytes, "hex"),
),
),
),
authInfo: AuthInfo.toJSON(
AuthInfo.decode(
Uint8Array.from(
Buffer.from(request.params.signDoc.authInfoBytes, 'hex'),
Buffer.from(request.params.signDoc.authInfoBytes, "hex"),
),
),
),
};
navigation.navigate('SignRequest', {
navigation.navigate("SignRequest", {
namespace: COSMOS,
address: request.params.signerAddress,
message: JSON.stringify(message, undefined, 2),
@ -158,7 +159,7 @@ const App = (): React.JSX.Element => {
break;
case COSMOS_METHODS.COSMOS_SIGN_AMINO:
navigation.navigate('SignRequest', {
navigation.navigate("SignRequest", {
namespace: COSMOS,
address: request.params.signerAddress,
message: request.params.signDoc.memo,
@ -168,7 +169,7 @@ const App = (): React.JSX.Element => {
break;
case COSMOS_METHODS.COSMOS_SEND_TOKENS:
navigation.navigate('ApproveTransfer', {
navigation.navigate("ApproveTransfer", {
transaction: request.params[0],
requestEvent,
requestSessionData,
@ -177,7 +178,7 @@ const App = (): React.JSX.Element => {
case COSMOS_METHODS.COSMOS_SEND_TRANSACTION:
const { transactionMessage, signer } = request.params;
navigation.navigate('ApproveTransaction', {
navigation.navigate("ApproveTransaction", {
transactionMessage,
signer,
requestEvent,
@ -186,7 +187,7 @@ const App = (): React.JSX.Element => {
break;
default:
throw new Error('Invalid method');
throw new Error("Invalid method");
}
},
[
@ -195,7 +196,7 @@ const App = (): React.JSX.Element => {
setSelectedNetwork,
setCurrentIndex,
selectedNetwork,
web3wallet
web3wallet,
],
);
@ -205,18 +206,18 @@ const App = (): React.JSX.Element => {
}, [setActiveSessions, web3wallet]);
useEffect(() => {
web3wallet?.on('session_proposal', onSessionProposal);
web3wallet?.on('session_request', onSessionRequest);
web3wallet?.on('session_delete', onSessionDelete);
web3wallet?.on("session_proposal", onSessionProposal);
web3wallet?.on("session_request", onSessionRequest);
web3wallet?.on("session_delete", onSessionDelete);
return () => {
web3wallet?.off('session_proposal', onSessionProposal);
web3wallet?.off('session_request', onSessionRequest);
web3wallet?.off('session_delete', onSessionDelete);
web3wallet?.off("session_proposal", onSessionProposal);
web3wallet?.off("session_request", onSessionRequest);
web3wallet?.off("session_delete", onSessionDelete);
};
});
return (
<>
<Surface id="surfface" style={styles.appSurface}>
<Stack.Navigator
screenOptions={{
headerBackTitleVisible: true,
@ -227,7 +228,19 @@ const App = (): React.JSX.Element => {
component={HomeScreen}
options={{
// eslint-disable-next-line react/no-unstable-nested-components
headerTitle: () => <Text variant="titleLarge">Laconic Wallet</Text>,
header: () => (
<Text
variant="titleLarge"
style={{
paddingLeft: 24,
paddingVertical: 12,
width: "auto",
backgroundColor: "#18181A",
}}
>
Laconic Wallet
</Text>
),
}}
/>
<Stack.Screen
@ -258,7 +271,7 @@ const App = (): React.JSX.Element => {
name="AddSession"
component={AddSession}
options={{
title: 'New session',
title: "New session",
}}
/>
<Stack.Screen
@ -271,8 +284,9 @@ const App = (): React.JSX.Element => {
headerRight: () => (
<Button
onPress={() => {
navigation.navigate('AddSession');
}}>
navigation.navigate("AddSession");
}}
>
{<Text>PAIR</Text>}
</Button>
),
@ -282,28 +296,28 @@ const App = (): React.JSX.Element => {
name="ApproveTransfer"
component={ApproveTransfer}
options={{
title: 'Approve transfer',
title: "Approve transfer",
}}
/>
<Stack.Screen
name="AddNetwork"
component={AddNetwork}
options={{
title: 'Add Network',
title: "Add Network",
}}
/>
<Stack.Screen
name="EditNetwork"
component={EditNetwork}
options={{
title: 'Edit Network',
title: "Edit Network",
}}
/>
<Stack.Screen
name="ApproveTransaction"
component={ApproveTransaction}
options={{
title: 'Approve Transaction',
title: "Approve Transaction",
}}
/>
</Stack.Navigator>
@ -317,10 +331,11 @@ const App = (): React.JSX.Element => {
<Snackbar
visible={toastVisible}
onDismiss={() => setToastVisible(false)}
duration={3000}>
duration={3000}
>
Session approved
</Snackbar>
</>
</Surface>
);
};

View File

@ -1,59 +1,85 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { PaperProvider, MD3LightTheme as DefaultTheme, } from 'react-native-paper';
import { NavigationContainer } from '@react-navigation/native';
import { Platform } from 'react-native';
import { Buffer } from 'buffer';
import React from "react";
import ReactDOM from "react-dom/client";
import {
PaperProvider,
MD3DarkTheme as DefaultTheme,
} from "react-native-paper";
import { NavigationContainer, DarkTheme } from "@react-navigation/native";
import { Platform } from "react-native";
import { Buffer } from "buffer";
import './index.css';
import App from './App';
import { AccountsProvider } from './context/AccountsContext';
import { NetworksProvider } from './context/NetworksContext';
import reportWebVitals from './reportWebVitals';
import { WalletConnectProvider } from './context/WalletConnectContext';
import "./index.css";
import App from "./App";
import { AccountsProvider } from "./context/AccountsContext";
import { NetworksProvider } from "./context/NetworksContext";
import reportWebVitals from "./reportWebVitals";
import { WalletConnectProvider } from "./context/WalletConnectContext";
import { createTheme, ThemeProvider } from "@mui/material";
globalThis.Buffer = Buffer;
const linking = {
prefixes: ['https://wallet.laconic.com']
prefixes: ["https://wallet.laconic.com"],
};
const theme = {
...DefaultTheme,
dark: false,
dark: true,
};
const navigationTheme: typeof DarkTheme = {
...DarkTheme,
colors: {
...DarkTheme.colors,
primary: "#0000F4",
background: "#0F0F0F",
card: "#18181A",
},
};
const muiTheme = createTheme({
palette: {
mode: "dark",
primary: {
main: "#0000F4",
},
},
});
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
document.getElementById("root") as HTMLElement,
);
root.render(
<PaperProvider theme={theme}>
<NetworksProvider>
<AccountsProvider>
<WalletConnectProvider>
<NavigationContainer
linking={linking}
documentTitle={{
formatter: () =>
`Laconic Wallet`,
}}
>
<React.Fragment>
{Platform.OS === 'web' ? (
<style type="text/css">{`
<div id="app">
<PaperProvider theme={theme}>
<NetworksProvider>
<AccountsProvider>
<WalletConnectProvider>
<NavigationContainer
linking={linking}
documentTitle={{
formatter: () => `Laconic Wallet`,
}}
theme={navigationTheme}
>
<React.Fragment>
{Platform.OS === "web" ? (
<style type="text/css">{`
@font-face {
font-family: 'MaterialCommunityIcons';
src: url(${require('react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf')}) format('truetype');
src: url(${require("react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf")}) format('truetype');
}
`}</style>
) : null}
<App />
</React.Fragment>
</NavigationContainer>
</WalletConnectProvider>
</AccountsProvider>
</NetworksProvider>
</PaperProvider>
) : null}
<ThemeProvider theme={muiTheme}>
<App />
</ThemeProvider>
</React.Fragment>
</NavigationContainer>
</WalletConnectProvider>
</AccountsProvider>
</NetworksProvider>
</PaperProvider>
</div>,
);
// If you want to start measuring performance in your app, pass a function

View File

@ -29,10 +29,14 @@ const styles = StyleSheet.create({
accountComponent: {
flex: 4,
},
appSurface: {
backgroundColor: '#0f0f0f',
},
appContainer: {
flexGrow: 1,
marginTop: 24,
paddingHorizontal: 24,
backgroundColor: '#0f0f0f',
},
resetContainer: {
flex: 1,
@ -178,7 +182,7 @@ const styles = StyleSheet.create({
width: '100%',
height: '50%',
position: 'absolute',
backgroundColor: 'white',
backgroundColor: '#0f0f0f',
bottom: 0,
},
modalOuterContainer: { flex: 1 },