feat: 引入手势组件
This commit is contained in:
parent
8969e45d6b
commit
e74622b009
@ -4,6 +4,7 @@ import YesSvg from "@/assets/icons/svg/yes.svg";
|
|||||||
import { TFunction } from "i18next";
|
import { TFunction } from "i18next";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FlatList, Image, Modal, StyleSheet, TouchableOpacity, View } from "react-native";
|
import { FlatList, Image, Modal, StyleSheet, TouchableOpacity, View } from "react-native";
|
||||||
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
||||||
import { ThemedText } from "../ThemedText";
|
import { ThemedText } from "../ThemedText";
|
||||||
import { mergeArrays } from "./utils";
|
import { mergeArrays } from "./utils";
|
||||||
|
|
||||||
@ -16,7 +17,11 @@ interface SelectModelProps {
|
|||||||
t: TFunction;
|
t: TFunction;
|
||||||
}
|
}
|
||||||
const SelectModel = ({ modalDetailsVisible, setModalDetailsVisible, insets, setSelectedImages, selectedImages, t }: SelectModelProps) => {
|
const SelectModel = ({ modalDetailsVisible, setModalDetailsVisible, insets, setSelectedImages, selectedImages, t }: SelectModelProps) => {
|
||||||
|
const longPressGesture = Gesture.LongPress().onEnd((e, success) => {
|
||||||
|
if (success) {
|
||||||
|
console.log(`Long pressed for ${e.duration} ms!`);
|
||||||
|
}
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
animationType="fade"
|
animationType="fade"
|
||||||
@ -63,32 +68,34 @@ const SelectModel = ({ modalDetailsVisible, setModalDetailsVisible, insets, setS
|
|||||||
style={detailsStyles.gridItemContainer}
|
style={detailsStyles.gridItemContainer}
|
||||||
key={item.id}
|
key={item.id}
|
||||||
>
|
>
|
||||||
<View style={detailsStyles.gridItem}>
|
<GestureDetector gesture={longPressGesture}>
|
||||||
<ThemedText style={detailsStyles.imageNumber}>
|
<View style={detailsStyles.gridItem}>
|
||||||
{selectedImages?.map((image, index) => {
|
<ThemedText style={detailsStyles.imageNumber}>
|
||||||
if (image === item.id || image === item.video?.id) {
|
{selectedImages?.map((image, index) => {
|
||||||
return index + 1
|
if (image === item.id || image === item.video?.id) {
|
||||||
}
|
return index + 1
|
||||||
})}
|
}
|
||||||
</ThemedText>
|
})}
|
||||||
<Image
|
</ThemedText>
|
||||||
source={{ uri: item?.preview_file_info?.url || item.video?.preview_file_info?.url }}
|
<Image
|
||||||
style={detailsStyles.image}
|
source={{ uri: item?.preview_file_info?.url || item.video?.preview_file_info?.url }}
|
||||||
onError={(error) => console.log('Image load error:', error.nativeEvent.error)}
|
style={detailsStyles.image}
|
||||||
onLoad={() => console.log('Image loaded successfully')}
|
onError={(error) => console.log('Image load error:', error.nativeEvent.error)}
|
||||||
loadingIndicatorSource={require('@/assets/images/png/placeholder.png')}
|
onLoad={() => console.log('Image loaded successfully')}
|
||||||
/>
|
loadingIndicatorSource={require('@/assets/images/png/placeholder.png')}
|
||||||
<TouchableOpacity
|
/>
|
||||||
style={[
|
<TouchableOpacity
|
||||||
detailsStyles.circleMarker,
|
style={[
|
||||||
isSelected && detailsStyles.circleMarkerSelected
|
detailsStyles.circleMarker,
|
||||||
]}
|
isSelected && detailsStyles.circleMarkerSelected
|
||||||
onPress={toggleSelection}
|
]}
|
||||||
activeOpacity={0.8}
|
onPress={toggleSelection}
|
||||||
>
|
activeOpacity={0.8}
|
||||||
{isSelected && <YesSvg width={16} height={16} />}
|
>
|
||||||
</TouchableOpacity>
|
{isSelected && <YesSvg width={16} height={16} />}
|
||||||
</View>
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</GestureDetector>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|||||||
39
provider.tsx
39
provider.tsx
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import { I18nextProvider } from "react-i18next";
|
import { I18nextProvider } from "react-i18next";
|
||||||
import { Platform } from 'react-native';
|
import { Platform } from 'react-native';
|
||||||
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
||||||
import Toast, { BaseToast, ErrorToast, ToastConfig } from 'react-native-toast-message';
|
import Toast, { BaseToast, ErrorToast, ToastConfig } from 'react-native-toast-message';
|
||||||
import { Provider as ReduxProvider } from "react-redux";
|
import { Provider as ReduxProvider } from "react-redux";
|
||||||
import { AuthProvider } from "./contexts/auth-context";
|
import { AuthProvider } from "./contexts/auth-context";
|
||||||
@ -70,24 +71,24 @@ const toastConfig: ToastConfig = {
|
|||||||
|
|
||||||
export function Provider({ children }: { children: React.ReactNode }) {
|
export function Provider({ children }: { children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||||
<I18nextProvider i18n={i18n}>
|
<I18nextProvider i18n={i18n}>
|
||||||
<LanguageProvider>
|
<LanguageProvider>
|
||||||
<ReduxProvider store={store}>
|
<ReduxProvider store={store}>
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
{children}
|
{children}
|
||||||
<Toast
|
<Toast
|
||||||
config={toastConfig}
|
config={toastConfig}
|
||||||
position={Platform.OS === 'web' ? 'top' : 'bottom'}
|
position={Platform.OS === 'web' ? 'top' : 'bottom'}
|
||||||
topOffset={Platform.OS === 'web' ? 20 : undefined}
|
topOffset={Platform.OS === 'web' ? 20 : undefined}
|
||||||
bottomOffset={Platform.OS === 'web' ? undefined : 40}
|
bottomOffset={Platform.OS === 'web' ? undefined : 40}
|
||||||
visibilityTime={3000}
|
visibilityTime={3000}
|
||||||
autoHide
|
autoHide
|
||||||
/>
|
/>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
</ReduxProvider>
|
</ReduxProvider>
|
||||||
</LanguageProvider>
|
</LanguageProvider>
|
||||||
</I18nextProvider>
|
</I18nextProvider>
|
||||||
|
</GestureHandlerRootView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user