Commit 66491651 authored by Malsha Jayakody's avatar Malsha Jayakody

Merge remote-tracking branch 'origin/exercise-manage' into final-app

parents 02666913 03d5b126
...@@ -85,6 +85,15 @@ android { ...@@ -85,6 +85,15 @@ android {
versionName "1.0" versionName "1.0"
} }
signingConfigs { signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
debug { debug {
storeFile file('debug.keystore') storeFile file('debug.keystore')
storePassword 'android' storePassword 'android'
...@@ -99,7 +108,7 @@ android { ...@@ -99,7 +108,7 @@ android {
release { release {
// Caution! In production, you need to generate your own keystore file. // Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android. // see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
} }
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
......
...@@ -39,3 +39,8 @@ newArchEnabled=false ...@@ -39,3 +39,8 @@ newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine. # Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead. # If set to false, you will be using JSC instead.
hermesEnabled=true hermesEnabled=true
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=midwife
MYAPP_UPLOAD_KEY_PASSWORD=midwife
\ No newline at end of file
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useRef, useEffect } from 'react';
import { StyleSheet, Text, View, ActivityIndicator, TouchableOpacity } from 'react-native'; import { StyleSheet, Text, View, ActivityIndicator, TouchableOpacity } from 'react-native';
import Video from 'react-native-video'; import Video from 'react-native-video';
import { Camera, useCameraDevice, CameraPermissionStatus } from 'react-native-vision-camera';
import CircleProgressBar from '../../../components/CircleProgressBar'; import CircleProgressBar from '../../../components/CircleProgressBar';
import { COLORS, ROUTES } from '../../../constants'; import { COLORS, ROUTES } from '../../../constants';
import Dot from '../../../assets/icons/dot.svg'; import Dot from '../../../assets/icons/dot.svg';
...@@ -9,10 +10,14 @@ const ExerciseView = (props) => { ...@@ -9,10 +10,14 @@ const ExerciseView = (props) => {
const { route } = props; const { route } = props;
const { data } = route.params; // Assuming you pass videoUrl as a route parameter const { data } = route.params; // Assuming you pass videoUrl as a route parameter
const videoRef = useRef(null); const videoRef = useRef(null);
const cameraRef = useRef(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true); const [videoPaused, setVideoPaused] = useState(true);
const [remainingTime, setRemainingTime] = useState(data.duration); const [remainingTime, setRemainingTime] = useState(null);
const [startCountDown, setStartCountDown] = useState(false); const [startCountDown, setStartCountDown] = useState(false);
const [isRecording, setIsRecording] = useState(false);
const [videoSource, setVideoSource] = useState('');
const device = useCameraDevice('front')
const handleLoad = () => { const handleLoad = () => {
setLoading(false); setLoading(false);
...@@ -32,24 +37,112 @@ const ExerciseView = (props) => { ...@@ -32,24 +37,112 @@ const ExerciseView = (props) => {
const handleVideoEnd = () => { const handleVideoEnd = () => {
setVideoPaused(true); setVideoPaused(true);
setStartCountDown(true); // setStartCountDown(true);
setRemainingTime(data.duration); // Reset remaining time setRemainingTime(data.duration); // Reset remaining time
}; };
const startRecording = async () => {
if (cameraRef.current && !isRecording) {
setIsRecording(true);
const video = await cameraRef.current.startRecording({
onRecordingFinished: (video) => {
setVideoSource(video.path);
setIsRecording(false);
console.log(video.path);
},
onRecordingError: (error) => {
console.error(`Recording Error: ${error.message}`);
setIsRecording(false);
},
});
}
};
const stopRecording = () => {
if (cameraRef.current && isRecording) {
cameraRef.current.stopRecording();
setIsRecording(false);
}
};
useEffect(() => {
// Initialize remainingTime when component mounts
setRemainingTime(data.duration * 2);
}, [data.duration]);
useEffect(() => { useEffect(() => {
if (remainingTime > 0 && startCountDown) { let interval;
const interval = setInterval(() => { if (!videoPaused && remainingTime > 0) {
setRemainingTime((prevTime) => prevTime - 1); interval = setInterval(() => {
setRemainingTime(prevTime => prevTime - 1);
}, 1000); }, 1000);
}
return () => clearInterval(interval);
}, [videoPaused, remainingTime]);
return () => clearInterval(interval); useEffect(() => {
async function requestPermissions() {
const cameraPermission = await Camera.requestCameraPermission();
const microphonePermission = await Camera.requestMicrophonePermission();
if (cameraPermission !== CameraPermissionStatus.AUTHORIZED || microphonePermission !== CameraPermissionStatus.AUTHORIZED) {
Linking.openSettings();
}
} }
}, [remainingTime, startCountDown]); requestPermissions();
}, []);
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Text style={styles.title}>Exercise Details</Text> <Text style={styles.title}>Exercise Details</Text>
<View style={styles.videoContainer}> <View style={styles.videoContainer}>
<Video
ref={videoRef}
source={{ uri: data.exercise_video_url }}
style={styles.video}
controls={true}
paused={videoPaused}
resizeMode="contain"
onLoad={handleLoad}
onBuffer={handleBuffer}
/>
{loading && <ActivityIndicator style={styles.loader} size="large" color="#0000ff" />}
</View>
<View style={styles.progressMainView}>
<CircleProgressBar percentage={(remainingTime / (data.duration * 2)) * 100} />
<View style={styles.progressSecondView}>
<Text>Remaining</Text>
<Text>{remainingTime} seconds</Text>
</View>
</View>
<View style={styles.buttonsContainer}>
<TouchableOpacity style={styles.button} onPress={videoPaused ? handlePlay : handlePause}>
<Text style={styles.buttonText}>{videoPaused ? 'Play' : 'Pause'}</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonRed} onPress={handlePause}>
<Text style={styles.buttonText}>Stop</Text>
</TouchableOpacity>
</View>
<View>
{device != null && (
<View style={styles.cameraContainer}>
<Camera
ref={cameraRef}
style={styles.camera}
device={device}
isActive={true}
video={true}
audio={true}
/>
</View>
)}
</View>
{/* <View style={styles.videoContainer}>
<Video <Video
ref={videoRef} ref={videoRef}
source={{ uri: data.exercise_video_url }} source={{ uri: data.exercise_video_url }}
...@@ -89,22 +182,23 @@ const ExerciseView = (props) => { ...@@ -89,22 +182,23 @@ const ExerciseView = (props) => {
))} ))}
</View> </View>
</View> </View>
</View> </View> */}
</View> </View>
); );
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1,
backgroundColor: '#fff', backgroundColor: '#fff',
alignItems: 'center', alignItems: 'center',
width: '100%',
height: 'auto'
}, },
title: { title: {
fontSize: 20, fontSize: 20,
fontWeight: 'bold', fontWeight: 'bold',
marginBottom: 20, marginBottom: 20,
marginTop: 10,
textAlign: 'center', textAlign: 'center',
}, },
videoContainer: { videoContainer: {
...@@ -112,9 +206,8 @@ const styles = StyleSheet.create({ ...@@ -112,9 +206,8 @@ const styles = StyleSheet.create({
aspectRatio: 16 / 9, aspectRatio: 16 / 9,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
marginTop: 40, marginTop: 10,
position: 'relative', position: 'relative',
top: '25%',
}, },
video: { video: {
width: '100%', width: '100%',
...@@ -133,10 +226,22 @@ const styles = StyleSheet.create({ ...@@ -133,10 +226,22 @@ const styles = StyleSheet.create({
paddingBottom: 10, paddingBottom: 10,
}, },
button: { button: {
backgroundColor: '#2196F3', backgroundColor: COLORS.primary,
padding: 10, justifyContent: 'center',
borderRadius: 50, alignItems: 'center',
marginHorizontal: 5, width: 80, // Adjust width and height as needed
height: 80,
borderRadius: 40, // Make the radius half of the width/height to make it circular
marginRight: 10
},
buttonRed: {
backgroundColor: COLORS.warning,
justifyContent: 'center',
alignItems: 'center',
width: 80, // Adjust width and height as needed
height: 80,
borderRadius: 40, // Make the radius half of the width/height to make it circular
marginRight: 10
}, },
buttonText: { buttonText: {
color: 'white', color: 'white',
...@@ -157,7 +262,7 @@ const styles = StyleSheet.create({ ...@@ -157,7 +262,7 @@ const styles = StyleSheet.create({
backgroundColor: COLORS.white, backgroundColor: COLORS.white,
marginHorizontal: 20, marginHorizontal: 20,
borderRadius: 15, borderRadius: 15,
marginTop: 10, marginTop: 20,
paddingVertical: 10, paddingVertical: 10,
}, },
progressSecondView: { progressSecondView: {
...@@ -197,6 +302,11 @@ const styles = StyleSheet.create({ ...@@ -197,6 +302,11 @@ const styles = StyleSheet.create({
backgroundColor: 'black', backgroundColor: 'black',
marginHorizontal: 5, marginHorizontal: 5,
}, },
cameraContainer: {
width: '100%',
aspectRatio: 16 / 9,
marginTop: 20,
},
}); });
export default ExerciseView; export default ExerciseView;
......
...@@ -9,7 +9,8 @@ import { ...@@ -9,7 +9,8 @@ import {
Image, Image,
View, View,
ScrollView, ScrollView,
Button Button,
ActivityIndicator
} from 'react-native'; } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'; import Icon from 'react-native-vector-icons/Ionicons';
import Logo from '../../../assets/icons/progress.svg'; import Logo from '../../../assets/icons/progress.svg';
...@@ -20,26 +21,6 @@ import { getAllExerciseDay } from '../../../services/exercises/index'; ...@@ -20,26 +21,6 @@ import { getAllExerciseDay } from '../../../services/exercises/index';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
const moment = require('moment'); const moment = require('moment');
// import Button from '../../../components/Button';
// import Carousel from 'react-native-snap-carousel-v4';
// const carouselRef = useRef(null);
// const sliderrenderItem = ({ item, index }) => {
// return (
// <View style={{
// backgroundColor: 'floralwhite',
// borderRadius: 5,
// height: 250,
// padding: 50,
// marginLeft: 25,
// marginRight: 25,
// }}>
// <Text style={{ fontSize: 30 }}>{item.title}</Text>
// <Text>{item.text}</Text>
// </View>
// );
// };
const Item = ({ item, onPress, backgroundColor, textColor }) => ( const Item = ({ item, onPress, backgroundColor, textColor }) => (
<TouchableOpacity onPress={onPress} style={[styles.item, { backgroundColor, flexDirection: "row", width: '100%' }]}> <TouchableOpacity onPress={onPress} style={[styles.item, { backgroundColor, flexDirection: "row", width: '100%' }]}>
<Image <Image
...@@ -58,6 +39,7 @@ const Item = ({ item, onPress, backgroundColor, textColor }) => ( ...@@ -58,6 +39,7 @@ const Item = ({ item, onPress, backgroundColor, textColor }) => (
); );
const MainMenuExercise = (props) => { const MainMenuExercise = (props) => {
const [loading, setLoading] = useState(true);
const { navigation } = props; const { navigation } = props;
const [selectedId, setSelectedId] = useState(null); const [selectedId, setSelectedId] = useState(null);
const [exerciseDataArray, setExerciseData] = useState(); const [exerciseDataArray, setExerciseData] = useState();
...@@ -99,6 +81,7 @@ const MainMenuExercise = (props) => { ...@@ -99,6 +81,7 @@ const MainMenuExercise = (props) => {
}; };
const retriveExerciseList = async () => { const retriveExerciseList = async () => {
setLoading(true)
let userDataString = await AsyncStorage.getItem('userData'); let userDataString = await AsyncStorage.getItem('userData');
let userData = JSON.parse(userDataString); let userData = JSON.parse(userDataString);
let todayDate = moment().format(); let todayDate = moment().format();
...@@ -111,7 +94,7 @@ const MainMenuExercise = (props) => { ...@@ -111,7 +94,7 @@ const MainMenuExercise = (props) => {
dataNum = 2; dataNum = 2;
} }
if (todayDateByFormat === "Friday" || todayDateByFormat === "Saturday" || todayDateByFormat === "Sunday") { if (todayDateByFormat === "Friday" || todayDateByFormat === "Saturday" || todayDateByFormat === "Sunday") {
dataNum = 3; dataNum = 2;
} }
let exerciseData = await getAllExerciseDay(userData._id, dataNum); let exerciseData = await getAllExerciseDay(userData._id, dataNum);
let dataArray = exerciseData.data.data; let dataArray = exerciseData.data.data;
...@@ -147,6 +130,8 @@ const MainMenuExercise = (props) => { ...@@ -147,6 +130,8 @@ const MainMenuExercise = (props) => {
} }
setExerciseData(exerciseModifiedAarray); setExerciseData(exerciseModifiedAarray);
setLoading(false)
console.log("new data ",exerciseModifiedAarray )
} }
} }
...@@ -172,6 +157,7 @@ const MainMenuExercise = (props) => { ...@@ -172,6 +157,7 @@ const MainMenuExercise = (props) => {
extraData={selectedId} extraData={selectedId}
style={{ marginBottom: 20 }} style={{ marginBottom: 20 }}
/> />
{loading && <ActivityIndicator style={styles.loader} size="large" color="#0000ff" />}
</ScrollView> </ScrollView>
<Text style={styles.topText}>Progress</Text> <Text style={styles.topText}>Progress</Text>
<View style={styles.progressMainView}> <View style={styles.progressMainView}>
...@@ -279,6 +265,12 @@ const styles = StyleSheet.create({ ...@@ -279,6 +265,12 @@ const styles = StyleSheet.create({
marginVertical: 5, marginVertical: 5,
marginHorizontal: 16, marginHorizontal: 16,
}, },
loader: {
position: 'absolute',
top: '50%',
left: '50%',
transform: [{ translateX: -25 }, { translateY: -25 }],
},
title: { title: {
fontSize: 14, fontSize: 14,
}, },
......
import axios from 'axios'; import axios from 'axios';
const BASE_PATH = 'http://10.0.2.2:8070/api/mother'; const BASE_PATH = 'https://emidwife-api.onrender.com/api/mother';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
//signIn API Call //signIn API Call
......
import axios from "axios"; import axios from "axios";
const BASE_PATH = 'http://16.170.242.186:8080'; let BASE_PATH = 'http://16.170.242.186:8080';
const BASE_PATH2 = 'http://10.0.2.2:8070/api/mother'; let BASE_PATH2 = 'https://emidwife-api.onrender.com/api/mother';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
...@@ -34,9 +34,9 @@ export let addInitialExercises = async (id, riskLevel) => { ...@@ -34,9 +34,9 @@ export let addInitialExercises = async (id, riskLevel) => {
} }
export let getAllExerciseDay = async (id, dateNum) => { export let getAllExerciseDay = async (id, dateNum) => {
try { try {
console.log("id", id)
let value = await axios.post(BASE_PATH2 + '/get_all_exercise_day', { let value = await axios.post(BASE_PATH2 + '/get_all_exercise_day', {
_id: id, _id: id,
day: dateNum day: dateNum
...@@ -47,7 +47,6 @@ export let getAllExerciseDay = async (id, dateNum) => { ...@@ -47,7 +47,6 @@ export let getAllExerciseDay = async (id, dateNum) => {
} }
} }
export let updateDeviceStatus = async (id, deviceStatus) => { export let updateDeviceStatus = async (id, deviceStatus) => {
try { try {
let value = await axios.post(BASE_PATH2 + '/update_device_status', { let value = await axios.post(BASE_PATH2 + '/update_device_status', {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment