fix(ui): adjust keyboard handling and prevent duplicate view recording
All checks were successful
Frontend CI / ota-android (push) Successful in 1m21s
Frontend CI / ota-ios (push) Successful in 1m28s
Frontend CI / build-and-push-web (push) Successful in 2m56s
Frontend CI / build-android-apk (push) Successful in 2h32m37s

- Fix keyboard avoidance logic in PostDetailScreen and ChatScreen by applying manual keyboard height offsets only on Android, preventing double padding on iOS.
- Prevent multiple view recording calls in TradeDetailScreen by using a ref to track if the view has already been recorded.
This commit is contained in:
2026-05-06 12:53:39 +08:00
parent 64493baf7f
commit 7f606e14dd
4 changed files with 16 additions and 4 deletions

View File

@@ -47,6 +47,8 @@ interface PostMentionInputProps {
minHeight?: number;
autoExpand?: boolean;
onPostRefPasted?: (postId: string, title: string) => void;
onSubmitEditing?: () => void;
returnKeyType?: 'default' | 'send' | 'done';
}
const PostMentionInput: React.FC<PostMentionInputProps> = ({
@@ -59,6 +61,8 @@ const PostMentionInput: React.FC<PostMentionInputProps> = ({
minHeight = 100,
autoExpand = false,
onPostRefPasted,
onSubmitEditing,
returnKeyType = 'default',
}) => {
const colors = useAppColors();
const currentUser = useAuthStore(s => s.currentUser);
@@ -281,6 +285,9 @@ const PostMentionInput: React.FC<PostMentionInputProps> = ({
multiline
textAlignVertical="top"
scrollEnabled={!autoExpand}
returnKeyType={returnKeyType}
onSubmitEditing={onSubmitEditing}
blurOnSubmit={false}
style={[
styles.input,
autoExpand && styles.inputAutoExpand,

View File

@@ -1401,7 +1401,7 @@ export const PostDetailScreen: React.FC = () => {
{
paddingHorizontal: responsivePadding,
paddingVertical: responsiveGap,
paddingBottom: keyboardHeight + responsiveGap + insets.bottom,
paddingBottom: (Platform.OS === 'android' ? keyboardHeight : 0) + responsiveGap + insets.bottom,
}
]}>
{/* 回复提示 */}
@@ -1486,6 +1486,8 @@ export const PostDetailScreen: React.FC = () => {
minHeight={60}
autoExpand
style={styles.expandedTextInput}
returnKeyType="send"
onSubmitEditing={handleSendComment}
/>
{/* Image preview */}

View File

@@ -545,7 +545,8 @@ export const ChatScreen: React.FC<ChatScreenProps> = (props) => {
</View>
{/* 底部区域:输入框 + 面板 */}
<View style={{ marginBottom: keyboardHeight > 0 ? keyboardHeight : 0 }}>
{/* iOS 由外层 KeyboardAvoidingView(behavior=padding) 处理键盘避让Android 需要手动推起 */}
<View style={{ marginBottom: Platform.OS === 'android' && keyboardHeight > 0 ? keyboardHeight : 0 }}>
{/* 输入框区域 */}
<View
style={[inputWrapperStyle, insets.bottom > 0 && { paddingBottom: insets.bottom }]}

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import {
View,
ScrollView,
@@ -519,6 +519,7 @@ export function TradeDetailScreen({ tradeId }: TradeDetailScreenProps) {
const [item, setItem] = useState<TradeItemDetailDTO | null>(null);
const [loading, setLoading] = useState(true);
const [manageModalVisible, setManageModalVisible] = useState(false);
const hasRecordedView = useRef(false);
const [showImageModal, setShowImageModal] = useState(false);
const [selectedImageIndex, setSelectedImageIndex] = useState(0);
@@ -548,7 +549,8 @@ export function TradeDetailScreen({ tradeId }: TradeDetailScreenProps) {
}, [fetchItem]);
useEffect(() => {
if (tradeId) {
if (tradeId && !hasRecordedView.current) {
hasRecordedView.current = true;
tradeService.recordView(tradeId).catch(() => {});
}
}, [tradeId]);