Add button to controls, respace
This commit is contained in:
@@ -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 |
@@ -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>
|
||||
)
|
||||
})
|
||||
@@ -26,8 +26,9 @@ import {
|
||||
} from '#/state/shell/progress-guide'
|
||||
import {formatCount} from '#/view/com/util/numeric/format'
|
||||
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 {BookmarkButton} from './BookmarkButton'
|
||||
import {
|
||||
PostControlButton,
|
||||
PostControlButtonIcon,
|
||||
@@ -67,7 +68,6 @@ let PostControls = ({
|
||||
viaRepost?: {uri: string; cid: string}
|
||||
}): React.ReactNode => {
|
||||
const {_, i18n} = useLingui()
|
||||
const {gtMobile} = useBreakpoints()
|
||||
const {openComposer} = useOpenComposer()
|
||||
const {feedDescriptor} = useFeedFeedbackContext()
|
||||
const [queueLike, queueUnlike] = usePostLikeMutationQueue(
|
||||
@@ -193,102 +193,108 @@ let PostControls = ({
|
||||
!big && a.pt_2xs,
|
||||
style,
|
||||
]}>
|
||||
<View
|
||||
style={[
|
||||
big ? a.align_center : [a.flex_1, a.align_start, {marginLeft: -6}],
|
||||
replyDisabled ? {opacity: 0.5} : undefined,
|
||||
]}>
|
||||
<PostControlButton
|
||||
testID="replyBtn"
|
||||
onPress={
|
||||
!replyDisabled ? () => requireAuth(() => onPressReply()) : undefined
|
||||
}
|
||||
label={_(
|
||||
msg({
|
||||
message: `Reply (${plural(post.replyCount || 0, {
|
||||
one: '# reply',
|
||||
other: '# replies',
|
||||
})})`,
|
||||
comment:
|
||||
'Accessibility label for the reply button, verb form followed by number of replies and noun form',
|
||||
}),
|
||||
)}
|
||||
big={big}>
|
||||
<PostControlButtonIcon icon={Bubble} />
|
||||
{typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
|
||||
<PostControlButtonText>
|
||||
{formatCount(i18n, post.replyCount)}
|
||||
</PostControlButtonText>
|
||||
)}
|
||||
</PostControlButton>
|
||||
</View>
|
||||
<View style={big ? a.align_center : [a.flex_1, a.align_start]}>
|
||||
<RepostButton
|
||||
isReposted={!!post.viewer?.repost}
|
||||
repostCount={(post.repostCount ?? 0) + (post.quoteCount ?? 0)}
|
||||
onRepost={onRepost}
|
||||
onQuote={onQuote}
|
||||
big={big}
|
||||
embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)}
|
||||
/>
|
||||
</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)}
|
||||
<View style={[a.flex_row, a.justify_between, a.flex_1]}>
|
||||
<View
|
||||
style={[
|
||||
big ? a.align_center : [a.flex_1, a.align_start, {marginLeft: -6}],
|
||||
replyDisabled ? {opacity: 0.5} : undefined,
|
||||
]}>
|
||||
<PostControlButton
|
||||
testID="replyBtn"
|
||||
onPress={
|
||||
!replyDisabled
|
||||
? () => requireAuth(() => onPressReply())
|
||||
: undefined
|
||||
}
|
||||
label={_(
|
||||
msg({
|
||||
message: `Reply (${plural(post.replyCount || 0, {
|
||||
one: '# reply',
|
||||
other: '# replies',
|
||||
})})`,
|
||||
comment:
|
||||
'Accessibility label for the reply button, verb form followed by number of replies and noun form',
|
||||
}),
|
||||
)}
|
||||
big={big}>
|
||||
<PostControlButtonIcon icon={Bubble} />
|
||||
{typeof post.replyCount !== 'undefined' && post.replyCount > 0 && (
|
||||
<PostControlButtonText>
|
||||
{formatCount(i18n, post.replyCount)}
|
||||
</PostControlButtonText>
|
||||
)}
|
||||
</PostControlButton>
|
||||
</View>
|
||||
<View style={big ? a.align_center : [a.flex_1, a.align_start]}>
|
||||
<RepostButton
|
||||
isReposted={!!post.viewer?.repost}
|
||||
repostCount={(post.repostCount ?? 0) + (post.quoteCount ?? 0)}
|
||||
onRepost={onRepost}
|
||||
onQuote={onQuote}
|
||||
big={big}
|
||||
hasBeenToggled={hasLikeIconBeenToggled}
|
||||
embeddingDisabled={Boolean(post.viewer?.embeddingDisabled)}
|
||||
/>
|
||||
<CountWheel
|
||||
likeCount={post.likeCount ?? 0}
|
||||
</View>
|
||||
<View style={big ? a.align_center : [a.flex_1, a.align_start]}>
|
||||
<PostControlButton
|
||||
testID="likeBtn"
|
||||
big={big}
|
||||
isLiked={Boolean(post.viewer?.like)}
|
||||
hasBeenToggled={hasLikeIconBeenToggled}
|
||||
/>
|
||||
</PostControlButton>
|
||||
</View>
|
||||
<View style={big ? a.align_center : [a.flex_1, a.align_start]}>
|
||||
<View style={[!big && a.ml_sm]}>
|
||||
<ShareMenuButton
|
||||
testID="postShareBtn"
|
||||
post={post}
|
||||
big={big}
|
||||
record={record}
|
||||
richText={richText}
|
||||
timestamp={post.indexedAt}
|
||||
threadgateRecord={threadgateRecord}
|
||||
onShare={onShare}
|
||||
/>
|
||||
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}
|
||||
hasBeenToggled={hasLikeIconBeenToggled}
|
||||
/>
|
||||
<CountWheel
|
||||
likeCount={post.likeCount ?? 0}
|
||||
big={big}
|
||||
isLiked={Boolean(post.viewer?.like)}
|
||||
hasBeenToggled={hasLikeIconBeenToggled}
|
||||
/>
|
||||
</PostControlButton>
|
||||
</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
|
||||
testID="postDropdownBtn"
|
||||
post={post}
|
||||
|
||||
@@ -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',
|
||||
})
|
||||
Reference in New Issue
Block a user