Constraint video max height to 14/9 (#8611)

* constraint video max height to 14/9

* Apply new default to web video embed too

* Retain web handling

* Rename prop for clarity

* Align no-crop handling on native/web

* make it always constrained

---------

Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
Samuel Newman
2025-09-23 17:24:31 +03:00
committed by GitHub
parent be324432bd
commit 6d85fe05d1
4 changed files with 24 additions and 7 deletions
@@ -71,7 +71,10 @@ export function VideoEmbed({embed, crop}: Props) {
) : ( ) : (
<ConstrainedImage <ConstrainedImage
fullBleed={crop === 'square'} fullBleed={crop === 'square'}
aspectRatio={constrained || 1}> aspectRatio={constrained || 1}
// slightly smaller max height than images
// images use 16 / 9, for reference
minMobileAspectRatio={14 / 9}>
{contents} {contents}
</ConstrainedImage> </ConstrainedImage>
)} )}
@@ -14,7 +14,7 @@ import {useLingui} from '@lingui/react'
import {isFirefox} from '#/lib/browser' import {isFirefox} from '#/lib/browser'
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
import {ConstrainedImage} from '#/view/com/util/images/AutoSizedImage' import {ConstrainedImage} from '#/view/com/util/images/AutoSizedImage'
import {atoms as a} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {useIsWithinMessage} from '#/components/dms/MessageContext' import {useIsWithinMessage} from '#/components/dms/MessageContext'
import {useFullscreen} from '#/components/hooks/useFullscreen' import {useFullscreen} from '#/components/hooks/useFullscreen'
import { import {
@@ -32,6 +32,7 @@ export function VideoEmbed({
embed: AppBskyEmbedVideo.View embed: AppBskyEmbedVideo.View
crop?: 'none' | 'square' | 'constrained' crop?: 'none' | 'square' | 'constrained'
}) { }) {
const t = useTheme()
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
const {active, setActive, sendPosition, currentActiveView} = const {active, setActive, sendPosition, currentActiveView} =
useActiveVideoWeb() useActiveVideoWeb()
@@ -114,13 +115,24 @@ export function VideoEmbed({
sendPosition={sendPosition} sendPosition={sendPosition}
isAnyViewActive={currentActiveView !== null}> isAnyViewActive={currentActiveView !== null}>
{cropDisabled ? ( {cropDisabled ? (
<View style={[a.w_full, a.overflow_hidden, {aspectRatio: max ?? 1}]}> <View
style={[
a.w_full,
a.overflow_hidden,
{aspectRatio: max ?? 1},
a.rounded_md,
a.overflow_hidden,
t.atoms.bg_contrast_25,
]}>
{contents} {contents}
</View> </View>
) : ( ) : (
<ConstrainedImage <ConstrainedImage
fullBleed={crop === 'square'} fullBleed={crop === 'square'}
aspectRatio={constrained || 1}> aspectRatio={constrained || 1}
// slightly smaller max height than images
// images use 16 / 9, for reference
minMobileAspectRatio={14 / 9}>
{contents} {contents}
</ConstrainedImage> </ConstrainedImage>
)} )}
+1 -1
View File
@@ -112,7 +112,7 @@ function MediaEmbed({
<ContentHider <ContentHider
modui={rest.moderation?.ui('contentMedia')} modui={rest.moderation?.ui('contentMedia')}
activeStyle={[a.mt_sm]}> activeStyle={[a.mt_sm]}>
<VideoEmbed embed={embed.view} /> <VideoEmbed embed={embed.view} crop="constrained" />
</ContentHider> </ContentHider>
) )
} }
+4 -2
View File
@@ -21,9 +21,11 @@ export function ConstrainedImage({
aspectRatio, aspectRatio,
fullBleed, fullBleed,
children, children,
minMobileAspectRatio,
}: { }: {
aspectRatio: number aspectRatio: number
fullBleed?: boolean fullBleed?: boolean
minMobileAspectRatio?: number
children: React.ReactNode children: React.ReactNode
}) { }) {
const t = useTheme() const t = useTheme()
@@ -35,10 +37,10 @@ export function ConstrainedImage({
const outerAspectRatio = React.useMemo<DimensionValue>(() => { const outerAspectRatio = React.useMemo<DimensionValue>(() => {
const ratio = const ratio =
isNative || !gtMobile isNative || !gtMobile
? Math.min(1 / aspectRatio, 16 / 9) // 9:16 bounding box ? Math.min(1 / aspectRatio, minMobileAspectRatio ?? 16 / 9) // 9:16 bounding box
: Math.min(1 / aspectRatio, 1) // 1:1 bounding box : Math.min(1 / aspectRatio, 1) // 1:1 bounding box
return `${ratio * 100}%` return `${ratio * 100}%`
}, [aspectRatio, gtMobile]) }, [aspectRatio, gtMobile, minMobileAspectRatio])
return ( return (
<View style={[a.w_full]}> <View style={[a.w_full]}>