Fix mobile markdown actions above keyboard (#4945)

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo Hong 2026-06-09 00:27:33 -04:00 committed by GitHub
parent 699bcf6478
commit b42b286879
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 3 deletions

View File

@ -123,6 +123,7 @@ import {
type MobileNewTabAgentOption,
type MobileNewTabAgentSettings
} from '../../../../src/session/mobile-new-tab-agent-options'
import { resolveMarkdownFloatingActionsBottom } from '../../../../src/session/markdown-floating-actions-layout'
import {
createMobileSessionCreateWarningState,
dismissMobileSessionCreateWarningState,
@ -411,7 +412,8 @@ function MarkdownReader({
onChange,
onSave,
onCopy,
onDiscard
onDiscard,
keyboardLift
}: {
documentId: string
doc: MarkdownDocState | undefined
@ -420,6 +422,7 @@ function MarkdownReader({
onSave: () => void
onCopy: () => void
onDiscard: () => void
keyboardLift: number
}) {
if (!doc || doc.status === 'loading') {
return (
@ -461,7 +464,21 @@ function MarkdownReader({
onChange={onChange}
/>
{showFloatingActions ? (
<View pointerEvents="box-none" style={styles.markdownFloatingBar}>
<View
pointerEvents="box-none"
style={[
styles.markdownFloatingBar,
// Why: the editor focus lives inside a WebView, so keep native
// Save/Discard controls lifted instead of resizing that surface.
{
bottom: resolveMarkdownFloatingActionsBottom({
keyboardLift,
restingBottom: spacing.lg,
liftedClearance: spacing.md
})
}
]}
>
{statusText ? (
<Text
style={[styles.markdownFloatingStatus, doc.saveError ? styles.markdownError : null]}
@ -3935,7 +3952,7 @@ export default function SessionScreen() {
</View>
</View>
) : activeMarkdownTab ? (
<View style={[styles.markdownFrame, { paddingBottom: keyboardLift }]}>
<View style={styles.markdownFrame}>
<MarkdownReader
documentId={activeMarkdownTab.id}
doc={markdownDocs.get(activeMarkdownTab.id)}
@ -3944,6 +3961,7 @@ export default function SessionScreen() {
onSave={() => void saveMarkdownTab(activeMarkdownTab)}
onCopy={() => void copyMarkdownLocalContent(activeMarkdownTab.id)}
onDiscard={() => discardMarkdownLocalContent(activeMarkdownTab)}
keyboardLift={keyboardLift}
/>
{toastMessage && (
<Animated.View pointerEvents="none" style={[styles.toast, toastAnimatedStyle]}>

View File

@ -0,0 +1,24 @@
import { describe, expect, it } from 'vitest'
import { resolveMarkdownFloatingActionsBottom } from './markdown-floating-actions-layout'
describe('resolveMarkdownFloatingActionsBottom', () => {
it('keeps markdown actions at their resting bottom when the keyboard is closed', () => {
expect(
resolveMarkdownFloatingActionsBottom({
keyboardLift: 0,
restingBottom: 16,
liftedClearance: 12
})
).toBe(16)
})
it('raises markdown actions above the keyboard with clearance', () => {
expect(
resolveMarkdownFloatingActionsBottom({
keyboardLift: 291,
restingBottom: 16,
liftedClearance: 12
})
).toBe(303)
})
})

View File

@ -0,0 +1,11 @@
export function resolveMarkdownFloatingActionsBottom({
keyboardLift,
restingBottom,
liftedClearance
}: {
keyboardLift: number
restingBottom: number
liftedClearance: number
}): number {
return keyboardLift > 0 ? keyboardLift + liftedClearance : restingBottom
}