summaryrefslogblamecommitdiffstats
path: root/js/timetable.js
blob: 290b7483d0d2b4421a59744f47f7ddeff96df94c (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                 


                                                         
 



                                                        
                             


















                                                   
   
  


                                                         
  
   







                                                        
   
  


                                                                             
  
   








                                                  
   
  



                                                                               














                                                                                                                
   
  



                                            






                                                     











                                                                 
                                                       







                                                                              




















































                                                                            







































                                                                       
                                                                    


                                                                 



                                           





                                                       
                                         













                                                           










                                                                                    




                                                  
 
                                                              













































                                                                         
   
// const API_ENDPOINT = "https://gimb.tk/test.php"; // deprecated
// const API_ENDPOINT = "http://localhost:5000/test.php";

var calendar_obj = null;

function checkLogin() {
    localforage.getItem("logged_in").then((value) => {
        // This code runs once the value has been loaded
        // from the offline store.
        if (value !== true) {
            window.location.replace("/index.html");
        }
    }).catch((err) => {
        // This code runs if there were any errors
        console.log(err);
    });
}

// Set loading bar visibility
function setLoading(state) {
    if (state) {
        $("#loading-bar").removeClass("hidden");
    } else {
        $("#loading-bar").addClass("hidden");
    }
}

// ----GET COLOR FROM STRING--------

/**
 *
 * Calculate hash code from a string
 * @param {string} input_string String to convert to hash
 * @returns {string} calculated hash code
 *
 */
function hashCode(str) { // java String#hashCode
    var hash = 0;
    for (var i = 0; i < str.length; i++) {
        hash = str.charCodeAt(i) + ((hash << 5) - hash);
    }
    return hash;
}

/**
 *
 * Convert last 3 bytes of an integer to RGB color
 * @param {integer} input_integer Integer that will be converted to RGB color
 * @returns {string} Hex color code
 *
 */
function intToRGB(i) {
    var c = (i & 0x00FFFFFF)
        .toString(16)
        .toUpperCase();

    return "00000".substring(0, 6 - c.length) + c;
}

// http://www.w3.org/TR/AERT#color-contrast
/**
 *
 * Calculate the matching foreground color for a given background (improves UX)
 * @param {string} background_color Background color of the object
 * @returns {string} Forground color that will match background color
 */
function getForegroundFromBackground(background_color) {
    let color_hex = background_color.replace("#", "");
    let rgb = [
        parseInt(color_hex.substring(0, 2), 16),
        parseInt(color_hex.substring(2, 4), 16),
        parseInt(color_hex.substring(4, 6), 16)
    ];
    let o = Math.round(((parseInt(rgb[0]) * 299) + (parseInt(rgb[1]) * 587) + (parseInt(rgb[2]) * 114)) / 1000);
    if (o > 180) {
        return "#000000";
    } else {
        return "#ffffff";
    }
}

/**
 *
 * Convert a given string to hex color
 * @param {string} input_string Input string
 * @returns {string} Hex RGB color
 */
function getHexColorFromString(str) {
    return "#" + intToRGB(hashCode(str));
}
// --------------------------------------------------

// ---------DATE FUNCTION-------------
function getDateString(date) {
    let year_str = date.getFullYear();
    let month_str = date.getMonth() + 1
    month_str = month_str.toString().padStart(2, "0");
    let day_str = date.getDate();
    day_str = day_str.toString().padStart(2, "0");

    let date_string = year_str + "-" + month_str + "-" + day_str;
    return date_string;
}

function getLastMonday(date_object) {
    if (date_object.getDay() === 0) {
        date_object.setDate(date_object.getDate() - 6);
    } else {
        date_object.setDate(date_object.getDate() - date_object.getDay() + 1);
    }
    return date_object;
}
// ----------------------------------

async function loadTimetable(date_object, force_refresh = false) {
    setLoading(true);
    var timetable, username, password;
    let date_monday = getLastMonday(date_object);
    let date_string = getDateString(date_monday);
    let promises_to_run = [
        localforage.getItem("username").then((value) => {
            username = value;
        }),
        localforage.getItem("password").then((value) => {
            password = value;
        }),
        localforage.getItem("timetable").then((value) => {
            timetable = value;
        })
    ];
    await Promise.all(promises_to_run);
    if (force_refresh || timetable == null || !(date_string in timetable)) {
        try {
            let gsecInstance = new gsec();
            await gsecInstance.login(username, password);
            gsecInstance.fetchTimetable(date_object).then( (value) => {
                containsPeriods = false;
                for(var iteration = 0; iteration <= 6; iteration++) {
                    if(Object.keys(value[iteration]).length > 0) {
                        containsPeriods = true;
                        // break;
                    }
                }
                if(!containsPeriods) {
                    UIAlert( D("noPeriods") );
                    setLoading(false);
                } else {
                    if (timetable === null) {
                        timetable = {};
                    }
                    timetable[date_string] = value;
                    localforage.setItem("timetable", timetable).then(() => {
                        displayTimetable(value, date_monday);
                        setLoading(false);
                    });
                }
            }).catch( (err) => {
                gsecErrorHandlerUI(err);
                setLoading(false);
            });
        } catch (err) {
            gsecErrorHandlerUI(err);
            setLoading(false);
        }
    } else {
        displayTimetable(timetable[date_string], date_monday);
        setLoading(false);
    }
}

function getLessonTimes(lesson_number) {
    const lessonTimes = [
        ["07:10:00", "07:55:00"],
        ["08:00:00", "08:45:00"],
        ["08:50:00", "09:35:00"],
        ["09:40:00", "10:25:00"],
        ["10:55:00", "11:40:00"],
        ["11:45:00", "12:30:00"],
        ["12:35:00", "13:20:00"],
        ["13:25:00", "14:10:00"],
        ["14:15:00", "15:00:00"],
        ["15:05:00", "15:50:00"],
        ["15:55:00", "16:40:00"],
        ["16:45:00", "17:30:00"],
        ["17:35:00", "18:20:00"],
        ["18:25:00", "19:10:00"]
    ];
    return lessonTimes[lesson_number];
}

function displayTimetable(weekly_timetable, date_object) {
    let transformed_timetable = [];

    let num_days = Object.keys(weekly_timetable).length;

    for (let i = 0; i < num_days; i++) {

        // Get date string (required by callendar)
        let date_string = getDateString(date_object);
        // Go to next day (for next loop iteration)
        date_object.setDate(date_object.getDate() + 1);

        let daily_timetable = weekly_timetable[i.toString()];

        Object.keys(daily_timetable).forEach((lesson_number) => {
            let lesson = daily_timetable[lesson_number];

            let lesson_times = getLessonTimes(parseInt(lesson_number));
            let bg_color = getHexColorFromString(lesson["acronym"]);
            let fg_color = getForegroundFromBackground(bg_color);

            let lesson_metadata = {
                subject: lesson["subject"],
                class: lesson["class"],
                teacher: lesson["teacher"],
                classroom: lesson["place"],
                start: lesson_times[0].substring(0, 5),
                end: lesson_times[1].substring(0, 5)
            }

            let lesson_object = {
                id: JSON.stringify(lesson_metadata),
                title: lesson["acronym"],
                start: date_string + " " + lesson_times[0],
                end: date_string + " " + lesson_times[1],
                backgroundColor: bg_color,
                textColor: fg_color
            };

            transformed_timetable.push(lesson_object);

        });

    }
    // Update calendar
    calendar_obj.removeAllEvents();
    calendar_obj.addEventSource(transformed_timetable);
}

function eventClickHandler(eventClickInfo) {
    let lesson_metadata = JSON.parse(eventClickInfo.event.id);

    let lesson_subject = lesson_metadata["subject"];
    let lesson_teacher = lesson_metadata["teacher"];
    let lesson_classroom = lesson_metadata["classroom"];
    let lesson_class = lesson_metadata["class"];
    let lesson_duration = lesson_metadata["start"] + " - " + lesson_metadata["end"];

    $("#lesson-subject").text(lesson_subject);
    $("#lesson-teacher").text(lesson_teacher);
    $("#lesson-class").text(lesson_class);
    $("#lesson-classroom").text(lesson_classroom);
    $("#lesson-duration").text(lesson_duration);

    const modal = document.querySelectorAll(".side-modal")[0];
    M.Sidenav.getInstance(modal).open();
}


document.addEventListener("DOMContentLoaded", () => {
    checkLogin();

    let calendarEl = document.getElementById("calendar");
    calendar_obj = new FullCalendar.Calendar(calendarEl, {
        plugins: ["timeGrid"],
        eventClick: eventClickHandler,

        defaultView: "timeGridWeek",
        contentHeight: "auto",
        height: "auto",
        width: "auto",
        timeGridEventMinHeight: 35,

        nowIndicator: true,
        firstDay: 1,
        weekends: false,

        minTime: "07:10:00",
        maxTime: "19:10:00"
    });
    calendar_obj.render();

    loadTimetable(new Date());

    // Handlers for next/prev/today buttons
    $(".fc-today-button, .fc-prev-button, .fc-next-button").click(() => {
        loadTimetable(calendar_obj.getDate());
    });

    // Setup refresh handler
    $("#refresh-icon").click(() => {
        loadTimetable(calendar_obj.getDate(), true);
    });

    // Setup side menu
    const menus = document.querySelectorAll(".side-menu");
    M.Sidenav.init(menus, { edge: "right", draggable: true });

    // Setup side modal
    const modals = document.querySelectorAll('.side-modal');
    M.Sidenav.init(modals, { edge: 'left', draggable: false });
});