Home Reference Source

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%',
    },
});