mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-29 17:39:27 +01:00
switch to useSafeAreaInsets().top (#85)
StatusBar.currentHeight seems just broken on some devices
This commit is contained in:
parent
8bc4caae78
commit
caf544069e
@ -4,6 +4,7 @@ import dimensions from '@app/styles/dimensions'
|
|||||||
import React, { ForwardedRef, PropsWithChildren } from 'react'
|
import React, { ForwardedRef, PropsWithChildren } from 'react'
|
||||||
import { ScrollView, ScrollViewProps, useWindowDimensions } from 'react-native'
|
import { ScrollView, ScrollViewProps, useWindowDimensions } from 'react-native'
|
||||||
import Animated from 'react-native-reanimated'
|
import Animated from 'react-native-reanimated'
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
|
|
||||||
export type GradientScrollViewProps = PropsWithChildren<
|
export type GradientScrollViewProps = PropsWithChildren<
|
||||||
Animated.AnimateProps<ScrollViewProps> & {
|
Animated.AnimateProps<ScrollViewProps> & {
|
||||||
@ -13,8 +14,9 @@ export type GradientScrollViewProps = PropsWithChildren<
|
|||||||
|
|
||||||
const GradientScrollView = React.forwardRef<ScrollView, GradientScrollViewProps>((props, ref) => {
|
const GradientScrollView = React.forwardRef<ScrollView, GradientScrollViewProps>((props, ref) => {
|
||||||
const layout = useWindowDimensions()
|
const layout = useWindowDimensions()
|
||||||
|
const paddingTop = useSafeAreaInsets().top
|
||||||
|
|
||||||
const minHeight = layout.height - (dimensions.top() + dimensions.bottom())
|
const minHeight = layout.height - (dimensions.header + paddingTop + dimensions.bottom())
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.ScrollView
|
<Animated.ScrollView
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
|
import { Album, Song } from '@app/models/library'
|
||||||
import colors from '@app/styles/colors'
|
import colors from '@app/styles/colors'
|
||||||
import dimensions from '@app/styles/dimensions'
|
import dimensions from '@app/styles/dimensions'
|
||||||
import font from '@app/styles/font'
|
import font from '@app/styles/font'
|
||||||
import { useNavigation } from '@react-navigation/core'
|
import { useNavigation } from '@react-navigation/core'
|
||||||
import React, { useCallback } from 'react'
|
|
||||||
import { View, StatusBar, Text, StyleSheet, ViewStyle } from 'react-native'
|
|
||||||
import Animated from 'react-native-reanimated'
|
|
||||||
import PressableOpacity from './PressableOpacity'
|
|
||||||
import IconMat from 'react-native-vector-icons/MaterialIcons'
|
|
||||||
import { ReactComponentLike } from 'prop-types'
|
import { ReactComponentLike } from 'prop-types'
|
||||||
|
import React, { useCallback } from 'react'
|
||||||
|
import { StyleSheet, Text, View, ViewStyle } from 'react-native'
|
||||||
|
import Animated from 'react-native-reanimated'
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
|
import IconMat from 'react-native-vector-icons/MaterialIcons'
|
||||||
import { AlbumContextPressable, NowPlayingContextPressable } from './ContextMenu'
|
import { AlbumContextPressable, NowPlayingContextPressable } from './ContextMenu'
|
||||||
import { Album, Song } from '@app/models/library'
|
import PressableOpacity from './PressableOpacity'
|
||||||
|
|
||||||
export type HeaderContextItem = Song | Album
|
export type HeaderContextItem = Song | Album
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ const HeaderBar = React.memo<{
|
|||||||
contextItem?: HeaderContextItem
|
contextItem?: HeaderContextItem
|
||||||
}>(({ title, headerStyle, HeaderCenter, contextItem }) => {
|
}>(({ title, headerStyle, HeaderCenter, contextItem }) => {
|
||||||
const navigation = useNavigation()
|
const navigation = useNavigation()
|
||||||
|
const top = useSafeAreaInsets().top
|
||||||
|
|
||||||
const back = useCallback(() => {
|
const back = useCallback(() => {
|
||||||
navigation.goBack()
|
navigation.goBack()
|
||||||
@ -61,7 +63,7 @@ const HeaderBar = React.memo<{
|
|||||||
const _headerStyle = Array.isArray(headerStyle) ? headerStyle : [headerStyle]
|
const _headerStyle = Array.isArray(headerStyle) ? headerStyle : [headerStyle]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.View style={[styles.container, ..._headerStyle]}>
|
<Animated.View style={[styles.container, { paddingTop: top, height: dimensions.header + top }, ..._headerStyle]}>
|
||||||
<PressableOpacity onPress={back} style={styles.icons}>
|
<PressableOpacity onPress={back} style={styles.icons}>
|
||||||
<IconMat name="arrow-back" color="white" size={25} />
|
<IconMat name="arrow-back" color="white" size={25} />
|
||||||
</PressableOpacity>
|
</PressableOpacity>
|
||||||
@ -81,8 +83,6 @@ const HeaderBar = React.memo<{
|
|||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
height: dimensions.top(),
|
|
||||||
paddingTop: StatusBar.currentHeight,
|
|
||||||
backgroundColor: colors.gradient.high,
|
backgroundColor: colors.gradient.high,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
|||||||
@ -3,11 +3,13 @@ import colors from '@app/styles/colors'
|
|||||||
import dimensions from '@app/styles/dimensions'
|
import dimensions from '@app/styles/dimensions'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { ScrollView, ScrollViewProps, useWindowDimensions } from 'react-native'
|
import { ScrollView, ScrollViewProps, useWindowDimensions } from 'react-native'
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
|
|
||||||
const ImageGradientScrollView: React.FC<ScrollViewProps & ImageGradientBackgroundProps> = props => {
|
const ImageGradientScrollView: React.FC<ScrollViewProps & ImageGradientBackgroundProps> = props => {
|
||||||
const layout = useWindowDimensions()
|
const layout = useWindowDimensions()
|
||||||
|
const paddingTop = useSafeAreaInsets().top
|
||||||
|
|
||||||
const minHeight = layout.height - (dimensions.top() + dimensions.bottom())
|
const minHeight = layout.height - (dimensions.header + paddingTop + dimensions.bottom())
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView
|
<ScrollView
|
||||||
|
|||||||
@ -6,14 +6,18 @@ import dimensions from '@app/styles/dimensions'
|
|||||||
import font from '@app/styles/font'
|
import font from '@app/styles/font'
|
||||||
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'
|
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { StatusBar, StyleSheet } from 'react-native'
|
import { StyleSheet } from 'react-native'
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
|
|
||||||
const Tab = createMaterialTopTabNavigator()
|
const Tab = createMaterialTopTabNavigator()
|
||||||
|
|
||||||
const LibraryTopTabNavigator = () => (
|
const LibraryTopTabNavigator = () => {
|
||||||
|
const marginTop = useSafeAreaInsets().top
|
||||||
|
|
||||||
|
return (
|
||||||
<Tab.Navigator
|
<Tab.Navigator
|
||||||
tabBarOptions={{
|
tabBarOptions={{
|
||||||
style: styles.tabBar,
|
style: [styles.tabBar, { marginTop }],
|
||||||
labelStyle: styles.tablabelStyle,
|
labelStyle: styles.tablabelStyle,
|
||||||
indicatorStyle: styles.tabindicatorStyle,
|
indicatorStyle: styles.tabindicatorStyle,
|
||||||
}}
|
}}
|
||||||
@ -23,11 +27,11 @@ const LibraryTopTabNavigator = () => (
|
|||||||
<Tab.Screen name="playlists" component={PlaylistsTab} options={{ tabBarLabel: 'Playlists' }} />
|
<Tab.Screen name="playlists" component={PlaylistsTab} options={{ tabBarLabel: 'Playlists' }} />
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
tabBar: {
|
tabBar: {
|
||||||
height: dimensions.header,
|
height: dimensions.header,
|
||||||
marginTop: StatusBar.currentHeight,
|
|
||||||
backgroundColor: colors.gradient.high,
|
backgroundColor: colors.gradient.high,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
|||||||
@ -12,7 +12,8 @@ import { useNavigation } from '@react-navigation/native'
|
|||||||
import equal from 'fast-deep-equal/es6/react'
|
import equal from 'fast-deep-equal/es6/react'
|
||||||
import produce from 'immer'
|
import produce from 'immer'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { RefreshControl, ScrollView, StatusBar, StyleSheet, Text, View } from 'react-native'
|
import { RefreshControl, ScrollView, StyleSheet, Text, View } from 'react-native'
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
import create, { StateSelector } from 'zustand'
|
import create, { StateSelector } from 'zustand'
|
||||||
|
|
||||||
const titles: { [key in GetAlbumListType]?: string } = {
|
const titles: { [key in GetAlbumListType]?: string } = {
|
||||||
@ -111,6 +112,7 @@ const Home = () => {
|
|||||||
const types = useStoreDeep(store => store.settings.screens.home.listTypes)
|
const types = useStoreDeep(store => store.settings.screens.home.listTypes)
|
||||||
const fetchAlbumList = useStore(store => store.fetchAlbumList)
|
const fetchAlbumList = useStore(store => store.fetchAlbumList)
|
||||||
const setList = useHomeStore(store => store.setList)
|
const setList = useHomeStore(store => store.setList)
|
||||||
|
const paddingTop = useSafeAreaInsets().top
|
||||||
|
|
||||||
const refresh = useCallback(async () => {
|
const refresh = useCallback(async () => {
|
||||||
setRefreshing(true)
|
setRefreshing(true)
|
||||||
@ -135,13 +137,13 @@ const Home = () => {
|
|||||||
return (
|
return (
|
||||||
<GradientScrollView
|
<GradientScrollView
|
||||||
style={styles.scroll}
|
style={styles.scroll}
|
||||||
contentContainerStyle={styles.scrollContentContainer}
|
contentContainerStyle={{ paddingTop }}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl
|
<RefreshControl
|
||||||
refreshing={refreshing}
|
refreshing={refreshing}
|
||||||
onRefresh={refresh}
|
onRefresh={refresh}
|
||||||
colors={[colors.accent, colors.accentLow]}
|
colors={[colors.accent, colors.accentLow]}
|
||||||
progressViewOffset={StatusBar.currentHeight}
|
progressViewOffset={paddingTop}
|
||||||
/>
|
/>
|
||||||
}>
|
}>
|
||||||
<View style={styles.content}>
|
<View style={styles.content}>
|
||||||
@ -157,9 +159,6 @@ const styles = StyleSheet.create({
|
|||||||
scroll: {
|
scroll: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
scrollContentContainer: {
|
|
||||||
paddingTop: StatusBar.currentHeight,
|
|
||||||
},
|
|
||||||
content: {
|
content: {
|
||||||
paddingBottom: 20,
|
paddingBottom: 20,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import ListItem from '@app/components/ListItem'
|
|||||||
import NothingHere from '@app/components/NothingHere'
|
import NothingHere from '@app/components/NothingHere'
|
||||||
import TextInput from '@app/components/TextInput'
|
import TextInput from '@app/components/TextInput'
|
||||||
import { useActiveServerRefresh } from '@app/hooks/settings'
|
import { useActiveServerRefresh } from '@app/hooks/settings'
|
||||||
import { Song, Album, Artist, SearchResults } from '@app/models/library'
|
import { Album, Artist, SearchResults, Song } from '@app/models/library'
|
||||||
import { useStore, useStoreDeep } from '@app/state/store'
|
import { useStore, useStoreDeep } from '@app/state/store'
|
||||||
import colors from '@app/styles/colors'
|
import colors from '@app/styles/colors'
|
||||||
import font from '@app/styles/font'
|
import font from '@app/styles/font'
|
||||||
@ -17,11 +17,11 @@ import {
|
|||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
InteractionManager,
|
InteractionManager,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
StatusBar,
|
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
TextInput as ReactTextInput,
|
TextInput as ReactTextInput,
|
||||||
View,
|
View,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
|
|
||||||
const SongItem = React.memo<{ item: Song }>(({ item }) => {
|
const SongItem = React.memo<{ item: Song }>(({ item }) => {
|
||||||
const setQueue = useStore(store => store.setQueue)
|
const setQueue = useStore(store => store.setQueue)
|
||||||
@ -110,6 +110,7 @@ const Search = () => {
|
|||||||
const [text, setText] = useState('')
|
const [text, setText] = useState('')
|
||||||
const searchBarRef = useRef<ReactTextInput>(null)
|
const searchBarRef = useRef<ReactTextInput>(null)
|
||||||
const scrollRef = useRef<ScrollView>(null)
|
const scrollRef = useRef<ScrollView>(null)
|
||||||
|
const paddingTop = useSafeAreaInsets().top
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
@ -153,7 +154,7 @@ const Search = () => {
|
|||||||
const resultsCount = results.albums.length + results.artists.length + results.songs.length
|
const resultsCount = results.albums.length + results.artists.length + results.songs.length
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GradientScrollView ref={scrollRef} style={styles.scroll} contentContainerStyle={styles.scrollContentContainer}>
|
<GradientScrollView ref={scrollRef} style={styles.scroll} contentContainerStyle={{ paddingTop }}>
|
||||||
<View style={styles.content}>
|
<View style={styles.content}>
|
||||||
<View style={styles.inputBar}>
|
<View style={styles.inputBar}>
|
||||||
<TextInput
|
<TextInput
|
||||||
@ -180,9 +181,6 @@ const styles = StyleSheet.create({
|
|||||||
scroll: {
|
scroll: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
scrollContentContainer: {
|
|
||||||
paddingTop: StatusBar.currentHeight,
|
|
||||||
},
|
|
||||||
content: {
|
content: {
|
||||||
paddingHorizontal: 20,
|
paddingHorizontal: 20,
|
||||||
paddingBottom: 20,
|
paddingBottom: 20,
|
||||||
|
|||||||
@ -184,7 +184,7 @@ const ServerView: React.FC<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GradientScrollView style={styles.scroll} contentContainerStyle={styles.scrollContentContainer}>
|
<GradientScrollView style={styles.scroll}>
|
||||||
<View style={styles.content}>
|
<View style={styles.content}>
|
||||||
<Text style={styles.inputTitle}>Address</Text>
|
<Text style={styles.inputTitle}>Address</Text>
|
||||||
<TextInput
|
<TextInput
|
||||||
@ -259,9 +259,6 @@ const styles = StyleSheet.create({
|
|||||||
scroll: {
|
scroll: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
scrollContentContainer: {
|
|
||||||
// paddingTop: StatusBar.currentHeight,
|
|
||||||
},
|
|
||||||
content: {
|
content: {
|
||||||
paddingHorizontal: 20,
|
paddingHorizontal: 20,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -12,8 +12,9 @@ import colors from '@app/styles/colors'
|
|||||||
import font from '@app/styles/font'
|
import font from '@app/styles/font'
|
||||||
import { useNavigation } from '@react-navigation/core'
|
import { useNavigation } from '@react-navigation/core'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { KeyboardTypeOptions, Linking, Modal, Pressable, StatusBar, StyleSheet, Text, View } from 'react-native'
|
import { KeyboardTypeOptions, Linking, Modal, Pressable, StyleSheet, Text, View } from 'react-native'
|
||||||
import { ScrollView } from 'react-native-gesture-handler'
|
import { ScrollView } from 'react-native-gesture-handler'
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||||
import { version } from '../../package.json'
|
import { version } from '../../package.json'
|
||||||
|
|
||||||
@ -296,8 +297,10 @@ const SettingsContent = React.memo(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const Settings = () => {
|
const Settings = () => {
|
||||||
|
const paddingTop = useSafeAreaInsets().top
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GradientScrollView style={styles.scroll} contentContainerStyle={styles.scrollContentContainer}>
|
<GradientScrollView style={styles.scroll} contentContainerStyle={{ paddingTop }}>
|
||||||
<SettingsContent />
|
<SettingsContent />
|
||||||
</GradientScrollView>
|
</GradientScrollView>
|
||||||
)
|
)
|
||||||
@ -307,9 +310,6 @@ const styles = StyleSheet.create({
|
|||||||
scroll: {
|
scroll: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
scrollContentContainer: {
|
|
||||||
paddingTop: StatusBar.currentHeight,
|
|
||||||
},
|
|
||||||
content: {
|
content: {
|
||||||
paddingHorizontal: 20,
|
paddingHorizontal: 20,
|
||||||
paddingBottom: 40,
|
paddingBottom: 40,
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
import { StatusBar } from 'react-native'
|
|
||||||
|
|
||||||
const header = 56
|
const header = 56
|
||||||
const tabBar = 54
|
const tabBar = 54
|
||||||
|
|
||||||
const top = () => header + (StatusBar.currentHeight || 0)
|
|
||||||
const bottom = () => tabBar
|
const bottom = () => tabBar
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
header,
|
header,
|
||||||
tabBar,
|
tabBar,
|
||||||
top,
|
|
||||||
bottom,
|
bottom,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user