Enhance app functionality and localization
- Added new dependencies: expo-file-system and expo-sharing. - Updated package versions for @babel/core and react-dom. - Introduced a new index screen for displaying prayer times with city selection. - Refactored ServicesGrid to accept a dynamic services array and improved layout. - Updated localization for new phrases and service titles in Turkmen. - Enhanced LostKeyModal with a close button and additional text. - Improved PhrasebookModal to allow expandable phrases for better user interaction.
This commit is contained in:
8
Umra.code-workspace
Normal file
8
Umra.code-workspace
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export default function TabLayout() {
|
||||
backgroundColor: Colors[colorScheme].secondary,
|
||||
borderTopColor: Colors[colorScheme].secondary,
|
||||
},
|
||||
headerShown: false, // Hide header globally for tabs
|
||||
headerShown: false, // hide header globally for tabs
|
||||
}}>
|
||||
<Tabs.Screen
|
||||
name="home"
|
||||
@@ -42,11 +42,18 @@ export default function TabLayout() {
|
||||
tabBarIcon: ({ color }) => <TabBarIcon name="th-large" color={color} />,
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
options={{
|
||||
title: i18n.t('menuSalah'),
|
||||
tabBarIcon: ({ color }) => <TabBarIcon name="moon-o" color={color} />,
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="programs"
|
||||
options={{
|
||||
title: i18n.t('programs'),
|
||||
tabBarIcon: ({ color }) => <TabBarIcon name="briefcase" color={color} />,
|
||||
title: i18n.t('Programs'),
|
||||
tabBarIcon: ({ color }) => <TabBarIcon name="calendar" color={color} />,
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
|
||||
@@ -31,14 +31,22 @@ export default function HomeScreen() {
|
||||
|
||||
const currentLanguage = languages.find(l => l.value === i18n.locale.substring(0, 2))?.label;
|
||||
|
||||
const services = [
|
||||
{ name: 'quran', icon: 'book-open-variant' },
|
||||
{ name: 'hadith', icon: 'book-open-page-variant' },
|
||||
{ name: 'dua', icon: 'human-greeting' },
|
||||
];
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.title}>{i18n.t('home')}</Text>
|
||||
<Pressable onPress={() => setModalVisible(true)} style={pickerSelectStyles.inputIOS}>
|
||||
<Text style={{ color: 'white' }}>{currentLanguage}</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
<Modal
|
||||
animationType="slide"
|
||||
transparent={true}
|
||||
@@ -69,7 +77,7 @@ export default function HomeScreen() {
|
||||
/>
|
||||
|
||||
<PrayerTimeCard />
|
||||
<ServicesGrid />
|
||||
<ServicesGrid services={services} />
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
@@ -85,6 +93,7 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: 15,
|
||||
},
|
||||
header: {
|
||||
display: 'none', // hide for now, will show later
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
|
||||
@@ -1,5 +1,179 @@
|
||||
import { Redirect } from 'expo-router';
|
||||
import { Pressable, SafeAreaView, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { getPrayerTimes, cities } from '../../utils/prayerTimeCalculator';
|
||||
import i18n from '../../i18n';
|
||||
import { useColorScheme } from 'react-native';
|
||||
import Colors from '../../constants/Colors';
|
||||
|
||||
type Prayer = {
|
||||
name: string;
|
||||
time: string;
|
||||
};
|
||||
|
||||
type City = keyof typeof cities;
|
||||
|
||||
export default function TabIndex() {
|
||||
return <Redirect href="/(tabs)/home" />;
|
||||
const colorScheme = useColorScheme();
|
||||
const theme = Colors[colorScheme ?? 'light'];
|
||||
const [selectedCity, setSelectedCity] = useState<City>('Makkah');
|
||||
const [prayerTimes, setPrayerTimes] = useState<Prayer[]>([]);
|
||||
const [nextPrayerName, setNextPrayerName] = useState<string | null>(null);
|
||||
|
||||
const prayerNameMapping: { [key: string]: string } = {
|
||||
fajr: i18n.t('fajr'),
|
||||
dhuhr: i18n.t('dhuhr'),
|
||||
asr: i18n.t('asr'),
|
||||
maghrib: i18n.t('maghrib'),
|
||||
isha: i18n.t('isha'),
|
||||
};
|
||||
|
||||
const updatePrayerTimes = useCallback(() => {
|
||||
const times = getPrayerTimes(selectedCity);
|
||||
const prayers: Prayer[] = Object.keys(prayerNameMapping).map((key) => ({
|
||||
name: prayerNameMapping[key],
|
||||
time: times[key] || '-----',
|
||||
}));
|
||||
setPrayerTimes(prayers);
|
||||
|
||||
const now = new Date();
|
||||
let nextPrayer: Prayer | null = null;
|
||||
|
||||
for (const prayer of prayers) {
|
||||
if (prayer.time === '-----') continue;
|
||||
const [hours, minutes] = prayer.time.split(':').map(Number);
|
||||
const prayerDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes);
|
||||
if (prayerDate > now) {
|
||||
nextPrayer = prayer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nextPrayer && prayers.length > 0) {
|
||||
const firstPrayer = prayers.find((p) => p.time !== '-----');
|
||||
if (firstPrayer) {
|
||||
nextPrayer = firstPrayer;
|
||||
}
|
||||
}
|
||||
|
||||
setNextPrayerName(nextPrayer ? nextPrayer.name : null);
|
||||
}, [selectedCity]);
|
||||
|
||||
useEffect(() => {
|
||||
updatePrayerTimes();
|
||||
const interval = setInterval(updatePrayerTimes, 60000); // Update every minute
|
||||
return () => clearInterval(interval);
|
||||
}, [updatePrayerTimes]);
|
||||
|
||||
const renderPrayerTime = (prayer: Prayer) => {
|
||||
const isNextPrayer = prayer.name === nextPrayerName;
|
||||
return (
|
||||
<View
|
||||
key={prayer.name}
|
||||
style={[styles.prayerRow, { backgroundColor: theme.secondary }, isNextPrayer && [styles.nextPrayerRow, { backgroundColor: theme.tint }]]}>
|
||||
<View>
|
||||
<Text style={[styles.prayerName, { color: theme.text }, isNextPrayer && styles.nextPrayerText]}>
|
||||
{prayer.name}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={[styles.prayerTime, { color: theme.text }, isNextPrayer && styles.nextPrayerTimeText]}>
|
||||
{new Date(`1970-01-01T${prayer.time}:00`).toLocaleTimeString('en-US', {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hour12: false,
|
||||
})}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: theme.background }]}>
|
||||
<View style={[styles.citySelector, { backgroundColor: theme.background }]}>
|
||||
{(Object.keys(cities) as City[]).map((city) => (
|
||||
<Pressable
|
||||
key={city}
|
||||
onPress={() => setSelectedCity(city)}
|
||||
style={[styles.cityButton, { backgroundColor: theme.secondary }, selectedCity === city && [styles.activeCityButton, { backgroundColor: theme.tint }]]}>
|
||||
<Text
|
||||
style={[
|
||||
styles.cityButtonText,
|
||||
{ color: theme.text },
|
||||
selectedCity === city && styles.activeCityButtonText,
|
||||
]}>
|
||||
{i18n.t(city)}
|
||||
</Text>
|
||||
</Pressable>
|
||||
))}
|
||||
</View>
|
||||
<ScrollView contentContainerStyle={styles.listContainer}>
|
||||
{prayerTimes.map(renderPrayerTime)}
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
citySelector: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
paddingVertical: 20,
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
cityButton: {
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 25,
|
||||
borderRadius: 20,
|
||||
marginHorizontal: 5,
|
||||
},
|
||||
activeCityButton: {},
|
||||
cityButtonText: {
|
||||
fontSize: 18,
|
||||
fontWeight: '500',
|
||||
},
|
||||
activeCityButtonText: {
|
||||
color: '#fff',
|
||||
},
|
||||
listContainer: {
|
||||
paddingHorizontal: 20,
|
||||
},
|
||||
prayerRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 25,
|
||||
paddingHorizontal: 20,
|
||||
borderRadius: 15,
|
||||
marginBottom: 10,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 1,
|
||||
},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 3,
|
||||
elevation: 2,
|
||||
},
|
||||
nextPrayerRow: {},
|
||||
prayerName: {
|
||||
fontSize: 28,
|
||||
fontWeight: '600',
|
||||
},
|
||||
inCityText: {
|
||||
fontSize: 18,
|
||||
},
|
||||
prayerTime: {
|
||||
fontSize: 28,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
nextPrayerText: {
|
||||
color: '#fff',
|
||||
},
|
||||
nextPrayerTimeText: {
|
||||
color: '#fff',
|
||||
fontSize: 32,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,14 +7,12 @@ import React, { useState } from 'react';
|
||||
import CurrencyConverterModal from '@/components/CurrencyConverterModal';
|
||||
import HotelBusinessCardModal from '@/components/HotelBusinessCardModal';
|
||||
import LostKeyModal from '@/components/LostKeyModal';
|
||||
import TranslatorModal from '@/components/TranslatorModal';
|
||||
import PhrasebookModal from '@/components/PhrasebookModal';
|
||||
|
||||
export default function ServicesScreen() {
|
||||
const [currencyModalVisible, setCurrencyModalVisible] = useState(false);
|
||||
const [hotelModalVisible, setHotelModalVisible] = useState(false);
|
||||
const [lostKeyModalVisible, setLostKeyModalVisible] = useState(false);
|
||||
const [translatorModalVisible, setTranslatorModalVisible] = useState(false);
|
||||
const [phrasebookModalVisible, setPhrasebookModalVisible] = useState(false);
|
||||
|
||||
const services = [
|
||||
@@ -36,12 +34,6 @@ export default function ServicesScreen() {
|
||||
icon: <FontAwesome5 name="key" size={24} color="#D4AF37" />,
|
||||
onPress: () => setLostKeyModalVisible(true),
|
||||
},
|
||||
{
|
||||
title: i18n.t('Translator'),
|
||||
name: 'translator',
|
||||
icon: <FontAwesome5 name="language" size={24} color="#D4AF37" />,
|
||||
onPress: () => setTranslatorModalVisible(true),
|
||||
},
|
||||
{
|
||||
title: i18n.t('Phrasebook'),
|
||||
name: 'phrasebook',
|
||||
@@ -73,10 +65,6 @@ export default function ServicesScreen() {
|
||||
visible={lostKeyModalVisible}
|
||||
onClose={() => setLostKeyModalVisible(false)}
|
||||
/>
|
||||
<TranslatorModal
|
||||
visible={translatorModalVisible}
|
||||
onClose={() => setTranslatorModalVisible(false)}
|
||||
/>
|
||||
<PhrasebookModal
|
||||
visible={phrasebookModalVisible}
|
||||
onClose={() => setPhrasebookModalVisible(false)}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { FontAwesome } from '@expo/vector-icons';
|
||||
import React from 'react';
|
||||
import { Modal, View, Text, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
|
||||
|
||||
@@ -18,7 +19,16 @@ const LostKeyModal: React.FC<LostKeyModalProps> = ({ visible, onClose }) => {
|
||||
>
|
||||
<TouchableOpacity style={styles.overlay} activeOpacity={1} onPress={onClose}>
|
||||
<View style={styles.modalContainer}>
|
||||
<Text style={styles.text}>Mastercard</Text>
|
||||
<TouchableOpacity style={styles.closeButton} onPress={onClose}>
|
||||
<FontAwesome name="close" size={24} color="black" />
|
||||
</TouchableOpacity>
|
||||
|
||||
<Text style={styles.smallText} >Aşak resepşyna şul aşakdaky haty görkeziň</Text>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
adjustsFontSizeToFit
|
||||
style={styles.text}
|
||||
>Mastercard</Text>
|
||||
<Text style={[styles.text, styles.arabicText]}>ماستركارد</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
@@ -34,7 +44,7 @@ const styles = StyleSheet.create({
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||
},
|
||||
modalContainer: {
|
||||
width: width * 0.6,
|
||||
width: width * 0.9,
|
||||
padding: 20,
|
||||
backgroundColor: 'white',
|
||||
borderRadius: 10,
|
||||
@@ -48,10 +58,22 @@ const styles = StyleSheet.create({
|
||||
shadowRadius: 3.84,
|
||||
elevation: 5,
|
||||
},
|
||||
closeButton: {
|
||||
position: 'absolute',
|
||||
top: 15,
|
||||
right: 15,
|
||||
zIndex: 1,
|
||||
},
|
||||
text: {
|
||||
fontSize: 40,
|
||||
marginBottom: 10,
|
||||
},
|
||||
smallText: {
|
||||
marginTop: 15,
|
||||
fontSize: 20,
|
||||
color: '#666',
|
||||
textAlign: 'center',
|
||||
},
|
||||
arabicText: {
|
||||
fontFamily: 'System',
|
||||
writingDirection: 'rtl',
|
||||
|
||||
@@ -10,6 +10,8 @@ type PhrasebookModalProps = {
|
||||
};
|
||||
|
||||
const PHRASES = [
|
||||
{ tk: 'Bu näçe?', ar: 'بكم هذا؟ (Bikam hadha?)' },
|
||||
{ tk: 'Arzanladyň', ar: 'تَخْفيض Takfidun' },
|
||||
{ tk: 'Salam', ar: 'مرحبا (Marhaban)' },
|
||||
{ tk: 'Hawa', ar: 'نعم (Na\'am)' },
|
||||
{ tk: 'Ýok', ar: 'لا (La)' },
|
||||
@@ -18,19 +20,26 @@ const PHRASES = [
|
||||
{ tk: 'Haýyş edýärin', ar: 'من فضلك (Min fadlik)' },
|
||||
{ tk: 'Bagyşlaň', ar: 'آسف (Asif)' },
|
||||
{ tk: 'Men size nähili kömek edip bilerin?', ar: 'كيف يمكنني مساعدتك؟ (Kayfa yumkinuni musa\'adatuk?)' },
|
||||
{ tk: 'Bu näçe?', ar: 'بكم هذا؟ (Bikam hadha?)' },
|
||||
{ tk: 'Hajathana nirede?', ar: 'أين الحمام؟ (Ayna al-hammam?)' },
|
||||
{ tk: 'Men ýolumy ýitirdim', ar: 'لقد ضللت طريقي (Laqad dalalt tariqi)' },
|
||||
{ tk: 'Lukman çagyryň', ar: 'اتصل بطبيب (Ittasil bi-tabib)' },
|
||||
];
|
||||
|
||||
const PhrasebookModal = ({ visible, onClose }: PhrasebookModalProps) => {
|
||||
const renderItem = ({ item }: { item: { tk: string; ar: string } }) => (
|
||||
const [expandedIndex, setExpandedIndex] = React.useState<number | null>(null);
|
||||
|
||||
const renderItem = ({ item, index }: { item: { tk: string; ar: string }; index: number }) => {
|
||||
const isExpanded = index === expandedIndex;
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={() => setExpandedIndex(isExpanded ? null : index)}>
|
||||
<View style={styles.phraseItem}>
|
||||
<Text style={styles.turkmenText}>{item.tk}</Text>
|
||||
<Text style={styles.arabicText}>{item.ar}</Text>
|
||||
{isExpanded && <Text style={styles.arabicText}>{item.ar}</Text>}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -51,6 +60,7 @@ const PhrasebookModal = ({ visible, onClose }: PhrasebookModalProps) => {
|
||||
renderItem={renderItem}
|
||||
keyExtractor={(item, index) => index.toString()}
|
||||
ItemSeparatorComponent={() => <View style={styles.separator} />}
|
||||
extraData={expandedIndex}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
|
||||
@@ -1,34 +1,42 @@
|
||||
import React from 'react';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
|
||||
import Colors from '@/constants/Colors';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { router } from 'expo-router';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
const services = [
|
||||
{ name: 'quran', icon: 'book-open-variant' },
|
||||
{ name: 'hadith', icon: 'book-open-page-variant' },
|
||||
{ name: 'dua', icon: 'human-greeting' },
|
||||
];
|
||||
type ServicesGridProps = {
|
||||
services: {
|
||||
name: string;
|
||||
icon: any;
|
||||
}[];
|
||||
};
|
||||
const ServicesGrid = ({ services }: ServicesGridProps) => {
|
||||
const handlePress = (name: string) => {
|
||||
if (name === 'quran') {
|
||||
|
||||
export default function ServicesGrid() {
|
||||
const colorScheme = 'dark';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>{i18n.t('servicesToEnrich')}</Text>
|
||||
<View style={styles.grid}>
|
||||
{services.map((service, index) => (
|
||||
<View key={index} style={styles.serviceItem}>
|
||||
<View style={[styles.iconContainer, { backgroundColor: Colors[colorScheme].secondary }]}>
|
||||
<MaterialCommunityIcons name={service.icon} size={30} color={Colors[colorScheme].tint} />
|
||||
{services.map((service) => (
|
||||
<TouchableOpacity
|
||||
key={service.name}
|
||||
style={styles.serviceItem}
|
||||
onPress={() => handlePress(service.name)}>
|
||||
<View style={[styles.iconContainer, { backgroundColor: Colors['dark'].secondary }]}>
|
||||
<MaterialCommunityIcons name={service.icon} size={30} color={Colors['dark'].tint} />
|
||||
</View>
|
||||
<Text style={styles.serviceName}>{i18n.t(service.name)}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
@@ -37,8 +45,8 @@ const styles = StyleSheet.create({
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
color: Colors.dark.text,
|
||||
marginBottom: 15,
|
||||
color: 'white',
|
||||
marginBottom: 10,
|
||||
},
|
||||
grid: {
|
||||
flexDirection: 'row',
|
||||
@@ -50,13 +58,15 @@ const styles = StyleSheet.create({
|
||||
iconContainer: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
borderRadius: 15,
|
||||
borderRadius: 30,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginBottom: 10,
|
||||
marginBottom: 5,
|
||||
},
|
||||
serviceName: {
|
||||
color: Colors.dark.text,
|
||||
fontSize: 14,
|
||||
color: 'white',
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default ServicesGrid;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"home": "Baş sahypa",
|
||||
"home": "Öý",
|
||||
"services": "Hyzmatlar",
|
||||
"supplications": "Dogalar",
|
||||
"yourJourneyToHajj": "Haj syýahatyňyz",
|
||||
@@ -10,6 +10,7 @@
|
||||
"newExperience": "Täze tejribe",
|
||||
"prayerTimes": "Namaz wagtlary",
|
||||
"programs": "Programmalar",
|
||||
"Programs": "Respisaniýa",
|
||||
"leftOnPrayer": "{{prayerName}} namazyna çenli galdy",
|
||||
"servicesToEnrich": "Ruhy tejribäňizi baýlaşdyrmak üçin hyzmatlar",
|
||||
"quran": "Kuran",
|
||||
@@ -45,5 +46,7 @@
|
||||
"Translator": "Perewod",
|
||||
"Phrasebook": "Sözlük",
|
||||
"Enter text in Turkmen": "Türkmençe sözleri gir",
|
||||
"Translate": "Terjime et"
|
||||
"Translate": "Terjime et",
|
||||
"Salah": "Namaz",
|
||||
"menuSalah": "Namaz"
|
||||
}
|
||||
|
||||
205
package-lock.json
generated
205
package-lock.json
generated
@@ -13,10 +13,12 @@
|
||||
"@react-navigation/native": "^7.1.6",
|
||||
"adhan": "^4.4.3",
|
||||
"expo": "~53.0.20",
|
||||
"expo-file-system": "~18.1.11",
|
||||
"expo-font": "~13.3.2",
|
||||
"expo-linking": "~7.1.7",
|
||||
"expo-localization": "^16.1.6",
|
||||
"expo-router": "~5.1.4",
|
||||
"expo-sharing": "~13.1.5",
|
||||
"expo-splash-screen": "~0.30.10",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"expo-system-ui": "~5.0.10",
|
||||
@@ -24,17 +26,15 @@
|
||||
"expo-web-browser": "~14.2.0",
|
||||
"i18n-js": "^4.5.1",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-picker-select": "^9.3.1",
|
||||
"react-native-reanimated": "~3.17.4",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "~4.11.1",
|
||||
"react-native-vector-icons": "^10.3.0",
|
||||
"react-native-web": "~0.20.0"
|
||||
"react-native-vector-icons": "^10.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/core": "^7.20.0",
|
||||
"@types/react": "~19.0.10",
|
||||
"@types/react-native-vector-icons": "^6.4.18",
|
||||
"jest": "^29.2.1",
|
||||
@@ -4349,6 +4349,8 @@
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
|
||||
"integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.7.0"
|
||||
}
|
||||
@@ -4378,6 +4380,8 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz",
|
||||
"integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"hyphenate-style-name": "^1.0.3"
|
||||
}
|
||||
@@ -5179,6 +5183,14 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-sharing": {
|
||||
"version": "13.1.5",
|
||||
"resolved": "https://registry.npmjs.org/expo-sharing/-/expo-sharing-13.1.5.tgz",
|
||||
"integrity": "sha512-X/5sAEiWXL2kdoGE3NO5KmbfcmaCWuWVZXHu8OQef7Yig4ZgHFkGD11HKJ5KqDrDg+SRZe4ISd6MxE7vGUgm4w==",
|
||||
"peerDependencies": {
|
||||
"expo": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen": {
|
||||
"version": "0.30.10",
|
||||
"resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.30.10.tgz",
|
||||
@@ -5291,6 +5303,13 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"node_modules/fast-loops": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.4.tgz",
|
||||
"integrity": "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/fast-uri": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
|
||||
@@ -5318,6 +5337,8 @@
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
|
||||
"integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cross-fetch": "^3.1.5",
|
||||
"fbjs-css-vars": "^1.0.0",
|
||||
@@ -5331,12 +5352,16 @@
|
||||
"node_modules/fbjs-css-vars": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
|
||||
"integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
|
||||
"integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/fbjs/node_modules/promise": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"asap": "~2.0.3"
|
||||
}
|
||||
@@ -5767,7 +5792,9 @@
|
||||
"node_modules/hyphenate-style-name": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
|
||||
"integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="
|
||||
"integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/i18n-js": {
|
||||
"version": "4.5.1",
|
||||
@@ -5900,11 +5927,14 @@
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||
},
|
||||
"node_modules/inline-style-prefixer": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz",
|
||||
"integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==",
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz",
|
||||
"integrity": "sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"css-in-js-utils": "^3.1.0"
|
||||
"css-in-js-utils": "^3.1.0",
|
||||
"fast-loops": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
@@ -6423,6 +6453,55 @@
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-expo/node_modules/react": {
|
||||
"version": "19.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
|
||||
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-expo/node_modules/react-dom": {
|
||||
"version": "19.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
|
||||
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.26.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-expo/node_modules/react-server-dom-webpack": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-server-dom-webpack/-/react-server-dom-webpack-19.0.0.tgz",
|
||||
"integrity": "sha512-hLug9KEXLc8vnU9lDNe2b2rKKDaqrp5gNiES4uyu2Up3FZfZJZmdwLFXlWzdA9gTB/6/cWduSB2K1Lfag2pSvw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"acorn-loose": "^8.3.0",
|
||||
"neo-async": "^2.6.1",
|
||||
"webpack-sources": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"webpack": "^5.59.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-expo/node_modules/scheduler": {
|
||||
"version": "0.26.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
|
||||
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/jest-get-type": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
|
||||
@@ -8058,6 +8137,8 @@
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
@@ -8076,17 +8157,23 @@
|
||||
"node_modules/node-fetch/node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
@@ -8619,7 +8706,9 @@
|
||||
"node_modules/postcss-value-parser": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/pretty-bytes": {
|
||||
"version": "5.6.0",
|
||||
@@ -8865,14 +8954,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
|
||||
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.25.0"
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.23.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.0.0"
|
||||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom/node_modules/scheduler": {
|
||||
"version": "0.23.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-fast-compare": {
|
||||
@@ -9121,33 +9223,39 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-web": {
|
||||
"version": "0.20.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.20.0.tgz",
|
||||
"integrity": "sha512-OOSgrw+aON6R3hRosCau/xVxdLzbjEcsLysYedka0ZON4ZZe6n9xgeN9ZkoejhARM36oTlUgHIQqxGutEJ9Wxg==",
|
||||
"version": "0.19.13",
|
||||
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.13.tgz",
|
||||
"integrity": "sha512-etv3bN8rJglrRCp/uL4p7l8QvUNUC++QwDbdZ8CB7BvZiMvsxfFIRM1j04vxNldG3uo2puRd6OSWR3ibtmc29A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.6",
|
||||
"@react-native/normalize-colors": "^0.74.1",
|
||||
"fbjs": "^3.0.4",
|
||||
"inline-style-prefixer": "^7.0.1",
|
||||
"inline-style-prefixer": "^6.0.1",
|
||||
"memoize-one": "^6.0.0",
|
||||
"nullthrows": "^1.1.1",
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
"styleq": "^0.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0"
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-web/node_modules/@react-native/normalize-colors": {
|
||||
"version": "0.74.89",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.89.tgz",
|
||||
"integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg=="
|
||||
"integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/react-native-web/node_modules/memoize-one": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
||||
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/react-native/node_modules/@react-native/virtualized-lists": {
|
||||
"version": "0.79.5",
|
||||
@@ -9246,25 +9354,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-server-dom-webpack": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-server-dom-webpack/-/react-server-dom-webpack-19.0.0.tgz",
|
||||
"integrity": "sha512-hLug9KEXLc8vnU9lDNe2b2rKKDaqrp5gNiES4uyu2Up3FZfZJZmdwLFXlWzdA9gTB/6/cWduSB2K1Lfag2pSvw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"acorn-loose": "^8.3.0",
|
||||
"neo-async": "^2.6.1",
|
||||
"webpack-sources": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"webpack": "^5.59.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-test-renderer": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-19.0.0.tgz",
|
||||
@@ -9780,7 +9869,9 @@
|
||||
"node_modules/setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
|
||||
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
@@ -10178,7 +10269,9 @@
|
||||
"node_modules/styleq": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz",
|
||||
"integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="
|
||||
"integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/sucrase": {
|
||||
"version": "3.35.0",
|
||||
@@ -10250,13 +10343,17 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
|
||||
"integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz",
|
||||
"integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
@@ -10591,6 +10688,8 @@
|
||||
"url": "https://github.com/sponsors/faisalman"
|
||||
}
|
||||
],
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"ua-parser-js": "script/cli.js"
|
||||
},
|
||||
@@ -10838,9 +10937,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.101.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.2.tgz",
|
||||
"integrity": "sha512-4JLXU0tD6OZNVqlwzm3HGEhAHufSiyv+skb7q0d2367VDMzrU1Q/ZeepvkcHH0rZie6uqEtTQQe0OEOOluH3Mg==",
|
||||
"version": "5.101.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz",
|
||||
"integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
"@react-navigation/native": "^7.1.6",
|
||||
"adhan": "^4.4.3",
|
||||
"expo": "~53.0.20",
|
||||
"expo-file-system": "~18.1.11",
|
||||
"expo-font": "~13.3.2",
|
||||
"expo-linking": "~7.1.7",
|
||||
"expo-localization": "^16.1.6",
|
||||
"expo-router": "~5.1.4",
|
||||
"expo-sharing": "~13.1.5",
|
||||
"expo-splash-screen": "~0.30.10",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"expo-system-ui": "~5.0.10",
|
||||
@@ -29,14 +31,12 @@
|
||||
"expo-web-browser": "~14.2.0",
|
||||
"i18n-js": "^4.5.1",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-picker-select": "^9.3.1",
|
||||
"react-native-reanimated": "~3.17.4",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "~4.11.1",
|
||||
"react-native-vector-icons": "^10.3.0",
|
||||
"react-native-web": "~0.19.6"
|
||||
"react-native-vector-icons": "^10.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
|
||||
16
utils/pdf.ts
Normal file
16
utils/pdf.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import * as FileSystem from 'expo-file-system';
|
||||
import * as Linking from 'expo-linking';
|
||||
import { Asset } from 'expo-asset';
|
||||
|
||||
export const openPdf = async () => {
|
||||
// const asset = Asset.fromModule(require('../assets/pdf/quran_in_turkmen.pdf'));
|
||||
// const localUri = `${FileSystem.documentDirectory}${asset.name}`;
|
||||
|
||||
// const fileInfo = await FileSystem.getInfoAsync(localUri);
|
||||
|
||||
// if (!fileInfo.exists) {
|
||||
// await FileSystem.downloadAsync(asset.uri, localUri);
|
||||
// }
|
||||
|
||||
// await Linking.openURL(localUri);
|
||||
};
|
||||
Reference in New Issue
Block a user