feat: PostControlsSkeleton (#9205)

* feat: new PostControlsSkeleton component

* feat: integrate PostControlsSkeleton into other usages

* fix: shrink skele pill and circle sizes a bit
This commit is contained in:
Elijah Seed-Arita
2025-11-04 07:02:47 -08:00
committed by GitHub
parent e1ee85622d
commit a5b2856fbc
4 changed files with 92 additions and 29 deletions
+86 -5
View File
@@ -28,6 +28,7 @@ import * as Toast from '#/view/com/util/Toast'
import {atoms as a, flatten, useBreakpoints} from '#/alf' import {atoms as a, flatten, useBreakpoints} from '#/alf'
import {Reply as Bubble} from '#/components/icons/Reply' import {Reply as Bubble} from '#/components/icons/Reply'
import {useFormatPostStatCount} from '#/components/PostControls/util' import {useFormatPostStatCount} from '#/components/PostControls/util'
import * as Skele from '#/components/Skeleton'
import {BookmarkButton} from './BookmarkButton' import {BookmarkButton} from './BookmarkButton'
import { import {
PostControlButton, PostControlButton,
@@ -188,11 +189,11 @@ let PostControls = ({
}) })
} }
const secondaryControlSpacingStyles = flatten([ const secondaryControlSpacingStyles = getSecondaryControlSpacingStyles({
{gap: 0}, // default, we want `gap` to be defined on the resulting object variant,
variant !== 'compact' && a.gap_xs, big,
(big || gtPhone) && a.gap_sm, gtPhone,
]) })
return ( return (
<View <View
@@ -336,3 +337,83 @@ let PostControls = ({
} }
PostControls = memo(PostControls) PostControls = memo(PostControls)
export {PostControls} export {PostControls}
export function PostControlsSkeleton({
big,
style,
variant,
}: {
big?: boolean
style?: StyleProp<ViewStyle>
variant?: 'compact' | 'normal' | 'large'
}) {
const {gtPhone} = useBreakpoints()
const rowHeight = big ? 32 : 28
const padding = 4
const size = rowHeight - padding * 2
const secondaryControlSpacingStyles = getSecondaryControlSpacingStyles({
variant,
big,
gtPhone,
})
const itemStyles = {
padding,
}
return (
<Skele.Row
style={[
a.flex_row,
a.justify_between,
a.align_center,
!big && a.pt_2xs,
a.gap_md,
style,
]}>
<View style={[a.flex_row, a.flex_1, {maxWidth: 320}]}>
<View
style={[itemStyles, a.flex_1, a.align_start, {marginLeft: -padding}]}>
<Skele.Pill blend size={size} />
</View>
<View style={[itemStyles, a.flex_1, a.align_start]}>
<Skele.Pill blend size={size} />
</View>
<View style={[itemStyles, a.flex_1, a.align_start]}>
<Skele.Pill blend size={size} />
</View>
</View>
<View style={[a.flex_row, a.justify_end, secondaryControlSpacingStyles]}>
<View style={itemStyles}>
<Skele.Circle blend size={size} />
</View>
<View style={itemStyles}>
<Skele.Circle blend size={size} />
</View>
<View style={itemStyles}>
<Skele.Circle blend size={size} />
</View>
</View>
</Skele.Row>
)
}
function getSecondaryControlSpacingStyles({
variant,
big,
gtPhone,
}: {
variant?: 'compact' | 'normal' | 'large'
big?: boolean
gtPhone: boolean
}) {
return flatten([
{gap: 0}, // default, we want `gap` to be defined on the resulting object
variant !== 'compact' && a.gap_xs,
(big || gtPhone) && a.gap_sm,
])
}
@@ -51,7 +51,7 @@ import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe'
import {PostAlerts} from '#/components/moderation/PostAlerts' import {PostAlerts} from '#/components/moderation/PostAlerts'
import {type AppModerationCause} from '#/components/Pills' import {type AppModerationCause} from '#/components/Pills'
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
import {PostControls} from '#/components/PostControls' import {PostControls, PostControlsSkeleton} from '#/components/PostControls'
import {useFormatPostStatCount} from '#/components/PostControls/util' import {useFormatPostStatCount} from '#/components/PostControls/util'
import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import * as Prompt from '#/components/Prompt' import * as Prompt from '#/components/Prompt'
@@ -732,13 +732,7 @@ export function ThreadItemAnchorSkeleton() {
<Skele.Text style={[a.text_sm, {width: '50%'}]} /> <Skele.Text style={[a.text_sm, {width: '50%'}]} />
<Skele.Row style={[a.justify_between]}> <PostControlsSkeleton big />
<Skele.Pill blend size={24} />
<Skele.Pill blend size={24} />
<Skele.Pill blend size={24} />
<Skele.Circle blend size={24} />
<Skele.Circle blend size={24} />
</Skele.Row>
</View> </View>
) )
} }
@@ -38,7 +38,7 @@ import {PostHider} from '#/components/moderation/PostHider'
import {type AppModerationCause} from '#/components/Pills' import {type AppModerationCause} from '#/components/Pills'
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
import {PostControls} from '#/components/PostControls' import {PostControls, PostControlsSkeleton} from '#/components/PostControls'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import * as Skele from '#/components/Skeleton' import * as Skele from '#/components/Skeleton'
import {SubtleWebHover} from '#/components/SubtleWebHover' import {SubtleWebHover} from '#/components/SubtleWebHover'
@@ -389,13 +389,7 @@ export function ThreadItemPostSkeleton({index}: {index: number}) {
)} )}
</Skele.Col> </Skele.Col>
<Skele.Row style={[a.justify_between, a.pt_xs]}> <PostControlsSkeleton />
<Skele.Pill blend size={16} />
<Skele.Pill blend size={16} />
<Skele.Pill blend size={16} />
<Skele.Circle blend size={16} />
<View />
</Skele.Row>
</Skele.Col> </Skele.Col>
</Skele.Row> </Skele.Row>
</View> </View>
@@ -37,7 +37,7 @@ import {PostHider} from '#/components/moderation/PostHider'
import {type AppModerationCause} from '#/components/Pills' import {type AppModerationCause} from '#/components/Pills'
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
import {PostControls} from '#/components/PostControls' import {PostControls, PostControlsSkeleton} from '#/components/PostControls'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import * as Skele from '#/components/Skeleton' import * as Skele from '#/components/Skeleton'
import {SubtleWebHover} from '#/components/SubtleWebHover' import {SubtleWebHover} from '#/components/SubtleWebHover'
@@ -434,13 +434,7 @@ export function ThreadItemTreePostSkeleton({index}: {index: number}) {
)} )}
</Skele.Col> </Skele.Col>
<Skele.Row style={[a.justify_between, a.pt_xs]}> <PostControlsSkeleton />
<Skele.Pill blend size={16} />
<Skele.Pill blend size={16} />
<Skele.Pill blend size={16} />
<Skele.Circle blend size={16} />
<View />
</Skele.Row>
</Skele.Col> </Skele.Col>
</Skele.Row> </Skele.Row>
</View> </View>