diff options
author | Hailey <me@haileyok.com> | 2024-09-25 08:32:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-25 08:32:58 -0700 |
commit | be3c6ab93a5e3f573ceb8909df068d8a87f86474 (patch) | |
tree | 3f0038e7526e468f719821124f57a35ac2d0c877 /src | |
parent | 2296ea338e8f7b4906a928e802267837c06754cc (diff) | |
download | voidsky-be3c6ab93a5e3f573ceb8909df068d8a87f86474.tar.zst |
Improve style of reply bar (#5447)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/custom-animations/PressableScale.tsx | 53 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThreadComposePrompt.tsx | 95 |
2 files changed, 107 insertions, 41 deletions
diff --git a/src/lib/custom-animations/PressableScale.tsx b/src/lib/custom-animations/PressableScale.tsx new file mode 100644 index 000000000..68315a978 --- /dev/null +++ b/src/lib/custom-animations/PressableScale.tsx @@ -0,0 +1,53 @@ +import React from 'react' +import {Pressable, PressableProps} from 'react-native' +import Animated, { + cancelAnimation, + runOnJS, + useAnimatedStyle, + useSharedValue, + withTiming, +} from 'react-native-reanimated' + +import {isTouchDevice} from '#/lib/browser' +import {isNative} from '#/platform/detection' + +const DEFAULT_TARGET_SCALE = isNative || isTouchDevice ? 0.98 : 1 + +export function PressableScale({ + targetScale = DEFAULT_TARGET_SCALE, + children, + ...rest +}: {targetScale?: number} & Exclude< + PressableProps, + 'onPressIn' | 'onPressOut' +>) { + const scale = useSharedValue(1) + + const style = useAnimatedStyle(() => ({ + transform: [{scale: scale.value}], + })) + + return ( + <Pressable + accessibilityRole="button" + onPressIn={e => { + 'worklet' + if (rest.onPressIn) { + runOnJS(rest.onPressIn)(e) + } + cancelAnimation(scale) + scale.value = withTiming(targetScale, {duration: 100}) + }} + onPressOut={e => { + 'worklet' + if (rest.onPressOut) { + runOnJS(rest.onPressOut)(e) + } + cancelAnimation(scale) + scale.value = withTiming(1, {duration: 100}) + }} + {...rest}> + <Animated.View style={style}>{children as React.ReactNode}</Animated.View> + </Pressable> + ) +} diff --git a/src/view/com/post-thread/PostThreadComposePrompt.tsx b/src/view/com/post-thread/PostThreadComposePrompt.tsx index 62b28cc75..7586bd976 100644 --- a/src/view/com/post-thread/PostThreadComposePrompt.tsx +++ b/src/view/com/post-thread/PostThreadComposePrompt.tsx @@ -1,14 +1,17 @@ import React from 'react' -import {StyleSheet, TouchableOpacity} from 'react-native' +import {View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {PressableScale} from '#/lib/custom-animations/PressableScale' +import {useHaptics} from '#/lib/haptics' +import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' +import {useHapticsDisabled} from '#/state/preferences' import {useProfileQuery} from '#/state/queries/profile' import {useSession} from '#/state/session' -import {usePalette} from 'lib/hooks/usePalette' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {Text} from '../util/text/Text' -import {UserAvatar} from '../util/UserAvatar' +import {UserAvatar} from '#/view/com/util/UserAvatar' +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' export function PostThreadComposePrompt({ onPressCompose, @@ -17,47 +20,57 @@ export function PostThreadComposePrompt({ }) { const {currentAccount} = useSession() const {data: profile} = useProfileQuery({did: currentAccount?.did}) - const pal = usePalette('default') const {_} = useLingui() - const {isDesktop} = useWebMediaQueries() + const {isTabletOrDesktop} = useWebMediaQueries() + const t = useTheme() + const playHaptics = useHaptics() + const isHapticsDisabled = useHapticsDisabled() + + const onPress = () => { + playHaptics('Light') + setTimeout( + () => { + onPressCompose() + }, + isHapticsDisabled ? 0 : 75, + ) + } + return ( - <TouchableOpacity - testID="replyPromptBtn" - style={[pal.view, pal.border, styles.prompt]} - onPress={() => onPressCompose()} + <PressableScale accessibilityRole="button" accessibilityLabel={_(msg`Compose reply`)} - accessibilityHint={_(msg`Opens composer`)}> - <UserAvatar - avatar={profile?.avatar} - size={38} - type={profile?.associated?.labeler ? 'labeler' : 'user'} - /> - <Text - type="xl" + accessibilityHint={_(msg`Opens composer`)} + style={[ + {paddingTop: 8, paddingBottom: isTabletOrDesktop ? 8 : 11}, + a.px_sm, + a.border_t, + t.atoms.border_contrast_low, + t.atoms.bg, + ]} + onPress={onPress}> + <View style={[ - pal.text, - isDesktop ? styles.labelDesktopWeb : styles.labelMobile, + a.flex_row, + a.align_center, + a.p_sm, + a.gap_sm, + a.rounded_full, + t.atoms.bg_contrast_25, ]}> - <Trans>Write your reply</Trans> - </Text> - </TouchableOpacity> + <UserAvatar + size={22} + avatar={profile?.avatar} + type={profile?.associated?.labeler ? 'labeler' : 'user'} + /> + <Text + style={[ + isTabletOrDesktop ? a.text_md : a.text_sm, + t.atoms.text_contrast_medium, + ]}> + <Trans>Write your reply</Trans> + </Text> + </View> + </PressableScale> ) } - -const styles = StyleSheet.create({ - prompt: { - paddingHorizontal: 16, - paddingTop: 10, - paddingBottom: 10, - flexDirection: 'row', - alignItems: 'center', - borderTopWidth: StyleSheet.hairlineWidth, - }, - labelMobile: { - paddingLeft: 12, - }, - labelDesktopWeb: { - paddingLeft: 12, - }, -}) |