Skip to content

Commit

Permalink
added listing of all subjects from current schedule
Browse files Browse the repository at this point in the history
  • Loading branch information
digas99 committed Sep 11, 2022
1 parent f718a9e commit fb27b12
Show file tree
Hide file tree
Showing 11 changed files with 240 additions and 106 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
## Bug Fixes
- Fixed bug of Changelog not loading in about page
- Changing pages within the extension while using a color theme doesn't flicker white anymore
- Fixed issue where choosing a subject color with the color picker on settings would break if many colors were clicked within the color picker (now, the color is only saved when the color picker is closed)
- Clicking on a class from a subject that has only one day on the schedule now shows the info panel on the right, instead of showing just one full sized schedule with one single day

## Popup
- Added button to lateral navbar to list all the subjects from the current schedule
- Color Themes:
- Sapphire
- Ambar

# [Changelog v1.2.0](https://github.com/digas99/schedule-ua/releases/tag/v1.2.0)
Released on 10/09/2022

## Popup
- Added Dark Mode
Expand Down
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,15 @@ Browser Extension for easy access to your Schedule from Universidade de Aveiro.

### Bug Fixes
- Fixed bug of Changelog not loading in about page

## [Changelog v1.2.0](https://github.com/digas99/schedule-ua/releases/tag/v1.2.0)
- Changing pages within the extension while using a color theme doesn't flicker white anymore
- Fixed issue where choosing a subject color with the color picker on settings would break if many colors were clicked within the color picker (now, the color is only saved when the color picker is closed)
- Clicking on a class from a subject that has only one day on the schedule now shows the info panel on the right, instead of showing just one full sized schedule with one single day

### Popup
- Added Dark Mode
- Added Changelog to about page
- Added button to lateral navbar to list all the subjects from the current schedule
- Color Themes:
- Light Mode
- Light High Contrast
- Dark Mode
- Dark High Contrast
- Sapphire
- Ambar

[(All changelogs)](CHANGELOG.md)

Expand Down
3 changes: 1 addition & 2 deletions home.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
</head>
<body style="font-family: sans-serif">
<div id="navbar">
<img title="SchedUA" src="images/logo.png">
<div class="separator"></div>
<div title="Schedule" id="schedule" class="button-inactive"><img class="icon" style="width: 25px;" src="images/icons/schedule.png"><div class="info-circle"><div>W</div></div></div>
<div title="List Subjects" id="list-subjects" class="clickable"><img class="icon" src="images/icons/list.png"></div>
<div title="Trim Schedule" id="shrink" class="clickable"><img class="icon" style="width: 25px;" src="images/icons/shrink.png"></div>
<div title="Download Schedule Configuration" id="download" class="clickable"><img class="icon" src="images/icons/download.png"></div>
<div title="Take a Picture of the Schedule" id="picture" class="clickable"><img class="icon" src="images/icons/camera.png"></div>
Expand Down
Binary file added images/icons/day.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/icons/list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
215 changes: 136 additions & 79 deletions scripts/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ window.addEventListener("click", e => {
const selected = target.innerText;
switch(selected) {
case "Week":
const listSubjectsButton = document.getElementById("list-subjects");
if (listSubjectsButton)
listSubjectsButton.classList.replace("button-inactive", "clickable");

scheduleWrapper.firstChild?.remove();
scheduleWrapper.querySelector(".info-panel")?.remove();

Expand Down Expand Up @@ -219,6 +223,10 @@ window.addEventListener("click", e => {
}

if (target.closest(".class")) {
const listSubjectsButton = document.getElementById("list-subjects");
if (listSubjectsButton)
listSubjectsButton.classList.replace("button-inactive", "clickable");

const targetSubject = target.closest(".class").innerText.split(" - ")[0];
const days = Object.entries(storage["schedule"])
.filter(([day, subjects]) => subjects.some(subject => subject["subject"]["abbrev"] == targetSubject))
Expand All @@ -233,30 +241,37 @@ window.addEventListener("click", e => {
scheduleWrapper.firstChild?.remove();
scheduleWrapper.querySelector(".info-panel")?.remove();

// adjust schedule
const newSchedule = JSON.parse(JSON.stringify(storage["schedule"])); // deep clone schedule
Object.keys(DAYS_INDEX).forEach(day => {
if (!days.includes(day))
delete newSchedule[day];
});
if (days.length == 1)
createDaySchedule(scheduleWrapper, days[0]);
else {
// adjust schedule
const newSchedule = JSON.parse(JSON.stringify(storage["schedule"])); // deep clone schedule
Object.keys(DAYS_INDEX).forEach(day => {
if (!days.includes(day))
delete newSchedule[day];
});

mySchedule = new Schedule(scheduleWrapper, {
"hours": defaultHours,
"days": days,
"schedule": newSchedule,
"colors": mySchedule.subjectColors,
"trimmed": mySchedule.trimmed,
"limitTrimming": mySchedule.limitTrimming,
"soonest": mySchedule.soonest,
"latest": mySchedule.latest
});

mySchedule.create();
mySchedule.setupOverlappedSubjects();
mySchedule = new Schedule(scheduleWrapper, {
"hours": defaultHours,
"days": days,
"schedule": newSchedule,
"colors": mySchedule.subjectColors,
"trimmed": mySchedule.trimmed,
"limitTrimming": mySchedule.limitTrimming,
"soonest": mySchedule.soonest,
"latest": mySchedule.latest
});

highlightNowCell();
mySchedule.create();
mySchedule.setupOverlappedSubjects();

highlightNowCell();
}
}
}

if (!target.closest(".floating-info-panel") && !target.closest("#list-subjects") && !target.closest("#darkmode") && document.querySelector(".floating-info-panel"))
document.querySelector("#list-subjects").click();
});

window.addEventListener("mouseover", e => {
Expand Down Expand Up @@ -369,6 +384,9 @@ window.addEventListener("mouseout", e => {
const createDaySchedule = (scheduleWrapper, scheduleDay) => {
scheduleWrapper.firstChild?.remove();
scheduleWrapper.querySelector(".info-panel")?.remove();
const listSubjectsButton = document.getElementById("list-subjects");
if (listSubjectsButton)
listSubjectsButton.classList.replace("clickable", "button-inactive");

mySchedule = new Schedule(scheduleWrapper, {
"hours": defaultHours,
Expand Down Expand Up @@ -434,68 +452,107 @@ const infoPanel = schedule => {
const title = document.createElement("h2");
wrapper.appendChild(title);
title.appendChild(document.createTextNode("Your classes"));

// general data
const genDataWrapper = document.createElement("div");
wrapper.appendChild(genDataWrapper);

const subjectsWrapper = document.createElement("div");
wrapper.appendChild(subjectsWrapper);
const subjects = Object.values(schedule).flat(1);
let pract = 0, theor = 0, hoursTotal = 0;
if (subjects) {
subjects.forEach(subject => {
if (subject) {
const subjectWrapper = document.createElement("div");
subjectsWrapper.appendChild(subjectWrapper);
subjectWrapper.classList.add("subject-info");
const classTitle = document.createElement("div");
subjectWrapper.appendChild(classTitle);
classTitle.appendChild(document.createTextNode(`${subject["subject"]["abbrev"]} - ${subject["subject"]["name"]}`));
classTitle.style.backgroundColor = mySchedule.subjectColors[subject["subject"]["abbrev"]];
const infoWrapper = document.createElement("div");
subjectWrapper.appendChild(infoWrapper);
const classNumberWrapper = document.createElement("div");
infoWrapper.appendChild(classNumberWrapper);
const classNumber = document.createElement("div");
classNumberWrapper.appendChild(classNumber);
classNumber.appendChild(document.createTextNode(subject["class"]));
const info = document.createElement("div");
infoWrapper.appendChild(info);
const start = parseFloat(subject["start"].replace(",", "."));
const duration = parseFloat(subject["duration"].replace(",", "."));
const end = start+duration;
subject["time"] = `${start}h - ${end}h`;
["time" ,"duration", "room", "capacity"].forEach(type => {
const rowWrapper = document.createElement("div");
info.appendChild(rowWrapper);
rowWrapper.title = type.charAt(0).toUpperCase()+type.slice(1);
const rowIcon = document.createElement("img");
rowWrapper.appendChild(rowIcon);
rowIcon.src = `images/icons/${type}.png`;
rowIcon.classList.add("icon");
const rowContent = document.createElement("div");
rowWrapper.appendChild(rowContent);
rowContent.appendChild(document.createTextNode(subject[type]));

if (schedule) {
const scheduleSize = Object.keys(schedule).length;

// summary
const genDataWrapper = document.createElement("div");
wrapper.appendChild(genDataWrapper);

let dayChooser;
if (scheduleSize > 1) {
// day chooser
dayChooser = document.createElement("div");
wrapper.appendChild(dayChooser);
dayChooser.classList.add("day-chooser");
}

const subjectsWrapper = document.createElement("div");
wrapper.appendChild(subjectsWrapper);
let pract = 0, theor = 0, hoursTotal = 0;

Object.entries(schedule).forEach(([day, subjects]) => {
if (subjects) {
const container = document.createElement("div");
subjectsWrapper.appendChild(container);
container.setAttribute("day", day);
subjects.forEach(subject => {
if (subject) {
const subjectWrapper = document.createElement("div");
container.appendChild(subjectWrapper);
subjectWrapper.classList.add("subject-info");
const classTitle = document.createElement("div");
subjectWrapper.appendChild(classTitle);
classTitle.appendChild(document.createTextNode(`${subject["subject"]["abbrev"]} - ${subject["subject"]["name"]}`));
classTitle.style.backgroundColor = mySchedule.subjectColors[subject["subject"]["abbrev"]];
const infoWrapper = document.createElement("div");
subjectWrapper.appendChild(infoWrapper);
const classNumberWrapper = document.createElement("div");
infoWrapper.appendChild(classNumberWrapper);
const classNumber = document.createElement("div");
classNumberWrapper.appendChild(classNumber);
classNumber.appendChild(document.createTextNode(subject["class"]));
const info = document.createElement("div");
infoWrapper.appendChild(info);
const start = parseFloat(subject["start"].replace(",", "."));
const duration = parseFloat(subject["duration"].replace(",", "."));
const end = start+duration;
subject["time"] = `${start}h - ${end}h`;
subject["day"] = day.slice(0, 3).toUpperCase();
const keys = ["day", "time" ,"duration", "room", "capacity"];
if (scheduleSize == 1)
delete keys[0];

keys.forEach(type => {
const rowWrapper = document.createElement("div");
info.appendChild(rowWrapper);
rowWrapper.title = type.charAt(0).toUpperCase()+type.slice(1);
const rowIcon = document.createElement("img");
rowWrapper.appendChild(rowIcon);
rowIcon.src = `images/icons/${type}.png`;
rowIcon.classList.add("icon");
const rowContent = document.createElement("div");
rowWrapper.appendChild(rowContent);
rowContent.appendChild(document.createTextNode(subject[type]));
});

if (subject["class"].charAt(0) == "P") pract++;
else theor++;

hoursTotal += parseFloat(subject["duration"].replace(",", "."));
}
});

if (subject["class"].charAt(0) == "P") pract++;
else theor++;

hoursTotal += parseFloat(subject["duration"].replace(",", "."));
}
}
});

// summary
const data = [scheduleSize, pract+theor, pract, theor, hoursTotal+"h"];
const titles = ["Days", "Classes", "Pract.", "Theor.", "Hours Total"];
if (scheduleSize == 1) {
delete data[0];
delete titles[0];
}
titles.forEach((title, i) => {
const wrapper = document.createElement("div");
genDataWrapper.appendChild(wrapper);
const titleElem = document.createElement("b");
wrapper.appendChild(titleElem);
titleElem.appendChild(document.createTextNode(title));
wrapper.appendChild(document.createTextNode(` ${data[i]}`));
});
}

const data = [pract+theor, pract, theor, hoursTotal+"h"];
["Classes", "Pract.", "Theor.", "Hours Total"].forEach((title, i) => {
const wrapper = document.createElement("div");
genDataWrapper.appendChild(wrapper);
const titleElem = document.createElement("b");
wrapper.appendChild(titleElem);
titleElem.appendChild(document.createTextNode(title));
wrapper.appendChild(document.createTextNode(` ${data[i]}`));
});
// day chooser
if (scheduleSize > 1) {
Object.keys(schedule).forEach(dayString => {
const dayWrapper = document.createElement("div");
dayChooser.appendChild(dayWrapper);
dayWrapper.appendChild(document.createTextNode(dayString));
dayWrapper.classList.add("clickable");
dayWrapper.addEventListener("click", () => wrapper.parentElement.scrollTo(0, subjectsWrapper.querySelector(`div[day="${dayString}"]`).offsetTop));
});
}
}

return wrapper;
}
Expand Down
13 changes: 10 additions & 3 deletions scripts/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@ chrome.storage.sync.get(SETTINGS_KEYS, result => {
colorPicker.type = "color";
colorPicker.value = color;

colorPicker.addEventListener("input", () => {
subjectColors[subject] = colorPicker.value;
chrome.storage.sync.set({"subject_colors": subjectColors});
let choosingColor = false;
colorPicker.addEventListener("click", () => choosingColor = true);

colorPicker.addEventListener("input", () => subjectColors[subject] = colorPicker.value);

colorPicker.addEventListener("mouseout", () => {
if (choosingColor) {
chrome.storage.sync.set({"subject_colors": subjectColors});
choosingColor = false;
}
});
});
}
Expand Down
41 changes: 35 additions & 6 deletions scripts/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,44 @@ window.addEventListener("click", e => {
const target = e.target;

chrome.storage.sync.get("color_schema", result => {
if (target.closest("#exit"))
chrome.storage.sync.remove([...SCHEDULE_CONFIGS, "subject_colors"]).then(() => window.location.href = `/login.html?theme=${result["color_schema"]}`);
if (target.closest("#exit"))
chrome.storage.sync.remove([...SCHEDULE_CONFIGS, "subject_colors"]).then(() => window.location.href = `/login.html?theme=${result["color_schema"]}`);

if (target.closest("#schedule") && !target.closest("#schedule").classList.contains("button-inactive")) window.location.href = `/home.html?theme=${result["color_schema"]}`;
if (target.closest("#schedule") && !target.closest("#schedule").classList.contains("button-inactive")) window.location.href = `/home.html?theme=${result["color_schema"]}`;

if (target.closest("#settings") && !target.closest("#settings").classList.contains("button-inactive")) window.location.href = `/settings.html?theme=${result["color_schema"]}`;
if (target.closest("#settings") && !target.closest("#settings").classList.contains("button-inactive")) window.location.href = `/settings.html?theme=${result["color_schema"]}`;

if (target.closest("#about") && !target.closest("#about").classList.contains("button-inactive")) window.location.href = `/about.html?theme=${result["color_schema"]}`;
if (target.closest("#about") && !target.closest("#about").classList.contains("button-inactive")) window.location.href = `/about.html?theme=${result["color_schema"]}`;
});

if (target.closest("#darkmode")) swapColorSchema(target.closest("#darkmode").title);
});

if (target.closest("#list-subjects") && !target.closest("#list-subjects").classList.contains("button-inactive") && document.getElementById("main") && mySchedule.schedule) {
let floatingInfoPanel = document.querySelector(".floating-info-panel");
if (!floatingInfoPanel) {
floatingInfoPanel = document.createElement("div");
document.getElementById("main").appendChild(floatingInfoPanel);
floatingInfoPanel.classList.add("floating-info-panel");
const sortedSchedule = Object.entries(mySchedule.schedule)
.filter(([, value]) => value && value.length > 0)
.sort(([a,], [b,]) => mySchedule.daysIndex[a] - mySchedule.daysIndex[b])
.reduce((acc, [key, value]) => ({...acc, [key]: value}), {});

const panel = infoPanel(sortedSchedule);
floatingInfoPanel.appendChild(panel);

floatingInfoPanel.style.transition = "0.3s";
floatingInfoPanel.style.right = `-${floatingInfoPanel.offsetWidth}px`;
setTimeout(() => {
floatingInfoPanel.style.right = "51px";
setTimeout(() => floatingInfoPanel.style.removeProperty("transition"), 300);
}, 50);

}
else {
floatingInfoPanel.style.transition = "0.3s";
floatingInfoPanel.style.right = `-${floatingInfoPanel.offsetWidth}px`;
setTimeout(() => floatingInfoPanel.remove(), 300);
}
}
});
2 changes: 1 addition & 1 deletion settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ <h2>Schedule</h2>
<option>Tomorrow</option>
</select>
</div>
<div title="Customize the colors of each subject." id="settings-subjects-colors">
<div title="Customize the colors of each subject. The color is only saved when the color picker is closed!" id="settings-subjects-colors">
<div>Subjects Colors</div>
<div title="New Random Colors" id="subjects-colors-refresh" class="clickable-light"><img class="icon" src="images/icons/refresh.png"></div>
<div>
Expand Down
Loading

0 comments on commit fb27b12

Please sign in to comment.