diff --git a/app.json b/app.json index ac4813f..493cf03 100644 --- a/app.json +++ b/app.json @@ -40,6 +40,14 @@ { "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone." } + ], + [ + "expo-build-properties", + { + "ios": { + "useFrameworks": "static" + } + } ] ] } diff --git a/package-lock.json b/package-lock.json index 38087ce..c7fc712 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@expo-google-fonts/inter": "^0.2.3", "@expo/webpack-config": "^19.0.0", "@react-native-async-storage/async-storage": "1.18.2", + "@react-native-community/netinfo": "9.3.10", "@react-native-firebase/app": "^18.5.0", "@react-native-firebase/storage": "^18.5.0", "@react-navigation/core": "^6.2.1", @@ -41,6 +42,7 @@ "react-dom": "18.2.0", "react-native": "0.72.5", "react-native-gesture-handler": "~2.12.0", + "react-native-google-mobile-ads": "^12.3.0", "react-native-keychain": "^8.1.1", "react-native-modal": "^13.0.1", "react-native-reanimated": "~3.3.0", @@ -3706,6 +3708,11 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@iabtcf/core": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@iabtcf/core/-/core-1.5.6.tgz", + "integrity": "sha512-u2q9thI9vLurYZdGtyJsDYOqoeLc4EgQsYGSc+UVibYII61B/ENJPZS6eFlML1F0hSoTR/goptpo5nGRDkKd2w==" + }, "node_modules/@ide/backoff": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz", @@ -5695,6 +5702,14 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/@react-native-community/netinfo": { + "version": "9.3.10", + "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-9.3.10.tgz", + "integrity": "sha512-OwnqoJUp/4sa9e3ju+wQavAa8l0fiA3DheeLMKzKxtKeAe0CA7bNxWRM752JvRQ6A/igPnt1V0zSlu5owvQEuA==", + "peerDependencies": { + "react-native": ">=0.59" + } + }, "node_modules/@react-native-firebase/app": { "version": "18.5.0", "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-18.5.0.tgz", @@ -8830,6 +8845,14 @@ "node": ">=8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -15642,6 +15665,15 @@ "react-native": "*" } }, + "node_modules/react-native-google-mobile-ads": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/react-native-google-mobile-ads/-/react-native-google-mobile-ads-12.3.0.tgz", + "integrity": "sha512-dtOxlikdZbcECIqhivRSpThu+WQuLNL6F5aVeQOU3jPgbER6VMrJFaDXZuLyXZOcnsn5tKpV1jTqwctaZtSlBA==", + "dependencies": { + "@iabtcf/core": "^1.5.3", + "use-deep-compare-effect": "^1.8.1" + } + }, "node_modules/react-native-iphone-x-helper": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz", @@ -17818,6 +17850,22 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-deep-compare-effect": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/use-deep-compare-effect/-/use-deep-compare-effect-1.8.1.tgz", + "integrity": "sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "dequal": "^2.0.2" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13" + } + }, "node_modules/use-latest-callback": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz", diff --git a/package.json b/package.json index ceaa41e..366a693 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@expo-google-fonts/inter": "^0.2.3", "@expo/webpack-config": "^19.0.0", "@react-native-async-storage/async-storage": "1.18.2", + "@react-native-community/netinfo": "9.3.10", "@react-native-firebase/app": "^18.5.0", "@react-native-firebase/storage": "^18.5.0", "@react-navigation/core": "^6.2.1", @@ -42,6 +43,7 @@ "react-dom": "18.2.0", "react-native": "0.72.5", "react-native-gesture-handler": "~2.12.0", + "react-native-google-mobile-ads": "^12.3.0", "react-native-keychain": "^8.1.1", "react-native-modal": "^13.0.1", "react-native-reanimated": "~3.3.0", diff --git a/screens/AudioBook.tsx b/screens/AudioBook.tsx index a65a680..92aebf4 100644 --- a/screens/AudioBook.tsx +++ b/screens/AudioBook.tsx @@ -5,14 +5,20 @@ import { FlatList, TouchableOpacity, Dimensions, + ActivityIndicator } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import Navbar from "../components/Navbar"; import { useSelector } from "react-redux"; +import Slider from "react-native-slider"; import { FontSize, color } from "../GlobalStyles"; import { Audio } from "expo-av"; +import { AntDesign } from '@expo/vector-icons'; +import { BannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads'; import storage from "@react-native-firebase/storage"; +const adUnitId = __DEV__ ? TestIds.BANNER : 'ca-app-pub-xxxxxxxxxxxxx/yyyyyyyyyyyyyy'; + interface Audiobook { id: string; title: string; @@ -25,6 +31,7 @@ export default function AudioBook({ navigation }) { null ); const [isPlaying, setIsPlaying] = useState(false); + const [loading, setLoading] = useState(true); const [sound, setSound] = useState(null); const [currentPosition, setCurrentPosition] = useState(null); const [totalDuration, setTotalDuration] = useState(null); @@ -47,6 +54,7 @@ export default function AudioBook({ navigation }) { }) ); setAudiobooks(audiobookList); + setLoading(false); } catch (error) { console.error("Error fetching audiobooks:", error); } @@ -83,16 +91,24 @@ export default function AudioBook({ navigation }) { }; }, [selectedAudiobook]); + const handleSelectAudiobookClick = (item: Audiobook | null) => { + setSound(null); + setCurrentPosition(null); + setTotalDuration(null); + setIsPlaying(false); + setSelectedAudiobook(item) + } + const togglePlayback = async () => { if (!sound) return; if (isPlaying) { await sound.pauseAsync(); + setIsPlaying(false); } else { await sound.playAsync(); + setIsPlaying(true); } - - setIsPlaying(!isPlaying); }; const formatTime = (time: number | null) => { @@ -117,7 +133,7 @@ export default function AudioBook({ navigation }) { ( - + Audio Books + + { + loading && + } item.id} - renderItem={({ item }) => ( - setSelectedAudiobook(item)}> + renderItem={({ item, index }) => ( + handleSelectAudiobookClick(item)}> {item.title} )} + style={{ + marginTop: 20 + }} /> - {selectedAudiobook && ( - + + + + )} + style={{ + paddingBottom: 50, + minHeight: Dimensions.get("window").height, + }} + /> + {selectedAudiobook && ( + {selectedAudiobook.title} - {isPlaying ? "Playing" : "Paused"} + - {formatTime(currentPosition)} / {formatTime(totalDuration)} + {formatTime(currentPosition)} - {/* + */} - - {isPlaying ? "Pause" : "Play"} + onSlidingComplete={handleSliderChange} + /> + + + {formatTime(totalDuration)} + + + + + + + + {isPlaying ? : } + + + )} - - - )} - style={{ - paddingBottom: 50, - minHeight: Dimensions.get("window").height, - }} - /> );