Add animations to post controls
parent
64d095a96b
commit
dcf6a49715
|
@ -1,5 +1,12 @@
|
|||
import React from 'react'
|
||||
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native'
|
||||
import Animated, {
|
||||
useSharedValue,
|
||||
useAnimatedStyle,
|
||||
withDelay,
|
||||
withTiming,
|
||||
interpolate,
|
||||
} from 'react-native-reanimated'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {UpIcon, UpIconSolid, DownIcon, DownIconSolid} from '../../lib/icons'
|
||||
import {s, colors} from '../../lib/styles'
|
||||
|
@ -19,8 +26,51 @@ interface PostCtrlsOpts {
|
|||
}
|
||||
|
||||
export function PostCtrls(opts: PostCtrlsOpts) {
|
||||
const interp1 = useSharedValue<number>(0)
|
||||
const interp2 = useSharedValue<number>(0)
|
||||
const interp3 = useSharedValue<number>(0)
|
||||
|
||||
const anim1Style = useAnimatedStyle(() => ({
|
||||
transform: [{scale: interpolate(interp1.value, [0, 1.0], [1.0, 3.0])}],
|
||||
opacity: interpolate(interp1.value, [0, 1.0], [1.0, 0.0]),
|
||||
}))
|
||||
const anim2Style = useAnimatedStyle(() => ({
|
||||
transform: [{scale: interpolate(interp2.value, [0, 1.0], [1.0, 3.0])}],
|
||||
opacity: interpolate(interp2.value, [0, 1.0], [1.0, 0.0]),
|
||||
}))
|
||||
const anim3Style = useAnimatedStyle(() => ({
|
||||
transform: [{scale: interpolate(interp3.value, [0, 1.0], [1.0, 3.0])}],
|
||||
opacity: interpolate(interp3.value, [0, 1.0], [1.0, 0.0]),
|
||||
}))
|
||||
|
||||
const onPressToggleRepostWrapper = () => {
|
||||
if (!opts.isReposted) {
|
||||
interp1.value = withTiming(1, {duration: 300}, () => {
|
||||
interp1.value = withDelay(100, withTiming(0, {duration: 20}))
|
||||
})
|
||||
}
|
||||
opts.onPressToggleRepost()
|
||||
}
|
||||
const onPressToggleUpvoteWrapper = () => {
|
||||
if (!opts.isUpvoted) {
|
||||
interp2.value = withTiming(1, {duration: 300}, () => {
|
||||
interp2.value = withDelay(100, withTiming(0, {duration: 20}))
|
||||
})
|
||||
}
|
||||
opts.onPressToggleUpvote()
|
||||
}
|
||||
const onPressToggleDownvoteWrapper = () => {
|
||||
if (!opts.isDownvoted) {
|
||||
interp3.value = withTiming(1, {duration: 300}, () => {
|
||||
interp3.value = withDelay(100, withTiming(0, {duration: 20}))
|
||||
})
|
||||
}
|
||||
opts.onPressToggleDownvote()
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.ctrls}>
|
||||
<View style={s.flex1}>
|
||||
<TouchableOpacity style={styles.ctrl} onPress={opts.onPressReply}>
|
||||
<FontAwesomeIcon
|
||||
style={styles.ctrlIcon}
|
||||
|
@ -29,39 +79,71 @@ export function PostCtrls(opts: PostCtrlsOpts) {
|
|||
/>
|
||||
<Text style={s.f13}>{opts.replyCount}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.ctrl} onPress={opts.onPressToggleRepost}>
|
||||
</View>
|
||||
<View style={s.flex1}>
|
||||
<TouchableOpacity
|
||||
onPress={onPressToggleRepostWrapper}
|
||||
style={styles.ctrl}>
|
||||
<Animated.View style={anim1Style}>
|
||||
<FontAwesomeIcon
|
||||
style={opts.isReposted ? styles.ctrlIconReposted : styles.ctrlIcon}
|
||||
style={
|
||||
opts.isReposted ? styles.ctrlIconReposted : styles.ctrlIcon
|
||||
}
|
||||
icon="retweet"
|
||||
size={18}
|
||||
/>
|
||||
<Text style={opts.isReposted ? [s.bold, s.green3, s.f13] : s.f13}>
|
||||
</Animated.View>
|
||||
<Text
|
||||
style={
|
||||
opts.isReposted
|
||||
? [s.bold, s.green3, s.f13, s.ml5]
|
||||
: [s.f13, s.ml5]
|
||||
}>
|
||||
{opts.repostCount}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.ctrl} onPress={opts.onPressToggleUpvote}>
|
||||
</View>
|
||||
<View style={s.flex1}>
|
||||
<TouchableOpacity
|
||||
style={styles.ctrl}
|
||||
onPress={onPressToggleUpvoteWrapper}>
|
||||
<Animated.View style={anim2Style}>
|
||||
{opts.isUpvoted ? (
|
||||
<UpIconSolid style={styles.ctrlIconUpvoted} size={18} />
|
||||
) : (
|
||||
<UpIcon style={styles.ctrlIcon} size={18} />
|
||||
)}
|
||||
<Text style={opts.isUpvoted ? [s.bold, s.red3, s.f13] : s.f13}>
|
||||
</Animated.View>
|
||||
<Text
|
||||
style={
|
||||
opts.isUpvoted ? [s.bold, s.red3, s.f13, s.ml5] : [s.f13, s.ml5]
|
||||
}>
|
||||
{opts.upvoteCount}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={s.flex1}>
|
||||
<TouchableOpacity
|
||||
style={styles.ctrl}
|
||||
onPress={opts.onPressToggleDownvote}>
|
||||
onPress={onPressToggleDownvoteWrapper}>
|
||||
<Animated.View style={anim3Style}>
|
||||
{opts.isDownvoted ? (
|
||||
<DownIconSolid style={styles.ctrlIconDownvoted} size={18} />
|
||||
) : (
|
||||
<DownIcon style={styles.ctrlIcon} size={18} />
|
||||
)}
|
||||
<Text style={opts.isDownvoted ? [s.bold, s.blue3, s.f13] : s.f13}>
|
||||
</Animated.View>
|
||||
<Text
|
||||
style={
|
||||
opts.isDownvoted
|
||||
? [s.bold, s.blue3, s.f13, s.ml5]
|
||||
: [s.f13, s.ml5]
|
||||
}>
|
||||
{opts.downvoteCount}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -72,24 +154,19 @@ const styles = StyleSheet.create({
|
|||
ctrl: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
paddingLeft: 4,
|
||||
paddingRight: 4,
|
||||
},
|
||||
ctrlIcon: {
|
||||
marginRight: 5,
|
||||
color: colors.gray5,
|
||||
},
|
||||
ctrlIconReposted: {
|
||||
marginRight: 5,
|
||||
color: colors.green3,
|
||||
},
|
||||
ctrlIconUpvoted: {
|
||||
marginRight: 5,
|
||||
color: colors.red3,
|
||||
},
|
||||
ctrlIconDownvoted: {
|
||||
marginRight: 5,
|
||||
color: colors.blue3,
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue