diff --git a/src/screens/Feeds/VibeScreen.tsx b/src/screens/Feeds/VibeScreen.tsx
index 120f781b3c..564a9c1c20 100644
--- a/src/screens/Feeds/VibeScreen.tsx
+++ b/src/screens/Feeds/VibeScreen.tsx
@@ -19,7 +19,7 @@ import Animated, {
} from 'react-native-reanimated'
import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'
import {useEvent, useEventListener} from 'expo'
-import {Image} from 'expo-image'
+import {Image, ImageStyle} from 'expo-image'
import {LinearGradient} from 'expo-linear-gradient'
import {createVideoPlayer, VideoPlayer, VideoView} from 'expo-video'
import {
@@ -54,7 +54,7 @@ import {useSetLightStatusBar} from '#/state/shell/light-status-bar'
import {List} from '#/view/com/util/List'
import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls'
import {formatTime} from '#/view/com/util/post-embeds/VideoEmbedInner/web-controls/utils'
-import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
+import {UserAvatar} from '#/view/com/util/UserAvatar'
import {Header} from '#/screens/VideoFeed/Header'
import {atoms as a, ThemeProvider, tokens, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
@@ -350,41 +350,12 @@ function VideoItem({
}) {
const postShadow = usePostShadow(post)
const {height, width} = useWindowDimensions()
- const insets = useSafeAreaInsets()
return (
+ style={[a.relative, {height, width}]}>
- {player ? (
-
- ) : (
- embed.thumbnail && (
-
- )
- )}
- {postShadow !== POST_TOMBSTONE ? (
- player && (
-
- )
- ) : (
+ {postShadow === POST_TOMBSTONE ? (
Post has been deleted
+ ) : (
+ <>
+
+ {player && (
+
+ )}
+
+ >
)}
)
}
+// TODO maybe unused
function VideoItemInner({
player,
embed,
@@ -420,44 +400,25 @@ function VideoItemInner({
embed: AppBskyEmbedVideo.View
active: boolean
}) {
- const insets = useSafeAreaInsets()
- const {status} = useEvent(player, 'statusChange', {status: player.status})
-
- const videoAspectRatio =
- (embed.aspectRatio?.width ?? 1) / (embed.aspectRatio?.height ?? 1)
-
- // if the video tall enough (tiktok/reels are 9:16) go cover mode
- const isCloseEnough = videoAspectRatio <= 9 / 16
+ // const {status} = useEvent(player, 'statusChange', {status: player.status})
return (
<>
+ {/*
+
+ */}
+
{active && player && (
)}
- {embed.thumbnail && (
-
- )}
>
)
}
@@ -467,41 +428,19 @@ function Overlay({
post,
active,
}: {
- player: VideoPlayer
+ player?: VideoPlayer
post: Shadow
active: boolean
}) {
- const insets = useSafeAreaInsets()
const t = useTheme()
const navigation = useNavigation()
- const {status} = useEvent(player, 'statusChange', {status: player.status})
- const doubleTapRef = useRef | null>(null)
- const [queueLike] = usePostLikeMutationQueue(post, 'ImmersiveVideo')
+ // const {status} = useEvent(player, 'statusChange', {status: player.status})
const seekingAnimationSV = useSharedValue(0)
const pushToProfile = useNonReactiveCallback(() => {
navigation.navigate('Profile', {name: post.author.did})
})
- const togglePlayPause = () => {
- doubleTapRef.current = null
- if (player.playing) {
- player.pause()
- } else {
- player.play()
- }
- }
-
- const onPress = () => {
- if (doubleTapRef.current) {
- clearTimeout(doubleTapRef.current)
- doubleTapRef.current = null
- queueLike()
- } else {
- doubleTapRef.current = setTimeout(togglePlayPause, 200)
- }
- }
-
const gesture = useMemo(() => {
const dragLeftGesture = Gesture.Pan()
.activeOffsetX([0, 10])
@@ -533,49 +472,43 @@ function Overlay({
<>
-
-
-
-
-
-
-
- {sanitizeDisplayName(
- post.author.displayName || post.author.handle,
- )}
-
-
- {sanitizeHandle(post.author.handle, '@')}
-
-
+
+
+
+
+
+
+
+
+
+
+
+ {sanitizeDisplayName(
+ post.author.displayName || post.author.handle,
+ )}
+
+
+ {sanitizeHandle(post.author.handle, '@')}
+
- {record?.text?.trim() && (
+
+ {record?.text?.trim() && (
+
- )}
- {record && (
+
+ )}
+ {record && (
+
- )}
-
+
+ )}
-
- {player && active ? (
-
- ) : (
-
- )}
+
+ {player && active ? (
+
+ ) : (
+
+ )}
+
+ {/*
{isAndroid && status === 'loading' && (
)}
+ */}
>
)
}
-function ExpandableRichTextView({
- value,
- authorHandle,
-}: {
- value: RichTextAPI
- authorHandle?: string
-}) {
- const {height: screenHeight} = useWindowDimensions()
- const [expanded, setExpanded] = useState(false)
- const [constrained, setConstrained] = useState(false)
- const [contentHeight, setContentHeight] = useState(0)
- const {_} = useLingui()
-
- return (
- {
- if (expanded) {
- LayoutAnimation.configureNext({
- duration: 500,
- update: {type: 'spring', springDamping: 0.6},
- })
- }
- setContentHeight(h)
- }}
- style={{height: Math.min(contentHeight, screenHeight * 0.5)}}
- contentContainerStyle={[
- a.gap_xs,
- expanded ? [a.align_start] : a.flex_row,
- ]}>
- {
- if (!constrained && evt.nativeEvent.lines.length > 1) {
- setConstrained(true)
- }
- }}
- />
- {constrained && (
-
- )}
-
- )
+/**
+ * Magic number that matches the Scrubber height
+ */
+function ScrubberPlaceholder() {
+ return
}
function Scrubber({
@@ -796,7 +677,7 @@ function Scrubber({
{
left: 0,
right: 0,
- bottom: tokens.space.xl + tokens.space._4xl + insets.bottom,
+ bottom: insets.bottom + 48,
},
timeStyle,
]}
@@ -818,15 +699,18 @@ function Scrubber({
+
{
+ if (expanded) {
+ LayoutAnimation.configureNext({
+ duration: 500,
+ update: {type: 'spring', springDamping: 0.6},
+ })
+ }
+ setContentHeight(h)
+ }}
+ style={{height: Math.min(contentHeight, screenHeight * 0.5)}}
+ contentContainerStyle={[
+ a.gap_xs,
+ expanded ? [a.align_start] : a.flex_row,
+ ]}>
+ {
+ if (!constrained && evt.nativeEvent.lines.length > 1) {
+ setConstrained(true)
+ }
+ }}
+ />
+ {constrained && (
+
+ )}
+
+ )
+}
+
+function VideoItemPlaceholder({
+ embed,
+ style,
+}: {
+ embed: AppBskyEmbedVideo.View
+ style?: ImageStyle
+}) {
+ const src = embed.thumbnail
+ return src ? (
+
+ ) : null
+}
+
+function PlayPauseTapArea({
+ player,
+ post,
+}: {
+ player?: VideoPlayer
+ post: Shadow
+}) {
+ const doubleTapRef = useRef | null>(null)
+ const [queueLike] = usePostLikeMutationQueue(post, 'ImmersiveVideo')
+ const togglePlayPause = () => {
+ if (!player) return
+ doubleTapRef.current = null
+ if (player.playing) {
+ player.pause()
+ } else {
+ player.play()
+ }
+ }
+
+ const onPress = () => {
+ if (doubleTapRef.current) {
+ clearTimeout(doubleTapRef.current)
+ doubleTapRef.current = null
+ queueLike()
+ } else {
+ doubleTapRef.current = setTimeout(togglePlayPause, 200)
+ }
+ }
+
+ return (
+
+ )
+}
+
function clamp(num: number, min: number, max: number) {
'worklet'
return Math.min(Math.max(num, min), max)
}
+
+/*
+ * If the video is taller than 9:16
+ */
+function isTallAspectRatio(aspectRatio: AppBskyEmbedVideo.View['aspectRatio']) {
+ const videoAspectRatio =
+ (aspectRatio?.width ?? 1) / (aspectRatio?.height ?? 1)
+ return videoAspectRatio <= 9 / 16
+}