Skip to content

Commit

Permalink
feat: add tablet support (#300)
Browse files Browse the repository at this point in the history
* feat: support ipad in xcode

* feat: hide BottomBar

* feat: add search and collections buttons to navbar

* refactor: remove unused code

* fix: center logo better

* fix: include import for Platform

* fix: visually align backbutton with the same padding as gurbaniscreen buttons

* fix: only apply margin fix to outer icons (not every child in a group of icons)

* refactor: create isTablet in helpers

* feat: add iPad emulator to package.json

* feat: add split view support for iPad

* feat: hide title in logo when narrow width

* feat: widen range of bottom drawers

* fix: use correct edge for width in landscape test

* fix: nit

* refactor: remove unused style

* style: mega-nit

* fix: logic in isTablet

* refactor: remove duplicate assignment

* refactor: use theme constant for negative margin fix

* style: nit

* refactor: simplify code

* style: write negative values with preceding hyphen

* refactor: use name for breakpoint
  • Loading branch information
bhajneet committed May 2, 2022
1 parent 06730ad commit a6bcf74
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 42 deletions.
2 changes: 2 additions & 0 deletions ios/Mobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.shabados.app";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
Expand Down Expand Up @@ -646,6 +647,7 @@
PRODUCT_NAME = "Shabad OS";
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.shabados.app";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
Expand Down
1 change: 1 addition & 0 deletions ios/Mobile/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"test": "cross-env ENVFILE=config/.env.local jest --color",
"start:android": "cross-env ENVFILE=config/.env.local react-native run-android",
"start:ios": "cross-env ENVFILE=config/.env.local react-native run-ios --simulator='iPhone 12'",
"start:ios:ipad": "cross-env ENVFILE=config/.env.local react-native run-ios --simulator='iPad (9th generation)'",
"build:android": "bundle exec fastlane android build",
"build:ios": "bundle exec fastlane ios build",
"clean:android": "bundle exec fastlane android clean",
Expand Down
2 changes: 1 addition & 1 deletion src/components/BackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { StyleSheet } from 'react-native'

const styles = StyleSheet.create( {
native: {
margin: -16,
marginLeft: -8,
},
} )

Expand Down
13 changes: 1 addition & 12 deletions src/components/IconHeaderButton.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
import { StyleSheet } from 'react-native'
import Icon from 'react-native-vector-icons/Ionicons'
import { HeaderButton } from 'react-navigation-header-buttons'

import Colors from '../themes/colors'

const styles = StyleSheet.create( {
native: {
margin: -16,
},
} )

export type IconHeaderButtonProps = {
title: string,
disabled?: boolean,
// To fix https://github.com/react-navigation/react-navigation/issues/10058
// Native Stack Navigators + HeaderBackButton has funky margin otherwise
native?: boolean,
}

const IconHeaderButton = ( { disabled, native = true, ...props }: IconHeaderButtonProps ) => (
const IconHeaderButton = ( { disabled, ...props }: IconHeaderButtonProps ) => (
<HeaderButton
style={native && styles.native}
IconComponent={Icon}
iconSize={28}
color={( disabled ? Colors.Disabled : Colors.PrimaryText ) as string}
Expand Down
36 changes: 36 additions & 0 deletions src/components/Logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Image, StyleSheet, useWindowDimensions, View } from 'react-native'

import logo from '../../assets/images/logo.png'
import Units from '../themes/units'
import Typography from './Typography'

const styles = StyleSheet.create( {
headerTitle: {
flexDirection: 'row',
alignItems: 'center',
},
logoIcon: {
width: 28,
height: 28,
marginRight: 6.5,
},
logoText: {
fontSize: 20,
lineHeight: 24,
fontWeight: '300',
},
} )

const Logo = () => {
const { width } = useWindowDimensions()

return (
<View style={styles.headerTitle}>
<Image style={styles.logoIcon} source={logo} />
{width > Units.ThinSplitViewWidth
&& <Typography style={styles.logoText}>Shabad OS</Typography>}
</View>
)
}

export default Logo
2 changes: 1 addition & 1 deletion src/components/ModalSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const ModalSheet = ( {
children,
}: ModalSheetProps ) => {
const { isLandscape, landscapeStyle } = useLandscape()
const snapPoints = isLandscape ? [ '70%', '90%' ] : [ '40%', '70%' ]
const snapPoints = isLandscape ? [ '75%', '98%' ] : [ '40%', '75%' ]

const sheetRef = useRef<BottomSheetModal>( null )

Expand Down
4 changes: 2 additions & 2 deletions src/components/use-landscape.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ describe( 'useLandscape()', () => {
const { result: { current } } = setup( true )

expect( current.landscapeStyle ).toMatchObject( {
marginRight: SHORTER_EDGE / 2,
marginLeft: SHORTER_EDGE / 2,
marginRight: LONGER_EDGE / 6,
marginLeft: LONGER_EDGE / 6,
} )
} )
} )
Expand Down
2 changes: 1 addition & 1 deletion src/components/use-landscape.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const useLandscape = () => {

const isLandscape = width > height
const landscapeStyle: StyleProp<ViewStyle> = isLandscape
? { marginLeft: height / 2, marginRight: height / 2 }
? { marginLeft: width / 6, marginRight: width / 6 }
: {}

return { isLandscape, landscapeStyle }
Expand Down
7 changes: 7 additions & 0 deletions src/helpers/isTablet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Dimensions, Platform } from 'react-native'

const window = Dimensions.get( 'window' )
const { width, height } = window
const isTablet = ( Platform.OS === 'ios' && Platform.isPad ) || ( Platform.OS === 'android' && ( ( width >= 960 && height >= 720 ) || ( width >= 720 && height >= 960 ) ) )

export default isTablet
3 changes: 2 additions & 1 deletion src/screens/Gurbani/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useQuery } from 'react-query'

import Container from '../../components/Container'
import isTablet from '../../helpers/isTablet'
import { getBookmark, getShabad } from '../../services/data'
import { settings, useSetting } from '../../services/settings'
import { ContentType, LineData } from '../../types/data'
Expand Down Expand Up @@ -34,7 +35,7 @@ const GurbaniScreen = ( {
<Container safeArea left right>
{data && <Lines key={data.id} id={data.id} lines={data.lines} />}

<BottomBar />
{!isTablet && <BottomBar />}
</Container>
)
}
Expand Down
52 changes: 28 additions & 24 deletions src/screens/GurbaniNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,27 @@
import { createNativeStackNavigator, NativeStackNavigationOptions } from '@react-navigation/native-stack'
import { Image, StyleSheet, View } from 'react-native'
import { StyleSheet } from 'react-native'
import { HeaderButtons, Item } from 'react-navigation-header-buttons'

import logo from '../../assets/images/logo.png'
import IconHeaderButton from '../components/IconHeaderButton'
import Typography from '../components/Typography'
import Colors from '../themes/colors'
import { px } from '../themes/utils'
import Logo from '../components/Logo'
import isTablet from '../helpers/isTablet'
import Units from '../themes/units'
import { ContentType } from '../types/data'
import { GurbaniStackParams, GurbaniStackScreenProps } from '../types/navigation'
import GurbaniScreen from './Gurbani'

const { Navigator, Screen } = createNativeStackNavigator<GurbaniStackParams>()

const styles = StyleSheet.create( {
headerIcon: {
color: Colors.PrimaryText,
fontSize: 28,
...px( 10 ),
},
headerTitle: {
flexDirection: 'row',
alignItems: 'center',
},
logoIcon: {
width: 28,
height: 28,
marginRight: 10,
left: {
marginLeft: -Units.HorizontalLayoutMargin,
},
logoText: {
fontSize: 20,
fontWeight: '300',
right: {
marginRight: -Units.HorizontalLayoutMargin,
},
} )

Expand All @@ -45,25 +36,38 @@ const getOptions = ( {
iconName="menu"
testID="navbar-menu"
disabled
style={styles.left}
/>
</HeaderButtons>
),
headerRight: () => (
<HeaderButtons HeaderButtonComponent={IconHeaderButton}>
{isTablet && (
<>
<Item
title="search"
iconName="search-outline"
testID="navbar-settings"
onPress={() => navigation.navigate( 'Root.Search' )}
/>
<Item
title="collections"
iconName="bookmark-outline"
testID="navbar-settings"
onPress={() => navigation.navigate( 'Root.Collections' )}
/>
</>
)}
<Item
title="settings"
iconName="ios-options-outline"
iconName="options-outline"
testID="navbar-settings"
onPress={() => navigation.navigate( 'Home.Tab.Settings', { screen: 'Settings.View' } )}
style={styles.right}
/>
</HeaderButtons>
),
headerTitle: () => (
<View style={styles.headerTitle}>
<Image style={styles.logoIcon} source={logo} />
<Typography style={styles.logoText}>Shabad OS</Typography>
</View>
),
headerTitle: Logo,
} )

const GurbaniNavigator = () => (
Expand Down
1 change: 1 addition & 0 deletions src/themes/units.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum Units {
ThumbFingerRatio = 1.5,
Separator = StyleSheet.hairlineWidth,
BorderRadius = 25,
ThinSplitViewWidth = 350,
}

export default Units

0 comments on commit a6bcf74

Please sign in to comment.