Add like animation

This commit is contained in:
Paul Frazee
2024-06-06 19:11:16 -07:00
parent bd1e6fced9
commit 3aa0c3f2bb
+44 -8
View File
@@ -6,6 +6,14 @@ import {
View, View,
type ViewStyle, type ViewStyle,
} from 'react-native' } from 'react-native'
import Animated, {
Easing,
interpolate,
useAnimatedStyle,
useSharedValue,
withSequence,
withTiming,
} from 'react-native-reanimated'
import { import {
AppBskyFeedDefs, AppBskyFeedDefs,
AppBskyFeedPost, AppBskyFeedPost,
@@ -21,6 +29,7 @@ import {makeProfileLink} from '#/lib/routes/links'
import {shareUrl} from '#/lib/sharing' import {shareUrl} from '#/lib/sharing'
import {toShareUrl} from '#/lib/strings/url-helpers' import {toShareUrl} from '#/lib/strings/url-helpers'
import {s} from '#/lib/styles' import {s} from '#/lib/styles'
import {isWeb} from '#/platform/detection'
import {Shadow} from '#/state/cache/types' import {Shadow} from '#/state/cache/types'
import {useFeedFeedbackContext} from '#/state/feed-feedback' import {useFeedFeedbackContext} from '#/state/feed-feedback'
import { import {
@@ -72,6 +81,7 @@ let PostCtrls = ({
const requireAuth = useRequireAuth() const requireAuth = useRequireAuth()
const loggedOutWarningPromptControl = useDialogControl() const loggedOutWarningPromptControl = useDialogControl()
const {sendInteraction} = useFeedFeedbackContext() const {sendInteraction} = useFeedFeedbackContext()
const likeAnimValue = useSharedValue(0)
const playHaptic = useHaptics() const playHaptic = useHaptics()
const shouldShowLoggedOutWarning = React.useMemo(() => { const shouldShowLoggedOutWarning = React.useMemo(() => {
@@ -87,6 +97,17 @@ let PostCtrls = ({
[t], [t],
) as StyleProp<ViewStyle> ) as StyleProp<ViewStyle>
const likeAnimStyle = useAnimatedStyle(() => {
return {
transform: [
{
scale: interpolate(likeAnimValue.value, [0, 1], [0, 3], 'clamp'),
},
],
opacity: interpolate(likeAnimValue.value, [0, 1], [0.6, 0], 'clamp'),
}
})
const onPressToggleLike = React.useCallback(async () => { const onPressToggleLike = React.useCallback(async () => {
try { try {
if (!post.viewer?.like) { if (!post.viewer?.like) {
@@ -96,6 +117,15 @@ let PostCtrls = ({
event: 'app.bsky.feed.defs#interactionLike', event: 'app.bsky.feed.defs#interactionLike',
feedContext, feedContext,
}) })
likeAnimValue.value = withSequence(
withTiming(1, {
duration: isWeb ? 400 : 500,
easing: Easing.out(Easing.cubic),
}),
withTiming(0, {
duration: 0,
}),
)
await queueLike() await queueLike()
} else { } else {
await queueUnlike() await queueUnlike()
@@ -113,6 +143,7 @@ let PostCtrls = ({
queueUnlike, queueUnlike,
sendInteraction, sendInteraction,
feedContext, feedContext,
likeAnimValue,
]) ])
const onRepost = useCallback(async () => { const onRepost = useCallback(async () => {
@@ -256,14 +287,19 @@ let PostCtrls = ({
} }
accessibilityHint="" accessibilityHint=""
hitSlop={big ? HITSLOP_20 : HITSLOP_10}> hitSlop={big ? HITSLOP_20 : HITSLOP_10}>
{post.viewer?.like ? ( <View style={[a.relative]}>
<HeartIconFilled style={s.likeColor} width={big ? 22 : 18} /> <Animated.View style={[a.absolute, likeAnimStyle]}>
) : ( <HeartIconOutline style={[s.likeColor]} width={big ? 22 : 18} />
<HeartIconOutline </Animated.View>
style={[defaultCtrlColor, {pointerEvents: 'none'}]} {post.viewer?.like ? (
width={big ? 22 : 18} <HeartIconFilled style={s.likeColor} width={big ? 22 : 18} />
/> ) : (
)} <HeartIconOutline
style={[defaultCtrlColor, {pointerEvents: 'none'}]}
width={big ? 22 : 18}
/>
)}
</View>
{typeof post.likeCount !== 'undefined' && post.likeCount > 0 ? ( {typeof post.likeCount !== 'undefined' && post.likeCount > 0 ? (
<Text <Text
testID="likeCount" testID="likeCount"