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 {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({
player,
seekingAnimationSV,
scrollGesture,
children,
}: {
player: VideoPlayer
seekingAnimationSV: SharedValue<number>
scrollGesture: NativeGesture
children?: React.ReactNode
}) {
const {width: screenWidth} = useSafeAreaFrame()
const insets = useSafeAreaInsets()
@@ -153,6 +159,11 @@ export function Scrubber({
height: seekingAnimationSV.get() * 3 + 1,
}
})
const childrenStyle = useAnimatedStyle(() => {
return {
opacity: 1 - seekingAnimationSV.get(),
}
})
return (
<>
@@ -162,7 +173,7 @@ export function Scrubber({
{
left: 0,
right: 0,
bottom: insets.bottom + 48,
bottom: insets.bottom + 80,
},
timeStyle,
]}
@@ -189,17 +200,15 @@ export function Scrubber({
a.relative,
a.w_full,
a.justify_end,
a.py_lg,
{
paddingBottom: insets.bottom,
paddingTop: tokens.space.md,
height:
minHeight:
// bottom padding
insets.bottom +
// actual height
tokens.space.xl +
// top padding
tokens.space.md,
// scrubber height
tokens.space.lg +
// write reply height
VIDEO_PLAYER_BOTTOM_INSET,
},
a.z_10,
]}>
@@ -219,6 +228,10 @@ export function Scrubber({
]}
/>
</View>
<Animated.View
style={[{minHeight: VIDEO_PLAYER_BOTTOM_INSET}, childrenStyle]}>
{children}
</Animated.View>
</View>
</GestureDetector>
</>
@@ -228,18 +241,24 @@ export function Scrubber({
/**
* Magic number that matches the Scrubber height
*/
export function ScrubberPlaceholder() {
export function ScrubberPlaceholder({children}: {children?: React.ReactNode}) {
const {bottom} = useSafeAreaInsets()
return (
<View
onLayout={evt =>
console.log('placeholder', evt.nativeEvent.layout.height)
}
style={[
a.w_full,
a.justify_end,
{
// 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'
import {useProfileFollowMutationQueue} from '#/state/queries/profile'
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 {PostThreadComposePrompt} from '#/view/com/post-thread/PostThreadComposePrompt'
import {List} from '#/view/com/util/List'
import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls'
import {UserAvatar} from '#/view/com/util/UserAvatar'
@@ -87,7 +88,11 @@ import {ListFooter} from '#/components/Lists'
import * as Hider from '#/components/moderation/Hider'
import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
import {Scrubber, ScrubberPlaceholder} from './components/Scrubber'
import {
Scrubber,
ScrubberPlaceholder,
VIDEO_PLAYER_BOTTOM_INSET,
} from './components/Scrubber'
function createThreeVideoPlayers(
sources?: [string, string, string],
@@ -553,7 +558,12 @@ function VideoItemInner({
accessible={false}
style={[
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},
]}
player={player}
@@ -678,6 +688,7 @@ function Overlay({
}) {
const {_} = useLingui()
const t = useTheme()
const {openComposer} = useComposerControls()
const navigation = useNavigation<NavigationProp>()
const seekingAnimationSV = useSharedValue(0)
@@ -712,6 +723,18 @@ function Overlay({
return modui
}, [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 (
<Hider.Outer modui={mergedModui}>
<Hider.Mask>
@@ -826,10 +849,13 @@ function Overlay({
<Scrubber
player={player}
seekingAnimationSV={seekingAnimationSV}
scrollGesture={scrollGesture}
/>
scrollGesture={scrollGesture}>
<PostThreadComposePrompt onPressCompose={onPressReply} />
</Scrubber>
) : (
<ScrubberPlaceholder />
<ScrubberPlaceholder>
<PostThreadComposePrompt onPressCompose={onPressReply} />
</ScrubberPlaceholder>
)}
</LinearGradient>
</View>
@@ -937,7 +963,14 @@ function VideoItemPlaceholder({
source={{uri: src}}
style={[
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,
]}
contentFit={contentFit}
@@ -40,7 +40,6 @@ export function PostThreadComposePrompt({
t.atoms.border_contrast_low,
t.atoms.bg,
]}
onPressIn={ios(() => playHaptic('Light'))}
onPress={() => {
onPressCompose()
playHaptic('Light')