Add expo-asset dependency and update layout for safe area insets
- Included expo-asset in app.json and package.json for asset management. - Refactored layout components in HomeScreen, TabIndex, Programs, and ServicesScreen to utilize safe area insets for better UI on different devices. - Updated StatusBar style in RootLayoutNav for improved visibility.
This commit is contained in:
3
app.json
3
app.json
@@ -29,7 +29,8 @@
|
|||||||
"favicon": "./assets/images/favicon.png"
|
"favicon": "./assets/images/favicon.png"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"expo-router"
|
"expo-router",
|
||||||
|
"expo-asset"
|
||||||
],
|
],
|
||||||
"experiments": {
|
"experiments": {
|
||||||
"typedRoutes": true
|
"typedRoutes": true
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { StyleSheet, SafeAreaView, ScrollView, I18nManager, Modal, Pressable } from 'react-native';
|
import { StyleSheet, ScrollView, I18nManager, Modal, Pressable } from 'react-native';
|
||||||
import { Text, View } from '@/components/Themed';
|
import { Text, View } from '@/components/Themed';
|
||||||
import FeatureCard from '@/components/FeatureCard';
|
import FeatureCard from '@/components/FeatureCard';
|
||||||
import PrayerTimeCard from '@/components/PrayerTimeCard';
|
import PrayerTimeCard from '@/components/PrayerTimeCard';
|
||||||
@@ -8,10 +8,12 @@ import * as Updates from 'expo-updates';
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import Colors from '@/constants/Colors';
|
import Colors from '@/constants/Colors';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
|
|
||||||
export default function HomeScreen() {
|
export default function HomeScreen() {
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
const changeLanguage = async (lang: 'en' | 'tk' | 'ru') => {
|
const changeLanguage = async (lang: 'en' | 'tk' | 'ru') => {
|
||||||
if (!lang) return;
|
if (!lang) return;
|
||||||
@@ -38,7 +40,7 @@ export default function HomeScreen() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.container}>
|
<View style={[styles.container, { paddingTop: insets.top }]}>
|
||||||
|
|
||||||
<View style={styles.header}>
|
<View style={styles.header}>
|
||||||
<Text style={styles.title}>{i18n.t('home')}</Text>
|
<Text style={styles.title}>{i18n.t('home')}</Text>
|
||||||
@@ -81,7 +83,7 @@ export default function HomeScreen() {
|
|||||||
{/* <ServicesGrid services={services} /> */}
|
{/* <ServicesGrid services={services} /> */}
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</SafeAreaView>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Pressable, SafeAreaView, ScrollView, StyleSheet, Text, View } from 'react-native';
|
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
import { getPrayerTimes, cities } from '../../utils/prayerTimeCalculator';
|
import { getPrayerTimes, cities } from '../../utils/prayerTimeCalculator';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
@@ -19,6 +20,7 @@ export default function TabIndex() {
|
|||||||
const [selectedCity, setSelectedCity] = useState<City>('Makkah');
|
const [selectedCity, setSelectedCity] = useState<City>('Makkah');
|
||||||
const [prayerTimes, setPrayerTimes] = useState<Prayer[]>([]);
|
const [prayerTimes, setPrayerTimes] = useState<Prayer[]>([]);
|
||||||
const [nextPrayerName, setNextPrayerName] = useState<string | null>(null);
|
const [nextPrayerName, setNextPrayerName] = useState<string | null>(null);
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
const prayerNameMapping: { [key: string]: string } = {
|
const prayerNameMapping: { [key: string]: string } = {
|
||||||
fajr: i18n.t('fajr'),
|
fajr: i18n.t('fajr'),
|
||||||
@@ -88,7 +90,7 @@ export default function TabIndex() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={[styles.container, { backgroundColor: theme.background }]}>
|
<View style={[styles.container, { backgroundColor: theme.background, paddingTop: insets.top }]}>
|
||||||
<View style={[styles.citySelector, { backgroundColor: theme.background }]}>
|
<View style={[styles.citySelector, { backgroundColor: theme.background }]}>
|
||||||
{(Object.keys(cities) as City[]).map((city) => (
|
{(Object.keys(cities) as City[]).map((city) => (
|
||||||
<Pressable
|
<Pressable
|
||||||
@@ -109,7 +111,7 @@ export default function TabIndex() {
|
|||||||
<ScrollView contentContainerStyle={styles.listContainer}>
|
<ScrollView contentContainerStyle={styles.listContainer}>
|
||||||
{prayerTimes.map(renderPrayerTime)}
|
{prayerTimes.map(renderPrayerTime)}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</SafeAreaView>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { StyleSheet, SafeAreaView, Text, View, TouchableOpacity, ScrollView } from 'react-native';
|
import { StyleSheet, Text, View, TouchableOpacity, ScrollView } from 'react-native';
|
||||||
import Colors from '@/constants/Colors';
|
import Colors from '@/constants/Colors';
|
||||||
import { FontAwesome, FontAwesome5 } from '@expo/vector-icons';
|
import { FontAwesome, FontAwesome5 } from '@expo/vector-icons';
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
type Activity = {
|
type Activity = {
|
||||||
time: string;
|
time: string;
|
||||||
@@ -18,6 +19,7 @@ type Activities = {
|
|||||||
export default function Programs() {
|
export default function Programs() {
|
||||||
const colorScheme = 'dark';
|
const colorScheme = 'dark';
|
||||||
const [activeDay, setActiveDay] = useState('Day 1');
|
const [activeDay, setActiveDay] = useState('Day 1');
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
const activities: Activities = {
|
const activities: Activities = {
|
||||||
'Day 1': [
|
'Day 1': [
|
||||||
@@ -54,7 +56,7 @@ export default function Programs() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={[styles.container, { backgroundColor: Colors[colorScheme].background }]}>
|
<View style={[styles.container, { backgroundColor: Colors[colorScheme].background, paddingTop: insets.top }]}>
|
||||||
<View style={styles.header}>
|
<View style={styles.header}>
|
||||||
<Text style={[styles.title, { color: Colors[colorScheme].text }]}>Umrah Pilgrimage</Text>
|
<Text style={[styles.title, { color: Colors[colorScheme].text }]}>Umrah Pilgrimage</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -95,7 +97,7 @@ export default function Programs() {
|
|||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</SafeAreaView>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { StyleSheet, SafeAreaView, View, TouchableOpacity, Dimensions } from 'react-native';
|
import { StyleSheet, View, TouchableOpacity, Dimensions } from 'react-native';
|
||||||
import { Text } from '@/components/Themed';
|
import { Text } from '@/components/Themed';
|
||||||
import i18n from '@/i18n';
|
import i18n from '@/i18n';
|
||||||
import { FontAwesome5 } from '@expo/vector-icons';
|
import { FontAwesome5 } from '@expo/vector-icons';
|
||||||
@@ -8,12 +8,14 @@ import CurrencyConverterModal from '@/components/CurrencyConverterModal';
|
|||||||
import HotelBusinessCardModal from '@/components/HotelBusinessCardModal';
|
import HotelBusinessCardModal from '@/components/HotelBusinessCardModal';
|
||||||
import LostKeyModal from '@/components/LostKeyModal';
|
import LostKeyModal from '@/components/LostKeyModal';
|
||||||
import PhrasebookModal from '@/components/PhrasebookModal';
|
import PhrasebookModal from '@/components/PhrasebookModal';
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
export default function ServicesScreen() {
|
export default function ServicesScreen() {
|
||||||
const [currencyModalVisible, setCurrencyModalVisible] = useState(false);
|
const [currencyModalVisible, setCurrencyModalVisible] = useState(false);
|
||||||
const [hotelModalVisible, setHotelModalVisible] = useState(false);
|
const [hotelModalVisible, setHotelModalVisible] = useState(false);
|
||||||
const [lostKeyModalVisible, setLostKeyModalVisible] = useState(false);
|
const [lostKeyModalVisible, setLostKeyModalVisible] = useState(false);
|
||||||
const [phrasebookModalVisible, setPhrasebookModalVisible] = useState(false);
|
const [phrasebookModalVisible, setPhrasebookModalVisible] = useState(false);
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
const services = [
|
const services = [
|
||||||
{
|
{
|
||||||
@@ -43,7 +45,7 @@ export default function ServicesScreen() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.container}>
|
<View style={[styles.container, { paddingTop: insets.top }]}>
|
||||||
<Text style={styles.title}>{i18n.t('services')}</Text>
|
<Text style={styles.title}>{i18n.t('services')}</Text>
|
||||||
|
|
||||||
<View style={styles.grid}>
|
<View style={styles.grid}>
|
||||||
@@ -69,7 +71,7 @@ export default function ServicesScreen() {
|
|||||||
visible={phrasebookModalVisible}
|
visible={phrasebookModalVisible}
|
||||||
onClose={() => setPhrasebookModalVisible(false)}
|
onClose={() => setPhrasebookModalVisible(false)}
|
||||||
/>
|
/>
|
||||||
</SafeAreaView>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import * as SplashScreen from 'expo-splash-screen';
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import 'react-native-reanimated';
|
import 'react-native-reanimated';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
import { StatusBar } from 'expo-status-bar';
|
||||||
|
|
||||||
import { initializeLanguage } from '@/i18n';
|
import { initializeLanguage } from '@/i18n';
|
||||||
import { makeRequest } from '@/utils/makeRequest';
|
import { makeRequest } from '@/utils/makeRequest';
|
||||||
@@ -67,6 +68,7 @@ function RootLayoutNav() {
|
|||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<StatusBar style="light" />
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
2175
package-lock.json
generated
2175
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@
|
|||||||
"@react-navigation/native": "^7.1.6",
|
"@react-navigation/native": "^7.1.6",
|
||||||
"adhan": "^4.4.3",
|
"adhan": "^4.4.3",
|
||||||
"expo": "~53.0.20",
|
"expo": "~53.0.20",
|
||||||
|
"expo-asset": "~11.1.7",
|
||||||
"expo-file-system": "~18.1.11",
|
"expo-file-system": "~18.1.11",
|
||||||
"expo-font": "~13.3.2",
|
"expo-font": "~13.3.2",
|
||||||
"expo-linking": "~7.1.7",
|
"expo-linking": "~7.1.7",
|
||||||
|
|||||||
Reference in New Issue
Block a user