parent
b9f3a35cd0
commit
47a08eda39
28 changed files with 301 additions and 286 deletions
After Width: | Height: | Size: 816 B |
After Width: | Height: | Size: 843 B |
@ -1,185 +1,31 @@ |
||||
import React, { useState, useEffect } from "react"; |
||||
import { StyleSheet, TouchableOpacity, View, Image, Text } from "react-native"; |
||||
import { Ionicons } from "@expo/vector-icons"; |
||||
import { Audio } from "expo-av"; |
||||
import * as React from 'react'; |
||||
import { View, Button } from 'react-native'; |
||||
import { Audio } from 'expo-av'; |
||||
|
||||
const audioBookPlaylist = [ |
||||
{ |
||||
title: "Hamlet - Act I", |
||||
author: "William Shakespeare", |
||||
source: "Librivox", |
||||
uri: "", |
||||
imageSource: |
||||
"http://www.archive.org/download/LibrivoxCdCoverArt8/hamlet_1104.jpg", |
||||
}, |
||||
export default function VoicePlayer({fileIds}) { |
||||
const [sound, setSound] = React.useState(); |
||||
|
||||
]; |
||||
|
||||
const MusicPlayer = () => { |
||||
const [isPlaying, setIsPlaying] = useState(false); |
||||
const [playbackInstance, setPlaybackInstance] = useState(null); |
||||
const [currentIndex, setCurrentIndex] = useState(0); |
||||
const [volume, setVolume] = useState(1.0); |
||||
const [isBuffering, setIsBuffering] = useState(true); |
||||
|
||||
useEffect( async () => { |
||||
try { |
||||
await Audio.setAudioModeAsync({ |
||||
allowsRecordingIOS: false, |
||||
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX, |
||||
playsInSilentModeIOS: true, |
||||
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX, |
||||
shouldDuckAndroid: true, |
||||
staysActiveInBackground: true, |
||||
playThroughEarpieceAndroid: true, |
||||
}); |
||||
|
||||
loadAudio(); |
||||
} catch (e) { |
||||
console.log(e); |
||||
} |
||||
}); |
||||
|
||||
const loadAudio = async () => { |
||||
try { |
||||
const playbackInstance = new Audio.Sound(); |
||||
const source = { |
||||
uri: audioBookPlaylist[currentIndex].uri, |
||||
}; |
||||
|
||||
const status = { |
||||
shouldPlay: isPlaying, |
||||
volume: volume, |
||||
}; |
||||
|
||||
playbackInstance.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate); |
||||
await playbackInstance.loadAsync(source, status, false); |
||||
setPlaybackInstance(playbackInstance); |
||||
} catch (e) { |
||||
console.log(e); |
||||
} |
||||
}; |
||||
|
||||
const onPlaybackStatusUpdate = (status) => { |
||||
setIsBuffering(status.isBuffering); |
||||
}; |
||||
|
||||
const handlePlayPause = async () => { |
||||
if(isPlaying) { |
||||
await playbackInstance.pauseAsync(); |
||||
}else{ |
||||
await playbackInstance.playAsync(); |
||||
} |
||||
|
||||
setIsPlaying(() => !isPlaying); |
||||
}; |
||||
|
||||
const handlePreviousTrack = async () => { |
||||
let { playbackInstance, currentIndex } = state; |
||||
if (playbackInstance) { |
||||
await playbackInstance.unloadAsync(); |
||||
setCurrentIndex( |
||||
currentIndex === 0 ? audioBookPlaylist.length - 1 : currentIndex - 1 |
||||
async function playSound() { |
||||
console.log('Loading Sound'); |
||||
const { sound } = await Audio.Sound.createAsync( |
||||
{uri : `https://dnvn.ir/api/v1/file/${fileIds}`} |
||||
); |
||||
loadAudio(); |
||||
} |
||||
}; |
||||
setSound(sound); |
||||
|
||||
const handleNextTrack = async () => { |
||||
if (playbackInstance) { |
||||
await playbackInstance.unloadAsync(); |
||||
setCurrentIndex( |
||||
currentIndex + 1 > audioBookPlaylist.length - 1 ? 0 : currentIndex + 1 |
||||
); |
||||
loadAudio(); |
||||
} |
||||
}; |
||||
console.log('Playing Sound'); |
||||
await sound.playAsync(); } |
||||
|
||||
React.useEffect(() => { |
||||
return sound |
||||
? () => { |
||||
console.log('Unloading Sound'); |
||||
sound.unloadAsync(); } |
||||
: undefined; |
||||
}, [sound]); |
||||
|
||||
const renderFileInfo = () => { |
||||
return playbackInstance ? ( |
||||
<View style={styles.trackInfo}> |
||||
<Text style={[styles.trackInfoText, styles.largeText]}> |
||||
{audioBookPlaylist[currentIndex].title} |
||||
</Text> |
||||
<Text style={[styles.trackInfoText, styles.smallText]}> |
||||
{audioBookPlaylist[currentIndex].author} |
||||
</Text> |
||||
<Text style={[styles.trackInfoText, styles.smallText]}> |
||||
{audioBookPlaylist[currentIndex].source} |
||||
</Text> |
||||
</View> |
||||
) : null; |
||||
}; |
||||
return ( |
||||
<View style={styles.container}> |
||||
<Image |
||||
style={styles.albumCover} |
||||
source={{ |
||||
uri: "http://www.archive.org/download/LibrivoxCdCoverArt8/hamlet_1104.jpg", |
||||
}} |
||||
/> |
||||
<View style={styles.controls}> |
||||
<TouchableOpacity |
||||
style={styles.control} |
||||
onPress={() => handlePreviousTrack()} |
||||
> |
||||
<Ionicons name="play-back" size={48} color="#444" /> |
||||
</TouchableOpacity> |
||||
<TouchableOpacity |
||||
style={styles.control} |
||||
onPress={() => handlePlayPause()} |
||||
> |
||||
{isPlaying ? ( |
||||
<Ionicons name="ios-pause" size={48} color="#444" /> |
||||
) : ( |
||||
<Ionicons name="ios-play-circle" size={48} color="#444" /> |
||||
)} |
||||
</TouchableOpacity> |
||||
<TouchableOpacity |
||||
style={styles.control} |
||||
onPress={() => handleNextTrack()} |
||||
> |
||||
<Ionicons name="play-forward" size={48} color="#444" /> |
||||
</TouchableOpacity> |
||||
</View> |
||||
{renderFileInfo()} |
||||
<Button title="Play Sound" onPress={playSound} /> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
backgroundColor: "#fff", |
||||
alignItems: "center", |
||||
justifyContent: "center", |
||||
}, |
||||
albumCover: { |
||||
width: 250, |
||||
height: 250, |
||||
}, |
||||
trackInfo: { |
||||
padding: 40, |
||||
backgroundColor: "#fff", |
||||
}, |
||||
|
||||
trackInfoText: { |
||||
textAlign: "center", |
||||
flexWrap: "wrap", |
||||
color: "#550088", |
||||
}, |
||||
largeText: { |
||||
fontSize: 22, |
||||
}, |
||||
smallText: { |
||||
fontSize: 16, |
||||
}, |
||||
control: { |
||||
margin: 20, |
||||
}, |
||||
controls: { |
||||
flexDirection: "row", |
||||
}, |
||||
}); |
||||
|
||||
export default MusicPlayer; |
||||
} |
@ -0,0 +1,26 @@ |
||||
import { View, Text, Image, Dimensions } from "react-native"; |
||||
import React from "react"; |
||||
import tw from "tailwind-rn"; |
||||
import fontSize from '../../../constants/fontSize'; |
||||
import Colors from '../../../constants/Colors'; |
||||
|
||||
const { width } = Dimensions.get("window"); |
||||
|
||||
const Book = ({ book }) => { |
||||
return ( |
||||
<View |
||||
style={[tw("w-full flex flex-row-reverse rounded-md p-2 my-2"), {backgroundColor : Colors.theme1.light.blue3}]} |
||||
> |
||||
<Image |
||||
source={{ uri: `https://dnvn.ir/api/v1/file/${book.fileId}` }} |
||||
style={[ |
||||
tw("rounded-md"), |
||||
{ width: width / 5.5, height: ((width / 5.5) * 3) / 2 }, |
||||
]} |
||||
/> |
||||
<Text style={[{fontFamily: "regular", fontSize: fontSize.base, marginRight : 10 }]}>{book.title}</Text> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default Book; |
@ -1,13 +1,76 @@ |
||||
import React from 'react' |
||||
import { View, Text } from 'react-native'; |
||||
import {connect} from 'react-redux'; |
||||
import React, { useState, useEffect } from "react"; |
||||
import { |
||||
SafeAreaView, |
||||
ScrollView, |
||||
StatusBar, |
||||
LayoutAnimation, |
||||
Platform, |
||||
Dimensions, |
||||
} from "react-native"; |
||||
import { connect } from "react-redux"; |
||||
import { publicApi } from "../../redux/actions"; |
||||
|
||||
import Navbar from "../../components/Navbar"; |
||||
import Drawer from "../../components/Drawer"; |
||||
import Book from "./components/Book"; |
||||
|
||||
const { height } = Dimensions.get("window"); |
||||
|
||||
function AR({ getArList, arList }) { |
||||
const [position, setPosition] = useState("100%"); |
||||
|
||||
useEffect(() => { |
||||
getArList(); |
||||
}, []); |
||||
|
||||
const setBoxPosition = () => { |
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); |
||||
setPosition(position === "100%" ? "0%" : "100%"); |
||||
}; |
||||
|
||||
function AR({}) { |
||||
return ( |
||||
<View> |
||||
<Text></Text> |
||||
</View> |
||||
) |
||||
<SafeAreaView |
||||
style={{ |
||||
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0, |
||||
position: "relative", |
||||
// minHeight: height,
|
||||
backgroundColor: "white", |
||||
}} |
||||
> |
||||
<Navbar |
||||
setBoxPosition={setBoxPosition} |
||||
headerOptions={{ |
||||
logo: false, |
||||
menu: false, |
||||
hamburgerMenu: false, |
||||
title: "واقعیت افزوده", |
||||
bookmark: false, |
||||
qr: false, |
||||
back: true, |
||||
}} |
||||
/> |
||||
<Drawer setBoxPosition={setBoxPosition} position={position} /> |
||||
<ScrollView |
||||
style={{ |
||||
paddingHorizontal: 16, |
||||
height: height, |
||||
backgroundColor: "white", |
||||
}} |
||||
contentContainerStyle={{ paddingBottom: 100 }} |
||||
> |
||||
{arList.length > 0 && |
||||
arList.map((book, index) => <Book book={book} key={index} />)} |
||||
</ScrollView> |
||||
</SafeAreaView> |
||||
); |
||||
} |
||||
|
||||
export default AR; |
||||
const mapStateToProps = (state) => ({ |
||||
arList: state.publicApi.arList, |
||||
}); |
||||
|
||||
const mapDispatchToProps = { |
||||
getArList: publicApi.getArList, |
||||
}; |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AR); |
||||
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 175 KiB |
@ -1,23 +1,37 @@ |
||||
import React from "react"; |
||||
import { View, Text, Dimensions } from "react-native"; |
||||
import tw from "tailwind-rn"; |
||||
import { Video } from "expo-av"; |
||||
|
||||
const {width} = Dimensions.get("window"); |
||||
|
||||
export default function Video({ name, file }) { |
||||
export default function VideoContent({ data }) { |
||||
const [status, setStatus] = React.useState({}); |
||||
const video = React.useRef(null); |
||||
return ( |
||||
<View style={tw("w-full flex-col mt-5")}> |
||||
<Text |
||||
style={[ |
||||
tw("w-full text-right text-green-900 mb-2"), |
||||
tw("w-full text-right text-green-900 mb-4"), |
||||
{ fontSize: width / 34, fontFamily: "bold" }, |
||||
]} |
||||
> |
||||
{name} |
||||
{'موضوع:' + ' ' + data.name} |
||||
</Text> |
||||
<View |
||||
style={[tw("w-full bg-blue-200 rounded-md"), { minHeight: 200 }]} |
||||
></View> |
||||
<View style={tw("flex flex-col")}> |
||||
<Video |
||||
ref={video} |
||||
style={{ width: "100%", height: (width * 9) / 16 - 16 }} |
||||
source={{ |
||||
uri: `https://dnvn.ir/api/v1/file/${data.fileIds}`, |
||||
}} |
||||
useNativeControls |
||||
resizeMode="cover" |
||||
// onFullscreenUpdate={setOrientation}
|
||||
isLooping |
||||
onPlaybackStatusUpdate={(status) => setStatus(() => status)} |
||||
/> |
||||
</View> |
||||
</View> |
||||
); |
||||
} |
||||
|
@ -0,0 +1,12 @@ |
||||
import { View, Text } from 'react-native'; |
||||
import React from 'react'; |
||||
|
||||
const Tests = () => { |
||||
return ( |
||||
<View> |
||||
<Text></Text> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
export default Tests; |
Loading…
Reference in new issue