add compose prompt to scrubber

This commit is contained in:
Samuel Newman
2025-01-19 18:30:29 +00:00
parent 30789bd49d
commit 19984503e4
3 changed files with 71 additions and 20 deletions
+31 -12
View File
@@ -27,14 +27,20 @@ import {tokens} from '#/alf'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
// magic number that is roughly the min height of the write reply button
// we inset the video by this amount
export const VIDEO_PLAYER_BOTTOM_INSET = 57
export function Scrubber({ export function Scrubber({
player, player,
seekingAnimationSV, seekingAnimationSV,
scrollGesture, scrollGesture,
children,
}: { }: {
player: VideoPlayer player: VideoPlayer
seekingAnimationSV: SharedValue<number> seekingAnimationSV: SharedValue<number>
scrollGesture: NativeGesture scrollGesture: NativeGesture
children?: React.ReactNode
}) { }) {
const {width: screenWidth} = useSafeAreaFrame() const {width: screenWidth} = useSafeAreaFrame()
const insets = useSafeAreaInsets() const insets = useSafeAreaInsets()
@@ -153,6 +159,11 @@ export function Scrubber({
height: seekingAnimationSV.get() * 3 + 1, height: seekingAnimationSV.get() * 3 + 1,
} }
}) })
const childrenStyle = useAnimatedStyle(() => {
return {
opacity: 1 - seekingAnimationSV.get(),
}
})
return ( return (
<> <>
@@ -162,7 +173,7 @@ export function Scrubber({
{ {
left: 0, left: 0,
right: 0, right: 0,
bottom: insets.bottom + 48, bottom: insets.bottom + 80,
}, },
timeStyle, timeStyle,
]} ]}
@@ -189,17 +200,15 @@ export function Scrubber({
a.relative, a.relative,
a.w_full, a.w_full,
a.justify_end, a.justify_end,
a.py_lg,
{ {
paddingBottom: insets.bottom, paddingBottom: insets.bottom,
paddingTop: tokens.space.md, minHeight:
height:
// bottom padding // bottom padding
insets.bottom + insets.bottom +
// actual height // scrubber height
tokens.space.xl + tokens.space.lg +
// top padding // write reply height
tokens.space.md, VIDEO_PLAYER_BOTTOM_INSET,
}, },
a.z_10, a.z_10,
]}> ]}>
@@ -219,6 +228,10 @@ export function Scrubber({
]} ]}
/> />
</View> </View>
<Animated.View
style={[{minHeight: VIDEO_PLAYER_BOTTOM_INSET}, childrenStyle]}>
{children}
</Animated.View>
</View> </View>
</GestureDetector> </GestureDetector>
</> </>
@@ -228,18 +241,24 @@ export function Scrubber({
/** /**
* Magic number that matches the Scrubber height * Magic number that matches the Scrubber height
*/ */
export function ScrubberPlaceholder() { export function ScrubberPlaceholder({children}: {children?: React.ReactNode}) {
const {bottom} = useSafeAreaInsets() const {bottom} = useSafeAreaInsets()
return ( return (
<View <View
onLayout={evt =>
console.log('placeholder', evt.nativeEvent.layout.height)
}
style={[ style={[
a.w_full, a.w_full,
a.justify_end,
{ {
// same as Scrubber // same as Scrubber
height: bottom + tokens.space.xl + tokens.space.md, minHeight: bottom + tokens.space.lg + VIDEO_PLAYER_BOTTOM_INSET,
paddingBottom: bottom,
}, },
]} ]}>
/> {children}
</View>
) )
} }
+40 -7
View File
@@ -67,8 +67,9 @@ import {
} from '#/state/queries/post-feed' } from '#/state/queries/post-feed'
import {useProfileFollowMutationQueue} from '#/state/queries/profile' import {useProfileFollowMutationQueue} from '#/state/queries/profile'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useSetMinimalShellMode} from '#/state/shell' import {useComposerControls, useSetMinimalShellMode} from '#/state/shell'
import {useSetLightStatusBar} from '#/state/shell/light-status-bar' import {useSetLightStatusBar} from '#/state/shell/light-status-bar'
import {PostThreadComposePrompt} from '#/view/com/post-thread/PostThreadComposePrompt'
import {List} from '#/view/com/util/List' import {List} from '#/view/com/util/List'
import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls' import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls'
import {UserAvatar} from '#/view/com/util/UserAvatar' import {UserAvatar} from '#/view/com/util/UserAvatar'
@@ -87,7 +88,11 @@ import {ListFooter} from '#/components/Lists'
import * as Hider from '#/components/moderation/Hider' import * as Hider from '#/components/moderation/Hider'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {Scrubber, ScrubberPlaceholder} from './components/Scrubber' import {
Scrubber,
ScrubberPlaceholder,
VIDEO_PLAYER_BOTTOM_INSET,
} from './components/Scrubber'
function createThreeVideoPlayers( function createThreeVideoPlayers(
sources?: [string, string, string], sources?: [string, string, string],
@@ -553,7 +558,12 @@ function VideoItemInner({
accessible={false} accessible={false}
style={[ style={[
a.absolute, a.absolute,
{top: 0, left: 0, right: 0, bottom}, {
top: 0,
left: 0,
right: 0,
bottom: bottom + VIDEO_PLAYER_BOTTOM_INSET,
},
isAndroid && status === 'loading' && {opacity: 0}, isAndroid && status === 'loading' && {opacity: 0},
]} ]}
player={player} player={player}
@@ -678,6 +688,7 @@ function Overlay({
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const t = useTheme() const t = useTheme()
const {openComposer} = useComposerControls()
const navigation = useNavigation<NavigationProp>() const navigation = useNavigation<NavigationProp>()
const seekingAnimationSV = useSharedValue(0) const seekingAnimationSV = useSharedValue(0)
@@ -712,6 +723,18 @@ function Overlay({
return modui return modui
}, [moderation]) }, [moderation])
const onPressReply = useCallback(() => {
openComposer({
replyTo: {
uri: post.uri,
cid: post.cid,
text: record?.text || '',
author: post.author,
embed: post.embed,
},
})
}, [openComposer, post, record])
return ( return (
<Hider.Outer modui={mergedModui}> <Hider.Outer modui={mergedModui}>
<Hider.Mask> <Hider.Mask>
@@ -826,10 +849,13 @@ function Overlay({
<Scrubber <Scrubber
player={player} player={player}
seekingAnimationSV={seekingAnimationSV} seekingAnimationSV={seekingAnimationSV}
scrollGesture={scrollGesture} scrollGesture={scrollGesture}>
/> <PostThreadComposePrompt onPressCompose={onPressReply} />
</Scrubber>
) : ( ) : (
<ScrubberPlaceholder /> <ScrubberPlaceholder>
<PostThreadComposePrompt onPressCompose={onPressReply} />
</ScrubberPlaceholder>
)} )}
</LinearGradient> </LinearGradient>
</View> </View>
@@ -937,7 +963,14 @@ function VideoItemPlaceholder({
source={{uri: src}} source={{uri: src}}
style={[ style={[
a.absolute, a.absolute,
blur ? a.inset_0 : {top: 0, left: 0, right: 0, bottom}, blur
? a.inset_0
: {
top: 0,
left: 0,
right: 0,
bottom: bottom + VIDEO_PLAYER_BOTTOM_INSET,
},
style, style,
]} ]}
contentFit={contentFit} contentFit={contentFit}
@@ -40,7 +40,6 @@ export function PostThreadComposePrompt({
t.atoms.border_contrast_low, t.atoms.border_contrast_low,
t.atoms.bg, t.atoms.bg,
]} ]}
onPressIn={ios(() => playHaptic('Light'))}
onPress={() => { onPress={() => {
onPressCompose() onPressCompose()
playHaptic('Light') playHaptic('Light')