bu kodumda gereksiz kodlar varsa veya iyileştirmeler yapabileceksen gönderiyorum yap. çok büyük ve hantal gibi kodlar:

import React, { useEffect, useState, useCallback } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, ScrollView, Dimensions, Alert, Image } from 'react-native';
import { useThemeAndLanguage } from '../utils/ThemeAndLanguageContext';
import { db, auth, storage } from '../utils/firebase';
import { collection, query, where, getDoc, getDocs, doc, setDoc, deleteDoc } from 'firebase/firestore';
import { ref, getDownloadURL, uploadBytes } from 'firebase/storage';
import translate from 'translate-google-api';
import { useVocabulary } from '../screens/VocabularyContext';
import Constants from 'expo-constants';
import { Audio } from 'expo-av';
import * as Crypto from 'expo-crypto';
import { Ionicons } from '@expo/vector-icons';

const apiKeyGoogle = Constants.expoConfig?.extra?.apiKeyGoogle || '';
const apiKeyVoiceRSS = Constants.expoConfig?.extra?.apiKeyVoiceRSS || '';
const window = Dimensions.get('window');

const WordExplanationBox = ({ word, onClose, onLayout, storyId }) => {
  const [translation, setTranslation] = useState('');
  const [wordInfo, setWordInfo] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [isDetailedInfoLoading, setIsDetailedInfoLoading] = useState(false);
  const [isWordSaved, setIsWordSaved] = useState(false);
  const [sound, setSound] = useState();
  const [isPlayingAudio, setIsPlayingAudio] = useState(false);

  const { locale, t, theme } = useThemeAndLanguage();
  const { updateVocabulary } = useVocabulary();
  const currentUser = auth.currentUser;

  const cleanArabicPunctuation = (text) => {
    if (text.includes(' ')) return text;
    return text.replace(/[،؛؟.:!،".]/g, '').trim();
  };

  const fetchTranslation = useCallback(async () => {
    try {
      const cleanedWord = cleanArabicPunctuation(word);
      const translateResponse = await translate(cleanedWord, { to: locale === 'tr' ? 'tr' : 'en' });
      setTranslation(translateResponse[0]);
    } catch (error) {
      console.error('Error fetching translation:', error);
    } finally {
      setIsLoading(false);
    }
  }, [word, locale]);

  const fetchWordInfo = useCallback(async () => {
    if (word.includes(' ') || /^\d+$/.test(word)) {
      setIsLoading(false);
      return;
    }

    setIsDetailedInfoLoading(true);
    const cleanedWord = cleanArabicPunctuation(word);
    const wordsRef = collection(db, "dictionary");
    const q = query(wordsRef, where("word", "==", cleanedWord));
    
    try {
      const querySnapshot = await getDocs(q);
      if (!querySnapshot.empty) {
        const docData = querySnapshot.docs[0].data();
        setWordInfo(docData);
      } else {
        const aiResponse = await getArabicWordInfo(cleanedWord);
        const parsedResponse = JSON.parse(aiResponse);
        await setDoc(doc(db, "dictionary", cleanedWord), parsedResponse);
        setWordInfo(parsedResponse);
      }
    } catch (error) {
      console.error("Error fetching word info:", error);
    } finally {
      setIsDetailedInfoLoading(false);
    }
  }, [word]);

  const checkUserLoginAndWordStatus = useCallback(async () => {
    if (currentUser && !/^\d+$/.test(word)) {
      const cleanedWord = cleanArabicPunctuation(word);
      const userWordsRef = doc(db, `users/${currentUser.uid}/words/${cleanedWord}`);
      const userWordsSnapshot = await getDoc(userWordsRef);
      setIsWordSaved(userWordsSnapshot.exists());
    } else {
      setIsWordSaved(false);
    }
  }, [currentUser, word]);

  useEffect(() => {
    fetchTranslation();
    if (!/^\d+$/.test(word)) {
      fetchWordInfo();
      checkUserLoginAndWordStatus();
    }
  }, [fetchTranslation, fetchWordInfo, checkUserLoginAndWordStatus, word]);

  const getArabicWordInfo = async (word) => {
    const englishPrompt = `
Provide brief information about an Arabic word in this JSON format. Include the following:
{
  "word": "given word without any changes",
  "root": "arabic root of the word",
  "meaningEN": "[English equivalents]",
  "meaningTR": "[turkish equivalents]",
  "wordTypeEN": "[Noun, verb, adjective, adverb, pronoun, preposition or null (select one of them and write)]",
  "wordTypeTR":"[isim, fiil, sıfat, zarf, zamir ve edat or null (select one of them and write lowercased)]",
  "exampleSentences": [
    {
      "sentence_no": 1,
      "arabic": "first arabic sentence example",
      "english": "English translation of the sentence.",
      "turkish": "Turkish translation of the example sentence."
    },
    ....write 3 senteces max.
  ]
}
The example sentences should reflect Islamic teachings or contexts. But do not use Quran verses and hadiths.
The given word is ${word}. Do not write anything else or the code will be broken.`;

    try {
      const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=${apiKeyGoogle}`, {
        method: 'POST',
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          contents: [
            {
              parts: [
                {
                  text: englishPrompt
                }
              ]
            }
          ]
        })
      });

      if (!response.ok) {
        throw new Error('Network response was not ok');
      }

      const data = await response.json();
      if (data.candidates && data.candidates[0] && data.candidates[0].content && data.candidates[0].content.parts && data.candidates[0].content.parts[0]) {
        return data.candidates[0].content.parts[0].text;
      } else {
        throw new Error('Unexpected response structure');
      }
    } catch (error) {
      console.error('Error fetching AI explanation:', error);
      return 'Failed to fetch AI explanation.';
    }
  };

  const renderWordInfo = () => {
    if (!wordInfo) return null;

    return (
      <View style={[styles.wordInfoContainer, { color: theme.textColor }]}>
        {/* Render Image Thumbnail if Available */}
        {wordInfo.image && (
          <View style={styles.imageContainer}>
            <Image
              source={{ uri: wordInfo.image }}
              style={styles.imageThumbnail}
              resizeMode="cover"
            />
          </View>
        )}

        {/* Information Table */}
        <View style={styles.table}>
          <View style={styles.tableRow}>
            <Text style={[styles.tableHeader, { color: theme.textColor }]}>
              {locale === 'tr' ? 'Kelime' : 'Word'}
            </Text>
            <Text style={[styles.tableContent, styles.arabicText, { color: theme.textColor }]}>
              {wordInfo.word}
            </Text>
          </View>
          <View style={styles.tableRow}>
            <Text style={[styles.tableHeader, { color: theme.textColor }]}>
              {locale === 'tr' ? 'Kök' : 'Root'}
            </Text>
            <Text style={[styles.tableContent, styles.arabicText, { color: theme.textColor }]}>
              {wordInfo.root}
            </Text>
          </View>
          <View style={styles.tableRow}>
            <Text style={[styles.tableHeader, { color: theme.textColor }]}>
              {locale === 'tr' ? 'Anlamı' : 'Meaning'}
            </Text>
            <Text style={[styles.tableContent, styles.alignRight, { color: theme.textColor }]}>
              {locale === 'tr' ? wordInfo.meaningTR.join(', ') : wordInfo.meaningEN.join(', ')}
            </Text>
          </View>
          <View style={styles.tableRow}>
            <Text style={[styles.tableHeader, { color: theme.textColor }]}>
              {locale === 'tr' ? 'Kelime Türü' : 'Word Type'}
            </Text>
            <Text style={[styles.tableContent, styles.alignRight, { color: theme.textColor }]}>
              {locale === 'tr' ? wordInfo.wordTypeTR : wordInfo.wordTypeEN}
            </Text>
          </View>
          <View style={styles.tableRow}>
            <Text style={[styles.tableHeader, styles.exampleTitle, { color: theme.textColor }]}>
              {locale === 'tr' ? 'Örnek Cümleler' : 'Example Sentences'}
            </Text>
          </View>
          {wordInfo.exampleSentences.map((sentence, index) => (
            <View key={index} style={styles.exampleContainer}>
              <Text style={[styles.tableContent, styles.arabicText, { color: theme.textColor }]}>
                {sentence.arabic}
              </Text>
              <Text style={[styles.tableContent, { color: theme.textColor }]}>
                {locale === 'tr' ? sentence.turkish : sentence.english}
              </Text>
            </View>
          ))}
        </View>
        <Text style={styles.warningText}>{t('geminiInfoWarning')}</Text>
      </View>
    );
  };

  const handleAddWord = async () => {
    if (!currentUser) {
      Alert.alert(t('notLoggedIn'), t('loginToAddWord'));
      return;
    }

    if (word.includes(' ') || /^\d+$/.test(word)) {
      Alert.alert(t('cannotAddSentence'), t('onlyWordsCanBeAdded'));
      return;
    }

    const cleanedWord = cleanArabicPunctuation(word);
    const userWordsRef = doc(db, `users/${currentUser.uid}/words/${cleanedWord}`);

    try {
      if (isWordSaved) {
        await deleteDoc(userWordsRef);
        setIsWordSaved(false);
      } else {
        await setDoc(userWordsRef, { date: new Date(), points: 100, storyId: storyId });
        setIsWordSaved(true);
      }

      await updateVocabulary();
    } catch (error) {
      console.error("Error updating user's saved words:", error);
      Alert.alert(t('error'), t('errorUpdatingWords'));
    }
  };

  const playSound = async () => {
    const cleanedWord = cleanArabicPunctuation(word);
    const wordHash = await Crypto.digestStringAsync(
      Crypto.CryptoDigestAlgorithm.SHA256,
      cleanedWord
    );
    const audioRef = ref(storage, `sounds/${wordHash}.mp3`);

    try {
      setIsPlayingAudio(true); // Oynatma başladığında durumu true yap

      let audioUrl;
      try {
        audioUrl = await getDownloadURL(audioRef);
      } catch (error) {
        const apiUrl = `https://api.voicerss.org/?key=${apiKeyVoiceRSS}&hl=ar-sa&c=MP3&f=44khz_16bit_stereo&r=-1&src=${encodeURIComponent(cleanedWord)}`;
        const response = await fetch(apiUrl);
        const blob = await response.blob();
        await uploadBytes(audioRef, blob);
        audioUrl = await getDownloadURL(audioRef);
      }

      const { sound: newSound } = await Audio.Sound.createAsync(
        { uri: audioUrl },
        { shouldPlay: true }
      );
      setSound(newSound);

      // Ses çalmaya başladıktan sonra dinle
      newSound.setOnPlaybackStatusUpdate((status) => {
        if (status.didJustFinish) {
          setIsPlayingAudio(false); // Ses bittiğinde durumu false yap
        }
      });
    } catch (error) {
      console.error('Error in playSound function:', error);
      Alert.alert(t('error'), t('errorPlayingAudio'));
    }
  };


  useEffect(() => {
    return sound
      ? () => {
          console.log('Unloading Sound');
          sound.unloadAsync();
        }
      : undefined;
  }, [sound]);

  if (isLoading) {
    return (
      <View style={[styles.container, { backgroundColor: theme.backgroundColorForWordBox }]}>
        <ActivityIndicator size="large" color="#81C784" />
      </View>
    );
  }

  return (
    <View style={[styles.container, { backgroundColor: theme.backgroundColorForWordBox }]} onLayout={onLayout}>
      <ScrollView contentContainerStyle={styles.scrollViewContent}>
        <Text style={[styles.wordText, { color: theme.textColor }]}>{word}</Text>
        <Text style={[styles.translationText, { color: theme.textColor }]}>{translation}</Text>

        <TouchableOpacity 
          style={[styles.listenButton, isPlayingAudio && styles.listenButtonDisabled, styles.playButton]} 
          onPress={playSound}
          disabled={isPlayingAudio}
        >
          <Text style={styles.listenButtonText}>
            {isPlayingAudio ? (
              <Text style={{ color: theme.primaryColor }}>{t('playing')}</Text>
            ) : (
              <>
                <Ionicons name="play" size={32} color={theme.primaryColor} />
              </>
            )}
          </Text>
        </TouchableOpacity>

        <Text style={styles.warningText}>{t('googleTranslateWarning')}</Text>

        {!(/^\d+$/.test(word)) && (
          <>
            {isDetailedInfoLoading ? (
              <>
                <Text style={styles.warningText}>{t('loadingGemini')}</Text>
                <ActivityIndicator size="large" color="#81C784" />
              </>
            ) : (
              <>
                {currentUser && !word.includes(' ') && (
                  <TouchableOpacity 
                    style={[
                      styles.addRemoveButton, 
                      isWordSaved && { backgroundColor: '#FF5252' }
                    ]} 
                    onPress={handleAddWord}
                  >
                    <Text style={styles.addRemoveButtonText}>
                      {isWordSaved ? t('removeWord') : t('addWord')}
                    </Text>
                  </TouchableOpacity>
                )}
                {!currentUser && !word.includes(' ') && (
                  <Text style={styles.warningText}>{t('loginToAddWord')}</Text>
                )}
                {renderWordInfo()}
              </>
            )}
          </>
        )}
      </ScrollView>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  closeButton: {
    alignSelf: 'flex-end',
  },
  scrollViewContent: {
    flexGrow: 1,
    minHeight: window.height,
  },
  wordText: {
    fontSize: 30,
    fontWeight: 'normal',
    textAlign: 'center',
  },
  translationText: {
    fontSize: 20,
    marginVertical: 10,
    textAlign: 'center',
  },
  wordInfoContainer: {
    marginTop: 20,
  },
  imageContainer: {
    alignItems: 'center',
    marginBottom: 15,
  },
  imageThumbnail: {
    width: window.width * 0.6,
    height: window.width * 0.6,
    borderRadius: 10,
  },
  table: {
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius: 5,
    overflow: 'hidden',
  },
  tableRow: {
    flexDirection: 'row',
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
    paddingVertical: 10,
    paddingHorizontal: 15,
    alignItems: 'center',
  },
  tableHeader: {
    flex: 1,
    fontWeight: 'bold',
  },
  tableContent: {
    flex: 2,
    textAlign: 'center',
  },
  exampleTitle: {
    fontWeight: 'bold',
    textAlign: 'center',
  },
  formattedTextContainer: {
    flexDirection: 'row-reverse',
    flexWrap: 'nowrap',
    justifyContent: 'flex-start',
    alignItems: 'right',
  },
  arabicText: {
    fontSize: 24,
    textAlign: 'right',
    writingDirection: 'rtl',
  },
  alignRight: {
    textAlign: 'right',
  },
  exampleContainer: {
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
    paddingVertical: 10,
    paddingHorizontal: 15,
  },
  warningText: {
    fontSize: 12,
    color: 'gray',
    textAlign: 'center',
    marginTop: 5,
  },
  addRemoveButton: {
    backgroundColor: '#81C784',
    padding: 10,
    borderRadius: 5,
    marginTop: 10,
    alignItems: 'center',
  },
  addRemoveButtonText: {
    color: 'white',
    fontWeight: 'bold',
  },
  listenButton: {
    marginTop: 10,
    alignSelf: 'center',
  },
  listenButtonDisabled: {
    opacity: 0.5,
  },
  playButton: {
    // Additional styles if needed
  },
  listenButtonText: {
    textAlign: 'center',
    justifyContent: 'center',
    alignItems: 'center',
    flexDirection: 'row',
  },
});

export default WordExplanationBox;

import React, { useEffect, useState, useRef, useCallback, useMemo } from 'react';
import { View, StyleSheet, Text, FlatList, Image, TouchableOpacity, ActivityIndicator, BackHandler } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import WordExplanationBox from './WordExplanationBox';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Font from 'expo-font';
import { useThemeAndLanguage } from '../utils/ThemeAndLanguageContext';
import { BottomSheetModal, BottomSheetModalProvider, BottomSheetScrollView } from '@gorhom/bottom-sheet';
import QuizScreen from './QuizScreen';
import { doc, getDoc } from 'firebase/firestore';
import { db } from '../utils/firebase';
import { useFocusEffect } from '@react-navigation/native';
import { useVocabulary } from './VocabularyContext';
import PropTypes from 'prop-types';
import ToggleHeartButton from './heart';

const ARABIC_FONTS = {
  'Scheherazade': require('../../assets/fonts/scheherazade.ttf'),
  'Adobe Arabic': require('../../assets/fonts/adobearabic.ttf'),
  'Amiri': require('../../assets/fonts/amiri.ttf'),
  'Noto Naskh Arabic': require('../../assets/fonts/noto.ttf'),
};
const STORAGE_KEY = '@user_words';
const Word = React.memo(({ word, onPress, style, isKnown }) => (
  <TouchableOpacity onPress={() => onPress(word)}>
    <Text style={[style, isKnown && styles.knownWord]}>{word}</Text>
  </TouchableOpacity>
));
Word.propTypes = {
  word: PropTypes.string.isRequired,
  onPress: PropTypes.func.isRequired,
  style: PropTypes.object,
  isKnown: PropTypes.bool,
};
const Sentence = React.memo(({ sentenceObj, selectedSentence, handleSentenceButtonPress, handleWordPress, fontSize, theme, arabicFont, knownWords }) => {
  if (sentenceObj.type === 'image') {
    return (
      <Image 
        source={{ uri: sentenceObj.content }} 
        style={[styles.imageStyle]} 
      />
    );
  }
  const isHeaderOrSubHeader = sentenceObj.type === 'header' || sentenceObj.type === 'subheader';
  return (
    <View style={[
      styles.sentenceContainer, 
      selectedSentence === sentenceObj.content && styles.selectedSentence,
 isHeaderOrSubHeader && (sentenceObj.type === 'header' ? styles.headerContainer : styles.subHeaderContainer),
    {
      borderRightColor: sentenceObj.type === 'header' ? theme.primaryColor : theme.secondaryColor
    }    ]}>
      <TouchableOpacity style={styles.explanationButton} onPress={() => handleSentenceButtonPress(sentenceObj.content)}>
        <Ionicons name="open" size={24} color={theme.primaryColor} />
      </TouchableOpacity>
      <View style={styles.arabicTextWrapper}>
        {sentenceObj.content.split(' ').map((word, wordIndex) => (
          <Word
            key={`${sentenceObj.id}-${wordIndex}`}
            word={word}
            onPress={handleWordPress}
            style={[
              styles.descriptionArabic,
              {
                fontSize: isHeaderOrSubHeader ? fontSize * 1.6 : fontSize * 1.4,
                color: theme.textColor,
                fontFamily: arabicFont,
               }
            ]}
            isKnown={knownWords.has(word)}
          />
        ))}
      </View>
    </View>
  );
});
Sentence.propTypes = {
  sentenceObj: PropTypes.shape({
    type: PropTypes.string,
    content: PropTypes.string,
    id: PropTypes.string,
  }).isRequired,
  selectedSentence: PropTypes.string,
  handleSentenceButtonPress: PropTypes.func.isRequired,
  handleWordPress: PropTypes.func.isRequired,
  fontSize: PropTypes.number.isRequired,
  theme: PropTypes.object.isRequired,
  arabicFont: PropTypes.string.isRequired,
  knownWords: PropTypes.instanceOf(Set).isRequired,
};

export default function ReadStoryScreen({ route, navigation }) {
  const { story, storyId } = route.params;
  const [fontSize, setFontSize] = useState(18);
  const [selectedWord, setSelectedWord] = useState(null);
  const [selectedSentence, setSelectedSentence] = useState(null);
  const [loading, setLoading] = useState(true);
  const [cachedStory, setCachedStory] = useState(null);
  const [hasQuiz, setHasQuiz] = useState(false);
  const bottomSheetModalRef = useRef(null);
  const settingsBottomSheetModalRef = useRef(null);
  const quizBottomSheetModalRef = useRef(null);
  const { locale, theme, arabicFont, setFontFamily, t } = useThemeAndLanguage();
  const [activeModal, setActiveModal] = useState(null);
  const [knownWords, setKnownWords] = useState(new Set());
  const { vocabulary, isLoggedIn, userId} = useVocabulary();


  const increaseFontSize = useCallback(() => setFontSize(prevSize => prevSize + 2), []);
  const decreaseFontSize = useCallback(() => setFontSize(prevSize => prevSize - 2), []);

  const closeAllModals = useCallback(() => {
    bottomSheetModalRef.current?.dismiss();
    settingsBottomSheetModalRef.current?.dismiss();
    quizBottomSheetModalRef.current?.dismiss();
    setActiveModal(null);
  }, []);

  const openSettingsModal = useCallback(() => {
    settingsBottomSheetModalRef.current?.present();
    setActiveModal('settings');
  }, []);

  const openQuizModal = useCallback(() => {
    quizBottomSheetModalRef.current?.present();
    setActiveModal('quiz');
  }, []);

  const handleWordPress = useCallback((word) => {
    setSelectedWord(word);
    setSelectedSentence(null);
    bottomSheetModalRef.current?.present();
    setActiveModal('word');
  }, []);

  const handleSentenceButtonPress = useCallback((sentence) => {
    setSelectedSentence(sentence);
    setSelectedWord(null);
    bottomSheetModalRef.current?.present();
    setActiveModal('sentence');
  }, []);

  const loadFonts = useCallback(async () => {
    await Font.loadAsync(ARABIC_FONTS);
  }, []);

  const fetchStoryFromFirestore = useCallback(async (id) => {
    const storyDocRef = doc(db, 'stories', id);
    const storyDoc = await getDoc(storyDocRef);
    return storyDoc.exists() ? { id: storyDoc.id, ...storyDoc.data() } : null;
  }, []);

  const fetchStory = useCallback(async () => {
    try {
      let storyData;
      if (story) {
        storyData = story;
      } else if (storyId) {
        const cachedData = await AsyncStorage.getItem(`story-${storyId}`);
        if (cachedData) {
          storyData = JSON.parse(cachedData);
        } else {
          storyData = await fetchStoryFromFirestore(storyId);
          if (storyData) {
            await AsyncStorage.setItem(`story-${storyId}`, JSON.stringify(storyData));
          }
        }
      }

      if (storyData) {
        setCachedStory(storyData);
        setHasQuiz(storyData.test_questions && storyData.test_questions.length > 0);
      }
    } catch (error) {
      console.error('Error fetching story:', error);
    } finally {
      setLoading(false);
    }
  }, [story, storyId, fetchStoryFromFirestore]);

  const fetchKnownWords = useCallback(async () => {
    if (!isLoggedIn) {
      setKnownWords(new Set());
      return;
    }

    try {
      const cachedWords = await AsyncStorage.getItem(STORAGE_KEY);
      if (cachedWords) {
        const wordsArray = JSON.parse(cachedWords);
        setKnownWords(new Set(wordsArray.map(word => word.word)));
      }
    } catch (error) {
      console.error('Error fetching known words:', error);
    }
  }, [isLoggedIn]);

  useEffect(() => {
    const initialize = async () => {
      await loadFonts();
      await fetchStory();
      await fetchKnownWords();
    };

    initialize();
  }, [loadFonts, fetchStory, fetchKnownWords]);

  useEffect(() => {
    if (cachedStory) {
      const storyTitle = locale === 'tr' ? cachedStory.storytitleturkish : cachedStory.storytitleenglish;
      const truncatedTitle = storyTitle.length > 23 ? `${storyTitle.substring(0, 23)}...` : storyTitle;

      navigation.setOptions({
        title: truncatedTitle,
        headerStyle: { backgroundColor: theme.lighterCardBackgroundColor },
        headerTintColor: theme.textColor,
        headerTitleStyle: { color: theme.textColor, fontWeight: 'bold' },
        headerRight: () => (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
  <ToggleHeartButton storyId={cachedStory.id} initialHeartCount={cachedStory.hearts} />
  <TouchableOpacity onPress={openSettingsModal} style={styles.fontSizeControl}>
    <Ionicons name="settings-outline" size={24} color={theme.textColor} />
  </TouchableOpacity>
</View>


          
        ),
      });
    }
  }, [navigation, cachedStory, theme, locale, openSettingsModal]);

  useFocusEffect(
    useCallback(() => {
      const onBackPress = () => {
        if (activeModal) {
          closeAllModals();
          return true;
        }
        return false;
      };

      BackHandler.addEventListener('hardwareBackPress', onBackPress);

      return () => BackHandler.removeEventListener('hardwareBackPress', onBackPress);
    }, [activeModal, closeAllModals])
  );

  const renderSentence = useCallback(({ item: sentenceObj }) => (
    <Sentence
      sentenceObj={sentenceObj}
      selectedSentence={selectedSentence}
      handleSentenceButtonPress={handleSentenceButtonPress}
      handleWordPress={handleWordPress}
      fontSize={fontSize}
      theme={theme}
      arabicFont={arabicFont}
      knownWords={knownWords}
    />
  ), [selectedSentence, handleSentenceButtonPress, handleWordPress, fontSize, theme, arabicFont, knownWords]);

  const memoizedData = useMemo(() => cachedStory?.sentences || [], [cachedStory]);

  const keyExtractor = useCallback((item) => item.id.toString(), []);

  useEffect(() => {
    const updatedKnownWords = new Set(vocabulary.map(word => word.word));
    setKnownWords(updatedKnownWords);
  }, [vocabulary]);

  if (loading) {
    return (
      <View style={[styles.loadingContainer, { backgroundColor: theme.backgroundColorForWordBox }]}>
        <ActivityIndicator size="large" color={theme.primaryColor} />
      </View>
    );
  }

  if (!cachedStory) {
    return (
      <View style={[styles.loadingContainer, { backgroundColor: theme.backgroundColorForWordBox }]}>
        <Text style={{ color: theme.textColor }}>{t('storyNotFound')}</Text>
      </View>
    );
  }

  return (
    <BottomSheetModalProvider>
      <View style={[styles.container, { backgroundColor: theme.backgroundColorForWordBox }]}>
        <FlatList
          data={memoizedData}
          renderItem={renderSentence}
          keyExtractor={keyExtractor}
          ListHeaderComponent={() => (
            <>
              <Image source={{ uri: cachedStory.thumbnail }} style={styles.thumbnail} />
              <View style={styles.content}>
                <View style={styles.header}>
                  <Text style={[styles.titleArabic, { color: theme.textColor, fontFamily: arabicFont }]}>{cachedStory.storytitlearabic}</Text>
                  <Text style={[styles.titleTurkish, { color: theme.secondaryColor }]}>
                    {locale === 'tr' ? cachedStory.storytitleturkish : cachedStory.storytitleenglish}
                  </Text>
                </View>
              </View>
            </>
          )}
          initialNumToRender={10}
          maxToRenderPerBatch={5}
          windowSize={10}
        />

        {hasQuiz && (
          <TouchableOpacity
            style={[styles.quizButton, { backgroundColor: theme.primaryColor }]}
            onPress={openQuizModal}
          >
            <Text style={styles.quizButtonText}>{t('startQuiz')}</Text>
          </TouchableOpacity>
        )}

<BottomSheetModal
          ref={bottomSheetModalRef}
          index={0}
          snapPoints={['45%', '90%']}
          handleStyle={{ backgroundColor: theme.backgroundColorForWordBox }}
          onDismiss={() => setActiveModal(null)}
        >
          <BottomSheetScrollView contentContainerStyle={styles.bottomSheetContent}>
            <WordExplanationBox
              word={selectedWord || selectedSentence}
              storyId={cachedStory.id}
              onClose={() => bottomSheetModalRef.current?.dismiss()}
            />
          </BottomSheetScrollView>
        </BottomSheetModal>

        <BottomSheetModal
          ref={settingsBottomSheetModalRef}
          index={0}
          snapPoints={['85%']}
          handleStyle={{ backgroundColor: theme.backgroundColorForWordBox }}
          onDismiss={() => setActiveModal(null)}
        >
          <BottomSheetScrollView 
            contentContainerStyle={[
              styles.settingsContent,
              { backgroundColor: theme.backgroundColorForWordBox }
            ]}
          >
            <View style={styles.exampleCard}>
              <Text style={[styles.exampleText, { fontSize: fontSize * 1.4, fontFamily: arabicFont }]}>
                (هذا مثال على الكتابة بالعربية)
              </Text>
            </View>
            
            <View style={styles.fontSizeControls}>
              <TouchableOpacity onPress={increaseFontSize} style={styles.fontSizeButton}>
                <Ionicons name="add-circle-outline" size={40} color={theme.primaryColor} />
                <Text style={styles.fontSizeButtonText}>{t('increaseFontSize')}</Text>
              </TouchableOpacity>
              <TouchableOpacity onPress={decreaseFontSize} style={styles.fontSizeButton}>
                <Ionicons name="remove-circle-outline" size={40} color={theme.primaryColor} />
                <Text style={styles.fontSizeButtonText}>{t('decreaseFontSize')}</Text>
              </TouchableOpacity>
            </View>
            
            <View style={styles.fontOptionsContainer}>
              {Object.keys(ARABIC_FONTS).map((font) => (
                <TouchableOpacity
                  key={font}
                  style={styles.fontOption}
                  onPress={() => setFontFamily(font)}
                >
                  <Text style={styles.fontOptionText}>{font}</Text>
                  <Text style={[styles.fontOptionSample, { fontFamily: font }]}>
                    (اقرأ العربية)
                  </Text>
                </TouchableOpacity>
              ))}
            </View>
          </BottomSheetScrollView>
        </BottomSheetModal>

        {hasQuiz && (
          <BottomSheetModal
            ref={quizBottomSheetModalRef}
            index={0}
            snapPoints={['90%']}
            handleStyle={{ backgroundColor: theme.backgroundColorForWordBox }}
            onDismiss={() => setActiveModal(null)}
          >
            <QuizScreen
              story={cachedStory}
              onClose={() => {
                quizBottomSheetModalRef.current?.dismiss();
                setActiveModal(null);
              }}
            />
          </BottomSheetModal>
        )}
      </View>
          </BottomSheetModalProvider>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  knownWord: {
    backgroundColor: 'rgba(0, 255, 0, 0.1)',
    borderRadius: 10,
  },
  loadingContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  thumbnail: {
    width: '100%',
    aspectRatio:1/1, 
      },
  content: {
    padding: 16,
  },
  header: {
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
  },
  titleArabic: {
    fontSize: 26,
  },
  titleTurkish: {
    fontSize: 20,
    marginTop: 4,
    textAlign: 'center',
  },
  headerRight: {
    flexDirection: 'row',
    alignItems: 'center',
    marginRight: 10,
  },
  fontSizeControl: {
    marginHorizontal: 5,
  },
  sentenceContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 8,
    paddingLeft: 10,
  },
  explanationButton: {
    marginRight: 2,
  },
  arabicTextWrapper: {
    flex: 1,
    flexDirection: 'row-reverse',
    flexWrap: 'wrap',
    paddingRight: 15,
  },
  descriptionArabic: {
    marginLeft: 2,
    padding: 2,
  },
  selectedSentence: {
    backgroundColor: 'rgba(255, 215, 0, 0.3)',
  },
  settingsContent: {
    flexGrow: 1,
    paddingBottom: 20,
  },
  fontExampleContainer: {
    alignItems: 'center',
    marginBottom: 20,
  },
  exampleLabel: {
    fontSize: 18,
    fontWeight: 'bold',
    marginBottom: 10,
  },
  exampleBox: {
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 10,
    padding: 10,
    width: '80%',
    alignItems: 'center',
    backgroundColor: 'white',
    elevation: 4,
  },
  fontSizeControls: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginVertical: 25,
    paddingHorizontal: 25,
    width: '80%',
    alignSelf: 'center',
  },
  fontSizeControl: {
    alignItems: 'center',
    padding: 10,
  },
  fontSizeControlText: {
    marginTop: 5,
    fontSize: 14,
    color: 'gray',
  },
  selectFontLabel: {
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 10,
  },
  fontGrid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
    marginTop: 20,
    width: '80%',
    alignSelf: 'center',
  },
  fontOptionGridItem: {
    width: '45%',
    padding: 5,
    marginBottom: 20,
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 10,
    alignItems: 'center',
    backgroundColor: 'white',
    elevation: 4,
  },
  fontOptionText: {
    fontSize: 16,
    marginBottom: 5,
    textAlign: 'center',
  },
  quizButton: {
 display: 'flex', // Flexbox ile genişliği içeriğe göre yap
  justifyContent: 'center', // İçeriği ortala
  alignItems: 'center', // İçeriği dikeyde ortala
    padding: 10,
  },
  quizButtonText: {
    color: 'white',
    fontWeight: 'bold',
  },
  bottomSheetContent: {
    flexGrow: 1,
  },
  settingsContent: {
    flexGrow: 1,
    paddingHorizontal: 20,
    paddingBottom: 20,
    alignItems: 'center',
  },
  exampleCard: {
    backgroundColor: 'white',
    borderRadius: 10,
    padding: 15,
    marginVertical: 20,
    width: '90%',
    alignItems: 'center',
    elevation: 4,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
  },
  exampleText: {
    textAlign: 'center',
  },
  fontSizeControls: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    width: '100%',
    marginBottom: 20,
  },
  fontSizeButton: {
    alignItems: 'center',
  },
  fontSizeButtonText: {
    marginTop: 5,
    fontSize: 12,
    color: 'gray',
    textAlign: 'center',
  },
  fontOptionsContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'space-between',
    width: '100%',
  },
  fontOption: {
    width: '48%',
    backgroundColor: 'white',
    borderRadius: 10,
    padding: 10,
    marginBottom: 15,
    alignItems: 'center',
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.22,
    shadowRadius: 2.22,
  },
  fontOptionText: {
    fontSize: 16,
    marginBottom: 5,
  },
  fontOptionSample: {
    fontSize: 18,
  },
headerContainer: {
  marginVertical: 10,
  backgroundColor: 'rgba(0, 0, 0, 0.03)',
  borderRightWidth: 5,
  width: '97%',  // Genişliği biraz küçülttük

},
subHeaderContainer: {
  marginVertical: 10,
  backgroundColor: 'rgba(0, 0, 0, 0.03)',
  borderRightWidth: 3,
  width: '97%', 
},
imageStyle: {
  width: "90%",
  alignSelf: "center", // Ortalamak için bunu ekledik
  marginBottom: 10,
  aspectRatio: 1 / 1, // Oranı sabit tutmak için ekledik
elevation:1,
borderRadius:15,
},
});

gereksiz kodları ve yorumları sil istersen