use RNKC for composer keyboard avoiding view

This commit is contained in:
Samuel Newman
2026-06-26 18:49:34 +03:00
parent 66250e45cc
commit a20afa9e43
2 changed files with 35 additions and 50 deletions
-12
View File
@@ -1969,18 +1969,6 @@
}
},
"src/view/com/composer/Composer.tsx": {
"@typescript-eslint/no-explicit-any": {
"count": 2
},
"@typescript-eslint/no-floating-promises": {
"count": 1
},
"@typescript-eslint/no-misused-promises": {
"count": 4
},
"@typescript-eslint/no-unsafe-member-access": {
"count": 2
},
"react-hooks/immutability": {
"count": 2
},
+35 -38
View File
@@ -13,7 +13,6 @@ import {
ActivityIndicator,
BackHandler,
Keyboard,
KeyboardAvoidingView,
type LayoutChangeEvent,
ScrollView,
type StyleProp,
@@ -21,6 +20,7 @@ import {
View,
type ViewStyle,
} from 'react-native'
import {KeyboardAvoidingView} from 'react-native-keyboard-controller'
// @ts-expect-error no type definition
import ProgressCircle from 'react-native-progress/Circle'
import Animated, {
@@ -71,7 +71,6 @@ import {
SUPPORTED_MIME_TYPES,
type SupportedMimeTypes,
} from '#/lib/constants'
import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {createVideoTelemetry} from '#/lib/media/video/telemetry'
import {mimeToExt} from '#/lib/media/video/util'
@@ -286,7 +285,6 @@ export const ComposePost = ({
const {data: preferences} = usePreferencesQuery()
const navigation = useNavigation<NavigationProp>()
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
const [isPublishing, setIsPublishing] = useState(false)
const [publishingStage, setPublishingStage] = useState('')
const [error, setError] = useState('')
@@ -641,7 +639,7 @@ export const ComposePost = ({
// This is async but we don't await - videos process in the background
for (const [postIndex, videoInfo] of restoredVideos) {
const postId = posts[postIndex].id
restoreVideo(postId, videoInfo)
void restoreVideo(postId, videoInfo)
}
},
[composerDispatch, restoreVideo, ax],
@@ -798,17 +796,9 @@ export const ComposePost = ({
const viewStyles = useMemo(
() => ({
paddingTop: IS_ANDROID ? insets.top : 0,
paddingBottom:
// iOS - when keyboard is closed, keep the bottom bar in the safe area
(IS_IOS && !isKeyboardVisible) ||
// Android - Android >=35 KeyboardAvoidingView adds double padding when
// keyboard is closed, so we subtract that in the offset and add it back
// here when the keyboard is open
(IS_ANDROID && isKeyboardVisible)
? insets.bottom
: 0,
paddingBottom: insets.bottom,
}),
[insets, isKeyboardVisible],
[insets.top, insets.bottom],
)
const onPressCancel = useCallback(() => {
@@ -1042,13 +1032,13 @@ export const ComposePost = ({
posts,
}
}
} catch (waitErr: any) {
} catch (waitErr) {
logger.info(`composer: waiting for app view failed`, {
safeMessage: waitErr,
})
}
} catch (e: any) {
logger.error(e, {
} catch (e) {
logger.error(e instanceof Error ? e : String(e), {
message: `Composer: create post failed`,
hasImages: filteredThread.posts.some(
p =>
@@ -1057,7 +1047,7 @@ export const ComposePost = ({
),
})
let err = cleanError(e.message)
let err = e instanceof Error ? cleanError(e.message) : String(e)
if (
e instanceof apilib.ReplyDeletedError ||
err.includes('not locate record')
@@ -1359,8 +1349,8 @@ export const ComposePost = ({
publishingStage={publishingStage}
topBarAnimatedStyle={topBarAnimatedStyle}
onCancel={onPressCancel}
onPublish={onPressPublish}
onSelectDraft={handleSelectDraft}
onPublish={() => void onPressPublish()}
onSelectDraft={draft => void handleSelectDraft(draft)}
onSaveDraft={saveCurrentDraft}
onDiscard={handleClearComposer}
isEmpty={isComposerEmpty}
@@ -1473,7 +1463,7 @@ export const ComposePost = ({
{allPostsWithinLimit && (
<Prompt.Action
cta={composerState.draftId ? l`Save changes` : l`Save draft`}
onPress={handleSaveDraft}
onPress={() => void handleSaveDraft()}
color="primary"
/>
)}
@@ -1633,7 +1623,7 @@ let ComposerPost = memo(function ComposerPost({
postId: post.id,
})
}}
onPhotoPasted={onPhotoPasted}
onPhotoPasted={uri => void onPhotoPasted(uri)}
onNewLink={onNewLink}
onError={onError}
onPressPublish={onPublish}
@@ -2124,7 +2114,7 @@ function ComposerFooter({
}),
).catch(e => {
logger.error(`createComposerImage failed`, {
safeMessage: e.message,
safeMessage: e instanceof Error ? e.message : String(e),
})
})
@@ -2361,24 +2351,31 @@ function useScrollTracker({
}
function useKeyboardVerticalOffset() {
const {top, bottom} = useSafeAreaInsets()
const insets = useSafeAreaInsets()
// Android etc
if (!IS_IOS) {
// need to account for the edge-to-edge nav bar
return bottom * -1
// the keyboardavoidingview has bottom padding to avoid being obscured by the safe area when keyboard is closed.
// however, this leads to a gap when the keyboard is open. we account for that by subtracting the bottom inset when open.
let keyboardVerticalOffset = insets.bottom * -1
// iOS requires a bit of extra offset to account for the native sheet not being at the top of the screen
if (IS_IOS) {
// they ditched the gap behaviour on 26
if (IS_LIQUID_GLASS) {
keyboardVerticalOffset += insets.top
}
// iPhone SE
else if (insets.top === 20) {
keyboardVerticalOffset += 40
}
// all other iPhones on <26
else {
keyboardVerticalOffset += insets.top + 10
}
}
// they ditched the gap behaviour on 26
if (IS_LIQUID_GLASS) {
return top
}
// iPhone SE
if (top === 20) return 40
// all other iPhones on <26
return top + 10
return keyboardVerticalOffset
}
async function whenAppViewReady(