refactored and cleaned up calendar
This commit is contained in:
@@ -36,4 +36,7 @@
|
||||
</body>
|
||||
<script src='js/lib/html2canvas.min.js'></script>
|
||||
<script src='js/lib/ics.min.js'></script>
|
||||
<script src='js/config.js'></script>
|
||||
<script src='js/util.js'></script>
|
||||
<script src='js/Template.js'></script>
|
||||
<script src='js/calendar.js'></script>
|
||||
@@ -50,4 +50,36 @@ class Template {
|
||||
static extensionButton() {
|
||||
return `<td data-th="Plus"><input type="image" class="distButton" id="distButton" width="20" height="20" src='${chrome.extension.getURL('images/disticon.png')}'/></td>`
|
||||
}
|
||||
|
||||
static calendarLine(line) {
|
||||
return `<p class='time' style='font-size:large;'>
|
||||
<span style='display:inline-block;'>${line[0]}:</span>
|
||||
<span style='margin-left:10px;display:inline-block;text-align:center;'>${line[1]} to ${line[2]}</span>
|
||||
<span style='float:right;display:inline-block;text-align:right;width: 25%;'>
|
||||
<a target='_blank' style='color:#3c87a3;text-decoration:none;'href='${line[3]}'>${line[4]}</a>
|
||||
</span>
|
||||
</p>`
|
||||
}
|
||||
|
||||
|
||||
static calendarModal() {
|
||||
return `<div id="myModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span class="close">×</span>
|
||||
<div class="card">
|
||||
<div id="colorStrip" style="height:10px;"></div>
|
||||
<div class="cardcontainer">
|
||||
<div id='header'>
|
||||
<div style="display:flex;">
|
||||
<h2 id="classname">Classname</h2>
|
||||
</div>
|
||||
<p id="prof">Prof</p>
|
||||
</div>
|
||||
<button id="info" class="matbut" style="font-size:medium; margin-right: auto; margin-left:auto; background: #2196F3;">More Info</button>
|
||||
<button id="register" class="matbut" style="font-size:medium; margin-right: auto; margin-left:10px; background: #4CAF50;">Register</button>
|
||||
<button id="remove" class="matbut" style="font-size:medium;margin:10px;background: #FF0000;">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,6 @@ chrome.runtime.onMessage.addListener(function (request, sender, response) {
|
||||
case "updateStatus":
|
||||
updateStatus(response);
|
||||
break;
|
||||
case "getLine":
|
||||
getLine(request.dtarr, response);
|
||||
break;
|
||||
case "alreadyContains":
|
||||
alreadyContains(request.unique, response);
|
||||
break;
|
||||
@@ -342,71 +339,3 @@ function updateStatus(sendResponse) {
|
||||
// console.log("updated status' and registerlinks");
|
||||
});
|
||||
}
|
||||
|
||||
/* Find if the unique is already contained within the storage*/
|
||||
function getLine(datetimearr, sendResponse) {
|
||||
var output = makeLine(datetimearr);
|
||||
console.log(output);
|
||||
sendResponse({
|
||||
line: output
|
||||
});
|
||||
}
|
||||
|
||||
/* convert from the dtarr and maek the time lines*/
|
||||
function makeLine(datetimearr) {
|
||||
//converted times back
|
||||
var output = [];
|
||||
var dtmap = makeMap(datetimearr);
|
||||
var timearr = Array.from(dtmap.keys());
|
||||
var dayarr = Array.from(dtmap.values());
|
||||
for (var i = 0; i < dayarr.length; i++) {
|
||||
var place = findLoc(dayarr[i], timearr[i], datetimearr);
|
||||
var building = place.substring(0, place.search(/\d/) - 1);
|
||||
if (building == "") {
|
||||
building = "Undecided Location";
|
||||
}
|
||||
output.push([dayarr[i], timearr[i].split(",")[0], timearr[i].split(",")[1], 'https://maps.utexas.edu/buildings/UTM/' + building, place]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function makeMap(datetimearr) {
|
||||
var dtmap = new Map([]);
|
||||
for (var i = 0; i < datetimearr.length; i++) {
|
||||
//console.log(datetimearr[i][1][0]);
|
||||
datetimearr[i][1][0] = moment(datetimearr[i][1][0], ["HH:mm A"]).format("h:mm A");
|
||||
datetimearr[i][1][1] = moment(datetimearr[i][1][1], ["HH:mm A"]).format("h:mm A");
|
||||
}
|
||||
for (var i = 0; i < datetimearr.length; i++) {
|
||||
if (dtmap.has(String(datetimearr[i][1]))) {
|
||||
dtmap.set(String(datetimearr[i][1]), dtmap.get(String(datetimearr[i][1])) + datetimearr[i][0]);
|
||||
} else {
|
||||
dtmap.set(String(datetimearr[i][1]), datetimearr[i][0]);
|
||||
}
|
||||
}
|
||||
return dtmap
|
||||
}
|
||||
//find the location of a class given its days and timearrs.
|
||||
function findLoc(day, timearr, datetimearr) {
|
||||
for (let i = 0; i < datetimearr.length; i++) {
|
||||
var dtl = datetimearr[i];
|
||||
// console.log(dtl[1]);
|
||||
// console.log(timearr);
|
||||
if (day.includes(dtl[0])) {
|
||||
if (JSON.stringify(timearr) == JSON.stringify(fixDtl1(dtl[1]))) {
|
||||
return dtl[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixDtl1(dtl1) {
|
||||
let output = "";
|
||||
for (let i = 0; i < dtl1.length; i++) {
|
||||
output += dtl1[i];
|
||||
if (i != dtl1.length - 1) {
|
||||
output += ",";
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
595
js/calendar.js
595
js/calendar.js
@@ -1,318 +1,307 @@
|
||||
$(function () {
|
||||
const materialColors = ['#4CAF50', '#CDDC39',
|
||||
'#FFC107', '#2196F3', '#F57C00', '#9C27B0', '#FF5722', '#673AB7',
|
||||
'#FF5252', '#E91E63', '#009688', '#00BCD4',
|
||||
'#4E342E', '#424242', '#9E9E9E'
|
||||
];
|
||||
var color_counter = 0;
|
||||
var {
|
||||
calendar_fade_time,
|
||||
button_delay
|
||||
} = Timing;
|
||||
|
||||
var options = {
|
||||
|
||||
foreignObjectRendering: true,
|
||||
logging: true,
|
||||
removeContainer: true,
|
||||
async: true,
|
||||
}
|
||||
|
||||
const days = new Map([
|
||||
["M", "Monday"],
|
||||
["T", "Tuesday"],
|
||||
["W", "Wednesday"],
|
||||
["TH", "Thursday"],
|
||||
["F", "Friday"]
|
||||
]);
|
||||
const fadetime = 150;
|
||||
const butdelay = 75;
|
||||
$("#calendar").after(`<div id="myModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span class="close">×</span>
|
||||
<div class="card">
|
||||
<div id="colorStrip" style="height:10px;"></div>
|
||||
<div class="cardcontainer">
|
||||
<div id='header'>
|
||||
<div style="display:flex;">
|
||||
<h2 id="classname">Classname</h2>
|
||||
</div>
|
||||
<p id="prof">Prof</p>
|
||||
</div>
|
||||
<button id="info" class="matbut" style="font-size:medium; margin-right: auto; margin-left:auto; background: #2196F3;">More Info</button>
|
||||
<button id="register" class="matbut" style="font-size:medium; margin-right: auto; margin-left:10px; background: #4CAF50;">Register</button>
|
||||
<button id="remove" class="matbut" style="font-size:medium;margin:10px;background: #FF0000;">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>`);
|
||||
// Counter to iterate through material colors to avoid duplicates
|
||||
var colorCounter = 0;
|
||||
// Each schedule needs to store 'TITLE - START TIME - END TIME - COLOR'
|
||||
var classSchedules = [];
|
||||
var savedCourses = [];
|
||||
var currindex = 0;
|
||||
chrome.storage.sync.get("savedCourses", function (data) {
|
||||
// Iterate through each saved course and add to 'event'
|
||||
savedCourses = data.savedCourses;
|
||||
setAllEvents(savedCourses);
|
||||
var saved_courses = [];
|
||||
var curr_course = {}
|
||||
|
||||
$("#calendar").fullCalendar({
|
||||
editable: false, // Don't allow editing of events
|
||||
handleWindowResize: true,
|
||||
weekends: false, // will hide Saturdays and Sundays
|
||||
slotDuration: "00:30:00", // 15 minute intervals on vertical column
|
||||
slotEventOverlap: false, // No overlapping between events
|
||||
defaultView: "agendaWeek", // Only show week view
|
||||
header: false, // Hide buttons/titles
|
||||
minTime: "08:00:00", // Start time
|
||||
maxTime: "21:00:01", // End time
|
||||
columnHeaderFormat: "ddd", // Only show day of the week names
|
||||
displayEventTime: true, // Display event time
|
||||
allDaySlot: false,
|
||||
Duration: {
|
||||
hours: 1
|
||||
},
|
||||
height: 'auto',
|
||||
events: classSchedules,
|
||||
slotLabelFormat: [
|
||||
'h:mm A' // lower level of text
|
||||
],
|
||||
eventRender: function (event, element, view) {
|
||||
$(element).css("padding", "5px");
|
||||
$(element).css("margin-bottom", "5px");
|
||||
$("#calendar").after(Template.calendarModal());
|
||||
|
||||
},
|
||||
eventClick: function (data, event, view) {
|
||||
$("#myModal").fadeIn(fadetime);
|
||||
$("#colorStrip").css('background-color', data.color);
|
||||
currindex = data.index;
|
||||
$("#classname").html(`${savedCourses[currindex].coursename} <span style='font-size:small'>(${savedCourses[currindex].unique})</span>`);
|
||||
chrome.runtime.sendMessage({
|
||||
command: "getLine",
|
||||
dtarr: savedCourses[currindex].datetimearr,
|
||||
}, function (response) {
|
||||
// update the DOM
|
||||
$('#timelines').remove();
|
||||
setTimeout(function () {
|
||||
var arr = response.line;
|
||||
console.log(arr);
|
||||
var output = "";
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let line = arr[i];
|
||||
output +=
|
||||
`<p class='time' style='font-size:large;'>
|
||||
<span style='display:inline-block;'>${line[0]}:</span>
|
||||
<span style='margin-left:10px;display:inline-block;text-align:center;'>${line[1]} to ${line[2]}</span>
|
||||
<span style='float:right;display:inline-block;text-align:right;width: 25%;'>
|
||||
<a target='_blank' style='color:#3c87a3;text-decoration:none;'href='${line[3]}'>${line[4]}</a>
|
||||
</span>
|
||||
</p>`;
|
||||
}
|
||||
$("#header").after("<div id='timelines'>" + output + "</div");
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
var uncapProf = prettifyName(savedCourses[currindex].profname);
|
||||
if (uncapProf == "") {
|
||||
uncapProf = "Undecided";
|
||||
}
|
||||
$("#prof").html(`with <span style='font-weight:bold;'>${uncapProf}</span>`);
|
||||
|
||||
let status = savedCourses[currindex].status;
|
||||
|
||||
let registerlink = savedCourses[currindex].registerlink;
|
||||
if (status.includes("closed") || status.includes("cancelled") || !status || !registerlink) {
|
||||
$("#register").text("Can't Register").css("background-color", "#FF5722");
|
||||
} else if (status.includes("waitlisted")) {
|
||||
$("#register").text("Join Waitlist").css("background-color", "#FF9800");
|
||||
} else {
|
||||
$("#register").text("Register").css("background-color", "#4CAF50");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// When the user clicks on <span> (x), close the modal
|
||||
$(".close").click(() => {
|
||||
$("#myModal").fadeOut(fadetime);
|
||||
});
|
||||
$("#info").click(() => {
|
||||
var currLink = savedCourses[currindex].link;
|
||||
setTimeout(() => {
|
||||
window.open(currLink);
|
||||
}, butdelay);
|
||||
});
|
||||
$("#save").click(() => {
|
||||
takePicture();
|
||||
});
|
||||
$("#clear").click(() => {
|
||||
/*Clear the list and the storage of courses*/
|
||||
chrome.storage.sync.set({
|
||||
savedCourses: []
|
||||
});
|
||||
chrome.tabs.query({}, function (tabs) {
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
chrome.tabs.sendMessage(tabs[i].id, {
|
||||
command: "updateCourseList"
|
||||
});
|
||||
}
|
||||
});
|
||||
updateCalendar();
|
||||
chrome.runtime.sendMessage({
|
||||
command: "updateBadge"
|
||||
});
|
||||
|
||||
});
|
||||
$("#remove").click(() => {
|
||||
setTimeout(() => {
|
||||
chrome.runtime.sendMessage({
|
||||
command: "courseStorage",
|
||||
course: savedCourses[currindex],
|
||||
action: "remove"
|
||||
}, function (response) {
|
||||
$("#myModal").fadeOut(fadetime);
|
||||
updateCalendar();
|
||||
chrome.tabs.query({}, function (tabs) {
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
chrome.tabs.sendMessage(tabs[i].id, {
|
||||
command: "updateCourseList"
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}, butdelay);
|
||||
});
|
||||
$("#register").click(function () {
|
||||
let registerlink = savedCourses[currindex].registerlink;
|
||||
let status = savedCourses[currindex].status;
|
||||
if (!(status.includes("closed") || status.includes("cancelled") || !status || !registerlink)) {
|
||||
setTimeout(() => {
|
||||
window.open(registerlink);
|
||||
}, butdelay);
|
||||
}
|
||||
});
|
||||
|
||||
$("#export").click(function () {
|
||||
var cal = ics();
|
||||
var calendarEvents = $('#calendar').fullCalendar('clientEvents');
|
||||
for (i in calendarEvents) {
|
||||
let event = calendarEvents[i];
|
||||
var title = event.title;
|
||||
var classname = title.substring(0, title.indexOf('with'));
|
||||
var description = title.substring(title.indexOf('with'));
|
||||
var time = event.start._d.toUTCString();
|
||||
cal.addEvent(classname, description, event.building, event.start._i, event.end._i, {
|
||||
rrule: `RRULE:FREQ=WEEKLY;BYDAY=${time.substring(0, time.indexOf(",") - 1).toUpperCase()};INTERVAL=1`
|
||||
});
|
||||
}
|
||||
cal.download("My_Course_Calendar");
|
||||
});
|
||||
|
||||
function takePicture() {
|
||||
var width = $("#calendar").width();
|
||||
var height = $("#calendar").height();
|
||||
let cropper = document.createElement('canvas').getContext('2d');
|
||||
html2canvas(document.querySelector("#calendar"), options).then(c => {
|
||||
cropper.canvas.width = width;
|
||||
cropper.canvas.height = height;
|
||||
cropper.drawImage(c, 0, 0);
|
||||
var a = document.createElement('a');
|
||||
a.href = cropper.canvas.toDataURL("image/png");
|
||||
a.download = 'mySchedule.png';
|
||||
a.click();
|
||||
});
|
||||
}
|
||||
|
||||
/*Close Modal when hit escape*/
|
||||
$(document).keydown((e) => {
|
||||
if (e.keyCode == 27) {
|
||||
$("#myModal").fadeOut(fadetime);
|
||||
}
|
||||
$("#snackbar").attr("class", "");
|
||||
});
|
||||
// When the user clicks anywhere outside of the modal, close it
|
||||
window.onclick = (event) => {
|
||||
var modal = document.getElementById("myModal");
|
||||
if (event.target == modal) {
|
||||
$("#myModal").fadeOut(fadetime);
|
||||
}
|
||||
}
|
||||
chrome.storage.sync.get("savedCourses", function (data) {
|
||||
// Iterate through each saved course and add to 'event'
|
||||
function setAllEvents(savedCourses) {
|
||||
colorCounter = 0;
|
||||
classSchedules = [];
|
||||
var hours = 0;
|
||||
for (let i = 0; i < savedCourses.length; i++) {
|
||||
var classInfo = savedCourses[i];
|
||||
var course_nbr = classInfo.coursename.substring(classInfo.coursename.search(/\d/), classInfo.coursename.indexOf(" ", classInfo.coursename.search(/\d/)));
|
||||
hours += parseInt(course_nbr.substring(course_nbr.search(/\d/), course_nbr.search(/\d/) + 1));
|
||||
for (let j = 0; j < savedCourses[i].datetimearr.length; j++) {
|
||||
let session = savedCourses[i].datetimearr[j]; // One single session for a class
|
||||
setEventForSection(session, colorCounter, i);
|
||||
}
|
||||
colorCounter++;
|
||||
}
|
||||
$("#hours").text(hours + " Hours");
|
||||
$("#num").text(savedCourses.length + " Courses");
|
||||
}
|
||||
saved_courses = data.savedCourses;
|
||||
let event_source = buildEventSource(saved_courses);
|
||||
|
||||
//create the event object for every section
|
||||
function setEventForSection(session, colorCounter, i) {
|
||||
// console.log(moment().startOf('month').format("YYYY-MM-D"));
|
||||
// console.log(moment().day(fullday));
|
||||
var fullday = days.get(session[0]);
|
||||
var classInfo = savedCourses[i];
|
||||
console.log(session);
|
||||
var department = classInfo.coursename.substring(0, classInfo.coursename.search(/\d/) - 2);
|
||||
var course_nbr = classInfo.coursename.substring(classInfo.coursename.search(/\d/), classInfo.coursename.indexOf(" ", classInfo.coursename.search(/\d/)));
|
||||
var uncapProf = prettifyName(classInfo.profname);
|
||||
if (uncapProf == "") {
|
||||
uncapProf = "Undecided";
|
||||
$("#calendar").fullCalendar({
|
||||
editable: false, // Don't allow editing of events
|
||||
handleWindowResize: true,
|
||||
weekends: false, // will hide Saturdays and Sundays
|
||||
slotDuration: "00:30:00", // 15 minute intervals on vertical column
|
||||
slotEventOverlap: false, // No overlapping between events
|
||||
defaultView: "agendaWeek", // Only show week view
|
||||
header: false, // Hide buttons/titles
|
||||
minTime: "08:00:00", // Start time
|
||||
maxTime: "21:00:01", // End time
|
||||
columnHeaderFormat: "ddd", // Only show day of the week names
|
||||
displayEventTime: true, // Display event time
|
||||
allDaySlot: false,
|
||||
Duration: {
|
||||
hours: 1
|
||||
},
|
||||
height: 'auto',
|
||||
events: event_source,
|
||||
slotLabelFormat: [
|
||||
'h:mm A' // lower level of text
|
||||
],
|
||||
eventRender: function (event, element, view) {
|
||||
$(element).css("padding", "5px").css("margin-bottom", "5px");
|
||||
},
|
||||
eventClick: function (data, event, view) {
|
||||
displayModal(data)
|
||||
}
|
||||
var year = moment().day(fullday)._d.toString().split(" ")[3];
|
||||
var monthNum = moment(moment().day(fullday)._d.toString().split(" ")[1], "MMM").format('MM');
|
||||
var beg = `${year}-${monthNum}-`;
|
||||
classSchedules.push({
|
||||
title: `${department}-${course_nbr} with ${uncapProf}`,
|
||||
start: beg +
|
||||
moment()
|
||||
.day(fullday)
|
||||
._d.toString()
|
||||
.split(" ")[2] +
|
||||
"T" +
|
||||
session[1][0] +
|
||||
":00",
|
||||
end: beg +
|
||||
moment()
|
||||
.day(fullday)
|
||||
._d.toString()
|
||||
.split(" ")[2] +
|
||||
"T" +
|
||||
session[1][1] +
|
||||
":00",
|
||||
color: materialColors[colorCounter],
|
||||
building: session[2],
|
||||
index: i,
|
||||
allday: false
|
||||
});
|
||||
}
|
||||
chrome.runtime.onMessage.addListener(
|
||||
function (request, sender, sendResponse) {
|
||||
if (request.command == "updateCourseList" || request.command == "courseAdded") {
|
||||
updateCalendar();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function updateCalendar() {
|
||||
chrome.storage.sync.get("savedCourses", function (data) {
|
||||
savedCourses = data.savedCourses
|
||||
setAllEvents(data.savedCourses);
|
||||
// console.log(classSchedules);
|
||||
$('#calendar').fullCalendar('removeEventSources');
|
||||
$("#calendar").fullCalendar('addEventSource', classSchedules, true);
|
||||
});
|
||||
|
||||
|
||||
|
||||
function displayModal(data) {
|
||||
$("#myModal").fadeIn(calendar_fade_time);
|
||||
$("#colorStrip").css('background-color', data.color);
|
||||
curr_course = saved_courses[data.index];
|
||||
setUpModal()
|
||||
}
|
||||
|
||||
function setUpModal() {
|
||||
let {
|
||||
coursename,
|
||||
unique,
|
||||
datetimearr,
|
||||
profname,
|
||||
status,
|
||||
registerlink
|
||||
} = curr_course;
|
||||
$("#classname").html(`${coursename} <span style='font-size:small'>(${unique})</span>`);
|
||||
buildTimeTitle(datetimearr);
|
||||
$("#prof").html(`with <span style='font-weight:bold;'>${capitalizeString(profname)}</span>`);
|
||||
setRegisterButton(status, registerlink)
|
||||
}
|
||||
|
||||
function setRegisterButton(status, registerlink) {
|
||||
if (canNotRegister(status, registerlink))
|
||||
$("#register").text("Can't Register").css("background-color", "#FF5722");
|
||||
else if (status.includes("waitlisted"))
|
||||
$("#register").text("Join Waitlist").css("background-color", "#FF9800");
|
||||
else
|
||||
$("#register").text("Register").css("background-color", "#4CAF50");
|
||||
}
|
||||
|
||||
|
||||
function canNotRegister(status, registerlink) {
|
||||
return status.includes("closed") || status.includes("cancelled") || !status || !registerlink
|
||||
}
|
||||
|
||||
|
||||
function buildTimeTitle(datetimearr) {
|
||||
$('#timelines').remove();
|
||||
var arr = convertDateTimeArrToLine(datetimearr)
|
||||
var output = "";
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
output += Template.calendarLine(arr[i]);
|
||||
}
|
||||
/* Format the Professor Name */
|
||||
function prettifyName(profname) {
|
||||
return profname.replace(/\w\S*/g, function (txt) {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||
$("#header").after(`<div id='timelines'>${output}</div`);
|
||||
}
|
||||
|
||||
|
||||
// Iterate through each saved course and add to 'event'
|
||||
function buildEventSource(savedCourses) {
|
||||
color_counter = 0;
|
||||
let event_source = [];
|
||||
var hours = 0;
|
||||
for (let i = 0; i < savedCourses.length; i++) {
|
||||
let {
|
||||
coursename,
|
||||
datetimearr
|
||||
} = savedCourses[i];
|
||||
let number = seperateCourseNameParts(coursename).number;
|
||||
hours += parseInt(number.charAt(0));
|
||||
for (let j = 0; j < datetimearr.length; j++) {
|
||||
let session = datetimearr[j]; // One single session for a class
|
||||
let event_obj = setEventForSection(session, color_counter, i);
|
||||
event_source.push(event_obj);
|
||||
}
|
||||
color_counter++;
|
||||
}
|
||||
$("#hours").text(hours + " Hours");
|
||||
$("#num").text(savedCourses.length + " Courses");
|
||||
return event_source;
|
||||
}
|
||||
|
||||
//create the event object for every section
|
||||
function setEventForSection(session, colorCounter, i) {
|
||||
let full_day = days.get(session[0]);
|
||||
let course = saved_courses[i];
|
||||
let {
|
||||
coursename,
|
||||
profname,
|
||||
} = course;
|
||||
let {
|
||||
department,
|
||||
number
|
||||
} = seperateCourseNameParts(coursename)
|
||||
beg_day = calculateBeginningDate(full_day)
|
||||
start_date = formatCalculateDate(beg_day, full_day, session[1][0]);
|
||||
end_date = formatCalculateDate(beg_day, full_day, session[1][1]);
|
||||
|
||||
event_obj = {
|
||||
title: `${department}-${number} with ${capitalizeString(profname)}`,
|
||||
start: start_date,
|
||||
end: end_date,
|
||||
color: Colors.material_colors[colorCounter],
|
||||
building: session[2],
|
||||
index: i,
|
||||
allday: false
|
||||
};
|
||||
return event_obj;
|
||||
}
|
||||
|
||||
function formatCalculateDate(beg_day, full_day, hour) {
|
||||
return beg_day + moment().day(full_day)._d.toString().split(" ")[2] + "T" + hour + ":00";
|
||||
}
|
||||
|
||||
function calculateBeginningDate(full_day) {
|
||||
var year = moment().day(full_day)._d.toString().split(" ")[3];
|
||||
var month_num = moment(moment().day(full_day)._d.toString().split(" ")[1], "MMM").format('MM');
|
||||
return `${year}-${month_num}-`;
|
||||
}
|
||||
|
||||
function updateCalendar() {
|
||||
chrome.storage.sync.get("savedCourses", function (data) {
|
||||
saved_courses = data.savedCourses
|
||||
let event_source = buildEventSource(saved_courses);
|
||||
$('#calendar').fullCalendar('removeEventSources');
|
||||
$("#calendar").fullCalendar('addEventSource', event_source, true);
|
||||
});
|
||||
}
|
||||
chrome.runtime.onMessage.addListener(
|
||||
function (request, sender, sendResponse) {
|
||||
if (request.command == "updateCourseList" || request.command == "courseAdded") {
|
||||
updateCalendar();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
$("#info").click(() => {
|
||||
setTimeout(() => {
|
||||
window.open(curr_course.link);
|
||||
}, button_delay);
|
||||
});
|
||||
|
||||
|
||||
$("#save").click(() => {
|
||||
takePicture();
|
||||
});
|
||||
|
||||
|
||||
$("#clear").click(() => {
|
||||
/*Clear the list and the storage of courses*/
|
||||
chrome.storage.sync.set({
|
||||
savedCourses: []
|
||||
});
|
||||
chrome.tabs.query({}, function (tabs) {
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
chrome.tabs.sendMessage(tabs[i].id, {
|
||||
command: "updateCourseList"
|
||||
});
|
||||
}
|
||||
});
|
||||
updateCalendar();
|
||||
chrome.runtime.sendMessage({
|
||||
command: "updateBadge"
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$("#remove").click(() => {
|
||||
setTimeout(() => {
|
||||
chrome.runtime.sendMessage({
|
||||
command: "courseStorage",
|
||||
course: curr_course,
|
||||
action: "remove"
|
||||
}, function () {
|
||||
$("#myModal").fadeOut(calendar_fade_time);
|
||||
updateCalendar();
|
||||
chrome.tabs.query({}, function (tabs) {
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
chrome.tabs.sendMessage(tabs[i].id, {
|
||||
command: "updateCourseList"
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}, button_delay);
|
||||
});
|
||||
|
||||
|
||||
$("#register").click(function () {
|
||||
let {
|
||||
registerlink,
|
||||
status
|
||||
} = curr_course;
|
||||
if (!canNotRegister(status, registerlink)) {
|
||||
setTimeout(() => {
|
||||
window.open(registerlink);
|
||||
}, button_delay);
|
||||
}
|
||||
});
|
||||
|
||||
$("#export").click(function () {
|
||||
var cal = ics();
|
||||
var calendarEvents = $('#calendar').fullCalendar('clientEvents');
|
||||
for (i in calendarEvents) {
|
||||
var event = calendarEvents[i];
|
||||
buildICSFile(cal, event);
|
||||
}
|
||||
cal.download("My_Course_Calendar");
|
||||
});
|
||||
|
||||
|
||||
function buildICSFile(cal, event) {
|
||||
let {
|
||||
title,
|
||||
start,
|
||||
end,
|
||||
building
|
||||
} = event;
|
||||
let class_name = title.split('with')[0];
|
||||
let description = `with ${title.split('with')[1]}`;
|
||||
let time = start._d.toUTCString();
|
||||
cal.addEvent(class_name, description, building, start._i, end._i, {
|
||||
rrule: `RRULE:FREQ=WEEKLY;BYDAY=${time.substring(0, time.indexOf(",") - 1).toUpperCase()};INTERVAL=1`
|
||||
});
|
||||
}
|
||||
|
||||
function takePicture() {
|
||||
var width = $("#calendar").width();
|
||||
var height = $("#calendar").height();
|
||||
let cropper = document.createElement('canvas').getContext('2d');
|
||||
html2canvas(document.querySelector("#calendar"), Export.png_options).then(c => {
|
||||
cropper.canvas.width = width;
|
||||
cropper.canvas.height = height;
|
||||
cropper.drawImage(c, 0, 0);
|
||||
var a = document.createElement('a');
|
||||
a.href = cropper.canvas.toDataURL("image/png");
|
||||
a.download = 'mySchedule.png';
|
||||
a.click();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*Close Modal when hit escape*/
|
||||
$(document).keydown((e) => {
|
||||
if (e.keyCode == 27) {
|
||||
$("#myModal").fadeOut(calendar_fade_time);
|
||||
}
|
||||
});
|
||||
|
||||
$('.close').click(function () {
|
||||
close();
|
||||
});
|
||||
$('#myModal').click(function (event) {
|
||||
if (event.target.id == 'myModal') {
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
function close() {
|
||||
$("#myModal").fadeOut(calendar_fade_time);
|
||||
}
|
||||
26
js/config.js
26
js/config.js
@@ -1,2 +1,24 @@
|
||||
const fadetime = 150;
|
||||
const butdelay = 75;
|
||||
class Timing {
|
||||
static fade_time = 100;
|
||||
static calendar_fade_time = 100;
|
||||
static button_delay = 75;
|
||||
}
|
||||
|
||||
|
||||
class Colors {
|
||||
static material_colors = ['#4CAF50', '#CDDC39',
|
||||
'#FFC107', '#2196F3', '#F57C00', '#9C27B0', '#FF5722', '#673AB7',
|
||||
'#FF5252', '#E91E63', '#009688', '#00BCD4',
|
||||
'#4E342E', '#424242', '#9E9E9E'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
class Export {
|
||||
static png_options = {
|
||||
foreignObjectRendering: true,
|
||||
logging: true,
|
||||
removeContainer: true,
|
||||
async: true,
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,6 @@ $("body").on('click', '#distButton', function () {
|
||||
getDistribution(curr_course);
|
||||
});
|
||||
|
||||
|
||||
$("#myModal").on('click', '#saveCourse', function () {
|
||||
setTimeout(function () {
|
||||
saveCourse();
|
||||
@@ -74,25 +73,25 @@ $("#myModal").on('click', '#saveCourse', function () {
|
||||
$("#Syllabi").click(function () {
|
||||
setTimeout(function () {
|
||||
window.open(curr_course["links"]["syllabi"]);
|
||||
}, butdelay);
|
||||
}, Timing.button_delay);
|
||||
});
|
||||
$("#rateMyProf").click(function () {
|
||||
setTimeout(function () {
|
||||
window.open(curr_course["links"]["rate_my_prof"]);
|
||||
}, butdelay);
|
||||
}, Timing.button_delay);
|
||||
});
|
||||
$("#eCIS").click(function () {
|
||||
setTimeout(function () {
|
||||
window.open(curr_course["links"]["ecis"]);
|
||||
}, butdelay);
|
||||
}, Timing.button_delay);
|
||||
});
|
||||
$("#textbook").click(function () {
|
||||
setTimeout(function () {
|
||||
window.open(curr_course["links"]["textbook"]);
|
||||
}, butdelay);
|
||||
}, Timing.button_delay);
|
||||
});
|
||||
$("#semesters").on('change', function () {
|
||||
var sem = $(this).val();
|
||||
let sem = $(this).val();
|
||||
sem = sem == "Aggregate" ? undefined : sem;
|
||||
getDistribution(curr_course, sem);
|
||||
});
|
||||
@@ -104,13 +103,6 @@ $("#retry").click(function () {
|
||||
});
|
||||
|
||||
|
||||
function sepNameParts(name) {
|
||||
numIndex = name.search(/\d/);
|
||||
department = name.substring(0, numIndex).trim();
|
||||
number = name.substring(numIndex, name.indexOf(" ", numIndex)).trim();
|
||||
name = capitalizeString(name.substring(name.indexOf(" ", numIndex)).trim());
|
||||
return [name, department, number];
|
||||
}
|
||||
|
||||
function updateLinks(course_info, first_name) {
|
||||
let {
|
||||
@@ -143,14 +135,18 @@ function buildCourseLinks(course_info) {
|
||||
}
|
||||
|
||||
function buildBasicCourseInfo(row, course_name, individual) {
|
||||
let namedata = sepNameParts(course_name)
|
||||
let {
|
||||
name,
|
||||
department,
|
||||
number
|
||||
} = seperateCourseNameParts(course_name);
|
||||
let instructor_text = $(row).find('td[data-th="Instructor"]').text();
|
||||
let has_initial = instructor_text.indexOf(',') > 0;
|
||||
course_info = {
|
||||
"full_name": course_name,
|
||||
"name": namedata[0],
|
||||
"department": namedata[1],
|
||||
"number": namedata[2],
|
||||
"name": name,
|
||||
"department": department,
|
||||
"number": number,
|
||||
"individual": individual ? individual : $(row).find('td[data-th="Unique"] a').prop('href'),
|
||||
"register": $(row).find('td[data-th="Add"] a').prop('href'),
|
||||
"unique": $(row).find('td[data-th="Unique"]').text(),
|
||||
@@ -282,7 +278,7 @@ function getDayTimeArray(row, course_info) {
|
||||
return daytimearray;
|
||||
}
|
||||
|
||||
function makeLine(date, time, place) {
|
||||
function convertDateTimeArrToLine(date, time, place) {
|
||||
var arr = seperateDays(date)
|
||||
var output = prettifyDaysText(arr)
|
||||
var building = place.substring(0, place.search(/\d/) - 1);
|
||||
@@ -329,7 +325,7 @@ function buildTimeTitle(course_info) {
|
||||
var date = days[i];
|
||||
var time = times[i];
|
||||
var place = places[i];
|
||||
lines.push($(`<h2 class="dateTimePlace">${makeLine(date, time, place)}</th>`));
|
||||
lines.push($(`<h2 class="dateTimePlace">${convertDateTimeArrToLine(date, time, place)}</th>`));
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
@@ -365,7 +361,7 @@ function openDialog(course_info, res) {
|
||||
$("#title").text(buildTitle(course_info))
|
||||
$("#topbuttons").before(buildTimeTitle(course_info));
|
||||
$("#profname").text(buildProfTitle(course_info));
|
||||
$("#myModal").fadeIn(fadetime);
|
||||
$("#myModal").fadeIn(Timing.fade_time);
|
||||
//initial text on the "save course button"
|
||||
chrome.runtime.sendMessage({
|
||||
command: "alreadyContains",
|
||||
@@ -576,6 +572,6 @@ function allowClosing() {
|
||||
}
|
||||
|
||||
function close() {
|
||||
$("#myModal").fadeOut(fadetime);
|
||||
$("#myModal").fadeOut(Timing.fade_time);
|
||||
$("#snackbar").attr("class", "");
|
||||
}
|
||||
70
js/util.js
70
js/util.js
@@ -229,3 +229,73 @@ function buildChartConfig(data) {
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
function seperateCourseNameParts(name) {
|
||||
let num_index = name.search(/\d/);
|
||||
department = name.substring(0, num_index).trim();
|
||||
number = name.substring(num_index, name.indexOf(" ", num_index)).trim();
|
||||
name = capitalizeString(name.substring(name.indexOf(" ", num_index)).trim());
|
||||
return {
|
||||
name: name,
|
||||
department: department,
|
||||
number: number
|
||||
}
|
||||
}
|
||||
|
||||
/* convert from the dtarr and maek the time lines*/
|
||||
function convertDateTimeArrToLine(datetimearr) {
|
||||
var output = [];
|
||||
var dtmap = makeDateTimeApp(datetimearr);
|
||||
var timearr = Array.from(dtmap.keys());
|
||||
var dayarr = Array.from(dtmap.values());
|
||||
for (var i = 0; i < dayarr.length; i++) {
|
||||
var place = findLocation(dayarr[i], timearr[i], datetimearr);
|
||||
var building = place.substring(0, place.search(/\d/) - 1);
|
||||
if (building == "") {
|
||||
building = "Undecided Location";
|
||||
}
|
||||
output.push([dayarr[i], timearr[i].split(",")[0], timearr[i].split(",")[1], 'https://maps.utexas.edu/buildings/UTM/' + building, place]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function makeDateTimeApp(datetimearr) {
|
||||
var dtmap = new Map([]);
|
||||
for (var i = 0; i < datetimearr.length; i++) {
|
||||
//console.log(datetimearr[i][1][0]);
|
||||
datetimearr[i][1][0] = moment(datetimearr[i][1][0], ["HH:mm A"]).format("h:mm A");
|
||||
datetimearr[i][1][1] = moment(datetimearr[i][1][1], ["HH:mm A"]).format("h:mm A");
|
||||
}
|
||||
for (var i = 0; i < datetimearr.length; i++) {
|
||||
if (dtmap.has(String(datetimearr[i][1]))) {
|
||||
dtmap.set(String(datetimearr[i][1]), dtmap.get(String(datetimearr[i][1])) + datetimearr[i][0]);
|
||||
} else {
|
||||
dtmap.set(String(datetimearr[i][1]), datetimearr[i][0]);
|
||||
}
|
||||
}
|
||||
return dtmap
|
||||
}
|
||||
//find the location of a class given its days and timearrs.
|
||||
function findLocation(day, timearr, datetimearr) {
|
||||
for (let i = 0; i < datetimearr.length; i++) {
|
||||
var dtl = datetimearr[i];
|
||||
// console.log(dtl[1]);
|
||||
// console.log(timearr);
|
||||
if (day.includes(dtl[0])) {
|
||||
if (JSON.stringify(timearr) == JSON.stringify(reformatDateTime(dtl[1]))) {
|
||||
return dtl[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reformatDateTime(dtl1) {
|
||||
let output = "";
|
||||
for (let i = 0; i < dtl1.length; i++) {
|
||||
output += dtl1[i];
|
||||
if (i != dtl1.length - 1) {
|
||||
output += ",";
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ function openDialog(course_data, res) {
|
||||
$("#title").text(buildTitle(course_data))
|
||||
$("#topbuttons").before(buildTimeTitle(course_data["times"]));
|
||||
$("#profname").text(buildProfTitle(course_data));
|
||||
$("#myModal").fadeIn(fadetime);
|
||||
$("#myModal").fadeIn(Timing.fade_time);
|
||||
buildSemestersDropdown(course_data, res)
|
||||
var data = []
|
||||
if (!badData(course_data, res))
|
||||
@@ -198,5 +198,5 @@ function setChart(data) {
|
||||
}
|
||||
|
||||
function close() {
|
||||
$("#myModal").fadeOut(fadetime);
|
||||
$("#myModal").fadeOut(Timing.fade_time);
|
||||
}
|
||||
Reference in New Issue
Block a user