src/views/assessment/menu/MenuView.js
import React from 'react';
import {
Image,
StyleSheet,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import DrawingView from '../drawing/DrawingView';
import FreeTextView from '../freetext/FreeTextView';
import Grading from '../grading/Grading';
import Helper from '../../../components/helper/Helper';
import MenuIcon from './components/MenuIcon';
import ScoreBoard from '../ScoreBoard';
import {
getAssessmentId,
getComment,
getDrawing,
getGrading,
setAssessmentId,
setCreateDate,
} from '../../../objects/Assessment';
import {addAssessment, numberOfAssessments} from '../../../database/UsersDAO';
import {compliments} from '../../../utils/HelpString';
import {globalStyles} from '../../../styles/styles';
/**
* The assessment menu where the user can go to Grading, Freetext, Drawing or back to StartView.
* @param {function} setGoToActivity - If set to false, the user is redirected back to main menu (StartView)
* @returns {Object} The menu and button to finish assessing the activity
*/
export default function Menu({setGoToActivity}) {
//Determining whether to show the moodmenu or not
const [showGrading, setShowGrading] = React.useState(false);
//Determining whether to show textpage or not
const [showFreeTextView, setShowFreeTextView] = React.useState(false);
//Determining whether to show drawing or not
const [showDrawingView, setShowDrawingView] = React.useState(false);
//Determining whether to show
const [showScoreboard, setShowScoreboard] = React.useState(false);
//If true, go to freetext. Pass down method to close freetext and come back to menu
if (showFreeTextView)
return <FreeTextView setShowFreeText={setShowFreeTextView} />;
//If true, go to drawing. Pass down method to close drawing and come back to menu
else if (showDrawingView)
return <DrawingView setShowDrawingView={setShowDrawingView} />;
//If true, show scoreboard. Pass random number used to give random compliment
else if (showScoreboard) {
const randomIndex = Math.floor(Math.random() * compliments.length);
return <ScoreBoard randomIndex={randomIndex} />;
} else {
//Getting the comment from the assessment object
const comment = getComment();
return (
<TouchableWithoutFeedback //Touch outside of the Grading-component will close the grading component
style={{flex: 1, position: 'absolute'}}
onPress={() => setShowGrading(false)}>
{/* Make the navigation menu */}
<View style={[styles.container]}>
<View
style={[
styles.menuBox,
!showGrading && globalStyles.border, //Only shows border when grading is not showing
{height: showGrading ? 0 : '60%'}, //Only shows menu if grading is not showing
]}>
<MenuIcon
delay={100} //Ripple effect
onPress={() => setShowGrading(!showGrading)} //Show Grading if pressed
/>
<MenuIcon
delay={300} //Ripple effect
onPress={() => setShowFreeTextView(true)} //Show FreeText if pressed
png={require('../../../assets/notebook.png')} /* Education icons created by Freepik - Flaticon */
/>
<MenuIcon
delay={500} //Ripple effect
onPress={() => setShowDrawingView(true)} //Show Drawing if pressed
png={require('../../../assets/color-palette.png')} /* Education icons created by Freepik - Flaticon */
/>
</View>
<View
style={[
styles.bubbleContainer,
//Only show the bubble if there is a comment
{
height:
comment.length > 0 && comment.length < 80
? '45%'
: 0,
},
]}>
<Image //The picture for the bubble
source={require('../../../assets/thinkbubble.png')}
style={globalStyles.coverAll}
/>
{/* The text inside the bubble */}
<Text style={styles.textBox}>{comment}</Text>
</View>
{showGrading ? ( //If showGrading is true, the Grading component is shown with method to close
<Grading setShowGrading={setShowGrading} />
) : (
//If not, show the button to save the assessment and go back to StartView
<TouchableOpacity
style={styles.backButton}
onPress={() => {
const hasComment = getComment().length != 0;
const hasGrading = getGrading().length != 0;
const hasDrawing = getDrawing() != null;
//Only do the saving-logic if there is anything to save
if (hasComment || hasGrading || hasDrawing) {
if (getAssessmentId() === 0)
setAssessmentId(
numberOfAssessments() + 1, //Serial ID
);
const today = new Date();
setCreateDate(today.toDateString()); //Add current date to assessment
addAssessment(); //Add the current assessment to user assessments
setShowScoreboard(true); //Show the scoreboard
//Define how long before user is redirected back to startview
const timer =
6500 -
(hasComment ? 0 : 1000) -
(hasGrading ? 0 : 1000) -
(hasDrawing ? 0 : 1000);
//After that amount of time, go back to startview
setTimeout(() => {
setGoToActivity(false);
}, timer);
} else {
//If nothing to save, simply go back to startview
setGoToActivity(false);
}
}}>
<Image //Image for the button
source={require('../../../assets/ok.png')}
style={[
globalStyles.coverAll,
{resizeMode: 'contain'},
]}
/>
</TouchableOpacity>
)}
{/* Shows the helper for both Grading (id === 2) and Menu (id === 1) */}
<Helper id={showGrading ? 2 : 1} />
</View>
</TouchableWithoutFeedback>
);
}
}
/**
* Local styles
* @type {Object}
*/
const styles = StyleSheet.create({
container: {
flex: 1, //Covers all available space
justifyContent: 'center', //In the vertical center
},
menuBox: {
width: '8%',
borderRadius: 50,
backgroundColor: '#05A3C7',
position: 'absolute',
right: '1%',
},
icon: {
flex: 1,
resizeMode: 'contain',
width: '100%',
},
bubbleContainer: {
position: 'absolute',
width: '35%',
right: '68%',
top: '2%',
},
textBox: {
position: 'absolute',
height: '30%',
width: '55%',
top: '15%',
left: '20%',
fontSize: 20,
},
backButton: {
position: 'absolute',
height: '11%',
aspectRatio: 1,
right: '1%',
bottom: '5%',
},
});