diff options
Diffstat (limited to 'src/view/com/util/PostCtrls.tsx')
-rw-r--r-- | src/view/com/util/PostCtrls.tsx | 167 |
1 files changed, 122 insertions, 45 deletions
diff --git a/src/view/com/util/PostCtrls.tsx b/src/view/com/util/PostCtrls.tsx index 707030ea2..ab9e261cf 100644 --- a/src/view/com/util/PostCtrls.tsx +++ b/src/view/com/util/PostCtrls.tsx @@ -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,48 +26,123 @@ 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}> - <TouchableOpacity style={styles.ctrl} onPress={opts.onPressReply}> - <FontAwesomeIcon - style={styles.ctrlIcon} - icon={['far', 'comment']} - size={14} - /> - <Text style={s.f13}>{opts.replyCount}</Text> - </TouchableOpacity> - <TouchableOpacity style={styles.ctrl} onPress={opts.onPressToggleRepost}> - <FontAwesomeIcon - style={opts.isReposted ? styles.ctrlIconReposted : styles.ctrlIcon} - icon="retweet" - size={18} - /> - <Text style={opts.isReposted ? [s.bold, s.green3, s.f13] : s.f13}> - {opts.repostCount} - </Text> - </TouchableOpacity> - <TouchableOpacity style={styles.ctrl} onPress={opts.onPressToggleUpvote}> - {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}> - {opts.upvoteCount} - </Text> - </TouchableOpacity> - <TouchableOpacity - style={styles.ctrl} - onPress={opts.onPressToggleDownvote}> - {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}> - {opts.downvoteCount} - </Text> - </TouchableOpacity> + <View style={s.flex1}> + <TouchableOpacity style={styles.ctrl} onPress={opts.onPressReply}> + <FontAwesomeIcon + style={styles.ctrlIcon} + icon={['far', 'comment']} + size={14} + /> + <Text style={s.f13}>{opts.replyCount}</Text> + </TouchableOpacity> + </View> + <View style={s.flex1}> + <TouchableOpacity + onPress={onPressToggleRepostWrapper} + style={styles.ctrl}> + <Animated.View style={anim1Style}> + <FontAwesomeIcon + style={ + opts.isReposted ? styles.ctrlIconReposted : styles.ctrlIcon + } + icon="retweet" + size={18} + /> + </Animated.View> + <Text + style={ + opts.isReposted + ? [s.bold, s.green3, s.f13, s.ml5] + : [s.f13, s.ml5] + }> + {opts.repostCount} + </Text> + </TouchableOpacity> + </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} /> + )} + </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={onPressToggleDownvoteWrapper}> + <Animated.View style={anim3Style}> + {opts.isDownvoted ? ( + <DownIconSolid style={styles.ctrlIconDownvoted} size={18} /> + ) : ( + <DownIcon style={styles.ctrlIcon} size={18} /> + )} + </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, }, }) |