- 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.
174 lines
4.6 KiB
TypeScript
174 lines
4.6 KiB
TypeScript
import { StyleSheet, SafeAreaView, ScrollView, I18nManager, Modal, Pressable } from 'react-native';
|
|
import { Text, View } from '@/components/Themed';
|
|
import FeatureCard from '@/components/FeatureCard';
|
|
import PrayerTimeCard from '@/components/PrayerTimeCard';
|
|
import ServicesGrid from '@/components/ServicesGrid';
|
|
import i18n from '@/i18n';
|
|
import * as Updates from 'expo-updates';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import Colors from '@/constants/Colors';
|
|
import { useState } from 'react';
|
|
|
|
|
|
export default function HomeScreen() {
|
|
const [modalVisible, setModalVisible] = useState(false);
|
|
|
|
const changeLanguage = async (lang: 'en' | 'tk' | 'ru') => {
|
|
if (!lang) return;
|
|
setModalVisible(false);
|
|
if (lang === i18n.locale.substring(0, 2)) return;
|
|
await AsyncStorage.setItem('user-language', lang);
|
|
i18n.locale = lang;
|
|
I18nManager.forceRTL(false); // Assuming LTR for all three languages
|
|
Updates.reloadAsync();
|
|
};
|
|
|
|
const languages = [
|
|
{ label: 'English', value: 'en' },
|
|
{ label: 'Türkmen', value: 'tk' },
|
|
{ label: 'Русский', value: 'ru' },
|
|
];
|
|
|
|
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}
|
|
visible={modalVisible}
|
|
onRequestClose={() => {
|
|
setModalVisible(!modalVisible);
|
|
}}>
|
|
<Pressable style={styles.modalOverlay} onPress={() => setModalVisible(false)}>
|
|
<View style={styles.modalView}>
|
|
{languages.map((lang) => (
|
|
<Pressable
|
|
key={lang.value}
|
|
style={styles.modalButton}
|
|
onPress={() => changeLanguage(lang.value as 'en' | 'tk' | 'ru')}>
|
|
<Text style={styles.modalButtonText}>{lang.label}</Text>
|
|
</Pressable>
|
|
))}
|
|
</View>
|
|
</Pressable>
|
|
</Modal>
|
|
<ScrollView>
|
|
<View style={styles.innerContainer}>
|
|
<FeatureCard
|
|
badgeText="Şu gün, 07:00"
|
|
title="Aýşe metjidi"
|
|
description="Oteldan ugraýar, 1-njy etazda garaşmaly"
|
|
image={require('@/assets/images/aisha.jpg')}
|
|
/>
|
|
|
|
<PrayerTimeCard />
|
|
<ServicesGrid services={services} />
|
|
</View>
|
|
</ScrollView>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: Colors.dark.background,
|
|
},
|
|
innerContainer: {
|
|
paddingHorizontal: 15,
|
|
},
|
|
header: {
|
|
display: 'none', // hide for now, will show later
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
paddingHorizontal: 15,
|
|
},
|
|
title: {
|
|
fontSize: 22,
|
|
fontWeight: 'bold',
|
|
marginVertical: 15,
|
|
},
|
|
langSwitcher: {
|
|
flexDirection: 'row',
|
|
},
|
|
langText: {
|
|
color: '#fff',
|
|
paddingHorizontal: 5,
|
|
fontWeight: 'bold',
|
|
},
|
|
cardRow: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
},
|
|
modalOverlay: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
},
|
|
modalView: {
|
|
margin: 20,
|
|
backgroundColor: Colors.dark.secondary,
|
|
borderRadius: 20,
|
|
padding: 35,
|
|
alignItems: 'center',
|
|
shadowColor: '#000',
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 2,
|
|
},
|
|
shadowOpacity: 0.25,
|
|
shadowRadius: 4,
|
|
elevation: 5,
|
|
},
|
|
modalButton: {
|
|
padding: 10,
|
|
borderBottomWidth: 1,
|
|
borderBottomColor: '#333',
|
|
width: '100%',
|
|
},
|
|
modalButtonText: {
|
|
color: 'white',
|
|
textAlign: 'center',
|
|
},
|
|
});
|
|
|
|
const pickerSelectStyles = StyleSheet.create({
|
|
inputIOS: {
|
|
fontSize: 16,
|
|
paddingVertical: 12,
|
|
paddingHorizontal: 10,
|
|
borderWidth: 1,
|
|
borderColor: Colors.dark.secondary,
|
|
borderRadius: 4,
|
|
color: 'white',
|
|
paddingRight: 30, // to ensure the text is never behind the icon
|
|
},
|
|
inputAndroid: {
|
|
fontSize: 16,
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 8,
|
|
borderWidth: 0.5,
|
|
borderColor: Colors.dark.secondary,
|
|
borderRadius: 8,
|
|
color: 'white',
|
|
paddingRight: 30, // to ensure the text is never behind the icon
|
|
},
|
|
});
|