refactor(LocalDataSource, PostRepository, ChatScreen): enhance database handling and message loading
- Introduced a promise-based initialization mechanism in LocalDataSource to prevent concurrent initialization issues. - Updated PostRepository to utilize an enqueueWrite method for database operations, ensuring thread-safe writes. - Refactored ChatScreen to improve message loading logic, including preloading history and managing scroll behavior more effectively. - Enhanced message rendering logic to maintain correct indices in inverted lists and optimize user experience during scrolling.
This commit is contained in:
@@ -7,11 +7,12 @@ import {
|
||||
View,
|
||||
Modal,
|
||||
TouchableOpacity,
|
||||
TouchableWithoutFeedback,
|
||||
Pressable,
|
||||
Animated,
|
||||
Alert,
|
||||
Clipboard,
|
||||
Dimensions,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { chatScreenStyles as styles } from './styles';
|
||||
@@ -35,34 +36,41 @@ export const LongPressMenu: React.FC<LongPressMenuProps> = ({
|
||||
}) => {
|
||||
const scaleAnimation = useRef(new Animated.Value(0)).current;
|
||||
const opacityAnimation = useRef(new Animated.Value(0)).current;
|
||||
const blurActiveElementOnWeb = () => {
|
||||
if (Platform.OS !== 'web') return;
|
||||
const active = (globalThis as any)?.document?.activeElement as { blur?: () => void } | undefined;
|
||||
active?.blur?.();
|
||||
};
|
||||
|
||||
// 显示动画 - 缩放弹出
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
blurActiveElementOnWeb();
|
||||
Animated.parallel([
|
||||
Animated.spring(scaleAnimation, {
|
||||
toValue: 1,
|
||||
useNativeDriver: true,
|
||||
useNativeDriver: Platform.OS !== 'web',
|
||||
friction: 8,
|
||||
tension: 100,
|
||||
}),
|
||||
Animated.timing(opacityAnimation, {
|
||||
toValue: 1,
|
||||
duration: 150,
|
||||
useNativeDriver: true,
|
||||
useNativeDriver: Platform.OS !== 'web',
|
||||
}),
|
||||
]).start();
|
||||
} else {
|
||||
blurActiveElementOnWeb();
|
||||
Animated.parallel([
|
||||
Animated.timing(scaleAnimation, {
|
||||
toValue: 0,
|
||||
duration: 150,
|
||||
useNativeDriver: true,
|
||||
useNativeDriver: Platform.OS !== 'web',
|
||||
}),
|
||||
Animated.timing(opacityAnimation, {
|
||||
toValue: 0,
|
||||
duration: 150,
|
||||
useNativeDriver: true,
|
||||
useNativeDriver: Platform.OS !== 'web',
|
||||
}),
|
||||
]).start();
|
||||
}
|
||||
@@ -242,11 +250,18 @@ export const LongPressMenu: React.FC<LongPressMenuProps> = ({
|
||||
visible={visible}
|
||||
transparent
|
||||
animationType="none"
|
||||
onShow={blurActiveElementOnWeb}
|
||||
onRequestClose={onClose}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={onClose}>
|
||||
<View style={styles.qqMenuOverlay}>
|
||||
<TouchableWithoutFeedback>
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
blurActiveElementOnWeb();
|
||||
onClose();
|
||||
}}
|
||||
style={styles.qqMenuOverlay}
|
||||
>
|
||||
<View>
|
||||
<Pressable onPress={() => {}}>
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.qqMenuContainer,
|
||||
@@ -286,9 +301,9 @@ export const LongPressMenu: React.FC<LongPressMenuProps> = ({
|
||||
))}
|
||||
</View>
|
||||
</Animated.View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Pressable>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Pressable>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user