Skip to content

Commit

Permalink
Added list of all events marked as complete
Browse files Browse the repository at this point in the history
- Added list of all events marked as complete
- Remove debugging `console.log`s
- Refactored marking complete/incomplete functions
  • Loading branch information
da-stoi committed Nov 13, 2023
1 parent 27eb25d commit 5ef32fa
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 62 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ After installing the extension, either visit the Canvas calendar, or go to a ass
### Features
- Mark assignments/pages as complete from the calendar.
- Mark assignments/pages as complete from the assignment/page itself.
- View a list of all events manually marked as complete.

### Things to note
- Marking an assignment as complete is only for your own reference. It does not affect your submission/grade, nor does it notify your instructor.
Expand Down
11 changes: 4 additions & 7 deletions src/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getCheckedTodos } from "./storage";
import { Todo, CalendarEvent } from "./types";
import { checkEvent } from "./updateCalendarEvent";
import { displayCheckButton } from "./displayCheckButton";
import { displayCheckedTodos } from "./displayCheckedTodos";

export async function calendar() {

Expand All @@ -12,15 +13,13 @@ export async function calendar() {

// Get all checked assignments
const checkedTodos: Todo[] = getCheckedTodos(courseList);
// const checkedTodoIds: number[] = checkedTodos.map((todo: Todo) => todo.id);

// Display checked todos list
displayCheckedTodos();

// Get all calendar events
const calendarEvents: CalendarEvent[] = getCalendarEvents();

console.log(courseList);
console.log(checkedTodos);
console.log(calendarEvents);

calendarEvents.forEach((event: CalendarEvent) => {
const { name, element } = event;

Expand Down Expand Up @@ -54,7 +53,6 @@ if (path.includes('calendar')) {
const now = new Date().getTime();
// Only allow calendar to update once every 100ms
if (now - domLastModified > 100) {
console.log('calendar change');
calendar();
domLastModified = now;
}
Expand Down Expand Up @@ -83,7 +81,6 @@ if (path.includes('calendar')) {
lastPopupUrl = '';
} else {
if (lastPopupUrl !== eventLinkElement.getAttribute('href')) {
console.log('popup change');
displayCheckButton();
}
lastPopupUrl = eventLinkElement.getAttribute('href') || '';
Expand Down
53 changes: 3 additions & 50 deletions src/displayCheckButton.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { getCalendarEvents } from "./getCalendarEvents";
import { addCheckedTodo, isTodoChecked, removeCheckedTodo } from "./storage";
import { CalendarEvent, Todo } from "./types";
import { checkEvent, uncheckEvent } from "./updateCalendarEvent";
import { markCompleteOnclick, markIncompleteOnclick } from "./markTodos";
import { isTodoChecked } from "./storage";
import { Todo } from "./types";

function checkButtonHtml(courseId: number, todo: Todo, isChecked: boolean, isSubmitted: boolean): HTMLButtonElement {
const checkButton: HTMLButtonElement = document.createElement('button');
Expand Down Expand Up @@ -45,50 +44,6 @@ function gradedDisclaimer(): HTMLSpanElement {

}

function markIncompleteOnclick(courseId: number, todo: Todo, checkButton: HTMLButtonElement, updateCalendar: boolean = false) {
// Remove checked assignment
removeCheckedTodo(todo.id);
checkButton.innerHTML = 'Mark as complete';

// Uncheck event on calendar if updateCalendar is true
if (updateCalendar) {
const calendarEvents: CalendarEvent[] = getCalendarEvents();

calendarEvents.forEach((event: CalendarEvent) => {
const { name, element } = event;

// If assignment is checked
if (name === todo.name) {
uncheckEvent(element);
}
});
}

checkButton.onclick = () => { markCompleteOnclick(courseId, todo, checkButton, updateCalendar) };
}

function markCompleteOnclick(courseId: number, todo: Todo, checkButton: HTMLButtonElement, updateCalendar: boolean = false) {
// Add checked assignment
addCheckedTodo(todo)
checkButton.innerHTML = 'Mark as incomplete';

// Check event on calendar if updateCalendar is true
if (updateCalendar) {
const calendarEvents: CalendarEvent[] = getCalendarEvents();

calendarEvents.forEach((event: CalendarEvent) => {
const { name, element } = event;

// If assignment is checked
if (name === todo.name) {
checkEvent(element);
}
});
}

checkButton.onclick = () => { markIncompleteOnclick(courseId, todo, checkButton, updateCalendar) };
}

async function handleAssignment(courseId: number, assignmentId: number) {

const rightSide = document.querySelector('#right-side');
Expand Down Expand Up @@ -171,8 +126,6 @@ async function handlePage(courseId: number, pageUrl: string) {

async function handleEvent(courseId: number, todoId: number | string, eventType: 'assignment' | 'page') {

console.log('handling event', courseId, todoId);

let isChecked = false;
let todo: Todo | undefined = undefined;
let isSubmitted = false;
Expand Down
109 changes: 109 additions & 0 deletions src/displayCheckedTodos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { getCheckedCourses } from "./getCheckedCourses";
import { markIncompleteOnclick } from "./markTodos";
import { getCheckedTodos } from "./storage";
import { Todo } from "./types";

export async function displayCheckedTodos() {

// Get checked courses
const courseList: number[] = getCheckedCourses();

// Get all checked assignments
const checkedTodos: Todo[] = getCheckedTodos(courseList);
checkedTodos.reverse();

// Remove existing checked todos section if it exists
const existingSection = document.querySelector('#checked-todos-section');
existingSection?.remove();

// Main div for checked todos
const rsSection = document.createElement('div');
rsSection.classList.add('rs-section');
rsSection.id = 'checked-todos-section';

// Header
const h2 = document.createElement('h2');
h2.tabIndex = -1;

// Header button
const span = document.createElement('span');
span.role = 'button';
span.id = 'checked-todos-button';
span.classList.add('element_toggler');
span.setAttribute('aria-controls', 'checked-todos');
span.setAttribute('aria-expanded', 'true');
span.setAttribute('aria-label', 'Undated items toggle list visibility');
span.tabIndex = 0;

// Header button icon
const i = document.createElement('i');
i.classList.add('auto_rotate');
i.classList.add('icon-mini-arrow-down');

span.appendChild(i);
span.appendChild(document.createTextNode(' Canvas Strikethrough Checked'));

h2.appendChild(span);

// List of checked todos
const div = document.createElement('div');
div.id = 'checked-todos';
div.style.display = 'block';
div.style.opacity = '1';
div.classList.add('ui-droppable');

const ul = document.createElement('ul');
ul.style.listStyleType = 'none';
ul.style.padding = '0';
ul.style.margin = '0';
ul.id = 'checked-todos-list';

checkedTodos.forEach((todo, index) => {

const event = document.createElement('div');
event.classList.add('checked-todo');
event.classList.add('event');
event.classList.add(`group_course_${todo.courseId}`);
event.id = `checked-todo-${index}`;
event.style.borderRadius = '3px';
event.style.marginBottom = '3px';
event.style.padding = '3px';
event.style.color = 'white';
event.setAttribute('data-course-id', `${todo.courseId}`);
event.setAttribute('data-todo-id', `${todo.id}`);

const spanInner = document.createElement('a');
spanInner.innerHTML = todo.name.length > 25 ? todo.name.substring(0, 25) + '...' : todo.name;
spanInner.classList.add('icon-calendar-month');
spanInner.style.color = 'white';
spanInner.style.textDecoration = 'none';
spanInner.style.cursor = 'pointer';

const markAsIncompleteButton = document.createElement('button');
markAsIncompleteButton.classList.add('Button');
markAsIncompleteButton.classList.add('Button--link');
markAsIncompleteButton.innerText = 'Mark as incomplete';
markAsIncompleteButton.style.padding = '5px';

markAsIncompleteButton.onclick = () => {
markIncompleteOnclick(todo.courseId, todo, markAsIncompleteButton, true);

// Remove checked todo from list
const checkedTodo = document.querySelector(`#checked-todo-${index}`);
checkedTodo?.remove();
};

event.appendChild(spanInner);
event.appendChild(document.createElement('br'));
event.appendChild(markAsIncompleteButton);
ul.appendChild(event);
});

div.appendChild(ul);

rsSection.appendChild(h2);
rsSection.appendChild(div);

const main = document.querySelector('#right-side');
main?.appendChild(rsSection);
}
1 change: 0 additions & 1 deletion src/getCheckedCourses.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// Get the course ID for the current grade page
export function getCheckedCourses(): number[] {

Expand Down
51 changes: 51 additions & 0 deletions src/markTodos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { displayCheckedTodos } from "./displayCheckedTodos";
import { getCalendarEvents } from "./getCalendarEvents";
import { addCheckedTodo, removeCheckedTodo } from "./storage";
import { CalendarEvent, Todo } from "./types";
import { checkEvent, uncheckEvent } from "./updateCalendarEvent";

export function markIncompleteOnclick(courseId: number, todo: Todo, checkButton: HTMLButtonElement, updateCalendar: boolean = false) {
// Remove checked assignment
removeCheckedTodo(todo.id);
checkButton.innerHTML = 'Mark as complete';

// Uncheck event on calendar if updateCalendar is true
if (updateCalendar) {
const calendarEvents: CalendarEvent[] = getCalendarEvents();

calendarEvents.forEach((event: CalendarEvent) => {
const { name, element } = event;

// If assignment is checked
if (name === todo.name) {
uncheckEvent(element);
displayCheckedTodos();
}
});
}

checkButton.onclick = () => { markCompleteOnclick(courseId, todo, checkButton, updateCalendar) };
}

export function markCompleteOnclick(courseId: number, todo: Todo, checkButton: HTMLButtonElement, updateCalendar: boolean = false) {
// Add checked assignment
addCheckedTodo(todo)
checkButton.innerHTML = 'Mark as incomplete';

// Check event on calendar if updateCalendar is true
if (updateCalendar) {
const calendarEvents: CalendarEvent[] = getCalendarEvents();

calendarEvents.forEach((event: CalendarEvent) => {
const { name, element } = event;

// If assignment is checked
if (name === todo.name) {
checkEvent(element);
displayCheckedTodos();
}
});
}

checkButton.onclick = () => { markIncompleteOnclick(courseId, todo, checkButton, updateCalendar) };
}
2 changes: 0 additions & 2 deletions src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export function getCheckedTodos(courseList?: number[]): Todo[] {

let checkedTodo: Todo[] = JSON.parse(localStorage.getItem('checkedTodo') || '[]');

console.log('getting checked todos', checkedTodo);

// Filter out todos when looking at specific courses
if (courseList !== undefined) {
// Filter checked todos by course list
Expand Down
2 changes: 0 additions & 2 deletions src/updateCalendarEvent.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// Check an event
export async function checkEvent(event: Element) {

event.querySelector('.fc-title')?.classList.add('calendar__event--completed');
}

// Uncheck an event
export async function uncheckEvent(event: Element) {

event.querySelector('.fc-title')?.classList.remove('calendar__event--completed');
}

0 comments on commit 5ef32fa

Please sign in to comment.