tooot/src/screens/Actions/Root.tsx

242 lines
6.8 KiB
TypeScript
Raw Normal View History

2021-02-10 00:40:44 +01:00
import analytics from '@components/analytics'
import Button from '@components/Button'
import { StackScreenProps } from '@react-navigation/stack'
2021-02-27 16:33:54 +01:00
import {
getInstanceAccount,
getInstanceUrl
} from '@utils/slices/instancesSlice'
2021-02-10 00:40:44 +01:00
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useCallback, useEffect, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { Dimensions, StyleSheet, View } from 'react-native'
import {
PanGestureHandler,
State,
TapGestureHandler
} from 'react-native-gesture-handler'
import Animated, {
Extrapolate,
interpolate,
runOnJS,
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
withTiming
} from 'react-native-reanimated'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useSelector } from 'react-redux'
import ActionsAccount from './Account'
import ActionsDomain from './Domain'
2021-03-17 15:30:28 +01:00
import ActionsNotificationsFilter from './NotificationsFilter'
2021-02-10 00:40:44 +01:00
import ActionsShare from './Share'
import ActionsStatus from './Status'
export type ScreenAccountProp = StackScreenProps<
Nav.RootStackParamList,
'Screen-Actions'
>
const ScreenActionsRoot = React.memo(
({ route: { params }, navigation }: ScreenAccountProp) => {
const { t } = useTranslation()
2021-03-17 15:30:28 +01:00
const instanceAccount = useSelector(
2021-02-27 16:33:54 +01:00
getInstanceAccount,
2021-02-10 00:40:44 +01:00
(prev, next) => prev?.id === next?.id
)
let sameAccount = false
switch (params.type) {
case 'status':
2021-03-17 15:30:28 +01:00
sameAccount = instanceAccount?.id === params.status.account.id
2021-02-10 00:40:44 +01:00
break
case 'account':
2021-03-17 15:30:28 +01:00
sameAccount = instanceAccount?.id === params.account.id
2021-02-10 00:40:44 +01:00
break
}
2021-03-17 15:30:28 +01:00
const instanceDomain = useSelector(getInstanceUrl)
2021-02-10 00:40:44 +01:00
let sameDomain = true
let statusDomain: string
switch (params.type) {
case 'status':
statusDomain = params.status.uri
? params.status.uri.split(new RegExp(/\/\/(.*?)\//))[1]
: ''
2021-03-17 15:30:28 +01:00
sameDomain = instanceDomain === statusDomain
2021-02-10 00:40:44 +01:00
break
}
const { theme } = useTheme()
const insets = useSafeAreaInsets()
const DEFAULT_VALUE = 350
const screenHeight = Dimensions.get('screen').height
const panY = useSharedValue(DEFAULT_VALUE)
useEffect(() => {
panY.value = withTiming(0)
}, [])
const styleTop = useAnimatedStyle(() => {
return {
bottom: interpolate(
panY.value,
[0, screenHeight],
[0, -screenHeight],
Extrapolate.CLAMP
)
}
})
const dismiss = useCallback(() => {
navigation.goBack()
}, [])
const onGestureEvent = useAnimatedGestureHandler({
onActive: ({ translationY }) => {
panY.value = translationY
},
onEnd: ({ velocityY }) => {
if (velocityY > 500) {
runOnJS(dismiss)()
} else {
panY.value = withTiming(0)
}
}
})
const actions = useMemo(() => {
switch (params.type) {
case 'status':
return (
<>
2021-06-11 23:07:41 +02:00
{!sameAccount ? (
2021-02-10 00:40:44 +01:00
<ActionsAccount
queryKey={params.queryKey}
2021-02-13 01:26:02 +01:00
rootQueryKey={params.rootQueryKey}
2021-02-10 00:40:44 +01:00
account={params.status.account}
dismiss={dismiss}
/>
2021-06-11 23:07:41 +02:00
) : null}
{sameAccount && params.status ? (
2021-02-10 00:40:44 +01:00
<ActionsStatus
navigation={navigation}
queryKey={params.queryKey}
2021-02-13 01:26:02 +01:00
rootQueryKey={params.rootQueryKey}
2021-02-10 00:40:44 +01:00
status={params.status}
dismiss={dismiss}
/>
2021-06-11 23:07:41 +02:00
) : null}
{!sameDomain && statusDomain ? (
2021-02-10 00:40:44 +01:00
<ActionsDomain
queryKey={params.queryKey}
2021-02-13 01:26:02 +01:00
rootQueryKey={params.rootQueryKey}
2021-02-10 00:40:44 +01:00
domain={statusDomain}
dismiss={dismiss}
/>
2021-06-11 23:07:41 +02:00
) : null}
{params.status.visibility !== 'direct' ? (
2021-03-29 23:56:13 +02:00
<ActionsShare
url={params.status.url || params.status.uri}
type={params.type}
dismiss={dismiss}
/>
2021-06-11 23:07:41 +02:00
) : null}
2021-03-17 15:30:28 +01:00
<Button
type='text'
content={t('common:buttons.cancel')}
onPress={() => {
analytics('bottomsheet_acknowledge')
}}
style={styles.button}
/>
2021-02-10 00:40:44 +01:00
</>
)
case 'account':
return (
<>
2021-06-11 23:07:41 +02:00
{!sameAccount ? (
2021-02-10 00:40:44 +01:00
<ActionsAccount account={params.account} dismiss={dismiss} />
2021-06-11 23:07:41 +02:00
) : null}
2021-02-10 00:40:44 +01:00
<ActionsShare
url={params.account.url}
type={params.type}
dismiss={dismiss}
/>
2021-03-17 15:30:28 +01:00
<Button
type='text'
content={t('common:buttons.cancel')}
onPress={() => {
analytics('bottomsheet_acknowledge')
}}
style={styles.button}
/>
2021-02-10 00:40:44 +01:00
</>
)
2021-03-17 15:30:28 +01:00
case 'notifications_filter':
return <ActionsNotificationsFilter />
2021-02-10 00:40:44 +01:00
}
}, [])
return (
<Animated.View style={{ flex: 1 }}>
<TapGestureHandler
onHandlerStateChange={({ nativeEvent }) => {
if (nativeEvent.state === State.ACTIVE) {
dismiss()
}
}}
>
<Animated.View
style={[
styles.overlay,
{ backgroundColor: theme.backgroundOverlayInvert }
2021-02-10 00:40:44 +01:00
]}
>
<PanGestureHandler onGestureEvent={onGestureEvent}>
<Animated.View
style={[
styles.container,
styleTop,
{
backgroundColor: theme.backgroundDefault,
2021-02-10 00:40:44 +01:00
paddingBottom: insets.bottom || StyleConstants.Spacing.L
}
]}
>
<View
style={[
styles.handle,
{ backgroundColor: theme.primaryOverlay }
]}
/>
{actions}
</Animated.View>
</PanGestureHandler>
</Animated.View>
</TapGestureHandler>
</Animated.View>
)
},
() => true
)
const styles = StyleSheet.create({
overlay: {
flex: 1,
justifyContent: 'flex-end'
},
container: {
paddingTop: StyleConstants.Spacing.M
},
handle: {
alignSelf: 'center',
width: StyleConstants.Spacing.S * 8,
height: StyleConstants.Spacing.S / 2,
borderRadius: 100,
top: -StyleConstants.Spacing.M * 2
},
button: {
marginHorizontal: StyleConstants.Spacing.Global.PagePadding * 2
}
})
export default ScreenActionsRoot