vibe controls
This commit is contained in:
committed by
Eric Bailey
parent
a4a5b57adf
commit
6b10ccf3da
@@ -27,6 +27,7 @@ import {useA11y} from '#/state/a11y'
|
||||
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||
import {List, ListMethods, ListProps} from '#/view/com/util/List'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {useThemeName} from '#/alf/util/useColorModeTheme'
|
||||
import {Context, useDialogContext} from '#/components/Dialog/context'
|
||||
import {
|
||||
DialogControlProps,
|
||||
@@ -55,7 +56,8 @@ export function Outer({
|
||||
nativeOptions,
|
||||
testID,
|
||||
}: React.PropsWithChildren<DialogOuterProps>) {
|
||||
const t = useTheme()
|
||||
const themeName = useThemeName()
|
||||
const t = useTheme(themeName)
|
||||
const ref = React.useRef<BottomSheetNativeComponent>(null)
|
||||
const closeCallbacks = React.useRef<(() => void)[]>([])
|
||||
const {setDialogIsOpen, setFullyExpandedCount} =
|
||||
|
||||
@@ -131,16 +131,16 @@ export type LogEvents = {
|
||||
doesPosterFollowLiker: boolean | undefined
|
||||
likerClout: number | undefined
|
||||
postClout: number | undefined
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'Vibe'
|
||||
}
|
||||
'post:repost': {
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'Vibe'
|
||||
}
|
||||
'post:unlike': {
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'Vibe'
|
||||
}
|
||||
'post:unrepost': {
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'Vibe'
|
||||
}
|
||||
'post:mute': {}
|
||||
'post:unmute': {}
|
||||
|
||||
@@ -10,8 +10,15 @@ import {runOnJS} from 'react-native-reanimated'
|
||||
import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {useEvent} from 'expo'
|
||||
import {BlurView} from 'expo-blur'
|
||||
import {LinearGradient} from 'expo-linear-gradient'
|
||||
import {useVideoPlayer, VideoPlayer, VideoView} from 'expo-video'
|
||||
import {AppBskyEmbedVideo, AppBskyFeedDefs} from '@atproto/api'
|
||||
import {
|
||||
AppBskyEmbedVideo,
|
||||
AppBskyFeedDefs,
|
||||
AppBskyFeedPost,
|
||||
AtUri,
|
||||
RichText as RichTextAPI,
|
||||
} from '@atproto/api'
|
||||
import {Trans} from '@lingui/macro'
|
||||
import {
|
||||
useFocusEffect,
|
||||
@@ -23,14 +30,21 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
import {VIBES_FEED_URI} from '#/lib/constants'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {POST_TOMBSTONE, usePostShadow} from '#/state/cache/post-shadow'
|
||||
import {FeedPostSliceItem, usePostFeedQuery} from '#/state/queries/post-feed'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useSetLightStatusBar} from '#/state/shell/light-status-bar'
|
||||
import {List} from '#/view/com/util/List'
|
||||
import {atoms as a, ThemeProvider} from '#/alf'
|
||||
import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls'
|
||||
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
|
||||
import {atoms as a, ThemeProvider, useTheme} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {ListFooter} from '#/components/Lists'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'TempVibe'>
|
||||
export function VibeScreen({}: Props) {
|
||||
@@ -121,7 +135,7 @@ function YoloFeed({headerHeight}: {headerHeight: number}) {
|
||||
player={player}
|
||||
post={post}
|
||||
embed={post.embed}
|
||||
loaded={Math.abs(index - currentIndex) < 2}
|
||||
loaded={isFocused && Math.abs(index - currentIndex) < 2}
|
||||
active={isFocused && index === currentIndex}
|
||||
headerHeight={headerHeight}
|
||||
/>
|
||||
@@ -172,6 +186,7 @@ function keyExtractor(item: FeedPostSliceItem) {
|
||||
|
||||
function VibeItem({
|
||||
player,
|
||||
post,
|
||||
embed,
|
||||
active,
|
||||
loaded,
|
||||
@@ -240,16 +255,25 @@ function VibeItem({
|
||||
nativeControls={false}
|
||||
/>
|
||||
)}
|
||||
<VibeOverlay player={player} />
|
||||
<VibeOverlay player={player} post={post} />
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
function VibeOverlay({player}: {player: VideoPlayer}) {
|
||||
function VibeOverlay({
|
||||
player,
|
||||
post,
|
||||
}: {
|
||||
player: VideoPlayer
|
||||
post: AppBskyFeedDefs.PostView
|
||||
}) {
|
||||
const postShadow = usePostShadow(post)
|
||||
const insets = useSafeAreaInsets()
|
||||
const t = useTheme()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
const pushToProfile = useNonReactiveCallback(() => {
|
||||
navigation.navigate('Profile', {name: 'lulaoficial.bsky.social'})
|
||||
navigation.navigate('Profile', {name: post.author.did})
|
||||
})
|
||||
|
||||
const togglePlayPause = () => {
|
||||
@@ -276,16 +300,60 @@ function VibeOverlay({player}: {player: VideoPlayer}) {
|
||||
return dragLeftGesture
|
||||
}, [pushToProfile])
|
||||
|
||||
const rkey = new AtUri(post.uri).rkey
|
||||
const record = AppBskyFeedPost.isRecord(post.record) ? post.record : undefined
|
||||
const richText = new RichTextAPI({
|
||||
text: record?.text || '',
|
||||
facets: record?.facets,
|
||||
})
|
||||
|
||||
return (
|
||||
<View style={[a.absolute, a.inset_0]}>
|
||||
<GestureDetector gesture={gesture}>
|
||||
<GestureDetector gesture={gesture}>
|
||||
<View style={[a.absolute, a.inset_0, {bottom: insets.bottom}]}>
|
||||
<Button
|
||||
label="Toggle play/pause"
|
||||
onPress={togglePlayPause}
|
||||
style={[a.flex_1]}>
|
||||
<View />
|
||||
</Button>
|
||||
</GestureDetector>
|
||||
</View>
|
||||
<LinearGradient
|
||||
colors={['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]}>
|
||||
<PreviewableUserAvatar profile={post.author} size={32} />
|
||||
<View>
|
||||
<Text style={[a.text_md, a.font_heavy]} numberOfLines={1}>
|
||||
{sanitizeDisplayName(
|
||||
post.author.displayName || post.author.handle,
|
||||
)}
|
||||
</Text>
|
||||
<Text
|
||||
style={[a.text_sm, t.atoms.text_contrast_high]}
|
||||
numberOfLines={1}>
|
||||
{sanitizeHandle(post.author.handle, '@')}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<RichText
|
||||
value={richText}
|
||||
style={[a.text_sm]}
|
||||
authorHandle={post.author.handle}
|
||||
enableTags
|
||||
/>
|
||||
{postShadow !== POST_TOMBSTONE && record && (
|
||||
<PostCtrls
|
||||
richText={richText}
|
||||
post={postShadow}
|
||||
record={record}
|
||||
logContext="FeedItem"
|
||||
onPressReply={() =>
|
||||
navigation.navigate('PostThread', {name: post.author.did, rkey})
|
||||
}
|
||||
big
|
||||
/>
|
||||
)}
|
||||
</LinearGradient>
|
||||
</View>
|
||||
</GestureDetector>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ let PostCtrls = ({
|
||||
style?: StyleProp<ViewStyle>
|
||||
onPressReply: () => void
|
||||
onPostReply?: (postUri: string | undefined) => void
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'Vibe'
|
||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||
}): React.ReactNode => {
|
||||
const t = useTheme()
|
||||
|
||||
Reference in New Issue
Block a user