keyboard scroll
This commit is contained in:
@@ -25,15 +25,16 @@ import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
KeyboardAvoidingView,
|
Keyboard,
|
||||||
Platform,
|
|
||||||
ScrollView,
|
ScrollView,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
TouchableWithoutFeedback,
|
||||||
|
View
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
|
||||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||||
import { auth_api } from '../login/lib/api';
|
import { auth_api } from '../login/lib/api';
|
||||||
import PhonePrefix from '../login/ui/PhonePrefix';
|
import PhonePrefix from '../login/ui/PhonePrefix';
|
||||||
@@ -360,27 +361,27 @@ export default function RegisterFormScreen() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAwareScrollView
|
||||||
behavior="padding"
|
showsVerticalScrollIndicator={false}
|
||||||
style={{ flex: 1 }}
|
keyboardShouldPersistTaps="handled"
|
||||||
|
enableOnAndroid
|
||||||
|
extraScrollHeight={120}
|
||||||
>
|
>
|
||||||
<View style={styles.container}>
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||||
<LinearGradient
|
<View style={styles.container}>
|
||||||
colors={['#0f172a', '#1e293b', '#334155']}
|
<LinearGradient
|
||||||
start={{ x: 0, y: 0 }}
|
colors={['#0f172a', '#1e293b', '#334155']}
|
||||||
end={{ x: 1, y: 1 }}
|
start={{ x: 0, y: 0 }}
|
||||||
style={StyleSheet.absoluteFill}
|
end={{ x: 1, y: 1 }}
|
||||||
/>
|
style={StyleSheet.absoluteFill}
|
||||||
<View style={styles.decorCircle1} />
|
/>
|
||||||
<View style={styles.decorCircle2} />
|
<View style={styles.decorCircle1} />
|
||||||
|
<View style={styles.decorCircle2} />
|
||||||
|
|
||||||
<AuthHeader />
|
<AuthHeader />
|
||||||
|
|
||||||
|
<SafeAreaView style={{ flex: 1 }} edges={['bottom']}>
|
||||||
|
|
||||||
<SafeAreaView style={{ flex: 1 }} edges={['bottom']}>
|
|
||||||
<KeyboardAvoidingView
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
|
||||||
>
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={styles.scrollContent}
|
contentContainerStyle={styles.scrollContent}
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
@@ -647,90 +648,90 @@ export default function RegisterFormScreen() {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</KeyboardAvoidingView>
|
</SafeAreaView>
|
||||||
</SafeAreaView>
|
|
||||||
|
|
||||||
{/* ---- Country BottomSheet ---- */}
|
{/* ---- Country BottomSheet ---- */}
|
||||||
<BottomSheet
|
<BottomSheet
|
||||||
ref={countrySheetRef}
|
ref={countrySheetRef}
|
||||||
index={-1}
|
index={-1}
|
||||||
snapPoints={snapPoints}
|
snapPoints={snapPoints}
|
||||||
enablePanDownToClose={true}
|
enablePanDownToClose={true}
|
||||||
enableDynamicSizing={false}
|
enableDynamicSizing={false}
|
||||||
enableOverDrag={false}
|
enableOverDrag={false}
|
||||||
backdropComponent={renderBackdrop}
|
backdropComponent={renderBackdrop}
|
||||||
backgroundStyle={styles.bottomSheetBg}
|
backgroundStyle={styles.bottomSheetBg}
|
||||||
handleIndicatorStyle={styles.handleIndicator}
|
handleIndicatorStyle={styles.handleIndicator}
|
||||||
android_keyboardInputMode="adjustResize"
|
android_keyboardInputMode="adjustResize"
|
||||||
keyboardBehavior="interactive"
|
keyboardBehavior="interactive"
|
||||||
keyboardBlurBehavior="restore"
|
keyboardBlurBehavior="restore"
|
||||||
>
|
>
|
||||||
<View style={styles.sheetHeader}>
|
<View style={styles.sheetHeader}>
|
||||||
<Text style={styles.sheetTitle}>{t('Davlat')}</Text>
|
<Text style={styles.sheetTitle}>{t('Davlat')}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Search input */}
|
{/* Search input */}
|
||||||
<View style={styles.searchContainer}>
|
<View style={styles.searchContainer}>
|
||||||
<Search size={16} color="#94a3b8" />
|
<Search size={16} color="#94a3b8" />
|
||||||
<BottomSheetTextInput
|
<BottomSheetTextInput
|
||||||
value={countrySearch}
|
value={countrySearch}
|
||||||
onChangeText={setCountrySearch}
|
onChangeText={setCountrySearch}
|
||||||
placeholder={t('Qidirish...')}
|
placeholder={t('Qidirish...')}
|
||||||
placeholderTextColor="#94a3b8"
|
placeholderTextColor="#94a3b8"
|
||||||
style={styles.searchInput}
|
style={styles.searchInput}
|
||||||
clearButtonMode="while-editing"
|
clearButtonMode="while-editing"
|
||||||
autoCorrect={false}
|
autoCorrect={false}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<BottomSheetFlatList
|
<BottomSheetFlatList
|
||||||
data={filteredCountries}
|
data={filteredCountries}
|
||||||
keyExtractor={(item: any) => item.id?.toString()}
|
keyExtractor={(item: any) => item.id?.toString()}
|
||||||
contentContainerStyle={styles.listContainer}
|
contentContainerStyle={styles.listContainer}
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
keyboardShouldPersistTaps="handled"
|
keyboardShouldPersistTaps="handled"
|
||||||
ListEmptyComponent={
|
ListEmptyComponent={
|
||||||
<View style={styles.emptyList}>
|
<View style={styles.emptyList}>
|
||||||
<Text style={styles.emptyListText}>{t('Natija topilmadi')}</Text>
|
<Text style={styles.emptyListText}>{t('Natija topilmadi')}</Text>
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
renderItem={({ item }: { item: any }) => {
|
renderItem={({ item }: { item: any }) => {
|
||||||
const isSelected = item.flag?.toUpperCase() === selectedCountry;
|
const isSelected = item.flag?.toUpperCase() === selectedCountry;
|
||||||
const flagCode = item.flag ? item.flag.toLowerCase() : '';
|
const flagCode = item.flag ? item.flag.toLowerCase() : '';
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[styles.listItem, isSelected && styles.selectedListItem]}
|
style={[styles.listItem, isSelected && styles.selectedListItem]}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setSelectedCountry(item.flag?.toUpperCase());
|
setSelectedCountry(item.flag?.toUpperCase());
|
||||||
closeCountrySheet();
|
closeCountrySheet();
|
||||||
}}
|
}}
|
||||||
activeOpacity={0.7}
|
activeOpacity={0.7}
|
||||||
>
|
>
|
||||||
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10, flex: 1 }}>
|
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10, flex: 1 }}>
|
||||||
{flagCode ? (
|
{flagCode ? (
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: `https://flagcdn.com/w320/${flagCode}.png` }}
|
source={{ uri: `https://flagcdn.com/w320/${flagCode}.png` }}
|
||||||
style={{ width: 34, height: 22, borderRadius: 2 }}
|
style={{ width: 34, height: 22, borderRadius: 2 }}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Globe size={20} color={isSelected ? '#2563eb' : '#94a3b8'} />
|
<Globe size={20} color={isSelected ? '#2563eb' : '#94a3b8'} />
|
||||||
)}
|
)}
|
||||||
<Text style={[styles.listItemText, isSelected && styles.selectedListItemText]}>
|
<Text style={[styles.listItemText, isSelected && styles.selectedListItemText]}>
|
||||||
{item.name}
|
{item.name}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
|
||||||
{isSelected && (
|
|
||||||
<View style={styles.checkmark}>
|
|
||||||
<CheckIcon color="#3b82f6" strokeWidth={2.5} size={16} />
|
|
||||||
</View>
|
</View>
|
||||||
)}
|
{isSelected && (
|
||||||
</TouchableOpacity>
|
<View style={styles.checkmark}>
|
||||||
);
|
<CheckIcon color="#3b82f6" strokeWidth={2.5} size={16} />
|
||||||
}}
|
</View>
|
||||||
/>
|
)}
|
||||||
</BottomSheet>
|
</TouchableOpacity>
|
||||||
</View>
|
);
|
||||||
</KeyboardAvoidingView>
|
}}
|
||||||
|
/>
|
||||||
|
</BottomSheet>
|
||||||
|
</View>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
</KeyboardAwareScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useTheme } from '@/components/ThemeContext';
|
import { useTheme } from '@/components/ThemeContext';
|
||||||
import { BottomSheetBackdrop, BottomSheetModal, BottomSheetScrollView } from '@gorhom/bottom-sheet';
|
import { BottomSheetBackdrop, BottomSheetModal, BottomSheetScrollView, TouchableWithoutFeedback } from '@gorhom/bottom-sheet';
|
||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { router, useFocusEffect } from 'expo-router';
|
import { router, useFocusEffect } from 'expo-router';
|
||||||
@@ -7,18 +7,19 @@ import React, { useCallback, useRef, useState } from 'react';
|
|||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
Image,
|
Image,
|
||||||
KeyboardAvoidingView,
|
Keyboard,
|
||||||
Linking,
|
Linking,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
|
||||||
import OneClick from '@/assets/images/one_click.png';
|
import OneClick from '@/assets/images/one_click.png';
|
||||||
import PAYME from '@/assets/images/Payme_NEW.png';
|
import PAYME from '@/assets/images/Payme_NEW.png';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
|
||||||
import { price_calculation } from '../lib/api';
|
import { price_calculation } from '../lib/api';
|
||||||
import { CreateAdsResponse } from '../lib/types';
|
import { CreateAdsResponse } from '../lib/types';
|
||||||
import StepFour from './StepFour';
|
import StepFour from './StepFour';
|
||||||
@@ -209,122 +210,127 @@ export default function CreateAdsScreens() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAwareScrollView
|
||||||
behavior="padding"
|
showsVerticalScrollIndicator={false}
|
||||||
|
keyboardShouldPersistTaps="handled"
|
||||||
|
enableOnAndroid
|
||||||
|
extraScrollHeight={120}
|
||||||
style={[styles.safeArea, isDark ? styles.darkBg : styles.lightBg]}
|
style={[styles.safeArea, isDark ? styles.darkBg : styles.lightBg]}
|
||||||
>
|
>
|
||||||
<ScrollView contentContainerStyle={[styles.container, { paddingBottom: 90 }]}>
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||||
<Image
|
<ScrollView contentContainerStyle={[styles.container, { paddingBottom: 90 }]}>
|
||||||
source={OneClick}
|
<Image
|
||||||
style={{ width: 180, height: 56, marginBottom: 10 }}
|
source={OneClick}
|
||||||
resizeMode="contain"
|
style={{ width: 180, height: 56, marginBottom: 10 }}
|
||||||
/>
|
resizeMode="contain"
|
||||||
<Text style={[styles.title, isDark ? styles.darkText : styles.lightText]}>
|
|
||||||
{t("Bir Zumda Jonatish")}
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
{currentStep === 1 && (
|
|
||||||
<StepOne ref={stepOneRef} formData={formData} updateForm={updateForm} />
|
|
||||||
)}
|
|
||||||
{currentStep === 2 && (
|
|
||||||
<StepTwo ref={stepTwoRef} formData={formData} updateForm={updateForm} />
|
|
||||||
)}
|
|
||||||
{currentStep === 3 && (
|
|
||||||
<StepThree
|
|
||||||
ref={stepThreeRef}
|
|
||||||
formData={formData}
|
|
||||||
updateForm={updateForm}
|
|
||||||
data={data?.data}
|
|
||||||
/>
|
/>
|
||||||
)}
|
<Text style={[styles.title, isDark ? styles.darkText : styles.lightText]}>
|
||||||
{currentStep === 4 && <StepFour data={ads} setPayment={setPaymentType} />}
|
{t("Bir Zumda Jonatish")}
|
||||||
<View style={styles.footer}>
|
</Text>
|
||||||
{currentStep > 1 && currentStep !== 4 && (
|
|
||||||
<TouchableOpacity
|
{currentStep === 1 && (
|
||||||
style={[styles.back, isDark ? styles.darkBack : styles.lightBack]}
|
<StepOne ref={stepOneRef} formData={formData} updateForm={updateForm} />
|
||||||
onPress={() => setCurrentStep((s) => s - 1)}
|
|
||||||
>
|
|
||||||
<Text style={[styles.btnText, isDark ? styles.darkBtnText : styles.lightBtnText]}>
|
|
||||||
{t('Orqaga')}
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
)}
|
||||||
|
{currentStep === 2 && (
|
||||||
<TouchableOpacity
|
<StepTwo ref={stepTwoRef} formData={formData} updateForm={updateForm} />
|
||||||
style={styles.next}
|
)}
|
||||||
disabled={isPending}
|
{currentStep === 3 && (
|
||||||
onPress={() => {
|
<StepThree
|
||||||
let isValid = true;
|
ref={stepThreeRef}
|
||||||
|
formData={formData}
|
||||||
if (currentStep === 1) isValid = stepOneRef.current?.validate() ?? false;
|
updateForm={updateForm}
|
||||||
if (currentStep === 2) isValid = stepTwoRef.current?.validate() ?? false;
|
data={data?.data}
|
||||||
if (currentStep === 3) isValid = stepThreeRef.current?.validate() ?? false;
|
/>
|
||||||
|
)}
|
||||||
if (!isValid) return;
|
{currentStep === 4 && <StepFour data={ads} setPayment={setPaymentType} />}
|
||||||
|
<View style={styles.footer}>
|
||||||
if (currentStep < 3) setCurrentStep((s) => s + 1);
|
{currentStep > 1 && currentStep !== 4 && (
|
||||||
if (currentStep === 3) handleSubmit();
|
<TouchableOpacity
|
||||||
if (currentStep === 4) handlePresentModalPress();
|
style={[styles.back, isDark ? styles.darkBack : styles.lightBack]}
|
||||||
}}
|
onPress={() => setCurrentStep((s) => s - 1)}
|
||||||
>
|
>
|
||||||
<Text style={styles.btnText}>
|
<Text style={[styles.btnText, isDark ? styles.darkBtnText : styles.lightBtnText]}>
|
||||||
{currentStep === 3
|
{t('Orqaga')}
|
||||||
? t('Yaratish')
|
</Text>
|
||||||
: currentStep === 4
|
</TouchableOpacity>
|
||||||
? t("To'lash")
|
)}
|
||||||
: t('Keyingisi')}
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
{/* FOOTER */}
|
|
||||||
|
|
||||||
{/* PAYMENT BOTTOM SHEET */}
|
|
||||||
<BottomSheetModal
|
|
||||||
ref={bottomSheetModalRef}
|
|
||||||
index={0}
|
|
||||||
snapPoints={['70%', '95%']}
|
|
||||||
backdropComponent={renderBackdrop}
|
|
||||||
handleIndicatorStyle={{ backgroundColor: '#94a3b8', width: 50 }}
|
|
||||||
backgroundStyle={{ backgroundColor: isDark ? '#0f172a' : '#ffffff' }}
|
|
||||||
enablePanDownToClose
|
|
||||||
>
|
|
||||||
<BottomSheetScrollView
|
|
||||||
style={styles.sheetContent}
|
|
||||||
contentContainerStyle={styles.sheetContentContainer}
|
|
||||||
>
|
|
||||||
<View style={{ padding: 20 }}>
|
|
||||||
<Text style={[styles.sheetTitle, isDark ? styles.darkText : styles.lightText]}>
|
|
||||||
{t("To'lov turini tanlang")}
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[
|
style={styles.next}
|
||||||
styles.paymentItem,
|
disabled={isPending}
|
||||||
isDark ? styles.darkPaymentItem : styles.lightPaymentItem,
|
onPress={() => {
|
||||||
{ flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center' },
|
let isValid = true;
|
||||||
]}
|
|
||||||
onPress={() => sendPayment('payme')}
|
|
||||||
>
|
|
||||||
<Image source={PAYME} style={{ width: 80, height: 80 }} />
|
|
||||||
</TouchableOpacity>
|
|
||||||
|
|
||||||
<TouchableOpacity
|
if (currentStep === 1) isValid = stepOneRef.current?.validate() ?? false;
|
||||||
style={[
|
if (currentStep === 2) isValid = stepTwoRef.current?.validate() ?? false;
|
||||||
styles.paymentItem,
|
if (currentStep === 3) isValid = stepThreeRef.current?.validate() ?? false;
|
||||||
isDark ? styles.darkPaymentItem : styles.lightPaymentItem,
|
|
||||||
]}
|
if (!isValid) return;
|
||||||
onPress={() => sendPayment('referral')}
|
|
||||||
|
if (currentStep < 3) setCurrentStep((s) => s + 1);
|
||||||
|
if (currentStep === 3) handleSubmit();
|
||||||
|
if (currentStep === 4) handlePresentModalPress();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Text style={[styles.paymentText, isDark ? styles.darkText : styles.lightText]}>
|
<Text style={styles.btnText}>
|
||||||
{t('Referal orqali')}
|
{currentStep === 3
|
||||||
|
? t('Yaratish')
|
||||||
|
: currentStep === 4
|
||||||
|
? t("To'lash")
|
||||||
|
: t('Keyingisi')}
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</BottomSheetScrollView>
|
</ScrollView>
|
||||||
</BottomSheetModal>
|
|
||||||
</KeyboardAvoidingView>
|
{/* FOOTER */}
|
||||||
|
|
||||||
|
{/* PAYMENT BOTTOM SHEET */}
|
||||||
|
<BottomSheetModal
|
||||||
|
ref={bottomSheetModalRef}
|
||||||
|
index={0}
|
||||||
|
snapPoints={['70%', '95%']}
|
||||||
|
backdropComponent={renderBackdrop}
|
||||||
|
handleIndicatorStyle={{ backgroundColor: '#94a3b8', width: 50 }}
|
||||||
|
backgroundStyle={{ backgroundColor: isDark ? '#0f172a' : '#ffffff' }}
|
||||||
|
enablePanDownToClose
|
||||||
|
>
|
||||||
|
<BottomSheetScrollView
|
||||||
|
style={styles.sheetContent}
|
||||||
|
contentContainerStyle={styles.sheetContentContainer}
|
||||||
|
>
|
||||||
|
<View style={{ padding: 20 }}>
|
||||||
|
<Text style={[styles.sheetTitle, isDark ? styles.darkText : styles.lightText]}>
|
||||||
|
{t("To'lov turini tanlang")}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.paymentItem,
|
||||||
|
isDark ? styles.darkPaymentItem : styles.lightPaymentItem,
|
||||||
|
{ flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center' },
|
||||||
|
]}
|
||||||
|
onPress={() => sendPayment('payme')}
|
||||||
|
>
|
||||||
|
<Image source={PAYME} style={{ width: 80, height: 80 }} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.paymentItem,
|
||||||
|
isDark ? styles.darkPaymentItem : styles.lightPaymentItem,
|
||||||
|
]}
|
||||||
|
onPress={() => sendPayment('referral')}
|
||||||
|
>
|
||||||
|
<Text style={[styles.paymentText, isDark ? styles.darkText : styles.lightText]}>
|
||||||
|
{t('Referal orqali')}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</BottomSheetScrollView>
|
||||||
|
</BottomSheetModal>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
</KeyboardAwareScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user