Skip to content

feat: Landscape mode #3

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 7 commits into from
Apr 18, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/app.json
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
"name": "web3modal-rn-example",
"slug": "web3modal-rn-example",
"version": "1.0.0",
"orientation": "portrait",
"orientation": "default",
"icon": "./assets/icon.png",
"userInterfaceStyle": "automatic",
"splash": {
Binary file removed src/assets/ViewAll.png
Binary file not shown.
1 change: 0 additions & 1 deletion src/components/NavHeader.tsx
Original file line number Diff line number Diff line change
@@ -67,7 +67,6 @@ function NavHeader({
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 16,
61 changes: 49 additions & 12 deletions src/components/ViewAllBox.tsx
Original file line number Diff line number Diff line change
@@ -4,22 +4,43 @@ import {
View,
Text,
TouchableOpacity,
useColorScheme,
StyleProp,
ViewStyle,
} from 'react-native';

import ViewAllIcon from '../assets/ViewAll.png';
import { DarkTheme, LightTheme } from '../constants/Colors';
import type { Listing } from '../types/controllerTypes';
import { ExplorerUtil } from '../utils/ExplorerUtil';

interface Props {
onPress: any;
wallets: Listing[];
isDarkMode: boolean;
style?: StyleProp<ViewStyle>;
}

function ViewAllBox({ onPress }: Props) {
const isDarkMode = useColorScheme() === 'dark';
const WalletIcon = ({ wallet }: { wallet: Listing }) => (
<Image
source={{ uri: ExplorerUtil.getWalletImageUrl(wallet.image_id) }}
style={styles.icon}
/>
);

function ViewAllBox({ onPress, wallets, style, isDarkMode }: Props) {
return (
<TouchableOpacity onPress={onPress} style={styles.container}>
<Image style={styles.icon} source={ViewAllIcon} />
<TouchableOpacity onPress={onPress} style={[styles.container, style]}>
<View style={[styles.icons, isDarkMode && styles.iconsDark]}>
<View style={styles.row}>
{wallets.slice(0, 2).map((wallet) => (
<WalletIcon key={wallet.id} wallet={wallet} />
))}
</View>
<View style={styles.row}>
{wallets.slice(2, 4).map((wallet) => (
<WalletIcon key={wallet.id} wallet={wallet} />
))}
</View>
</View>
<View>
<Text
style={[styles.text, isDarkMode && styles.textDark]}
@@ -33,22 +54,38 @@ function ViewAllBox({ onPress }: Props) {
}

const styles = StyleSheet.create({
icon: {
container: {
width: 80,
height: 80,
alignItems: 'center',
marginVertical: 16,
},
icons: {
height: 60,
width: 60,
borderRadius: 16,
borderWidth: 1,
borderColor: LightTheme.overlayThin,
},
container: {
width: '25%',
justifyContent: 'center',
alignItems: 'center',
marginVertical: 8,
},
iconsDark: {
backgroundColor: DarkTheme.background2,
},
icon: {
height: 23,
width: 23,
borderRadius: 8,
margin: 1,
borderWidth: 1,
borderColor: LightTheme.overlayThin,
},
row: {
flexDirection: 'row',
},
text: {
color: LightTheme.foreground1,
marginVertical: 8,
marginTop: 5,
maxWidth: 100,
fontWeight: '600',
fontSize: 12,
12 changes: 7 additions & 5 deletions src/components/WalletItem.tsx
Original file line number Diff line number Diff line change
@@ -4,20 +4,23 @@ import {
TouchableOpacity,
StyleSheet,
useColorScheme,
StyleProp,
ViewStyle,
} from 'react-native';

import type { Listing } from '../types/controllerTypes';
import { DarkTheme, LightTheme } from '../constants/Colors';
import { ExplorerUtil } from '../utils/ExplorerUtil';

interface WalletItemProps {
interface Props {
currentWCURI?: string;
walletInfo: Listing;
style?: StyleProp<ViewStyle>;
}

export const ITEM_HEIGHT = 80;

function WalletItem({ currentWCURI, walletInfo }: WalletItemProps) {
function WalletItem({ currentWCURI, walletInfo, style }: Props) {
const isDarkMode = useColorScheme() === 'dark';

const onPress = () => {
@@ -34,7 +37,7 @@ function WalletItem({ currentWCURI, walletInfo }: WalletItemProps) {
<TouchableOpacity
onPress={onPress}
key={walletInfo.id}
style={styles.container}
style={[styles.container, style]}
>
<Image
style={styles.icon}
@@ -52,9 +55,8 @@ function WalletItem({ currentWCURI, walletInfo }: WalletItemProps) {

const styles = StyleSheet.create({
container: {
width: '25%',
width: 80,
height: 80,
justifyContent: 'flex-start',
alignItems: 'center',
marginVertical: 16,
},
14 changes: 6 additions & 8 deletions src/components/Web3Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { useCallback, useEffect } from 'react';
import {
StyleSheet,
View,
useColorScheme,
ImageBackground,
Alert,
SafeAreaView,
} from 'react-native';
import Modal from 'react-native-modal';
import { useSnapshot } from 'valtio';

import { DEVICE_WIDTH } from '../constants/Platform';
import { DarkTheme, LightTheme } from '../constants/Colors';
import Background from '../assets/Background.png';
import Web3ModalHeader from './Web3ModalHeader';
@@ -20,6 +19,7 @@ import { ExplorerCtrl } from '../controllers/ExplorerCtrl';
import { ConfigCtrl } from '../controllers/ConfigCtrl';
import { OptionsCtrl } from '../controllers/OptionsCtrl';
import { ClientCtrl } from '../controllers/ClientCtrl';
import { useOrientation } from '../hooks/useOrientation';

interface Web3ModalProps {
projectId: string;
@@ -34,6 +34,7 @@ export function Web3Modal({
}: Web3ModalProps) {
const modalState = useSnapshot(ModalCtrl.state);
const isDarkMode = useColorScheme() === 'dark';
const { width } = useOrientation();

const onSessionCreated = useCallback(async () => {
OptionsCtrl.getAccount();
@@ -126,19 +127,19 @@ export function Web3Modal({
useNativeDriver
>
<ImageBackground
style={styles.wcContainer}
style={{ width }}
source={Background}
imageStyle={styles.wcImage}
>
<Web3ModalHeader onClose={ModalCtrl.close} />
<View
<SafeAreaView
style={[
styles.connectWalletContainer,
isDarkMode && styles.connectWalletContainerDark,
]}
>
<Web3ModalRouter onCopyClipboard={onCopyClipboard} />
</View>
</SafeAreaView>
</ImageBackground>
</Modal>
);
@@ -149,9 +150,6 @@ const styles = StyleSheet.create({
margin: 0,
justifyContent: 'flex-end',
},
wcContainer: {
width: DEVICE_WIDTH,
},
wcImage: {
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
12 changes: 6 additions & 6 deletions src/components/Web3ModalHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
Image,
SafeAreaView,
StyleSheet,
TouchableOpacity,
View,
useColorScheme,
} from 'react-native';

@@ -19,7 +19,7 @@ export function Web3ModalHeader({ onClose }: Web3ModalHeaderProps) {
const isDarkMode = useColorScheme() === 'dark';

return (
<View style={styles.container}>
<SafeAreaView style={styles.container}>
<Image style={styles.wcLogo} source={WCLogo} />
<TouchableOpacity
style={[styles.closeContainer, isDarkMode && styles.closeContainerDark]}
@@ -31,17 +31,17 @@ export function Web3ModalHeader({ onClose }: Web3ModalHeaderProps) {
source={isDarkMode ? CloseWhite : Close}
/>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
paddingVertical: 8,
display: 'flex',
height: 46,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 10,
marginHorizontal: 10,
},
wcLogo: {
width: 181,
21 changes: 18 additions & 3 deletions src/components/Web3ModalRouter.tsx
Original file line number Diff line number Diff line change
@@ -7,10 +7,17 @@ import { RouterCtrl } from '../controllers/RouterCtrl';
import InitialExplorer from '../views/InitialExplorer';
import { Account } from '../views/Account';
import { Error } from '../views/Error';
import type { RouterProps } from '../types/routerTypes';
import { useOrientation } from '../hooks/useOrientation';
import { useColorScheme } from 'react-native';

export function Web3ModalRouter(props: RouterProps) {
interface Props {
onCopyClipboard?: (value: string) => void;
}

export function Web3ModalRouter(props: Props) {
const routerState = useSnapshot(RouterCtrl.state);
const { height, width, isPortrait } = useOrientation();
const isDarkMode = useColorScheme() === 'dark';

const ViewComponent = useMemo(() => {
switch (routerState.view) {
@@ -27,5 +34,13 @@ export function Web3ModalRouter(props: RouterProps) {
}
}, [routerState.view]);

return <ViewComponent {...props} />;
return (
<ViewComponent
windowHeight={height}
windowWidth={width}
isPortrait={isPortrait}
isDarkMode={isDarkMode}
{...props}
/>
);
}
6 changes: 1 addition & 5 deletions src/constants/Platform.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { Dimensions, Platform } from 'react-native';

const windowDimensions = Dimensions.get('window');
export const DEVICE_HEIGHT = windowDimensions.height;
export const DEVICE_WIDTH = windowDimensions.width;
import { Platform } from 'react-native';

export const isAndroid = Platform.OS === 'android';
export const isIOS = Platform.OS === 'ios';
11 changes: 11 additions & 0 deletions src/hooks/useOrientation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useWindowDimensions } from 'react-native';

export function useOrientation() {
const window = useWindowDimensions();

return {
width: window.width,
height: window.height,
isPortrait: window.height >= window.width,
};
}
4 changes: 4 additions & 0 deletions src/types/routerTypes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export type RouterProps = {
isPortrait: boolean;
windowHeight: number;
windowWidth: number;
isDarkMode: boolean;
onCopyClipboard?: (value: string) => void;
};
27 changes: 15 additions & 12 deletions src/views/Account.tsx
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ import {
} from 'react-native';
import { useSnapshot } from 'valtio';

import { DEVICE_HEIGHT } from '../constants/Platform';
import { ClientCtrl } from '../controllers/ClientCtrl';
import DisconnectIcon from '../assets/Disconnect.png';
import { OptionsCtrl } from '../controllers/OptionsCtrl';
@@ -19,7 +18,7 @@ import { ModalCtrl } from '../controllers/ModalCtrl';
import type { RouterProps } from '../types/routerTypes';
import NavHeader from '../components/NavHeader';

export function Account(_: RouterProps) {
export function Account({ isPortrait, windowHeight }: RouterProps) {
const isDarkMode = useColorScheme() === 'dark';
const optionsState = useSnapshot(OptionsCtrl.state);

@@ -35,9 +34,14 @@ export function Account(_: RouterProps) {
}, []);

return (
<View style={styles.container}>
<>
<NavHeader title="Connected Account" />
<View>
<View
style={[
styles.container,
{ height: isPortrait ? windowHeight * 0.3 : windowHeight * 0.6 },
]}
>
<Text
style={[
styles.text,
@@ -57,20 +61,19 @@ export function Account(_: RouterProps) {
>
{optionsState.address}
</Text>
<TouchableOpacity onPress={onDisconnect} style={styles.button}>
<View style={styles.iconContainer}>
<Image source={DisconnectIcon} style={styles.icon} />
</View>
<Text style={styles.buttonText}>Disconnect</Text>
</TouchableOpacity>
</View>
<TouchableOpacity onPress={onDisconnect} style={styles.button}>
<View style={styles.iconContainer}>
<Image source={DisconnectIcon} style={styles.icon} />
</View>
<Text style={styles.buttonText}>Disconnect</Text>
</TouchableOpacity>
</View>
</>
);
}

const styles = StyleSheet.create({
container: {
height: DEVICE_HEIGHT * 0.4,
padding: 16,
},
button: {
Loading