better android loading
This commit is contained in:
@@ -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>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user