diff options
author | Ollie H <renahlee@outlook.com> | 2023-05-15 13:18:39 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-15 15:18:39 -0500 |
commit | 628d8773255d403347b0cbb98afa6681768d428e (patch) | |
tree | 364177969bc142dd71e871b9261c6304d2c19a42 | |
parent | 0a0afdf2c2c90c5460784935e9d1324dadf61d48 (diff) | |
download | voidsky-628d8773255d403347b0cbb98afa6681768d428e.tar.zst |
Use dropdown for web reposting and quote posting (#607)
* Use dropdown for web reposting and quote posting * Remove collateral damage * Tune the repost dropdown positioning * Move postctrls into their own folder * Factor out repost button into native/web build --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com>
-rw-r--r-- | src/view/com/post-thread/PostThreadItem.tsx | 2 | ||||
-rw-r--r-- | src/view/com/post/Post.tsx | 2 | ||||
-rw-r--r-- | src/view/com/posts/FeedItem.tsx | 2 | ||||
-rw-r--r-- | src/view/com/util/post-ctrls/PostCtrls.tsx (renamed from src/view/com/util/PostCtrls.tsx) | 90 | ||||
-rw-r--r-- | src/view/com/util/post-ctrls/RepostButton.tsx | 95 | ||||
-rw-r--r-- | src/view/com/util/post-ctrls/RepostButton.web.tsx | 86 |
6 files changed, 210 insertions, 67 deletions
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 563a3ead6..084e30a25 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -21,7 +21,7 @@ import {pluralize} from 'lib/strings/helpers' import {useStores} from 'state/index' import {PostMeta} from '../util/PostMeta' import {PostEmbeds} from '../util/post-embeds' -import {PostCtrls} from '../util/PostCtrls' +import {PostCtrls} from '../util/post-ctrls/PostCtrls' import {PostHider} from '../util/moderation/PostHider' import {ContentHider} from '../util/moderation/ContentHider' import {ImageHider} from '../util/moderation/ImageHider' diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 0b49995fe..614c5ea77 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -20,7 +20,7 @@ import {Link} from '../util/Link' import {UserInfoText} from '../util/UserInfoText' import {PostMeta} from '../util/PostMeta' import {PostEmbeds} from '../util/post-embeds' -import {PostCtrls} from '../util/PostCtrls' +import {PostCtrls} from '../util/post-ctrls/PostCtrls' import {PostHider} from '../util/moderation/PostHider' import {ContentHider} from '../util/moderation/ContentHider' import {ImageHider} from '../util/moderation/ImageHider' diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 1084fb6fc..fa6131d61 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -13,7 +13,7 @@ import {Link, DesktopWebTextLink} from '../util/Link' import {Text} from '../util/text/Text' import {UserInfoText} from '../util/UserInfoText' import {PostMeta} from '../util/PostMeta' -import {PostCtrls} from '../util/PostCtrls' +import {PostCtrls} from '../util/post-ctrls/PostCtrls' import {PostEmbeds} from '../util/post-embeds' import {PostHider} from '../util/moderation/PostHider' import {ContentHider} from '../util/moderation/ContentHider' diff --git a/src/view/com/util/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index 11b73cea0..5c0296e28 100644 --- a/src/view/com/util/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useCallback} from 'react' import { StyleProp, StyleSheet, @@ -18,18 +18,14 @@ import ReactNativeHapticFeedback, { // TriggerableAnimated, // TriggerableAnimatedRef, // } from './anim/TriggerableAnimated' -import {Text} from './text/Text' -import {PostDropdownBtn} from './forms/DropdownButton' -import { - HeartIcon, - HeartIconSolid, - RepostIcon, - CommentBottomArrow, -} from 'lib/icons' +import {Text} from '../text/Text' +import {PostDropdownBtn} from '../forms/DropdownButton' +import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons' import {s, colors} from 'lib/styles' import {useTheme} from 'lib/ThemeContext' import {useStores} from 'state/index' -import {isIOS} from 'platform/detection' +import {isIOS, isNative} from 'platform/detection' +import {RepostButton} from './RepostButton' interface PostCtrlsOpts { itemUri: string @@ -112,10 +108,12 @@ export function PostCtrls(opts: PostCtrlsOpts) { // DISABLED see #135 // const repostRef = React.useRef<TriggerableAnimatedRef | null>(null) // const likeRef = React.useRef<TriggerableAnimatedRef | null>(null) - const onRepost = () => { + const onRepost = useCallback(() => { store.shell.closeModal() if (!opts.isReposted) { - ReactNativeHapticFeedback.trigger(hapticImpact) + if (isNative) { + ReactNativeHapticFeedback.trigger(hapticImpact) + } opts.onPressToggleRepost().catch(_e => undefined) // DISABLED see #135 // repostRef.current?.trigger( @@ -128,9 +126,9 @@ export function PostCtrls(opts: PostCtrlsOpts) { } else { opts.onPressToggleRepost().catch(_e => undefined) } - } + }, [opts, store.shell]) - const onQuote = () => { + const onQuote = useCallback(() => { store.shell.closeModal() store.shell.openComposer({ quote: { @@ -141,17 +139,18 @@ export function PostCtrls(opts: PostCtrlsOpts) { indexedAt: opts.indexedAt, }, }) - ReactNativeHapticFeedback.trigger(hapticImpact) - } - const onPressToggleRepostWrapper = () => { - store.shell.openModal({ - name: 'repost', - onRepost: onRepost, - onQuote: onQuote, - isReposted: opts.isReposted, - }) - } + if (isNative) { + ReactNativeHapticFeedback.trigger(hapticImpact) + } + }, [ + opts.author, + opts.indexedAt, + opts.itemCid, + opts.itemUri, + opts.text, + store.shell, + ]) const onPressToggleLikeWrapper = async () => { if (!opts.isLiked) { @@ -181,7 +180,7 @@ export function PostCtrls(opts: PostCtrlsOpts) { onPress={opts.onPressReply} accessibilityRole="button" accessibilityLabel="Reply" - accessibilityHint="Opens reply composer"> + accessibilityHint="reply composer"> <CommentBottomArrow style={[defaultCtrlColor, opts.big ? s.mt2 : styles.mt1]} strokeWidth={3} @@ -193,39 +192,7 @@ export function PostCtrls(opts: PostCtrlsOpts) { </Text> ) : undefined} </TouchableOpacity> - <TouchableOpacity - testID="repostBtn" - hitSlop={HITSLOP} - onPress={onPressToggleRepostWrapper} - style={styles.ctrl} - accessibilityRole="button" - accessibilityLabel={opts.isReposted ? 'Undo repost' : 'Repost'} - accessibilityHint={ - opts.isReposted - ? `Remove your repost of ${opts.author}'s post` - : `Repost or quote post ${opts.author}'s post` - }> - <RepostIcon - style={ - opts.isReposted - ? (styles.ctrlIconReposted as StyleProp<ViewStyle>) - : defaultCtrlColor - } - strokeWidth={2.4} - size={opts.big ? 24 : 20} - /> - {typeof opts.repostCount !== 'undefined' ? ( - <Text - testID="repostCount" - style={ - opts.isReposted - ? [s.bold, s.green3, s.f15, s.ml5] - : [defaultCtrlColor, s.f15, s.ml5] - }> - {opts.repostCount} - </Text> - ) : undefined} - </TouchableOpacity> + <RepostButton {...opts} onRepost={onRepost} onQuote={onQuote} /> <TouchableOpacity testID="likeBtn" style={styles.ctrl} @@ -234,9 +201,7 @@ export function PostCtrls(opts: PostCtrlsOpts) { accessibilityRole="button" accessibilityLabel={opts.isLiked ? 'Unlike' : 'Like'} accessibilityHint={ - opts.isReposted - ? `Removes like from ${opts.author}'s post` - : `Like ${opts.author}'s post` + opts.isReposted ? `Removes like from the post` : `Like the post` }> {opts.isLiked ? ( <HeartIconSolid @@ -309,9 +274,6 @@ const styles = StyleSheet.create({ padding: 5, margin: -5, }, - ctrlIconReposted: { - color: colors.green3, - }, ctrlIconLiked: { color: colors.red3, }, diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx new file mode 100644 index 000000000..e6de4cb19 --- /dev/null +++ b/src/view/com/util/post-ctrls/RepostButton.tsx @@ -0,0 +1,95 @@ +import React, {useCallback} from 'react' +import {StyleProp, StyleSheet, TouchableOpacity, ViewStyle} from 'react-native' +import {RepostIcon} from 'lib/icons' +import {s, colors} from 'lib/styles' +import {useTheme} from 'lib/ThemeContext' +import {Text} from '../text/Text' +import {useStores} from 'state/index' + +const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5} + +interface Props { + isReposted: boolean + repostCount?: number + big?: boolean + onRepost: () => void + onQuote: () => void +} + +export const RepostButton = ({ + isReposted, + repostCount, + big, + onRepost, + onQuote, +}: Props) => { + const store = useStores() + const theme = useTheme() + + const defaultControlColor = React.useMemo( + () => ({ + color: theme.palette.default.postCtrl, + }), + [theme], + ) + + const onPressToggleRepostWrapper = useCallback(() => { + store.shell.openModal({ + name: 'repost', + onRepost: onRepost, + onQuote: onQuote, + isReposted, + }) + }, [onRepost, onQuote, isReposted, store.shell]) + + return ( + <TouchableOpacity + testID="repostBtn" + hitSlop={HITSLOP} + onPress={onPressToggleRepostWrapper} + style={styles.control} + accessibilityRole="button" + accessibilityLabel={isReposted ? 'Undo repost' : 'Repost'} + accessibilityHint={ + isReposted + ? `Remove your repost of the post` + : `Repost or quote post the post` + }> + <RepostIcon + style={ + isReposted + ? (styles.reposted as StyleProp<ViewStyle>) + : defaultControlColor + } + strokeWidth={2.4} + size={big ? 24 : 20} + /> + {typeof repostCount !== 'undefined' ? ( + <Text + testID="repostCount" + style={ + isReposted + ? [s.bold, s.green3, s.f15, s.ml5] + : [defaultControlColor, s.f15, s.ml5] + }> + {repostCount} + </Text> + ) : undefined} + </TouchableOpacity> + ) +} + +const styles = StyleSheet.create({ + control: { + flexDirection: 'row', + alignItems: 'center', + padding: 5, + margin: -5, + }, + reposted: { + color: colors.green3, + }, + repostCount: { + color: 'currentColor', + }, +}) diff --git a/src/view/com/util/post-ctrls/RepostButton.web.tsx b/src/view/com/util/post-ctrls/RepostButton.web.tsx new file mode 100644 index 000000000..66cc0d123 --- /dev/null +++ b/src/view/com/util/post-ctrls/RepostButton.web.tsx @@ -0,0 +1,86 @@ +import React, {useMemo} from 'react' +import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' +import {RepostIcon} from 'lib/icons' +import {DropdownButton} from '../forms/DropdownButton' +import {colors} from 'lib/styles' +import {useTheme} from 'lib/ThemeContext' +import {Text} from '../text/Text' + +interface Props { + isReposted: boolean + repostCount?: number + big?: boolean + onRepost: () => void + onQuote: () => void +} + +export const RepostButton = ({ + isReposted, + repostCount, + big, + onRepost, + onQuote, +}: Props) => { + const theme = useTheme() + + const defaultControlColor = React.useMemo( + () => ({ + color: theme.palette.default.postCtrl, + }), + [theme], + ) + + const items = useMemo( + () => [ + { + label: isReposted ? 'Undo repost' : 'Repost', + icon: 'retweet' as const, + onPress: onRepost, + }, + {label: 'Quote post', icon: 'quote-left' as const, onPress: onQuote}, + ], + [isReposted, onRepost, onQuote], + ) + + return ( + <DropdownButton + type="bare" + items={items} + bottomOffset={4} + openToRight + rightOffset={-40}> + <View + style={[ + styles.control, + (isReposted + ? styles.reposted + : defaultControlColor) as StyleProp<ViewStyle>, + ]}> + <RepostIcon strokeWidth={2.4} size={big ? 24 : 20} /> + {typeof repostCount !== 'undefined' ? ( + <Text + testID="repostCount" + type={isReposted ? 'md-bold' : 'md-medium'} + style={styles.repostCount}> + {repostCount ?? 0} + </Text> + ) : undefined} + </View> + </DropdownButton> + ) +} + +const styles = StyleSheet.create({ + control: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + gap: 4, + }, + reposted: { + color: colors.green3, + }, + repostCount: { + color: 'currentColor', + }, +}) |