diff --git a/css/popup.css b/css/popup.css index 87a67aac..abd6d89b 100644 --- a/css/popup.css +++ b/css/popup.css @@ -246,17 +246,6 @@ input[type=number]::-webkit-outer-spin-button { width: 120px; } -#import-export-popup { - background: white; - color: #747474; - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); - position: absolute; - margin: auto; - bottom: 42px; - right: 10px; - border-radius: inherit; - width: 160px; -} .flex-container { display: flex; @@ -329,15 +318,30 @@ input[type=number]::-webkit-outer-spin-button { margin: 8px 0px; } +#import-export-popup { + background: white; + color: #747474; + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + position: absolute; + margin: auto; + bottom: 42px; + right: 10px; + border-radius: inherit; + width: 140px; +} + + .simple-menu-option { display: inline-block; color: rgba(0, 0, 45, 0.48); border: none; - font-size: 17px; + background-color: white; + font-size: 15px; overflow: hidden; vertical-align: middle; + cursor: pointer; text-align: left; - padding: 10px 0px 5px 5px; + padding: 5px 0px 5px 5px; border-radius: 7px; } @@ -350,10 +354,11 @@ input[type=number]::-webkit-outer-spin-button { margin-bottom: 3px; } + .simple-menu-option:hover { - background-color: rgba(177, 175, 175, 0.324); - -webkit-transition-duration: 0.4s; /* Safari */ + background-color: rgba(177, 175, 175, 0.200); transition-duration: 0.4s; + color: #FF9800; } .simple-menu-option:focus { diff --git a/js/Template.js b/js/Template.js index 64ba781b..2f02da34 100644 --- a/js/Template.js +++ b/js/Template.js @@ -52,15 +52,64 @@ class Template { } static calendarLine(line) { + let { + days, + start_time, + end_time, + location_link, + location_full + } = line; return `

- ${line[0]}: - ${line[1]} to ${line[2]} + ${days}: + ${start_time} to ${end_time} - ${line[4]} + ${location_full}

` } + static popupListItem(i, list_tile_color, unique, department, number, profname, list_sub_color, line) { + return `
  • +
    +
    + +

    + ${department} ${number} with ${profname} (${unique}) +

    +

    +
    +
    + +
  • `; + } + + static popupLine(line) { + let { + days, + start_time, + end_time, + location_link, + location_full + } = line; + + return `${days}: + ${start_time} to ${end_time} + + ${location_full} + +
    ` + } + static calendarModal() { return ` ` } + + + static popupConflictMessage(conflict_message) { + return `

    ${conflict_message}` + } + } \ No newline at end of file diff --git a/js/calendar.js b/js/calendar.js index 801baabe..48bf26d8 100644 --- a/js/calendar.js +++ b/js/calendar.js @@ -80,17 +80,13 @@ function setRegisterButton(status, registerlink) { $("#register").text("Register").css("background-color", Colors.open); } -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]); + let line = arr[i]; + output += Template.calendarLine(line); } $("#header").after(`

    ${output} { 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" - }); - } - }); + updateAllTabsCourseList(); updateCalendar(); chrome.runtime.sendMessage({ command: "updateBadge" @@ -219,13 +209,7 @@ $("#remove").click(() => { }, 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" - }); - } - }); + updateAllTabsCourseList(); }); }, button_delay); }); diff --git a/js/config.js b/js/config.js index 115c5305..475dd0ca 100644 --- a/js/config.js +++ b/js/config.js @@ -15,6 +15,10 @@ class Colors { static waitlisted = "#FF9800"; static closed = "#FF5722"; + static open_light = "#C8E6C9"; + static waitlisted_light = "#FFE0B2"; + static closed_light = "#FFCCBC"; + static highlight_conflict = "#F44336"; static highlight_default = "#333333"; static highlight_saved = "#4CAF50"; @@ -32,4 +36,16 @@ class Export { class Text { + + static emptyText() { + let index = Math.floor(Math.random() * emptyText.length); + let arr = ["Doesn't Look Like Anything To Me.", "You Can't Fail Classes You're Not In.", "Pro-Tip: Don't Take O-Chem.", + "No Work Happens On PCL 5th Floor.", "Sophomore But Freshman By Credit.", "Pain is temporary, GPA is forever.", + "You've Yee'd Your Last Haw.", "lol everything is already waitlisted.", "At Least You're Not At A&M.", + `It's ${moment().format("h:mm")} and OU Still Sucks.`, 'TeXAs iS BaCK GuYZ', "'Academically Challenged'", + 'Does McCombs teach Parseltongue?', 'Lets make Daddy Fenves proud.', 'Feel bad if you say Wampus.', 'No Cruce Enfrente Del Bus.', + 'Midterm 1 has been Unmuted', 'Omae Wa Mou Shindeiru...', 'Bevo Bucks are the new Bitcoin' + ] + return arr[index]; + } } \ No newline at end of file diff --git a/js/courseCatalog.js b/js/courseCatalog.js index 8b282d0f..ce69248d 100644 --- a/js/courseCatalog.js +++ b/js/courseCatalog.js @@ -184,18 +184,17 @@ function updateListConflictHighlighting(start = 0) { $('table').find('tr').each(function (i) { if (i >= start) { if (!($(this).find('td').hasClass("course_header")) && $(this).has('th').length == 0) { - var this_form = this; var unique = $(this).find('td[data-th="Unique"]').text(); chrome.runtime.sendMessage({ command: "isSingleConflict", dtarr: getDayTimeArray(this), unique: unique - }, function (response) { + }, (response) => { let { isConflict, alreadyContains } = response - updateTextHighlighting($(this_form).find('td'), canHighlight, isConflict, alreadyContains); + updateTextHighlighting($(this).find('td'), canHighlight, isConflict, alreadyContains); }); } } diff --git a/js/options.js b/js/options.js index 65bfd7a3..3154838d 100644 --- a/js/options.js +++ b/js/options.js @@ -30,13 +30,7 @@ $("#togglecourseConflictHighlight").click(function () { off('courseConflictHighlight'); }); } - chrome.tabs.query({}, function (tabs) { - for (var i = 0; i < tabs.length; i++) { - chrome.tabs.sendMessage(tabs[i].id, { - command: "updateCourseList" - }); - } - }); + updateAllTabsCourseList(); }); diff --git a/js/popup.js b/js/popup.js index 48ccebe8..026b5418 100644 --- a/js/popup.js +++ b/js/popup.js @@ -1,99 +1,62 @@ var courses; -// get the courses from storage setCourseList(); - -// var modhtml = ''; -// $("#html").prepend(modhtml); getSemesters(); -var canremove = true; +var can_remove = true; + function setCourseList() { $("#courseList").empty() chrome.storage.sync.get('savedCourses', function (data) { updateConflicts(); courses = data.savedCourses - console.log(courses.length); - if (courses.length != 0) { - $("#empty").hide(); - $("#courseList").show(); - } else { - showEmpty(); - } + handleEmpty(); // build and append the course list element for (var i = 0; i < courses.length; i++) { - var color; - var subcolor; - status = courses[i].status; - if (status.includes("open")) { - color = "#4CAF50"; - subcolor = "#C8E6C9"; - } else if (status.includes("waitlisted")) { - color = "#FF9800" - subcolor = "#FFE0B2"; - } else if (status.includes("closed") || status.includes("cancelled")) { - color = "#FF5722"; - subcolor = "#FFCCBC"; - } - var department = courses[i].coursename.substring(0, courses[i].coursename.search(/\d/) - 2); - var course_nbr = courses[i].coursename.substring(courses[i].coursename.search(/\d/), courses[i].coursename.indexOf(" ", courses[i].coursename.search(/\d/))); - var profname = prettifyName(courses[i].profname); - if (profname == "") { - profname = "Undecided Professor"; - } - var listhtml = `
  • -
    -
    - -

    - ${department} ${course_nbr} with ${profname} (${courses[i].unique}) -

    -

    -
    -
    - -
  • `; - $("#courseList").append(listhtml); + let { + coursename, + unique, + profname, + status, + datetimearr + } = courses[i]; + profname = capitalizeString(profname); + let line = buildTimeLines(datetimearr); + let list_tile_color = getStatusColor(status) + let list_sub_color = getStatusColor(status, true); + let { + department, + number + } = seperateCourseNameParts(coursename) + + let list_html = Template.popupListItem(i, list_tile_color, unique, department, number, profname, list_sub_color, line); + $("#courseList").append(list_html); } }); } -function showEmpty() { - var emptyText = ["Doesn't Look Like Anything To Me.", "You Can't Fail Classes You're Not In.", "Pro-Tip: Don't Take O-Chem.", - "No Work Happens On PCL 5th Floor.", "Sophomore But Freshman By Credit.", "Pain is temporary, GPA is forever.", - "You've Yee'd Your Last Haw.", "lol everything is already waitlisted.", "At Least You're Not At A&M.", - `It's ${moment().format("h:mm")} and OU Still Sucks.`, 'TeXAs iS BaCK GuYZ', "'Academically Challenged'", - 'Does McCombs teach Parseltongue?', 'Lets make Daddy Fenves proud.', 'Feel bad if you say Wampus.', 'No Cruce Enfrente Del Bus.', - 'Midterm 1 has been Unmuted', 'Omae Wa Mou Shindeiru...', 'Bevo Bucks are the new Bitcoin' - ] - // console.log(emptyText.length); - $("#courseList").hide(); - $("#empty").fadeIn(200); - $("#main").html(emptyText[Math.floor(Math.random() * emptyText.length)]); +/* convert from the dtarr and maek the time lines*/ +function buildTimeLines(datetimearr) { + let lines = convertDateTimeArrToLine(datetimearr); + let output = ""; + if (lines.length == 0) { + output = "This class has no meeting times." + } else { + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + output += Template.popupLine(line) + } + } + return output; } /* prettify the name for the conflict messages*/ -function getSimpleName(coursename, unique) { - var department = coursename.substring(0, coursename.search(/\d/) - 2); - var course_nbr = coursename.substring(coursename.search(/\d/), coursename.indexOf(" ", coursename.search(/\d/))); - return department + " " + course_nbr + " (" + unique + ")"; -} - -/* Format the Professor Name */ -function prettifyName(profname) { - return profname.replace(/\w\S*/g, function (txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - }); +function formatShortenedCourseName(course) { + let { + number, + department + } = seperateCourseNameParts(course.coursename) + return `${department} ${number} (${course.unique})`; } /* Update the conflict messages */ @@ -101,213 +64,203 @@ function updateConflicts() { chrome.runtime.sendMessage({ command: "checkConflicts" }, function (response) { - var isConflicted = []; if (response.isConflict) { var between = response.between; - var text = ""; + let conflict_message = ""; for (var i = 0; i < between.length; i++) { - text += "CONFLICT: " + getSimpleName(between[i][0].coursename, between[i][0].unique) + " and " + getSimpleName(between[i][1].coursename, between[i][1].unique); - isConflicted.push(between[i][0].unique); - isConflicted.push(between[i][1].unique); - if (i != between.length - 1) { - text += "
    "; - } + let courseA = between[i][0]; + let courseB = between[i][1]; + conflict_message += `CONFLICT: ${formatShortenedCourseName(courseA)} and ${formatShortenedCourseName(courseB)}`; + if (i != between.length - 1) + conflict_message += "
    "; } - $("

    " + text + "").prependTo("#courseList").hide().fadeIn(200); + $(Template.popupConflictMessage(conflict_message)).prependTo("#courseList").hide().fadeIn(200); } }); } -/* Handle the button clicks */ -$(document).ready(function () { - $("#courseList").on('mouseover', '.copybut', function () { - $(this).addClass('shadow'); - }).on('mouseleave', '.copybut', function () { - $(this).removeClass('shadow'); - }); - $("#courseList").on('click', '.copybut', function (e) { - e.stopPropagation(); - var temp = $(""); - $(this).find('i').text('check'); - $(this).stop(true, false).removeAttr('style').removeClass('shadow', { - duration: 200 - }); - $(this).find('i').delay(400).queue(function (n) { - $(this).text('content_copy'); - $(this).parent().removeClass('shadow'); - if ($(this).parent().is(":hover")) { - $(this).parent().addClass('shadow'); - } - n(); +function handleRegisterButton(clicked_item, curr_course) { + let { + status, + registerlink + } = curr_course; + let register_button = $(clicked_item).find("#register"); + let can_not_register = canNotRegister(status, registerlink); + + let register_text = can_not_register ? "Can't Register" : + status.includes("waitlisted") ? "Join Waitlist" : "Register"; + let register_color = can_not_register ? Colors.closed : + status.includes("waitlisted") ? Colors.waitlisted : Colors.open; + + $(register_button).text(register_text).css('background-color', register_color); + if (!can_not_register) { + $(register_button).click(function () { + setCurrentTabUrl(registerlink); }) + } +} - $("body").append(temp); - temp.val($(this).val()).select(); - document.execCommand("copy"); - temp.remove(); - }); - - $("#courseList").on('click', 'li', function () { - $(this).find("#listMoreInfo").click(function () { - window.open(courses[$(this).closest("li").attr("id")].link); - }); - let status = courses[$(this).closest("li").attr("id")].status; - let registerlink = courses[$(this).closest("li").attr("id")].registerlink; - if (status.includes("closed") || status.includes("cancelled") || !status || !registerlink) { - $(this).find("#register").text("Can't Register").css("background-color", "#FF5722"); - } else { - if (status.includes("waitlisted")) { - $(this).find("#register").text("Join Waitlist").css("background-color", "#FF9800"); - } else { - $(this).find("#register").text("Register").css("background-color", "#4CAF50"); - } - $(this).find("#register").click(function () { - chrome.tabs.query({ - currentWindow: true, - active: true - }, function (tab) { - chrome.tabs.update(tab.id, { - url: registerlink - }); - }); - }) - } - - /* clear the conflict messages, then remove the course and updateConflicts. update the tabs*/ - $(this).find("#listRemove").click(function () { - var thisForm = this; - if (canremove) { - canremove = false; - $(thisForm).closest("ul").find("#conflict").fadeOut(300, function () { - $(this).remove(); - }); - chrome.runtime.sendMessage({ - command: "courseStorage", - course: courses[$(thisForm).closest("li").attr("id")], - action: "remove" - }, function (response) { - $(thisForm).closest("li").fadeOut(200); - if ($(thisForm).closest("ul").children(':visible').length === 1) { - showEmpty(); - } - canremove = true; - console.log('computedconflicts'); - updateConflicts(); - chrome.tabs.query({}, function (tabs) { - for (var i = 0; i < tabs.length; i++) { - chrome.tabs.sendMessage(tabs[i].id, { - command: "updateCourseList" - }); - } - }); - }); - } - - }); - /* Show the times popout and more info options*/ - if ($(this).find("#moreInfo").is(":hidden")) { - $(this).find("#moreInfo").fadeIn(200); - $(this).find('#arrow').css('transform', 'rotate(90deg)'); - - } else { - $(this).find("#moreInfo").fadeOut(200); - $(this).find('#arrow').css('transform', ''); +function handleRemoveButton(clicked_item, curr_course) { + let list = $(clicked_item).closest("ul"); + $(clicked_item).find("#listRemove").click(function () { + if (can_remove) { + can_remove = false; + $(list).find("#conflict").fadeOut(300, function () { + $(clicked_item).remove(); + }); + chrome.runtime.sendMessage({ + command: "courseStorage", + course: curr_course, + action: "remove" + }, () => { + $(clicked_item).fadeOut(200); + if ($(list).children(':visible').length === 1) + showEmpty(); + can_remove = true; + updateConflicts(); + updateAllTabsCourseList(); + }); } }); +} - $("#clear").click(function () { - clear(); +function handleMoreInfo(clicked_item, curr_course) { + $(clicked_item).find("#listMoreInfo").click(function () { + window.open(curr_course.link); }); +} - $("#schedule").click(function () { - chrome.tabs.create({ - 'url': 'https://registrar.utexas.edu/schedules' - }); +function copyButtonAnimation() { + $(this).find('i').text('check'); + $(this).stop(true, false).removeAttr('style').removeClass('shadow', { + duration: 200 }); - - $("#impexp").click(function () { - // Close import export window - if ($("#impexp>i").text() == 'close') { - hideImportExportPopup(); - // $(this).removeClass('selected'); - } else { - // Open import export window - - // If search window open, close it first to prevent overlap - if ($("#search>i").text() == 'close') { - hideSearchPopup(); - } - - showImportExportPopup(); - // $(this).addClass('selected'); + $(this).find('i').delay(400).queue(function (n) { + $(this).text('content_copy'); + $(this).parent().removeClass('shadow'); + if ($(this).parent().is(":hover")) { + $(this).parent().addClass('shadow'); } - }); + n(); + }) +} - $("#search").click(function () { - // Close search window + +function toggleTimeDropdown(clicked_item) { + let more_info_button = $(clicked_item).find('#moreInfo'); + let arrow = $('clicked_item').find("#arrow"); + if ($(more_info_button).is(":hidden")) { + $(more_info_button).fadeIn(200); + $(arrow).css('transform', 'rotate(90deg)'); + } else { + $(more_info_button).fadeOut(200); + $(arrow).css('transform', ''); + } +} + + +$("#courseList").on('mouseover', '.copybut', function () { + $(this).addClass('shadow'); +}).on('mouseleave', '.copybut', function () { + $(this).removeClass('shadow'); +}); + +$("#courseList").on('click', '.copybut', function (e) { + e.stopPropagation(); + var temp = $(""); + copyButtonAnimation(); + $("body").append(temp); + temp.val($(this).val()).select(); + document.execCommand("copy"); + temp.remove(); +}); + +$("#courseList").on('click', 'li', function () { + let clicked_item = $(this).closest('li'); + let curr_course = courses[$(clicked_item).attr("id")]; + handleMoreInfo(clicked_item, curr_course); + handleRegisterButton(clicked_item, curr_course) + handleRemoveButton(clicked_item, curr_course) + toggleTimeDropdown(clicked_item); +}); + +$("#clear").click(function () { + clear(); +}); + +$("#schedule").click(function () { + chrome.tabs.create({ + 'url': 'https://registrar.utexas.edu/schedules' + }); +}); + +$("#impexp").click(function () { + if ($("#impexp>i").text() == 'close') { + hideImportExportPopup(); + } else { if ($("#search>i").text() == 'close') { hideSearchPopup(); - // $(this).removeClass('selected'); + } + showImportExportPopup(); + } +}); + +$("#search").click(function () { + if ($("#search>i").text() == 'close') { + hideSearchPopup(); + } else { + if ($("#impexp>i").text() == 'close') { + hideImportExportPopup(); + } + showSearchPopup(); + } +}); + +$('#import-class').click(function () { + $("#importOrig").click(); +}); + +$('#export-class').click(function () { + chrome.storage.sync.get('savedCourses', function (data) { + if (data.savedCourses.length > 0) { + var exportlink = document.createElement('a'); + var url = window.URL.createObjectURL(new Blob([JSON.stringify(data.savedCourses, null, 4)], { + type: "octet/stream" + })); + exportlink.setAttribute('href', url); + exportlink.setAttribute('download', 'my_courses.json'); + exportlink.click(); } else { - // Open search window - - // If import export window open, close it first to prevent overlap - if ($("#impexp>i").text() == 'close') { - hideImportExportPopup(); - } - - showSearchPopup(); - // $(this).addClass('selected'); + alert('No Saved Courses to Export.'); } }); +}); - $('#import-class').click(function () { - $("#importOrig").click(); - }); - - $('#export-class').click(function () { - chrome.storage.sync.get('savedCourses', function (data) { - if (data.savedCourses.length > 0) { - var exportlink = document.createElement('a'); - var url = window.URL.createObjectURL(new Blob([JSON.stringify(data.savedCourses, null, 4)], { - type: "octet/stream" - })); - exportlink.setAttribute('href', url); - exportlink.setAttribute('download', 'my_courses.json'); - exportlink.click(); - } else { - alert('No Saved Courses to Export.'); - } - }); - }); - - $("#search-class").click(() => { - var uniqueId = $("#class_id_input").val(); - if (!isNaN(uniqueId)) { - if (uniqueId.length == 5) { - let selectedSemester = $("#semesters").find(":selected").val(); - openCoursePage(selectedSemester, uniqueId); - $("#class_id_input").val(''); - return; - } +$("#search-class").click(() => { + var unique_id = $("#class_id_input").val(); + if (!isNaN(unique_id)) { + if (unique_id.length == 5) { + let selected_semester = $("#semesters").find(":selected").val(); + openCoursePage(selected_semester, unique_id); + $("#class_id_input").val(''); + return; } - alert("Oops, check your input. Class IDs should have 5 digits!"); - }); + } + alert("Oops, check your input. Class IDs should have 5 digits!"); +}); - $("#open").click(function () { - chrome.tabs.create({ - 'url': "options.html" - }); +$("#options_button").click(function () { + chrome.tabs.create({ + 'url': "options.html" }); +}); - $("#calendar").click(function () { - chrome.tabs.create({ - 'url': "calendar.html" - }); +$("#calendar").click(function () { + chrome.tabs.create({ + 'url': "calendar.html" }); - }); $("#importOrig").change(function (e) { @@ -315,124 +268,50 @@ $("#importOrig").change(function (e) { var reader = new FileReader(); reader.onload = function () { try { - var impCourses = JSON.parse(this.result); - console.log(impCourses); - if (impCourses && impCourses.length && (impCourses.length == 0 || validateObject(impCourses))) { + var imported_courses = JSON.parse(this.result); + if (imported_courses && imported_courses.length && (imported_courses.length == 0 || validateObject(imported_courses))) { chrome.storage.sync.set({ - savedCourses: impCourses + savedCourses: imported_courses }); chrome.runtime.sendMessage({ command: "updateBadge" }); - chrome.tabs.query({}, function (tabs) { - for (var i = 0; i < tabs.length; i++) { - chrome.tabs.sendMessage(tabs[i].id, { - command: "updateCourseList" - }); - } - }); + updateAllTabsCourseList(); setCourseList(); chrome.runtime.sendMessage({ command: "updateStatus", }); } } catch (err) { - + console.log(err); } importOrig.value = ''; } reader.readAsText(files[0]); }); -function validateObject(impCourses) { - for (var i = 0; i < impCourses.length; i++) { - var course = impCourses[i]; - var isValid = true; +function validateObject(imported_courses) { + for (var i = 0; i < imported_courses.length; i++) { + var course = imported_courses[i]; + var is_valid = true; var props = ["coursename", "datetimearr", "link", "profname", "status", "unique"]; - console.log(course.coursename); for (let j = 0; j < props.length; j++) { - isValid &= course.hasOwnProperty(props[j]); + is_valid &= course.hasOwnProperty(props[j]); } - console.log(isValid); - if (!isValid) { + if (!is_valid) { return false; } } return true; } -/* convert from the dtarr and maek the time lines*/ -function makeLine(index) { - var datetimearr = courses[index].datetimearr; - //converted times back - var dtmap = new Map([]); - for (var i = 0; i < datetimearr.length; i++) { - datetimearr[i][1][0] = moment(datetimearr[i][1][0], ["HH:mm"]).format("h:mm a"); - datetimearr[i][1][1] = moment(datetimearr[i][1][1], ["HH:mm"]).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]); - } - } - var output = ""; - var timearr = Array.from(dtmap.keys()); - var dayarr = Array.from(dtmap.values()); - - if (timearr.length == 0) { - output = "This class has no meeting times." - } else { - 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 += `${dayarr[i]}:${timearr[i].split(",")[0]} to ${timearr[i].split(",")[1]}${place}
    `; - } - } - return output; -} - -//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; -} /*Clear the list and the storage of courses*/ function clear() { 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" - }); - } - }); + updateAllTabsCourseList(); chrome.runtime.sendMessage({ command: "updateBadge" }); @@ -442,8 +321,8 @@ function clear() { } function getSemesters() { - var schedulelist = 'https://registrar.utexas.edu/schedules'; - $.get(schedulelist, function (response) { + var schedule_list = 'https://registrar.utexas.edu/schedules'; + $.get(schedule_list, function (response) { if (response) { var object = $('

    ').html(response).contents(); object.find('.callout2>ul>li>a').each(function (index) { @@ -451,9 +330,9 @@ function getSemesters() { if ($(this).text() != "Course Schedule Archive") { const semester = $(this).text().split(" ")[0]; const year = $(this).text().split(" ")[1] - let semname = semester + " " + year; - console.log('semname:::: ' + semname); - $("#semesters").append(``); + let sem_name = semester + " " + year; + console.log('semname:::: ' + sem_name); + $("#semesters").append(``); $.get($(this).attr('href'), function (response) { if (response) { var object = $('
    ').html(response).contents(); @@ -465,12 +344,12 @@ function getSemesters() { console.log('name:::: ' + name); object.find('.gobutton>a').each(function () { - var semnum = $(this).attr('href').substring($(this).attr('href').lastIndexOf('/') + 1); - console.log('semnum:::: ' + semnum); + var sem_num = $(this).attr('href').substring($(this).attr('href').lastIndexOf('/') + 1); + console.log('semnum:::: ' + sem_num); $("option").each(function () { console.log($(this).text()); if ($(this).text() == name) { - $(this).val(semnum); + $(this).val(sem_num); console.log($(this).val()); } }) @@ -484,67 +363,24 @@ function getSemesters() { }); } -/*Course object for passing to background*/ -function Course(coursename, unique, profname, datetimearr, status, link, registerlink) { - this.coursename = coursename; - this.unique = unique; - this.profname = profname; - this.datetimearr = datetimearr; - this.status = status; - this.link = link; - this.registerlink = registerlink; -} - function openCoursePage(sem, unique) { var link = `https://utdirect.utexas.edu/apps/registrar/course_schedule/${sem}/${unique}/`; window.open(link); } -/*For a row, get all the course information and add the date-time-lines*/ -function getCourseObject(object, link) { - let coursename = object.find("#details h2").text(); - let uniquenum = object.find('td[data-th="Unique"]').text(); - let profname = object.find("td[data-th='Instructor']").text().split(', ')[0]; - if (profname.indexOf(" ") == 0) { - profname = profname.substring(1); +function handleEmpty() { + if (courses.length != 0) { + $("#empty").hide(); + $("#courseList").show(); + } else { + showEmpty(); } - let datetimearr = getDtarr(object); - let status = object.find('td[data-th="Status"]').text(); - let indlink = link; - let registerlink = object.find('td[data-th="Add"] a').prop('href'); - return new Course(coursename, uniquenum, profname, datetimearr, status, indlink, registerlink); } -/* For a row, get the date-time-array for checking conflicts*/ -function getDtarr(object) { - var numlines = object.find('td[data-th="Days"]>span').length; - var dtarr = []; - for (var i = 0; i < numlines; i++) { - var date = object.find('td[data-th="Days"]>span:eq(' + i + ')').text(); - var time = object.find('td[data-th="Hour"]>span:eq(' + i + ')').text(); - var place = object.find('td[data-th="Room"]>span:eq(' + i + ')').text(); - for (var j = 0; j < date.length; j++) { - var letter = date.charAt(j); - var day = ""; - if (letter == "T" && j < date.length - 1 && date.charAt(j + 1) == "H") { - dtarr.push(["TH", convertTime(time), place]); - } else { - if (letter != "H") { - dtarr.push([letter, convertTime(time), place]); - } - } - } - } - return dtarr; -} - -/* Convert time to 24hour format */ -function convertTime(time) { - var converted = time.replace(/\./g, '').split("-"); - for (var i = 0; i < 2; i++) { - converted[i] = moment(converted[i], ["h:mm A"]).format("HH:mm"); - } - return converted; +function showEmpty() { + $("#courseList").hide(); + $("#empty").fadeIn(200); + $("#main").html(Text.emptyText()); } function hideSearchPopup() { diff --git a/js/util.js b/js/util.js index f60745a7..78be7450 100644 --- a/js/util.js +++ b/js/util.js @@ -6,14 +6,14 @@ const days = new Map([ ["F", "Friday"] ]); -function getStatusColor(status) { +function getStatusColor(status, sub = false) { let color = "black"; if (status.includes("open")) { - color = Colors.open; + color = sub ? Colors.open_light : Colors.open; } else if (status.includes("waitlisted")) { - color = Colors.waitlisted; + color = sub ? Colors.waitlisted_light : Colors.waitlisted; } else if (status.includes("closed") || status.includes("cancelled")) { - color = Colors.closed; + color = sub ? Colors.closed_light : Colors.closed; } return color; } @@ -98,6 +98,42 @@ function prettifyDaysText(arr) { return output } +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 + } +} + + + + +function updateAllTabsCourseList() { + chrome.tabs.query({}, function (tabs) { + for (var i = 0; i < tabs.length; i++) { + chrome.tabs.sendMessage(tabs[i].id, { + command: "updateCourseList" + }); + } + }); +} + +function setCurrentTabUrl(link) { + chrome.tabs.query({ + currentWindow: true, + active: true + }, function (tab) { + chrome.tabs.update(tab.id, { + url: link + }); + }); +} + function semesterSort(semA, semB) { let semOrder = { @@ -121,6 +157,77 @@ function semesterSort(semA, semB) { return 0; } +/* convert from the dtarr and maek the time lines*/ +function convertDateTimeArrToLine(datetimearr) { + var output = []; + console.log(datetimearr) + var dtmap = makeDateTimeMap(datetimearr); + var timearr = Array.from(dtmap.keys()); + var dayarr = Array.from(dtmap.values()); + console.log(timearr); + console.log(dayarr); + for (var i = 0; i < dayarr.length; i++) { + var place = findLocation(dayarr[i], timearr[i], datetimearr); + var building = place.substring(0, place.search(/\d/)).trim(); + building = building ? building : "Undecided Location" + output.push({ + "days": dayarr[i], + "start_time": timearr[i].split(",")[0], + "end_time": timearr[i].split(',')[1], + "location_link": `https://maps.utexas.edu/buildings/UTM/${building}`, + "location_full": place + }) + } + return output; +} + +function makeDateTimeMap(datetimearr) { + var dtmap = new Map([]); + for (var i = 0; i < datetimearr.length; i++) { + 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]; + 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; +} + +function rgb2hex(rgb) { + rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); + + function hex(x) { + return ("0" + parseInt(x).toString(16)).slice(-2); + } + return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); +} + function buildChartConfig(data) { return { chart: { @@ -230,81 +337,6 @@ 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; -} - -function rgb2hex(rgb) { - rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); - - function hex(x) { - return ("0" + parseInt(x).toString(16)).slice(-2); - } - return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); +function canNotRegister(status, register_link) { + return status.includes("closed") || status.includes("cancelled") || !status || !register_link } \ No newline at end of file diff --git a/options.html b/options.html index 1c9cd0b8..a7723a92 100644 --- a/options.html +++ b/options.html @@ -22,9 +22,10 @@ Off
    -

    (v), Sriram Hariharan, 2018

    - - +

    (v), Sriram Hariharan, 2018

    + + + \ No newline at end of file diff --git a/popup.html b/popup.html index 2b94ed05..a0f424ac 100644 --- a/popup.html +++ b/popup.html @@ -74,7 +74,7 @@
    - @@ -83,6 +83,9 @@ + + +