fix(ui): adjust keyboard handling and prevent duplicate view recording
- 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:
@@ -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,
|
||||
|
||||
@@ -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 */}
|
||||
|
||||
@@ -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 }]}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user