Add button to controls, respace

This commit is contained in:
Eric Bailey
2025-08-22 16:23:41 -05:00
parent 0dafc2ccd6
commit 5782ce7a0e
5 changed files with 139 additions and 92 deletions
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M9.7 16.895a4 4 0 0 1 4.6 0l3.7 2.6V6.5a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v12.995l3.7-2.6Zm10.3 2.6c0 1.62-1.825 2.567-3.15 1.636l-3.7-2.6a2 2 0 0 0-2.3 0l-3.7 2.6C5.825 22.062 4 21.115 4 19.495V6.5a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v12.995Z"/></svg>

After

Width:  |  Height:  |  Size: 334 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#006AFF" d="M16 2.5a4 4 0 0 1 4 4v12.995c0 1.62-1.825 2.567-3.15 1.636l-3.7-2.6a2 2 0 0 0-2.3 0l-3.7 2.6C5.825 22.062 4 21.115 4 19.495V6.5a4 4 0 0 1 4-4h8Z"/></svg>

After

Width:  |  Height:  |  Size: 250 B

@@ -0,0 +1,28 @@
import {memo} from 'react'
import {type AppBskyFeedDefs, type AppBskyFeedPost} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {type Shadow} from '#/state/cache/post-shadow'
import {Bookmark} from '#/components/icons/Bookmark'
import {PostControlButton, PostControlButtonIcon} from './PostControlButton'
export const BookmarkButton = memo(function BookmarkButton({
big,
}: {
post: Shadow<AppBskyFeedDefs.PostView>
big?: boolean
record: AppBskyFeedPost.Record
}): React.ReactNode {
const {_} = useLingui()
return (
<PostControlButton
testID="postBookmarkBtn"
big={big}
label={_(msg`Bookmark this post`)}>
<PostControlButtonIcon icon={Bookmark} />
</PostControlButton>
)
})
+98 -92
View File
@@ -26,8 +26,9 @@ import {
} from '#/state/shell/progress-guide' } from '#/state/shell/progress-guide'
import {formatCount} from '#/view/com/util/numeric/format' import {formatCount} from '#/view/com/util/numeric/format'
import * as Toast from '#/view/com/util/Toast' import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useBreakpoints} from '#/alf' import {atoms as a} from '#/alf'
import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '#/components/icons/Bubble' import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '#/components/icons/Bubble'
import {BookmarkButton} from './BookmarkButton'
import { import {
PostControlButton, PostControlButton,
PostControlButtonIcon, PostControlButtonIcon,
@@ -67,7 +68,6 @@ let PostControls = ({
viaRepost?: {uri: string; cid: string} viaRepost?: {uri: string; cid: string}
}): React.ReactNode => { }): React.ReactNode => {
const {_, i18n} = useLingui() const {_, i18n} = useLingui()
const {gtMobile} = useBreakpoints()
const {openComposer} = useOpenComposer() const {openComposer} = useOpenComposer()
const {feedDescriptor} = useFeedFeedbackContext() const {feedDescriptor} = useFeedFeedbackContext()
const [queueLike, queueUnlike] = usePostLikeMutationQueue( const [queueLike, queueUnlike] = usePostLikeMutationQueue(
@@ -193,102 +193,108 @@ let PostControls = ({
!big && a.pt_2xs, !big && a.pt_2xs,
style, style,
]}> ]}>
<View <View style={[a.flex_row, a.justify_between, a.flex_1]}>
style={[ <View
big ? a.align_center : [a.flex_1, a.align_start, {marginLeft: -6}], style={[
replyDisabled ? {opacity: 0.5} : undefined, big ? a.align_center : [a.flex_1, a.align_start, {marginLeft: -6}],
]}> replyDisabled ? {opacity: 0.5} : undefined,
<PostControlButton ]}>
testID="replyBtn" <PostControlButton
onPress={ testID="replyBtn"
!replyDisabled ? () => requireAuth(() => onPressReply()) : undefined onPress={
} !replyDisabled
label={_( ? () => requireAuth(() => onPressReply())
msg({ : undefined
message: `Reply (${plural(post.replyCount || 0, { }
one: '# reply', label={_(
other: '# replies', msg({
})})`, message: `Reply (${plural(post.replyCount || 0, {
comment: one: '# reply',
'Accessibility label for the reply button, verb form followed by number of replies and noun form', other: '# replies',
}), })})`,
)} comment:
big={big}> 'Accessibility label for the reply button, verb form followed by number of replies and noun form',
<PostControlButtonIcon icon={Bubble} /> }),
{typeof post.replyCount !== 'undefined' && post.replyCount > 0 && ( )}
<PostControlButtonText> big={big}>
{formatCount(i18n, post.replyCount)} <PostControlButtonIcon icon={Bubble} />
</PostControlButtonText> {typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
)} <PostControlButtonText>
</PostControlButton> {formatCount(i18n, post.replyCount)}
</View> </PostControlButtonText>
<View style={big ? a.align_center : [a.flex_1, a.align_start]}> )}
<RepostButton </PostControlButton>
isReposted={!!post.viewer?.repost} </View>
repostCount={(post.repostCount ?? 0) + (post.quoteCount ?? 0)} <View style={big ? a.align_center : [a.flex_1, a.align_start]}>
onRepost={onRepost} <RepostButton
onQuote={onQuote} isReposted={!!post.viewer?.repost}
big={big} repostCount={(post.repostCount ?? 0) + (post.quoteCount ?? 0)}
embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)} onRepost={onRepost}
/> onQuote={onQuote}
</View>
<View style={big ? a.align_center : [a.flex_1, a.align_start]}>
<PostControlButton
testID="likeBtn"
big={big}
onPress={() => requireAuth(() => onPressToggleLike())}
label={
post.viewer?.like
? _(
msg({
message: `Unlike (${plural(post.likeCount || 0, {
one: '# like',
other: '# likes',
})})`,
comment:
'Accessibility label for the like button when the post has been liked, verb followed by number of likes and noun',
}),
)
: _(
msg({
message: `Like (${plural(post.likeCount || 0, {
one: '# like',
other: '# likes',
})})`,
comment:
'Accessibility label for the like button when the post has not been liked, verb form followed by number of likes and noun form',
}),
)
}>
<AnimatedLikeIcon
isLiked={Boolean(post.viewer?.like)}
big={big} big={big}
hasBeenToggled={hasLikeIconBeenToggled} embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)}
/> />
<CountWheel </View>
likeCount={post.likeCount ?? 0} <View style={big ? a.align_center : [a.flex_1, a.align_start]}>
<PostControlButton
testID="likeBtn"
big={big} big={big}
isLiked={Boolean(post.viewer?.like)} onPress={() => requireAuth(() => onPressToggleLike())}
hasBeenToggled={hasLikeIconBeenToggled} label={
/> post.viewer?.like
</PostControlButton> ? _(
</View> msg({
<View style={big ? a.align_center : [a.flex_1, a.align_start]}> message: `Unlike (${plural(post.likeCount || 0, {
<View style={[!big && a.ml_sm]}> one: '# like',
<ShareMenuButton other: '# likes',
testID="postShareBtn" })})`,
post={post} comment:
big={big} 'Accessibility label for the like button when the post has been liked, verb followed by number of likes and noun',
record={record} }),
richText={richText} )
timestamp={post.indexedAt} : _(
threadgateRecord={threadgateRecord} msg({
onShare={onShare} message: `Like (${plural(post.likeCount || 0, {
/> one: '# like',
other: '# likes',
})})`,
comment:
'Accessibility label for the like button when the post has not been liked, verb form followed by number of likes and noun form',
}),
)
}>
<AnimatedLikeIcon
isLiked={Boolean(post.viewer?.like)}
big={big}
hasBeenToggled={hasLikeIconBeenToggled}
/>
<CountWheel
likeCount={post.likeCount ?? 0}
big={big}
isLiked={Boolean(post.viewer?.like)}
hasBeenToggled={hasLikeIconBeenToggled}
/>
</PostControlButton>
</View> </View>
</View> </View>
<View <View
style={big ? a.align_center : [gtMobile && a.flex_1, a.align_start]}> style={[
a.flex_row,
a.justify_end,
a.flex_1,
big ? a.gap_sm : a.gap_xs,
]}>
<BookmarkButton post={post} big={big} record={record} />
<ShareMenuButton
testID="postShareBtn"
post={post}
big={big}
record={record}
richText={richText}
timestamp={post.indexedAt}
threadgateRecord={threadgateRecord}
onShare={onShare}
/>
<PostMenuButton <PostMenuButton
testID="postDropdownBtn" testID="postDropdownBtn"
post={post} post={post}
+11
View File
@@ -0,0 +1,11 @@
import {createSinglePathSVG} from './TEMPLATE'
// custom, not part of icon library
export const Bookmark = createSinglePathSVG({
path: 'M9.7 16.895a4 4 0 0 1 4.6 0l3.7 2.6V6.5a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v12.995l3.7-2.6Zm10.3 2.6c0 1.62-1.825 2.567-3.15 1.636l-3.7-2.6a2.001 2.001 0 0 0-2.3 0l-3.7 2.6C5.825 22.062 4 21.115 4 19.495V6.5a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v12.995Z',
})
// custom, not part of icon library
export const BookmarkFilled = createSinglePathSVG({
path: 'M16 2.5a4 4 0 0 1 4 4v12.995c0 1.62-1.825 2.567-3.15 1.636l-3.7-2.6a2.001 2.001 0 0 0-2.3 0l-3.7 2.6C5.825 22.062 4 21.115 4 19.495V6.5a4 4 0 0 1 4-4h8Z',
})