better android loading

This commit is contained in:
Samuel Newman
2025-01-16 00:38:16 +00:00
parent a8721e02e9
commit 4a173e5fd0
+84 -55
View File
@@ -10,9 +10,15 @@ import {
import {Gesture, GestureDetector} from 'react-native-gesture-handler' import {Gesture, GestureDetector} from 'react-native-gesture-handler'
import {runOnJS} from 'react-native-reanimated' import {runOnJS} from 'react-native-reanimated'
import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context' import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'
import {useEvent} from 'expo'
import {Image} from 'expo-image' import {Image} from 'expo-image'
import {LinearGradient} from 'expo-linear-gradient' import {LinearGradient} from 'expo-linear-gradient'
import {useVideoPlayer, VideoPlayer, VideoView} from 'expo-video' import {
useVideoPlayer,
VideoPlayer,
VideoPlayerStatus,
VideoView,
} from 'expo-video'
import { import {
AppBskyEmbedVideo, AppBskyEmbedVideo,
AppBskyFeedDefs, AppBskyFeedDefs,
@@ -45,6 +51,7 @@ import {atoms as a, ThemeProvider, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button' import {Button, ButtonText} from '#/components/Button'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
import {ListFooter} from '#/components/Lists' import {ListFooter} from '#/components/Lists'
import {Loader} from '#/components/Loader'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
@@ -268,6 +275,8 @@ function VibeItem({
// set the video to be cover rather than contain // set the video to be cover rather than contain
const isCloseEnough = videoAspectRatio < screenAspectRatio * 1.2 const isCloseEnough = videoAspectRatio < screenAspectRatio * 1.2
const {status} = useEvent(player, 'statusChange', {status: player.status})
return ( return (
<View <View
style={{ style={{
@@ -292,7 +301,7 @@ function VibeItem({
a.flex_1, a.flex_1,
a.absolute, a.absolute,
{ {
zIndex: -1, zIndex: status === 'loading' ? 1 : -1,
top: 0, top: 0,
left: insets.left, left: insets.left,
right: insets.right, right: insets.right,
@@ -302,7 +311,7 @@ function VibeItem({
contentFit={isCloseEnough ? 'cover' : 'contain'} contentFit={isCloseEnough ? 'cover' : 'contain'}
/> />
)} )}
<VibeOverlay player={player} post={post} /> <VibeOverlay player={player} post={post} status={status} />
</SafeAreaView> </SafeAreaView>
</View> </View>
) )
@@ -311,9 +320,11 @@ function VibeItem({
function VibeOverlay({ function VibeOverlay({
player, player,
post, post,
status,
}: { }: {
player: VideoPlayer player: VideoPlayer
post: AppBskyFeedDefs.PostView post: AppBskyFeedDefs.PostView
status: VideoPlayerStatus
}) { }) {
const postShadow = usePostShadow(post) const postShadow = usePostShadow(post)
const insets = useSafeAreaInsets() const insets = useSafeAreaInsets()
@@ -357,59 +368,77 @@ function VibeOverlay({
}) })
return ( return (
<GestureDetector gesture={gesture}> <>
<View style={[a.absolute, a.inset_0, {bottom: insets.bottom}]}> <GestureDetector gesture={gesture}>
<Button <View style={[a.absolute, a.inset_0, {bottom: insets.bottom}]}>
label="Toggle play/pause" <Button
onPress={togglePlayPause} label="Toggle play/pause"
style={[a.flex_1]}> onPress={togglePlayPause}
<View /> style={[a.flex_1]}>
</Button> <View />
<LinearGradient </Button>
colors={ <LinearGradient
expanded colors={
? ['rgba(0,0,0,0)', 'rgba(0,0,0,0.6)', 'rgba(0,0,0,0.8)'] expanded
: ['rgba(0,0,0,0)', 'rgba(0,0,0,0.8)'] ? ['rgba(0,0,0,0)', 'rgba(0,0,0,0.6)', 'rgba(0,0,0,0.8)']
} : ['rgba(0,0,0,0)', 'rgba(0,0,0,0.8)']
style={[a.w_full, a.px_xl, a.py_sm, a.gap_sm]}> }
<View style={[a.flex_row, a.gap_md, a.align_center]}> style={[a.w_full, a.px_xl, a.py_sm, a.gap_sm]}>
<PreviewableUserAvatar profile={post.author} size={32} /> <View style={[a.flex_row, a.gap_md, a.align_center]}>
<View> <PreviewableUserAvatar profile={post.author} size={32} />
<Text style={[a.text_md, a.font_heavy]} emoji numberOfLines={1}> <View>
{sanitizeDisplayName( <Text style={[a.text_md, a.font_heavy]} emoji numberOfLines={1}>
post.author.displayName || post.author.handle, {sanitizeDisplayName(
)} post.author.displayName || post.author.handle,
</Text> )}
<Text </Text>
style={[a.text_sm, t.atoms.text_contrast_high]} <Text
numberOfLines={1}> style={[a.text_sm, t.atoms.text_contrast_high]}
{sanitizeHandle(post.author.handle, '@')} numberOfLines={1}>
</Text> {sanitizeHandle(post.author.handle, '@')}
</Text>
</View>
</View> </View>
</View> {record?.text?.trim() && (
{record?.text?.trim() && ( <ExpandableRichTextView
<ExpandableRichTextView expanded={expanded}
expanded={expanded} setExpanded={setExpanded}
setExpanded={setExpanded} value={richText}
value={richText} authorHandle={post.author.handle}
authorHandle={post.author.handle} />
/> )}
)} {postShadow !== POST_TOMBSTONE && record && (
{postShadow !== POST_TOMBSTONE && record && ( <PostCtrls
<PostCtrls richText={richText}
richText={richText} post={postShadow}
post={postShadow} record={record}
record={record} logContext="FeedItem"
logContext="FeedItem" onPressReply={() =>
onPressReply={() => navigation.navigate('PostThread', {
navigation.navigate('PostThread', {name: post.author.did, rkey}) name: post.author.did,
} rkey,
big })
/> }
)} big
</LinearGradient> />
</View> )}
</GestureDetector> </LinearGradient>
</View>
</GestureDetector>
{status === 'loading' && (
<View
style={[
a.absolute,
a.inset_0,
a.align_center,
a.justify_center,
a.z_10,
]}
pointerEvents="none">
<Loader size="2xl" />
</View>
)}
</>
) )
} }