Hide pillarboxing on vertical videos

This commit is contained in:
Alex Benzer
2026-04-19 20:14:48 -07:00
parent 5df51bdea7
commit 35cedd0001
@@ -6,7 +6,7 @@ import {
useRef, useRef,
useState, useState,
} from 'react' } from 'react'
import {View} from 'react-native' import {type DimensionValue, View} from 'react-native'
import {type AppBskyEmbedVideo} from '@atproto/api' import {type AppBskyEmbedVideo} from '@atproto/api'
import {msg} from '@lingui/core/macro' import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
@@ -15,7 +15,6 @@ import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
import {atoms as a, useTheme} 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 {ConstrainedImage} from '#/components/images/AutoSizedImage'
import {MediaInsetBorder} from '#/components/MediaInsetBorder' import {MediaInsetBorder} from '#/components/MediaInsetBorder'
import { import {
HLSUnsupportedError, HLSUnsupportedError,
@@ -74,20 +73,12 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
[key], [key],
) )
let aspectRatio: number | undefined
const dims = embed.aspectRatio const dims = embed.aspectRatio
if (dims) { // Clamp to minimum 1:2 so very tall videos don't get too narrow
aspectRatio = dims.width / dims.height const aspectRatio = dims ? Math.max(dims.width / dims.height, 0.5) || 1 : 1
if (Number.isNaN(aspectRatio)) {
aspectRatio = undefined
}
}
let constrained: number | undefined // Portrait videos are narrower than full width; landscape fills it
if (aspectRatio !== undefined) { const widthPercent: DimensionValue = `${Math.min(aspectRatio, 1) * 100}%`
const ratio = 1 / 2 // max of 1:2 ratio in feeds
constrained = Math.max(aspectRatio, ratio)
}
const contents = ( const contents = (
<div <div
@@ -98,7 +89,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
cursor: 'default', cursor: 'default',
backgroundColor: t.palette.black, backgroundColor: t.palette.black,
backgroundImage: `url(${embed.thumbnail})`, backgroundImage: `url(${embed.thumbnail})`,
backgroundSize: 'contain', backgroundSize: 'cover',
backgroundPosition: 'center', backgroundPosition: 'center',
backgroundRepeat: 'no-repeat', backgroundRepeat: 'no-repeat',
}} }}
@@ -122,15 +113,15 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
<ViewportObserver <ViewportObserver
sendPosition={isGif ? noop : sendPosition} sendPosition={isGif ? noop : sendPosition}
isAnyViewActive={currentActiveView !== null}> isAnyViewActive={currentActiveView !== null}>
<ConstrainedImage <View
fullBleed style={[
aspectRatio={constrained || 1} a.rounded_md,
// slightly smaller max height than images a.overflow_hidden,
// images use 16 / 9, for reference {width: widthPercent, aspectRatio},
minMobileAspectRatio={14 / 9}> ]}>
{contents} {contents}
<MediaInsetBorder /> <MediaInsetBorder />
</ConstrainedImage> </View>
</ViewportObserver> </ViewportObserver>
</View> </View>
) )