Skip to content

Commit

Permalink
Merge pull request #159 from NIAEFEUP/feature/favorite-course
Browse files Browse the repository at this point in the history
Favorite course
  • Loading branch information
LuisDuarte1 authored Jan 21, 2024
2 parents b0a2e04 + cffba7b commit 857d5ee
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 7 deletions.
9 changes: 7 additions & 2 deletions content-scripts/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "./modules/initialize";
import { injectAllChanges, userPreferences } from "./modules/options/all";
import constructNewData from "./modules/utilities/constructNewData";
import { getStorage } from "./modules/utilities/storage";
import { getStorage, setStorage } from "./modules/utilities/storage";
import { rememberLogin } from "./modules/login";
import { replaceIcons } from "./modules/icons";
import { teacherPage } from "./pages/teacher_page";
Expand All @@ -16,6 +16,7 @@ import { changeCourseCards, changeProfileRow } from "./pages/profile_page";
import { courseUnitPage } from "./pages/course_unit_page";
import { fixPagination } from "./modules/pagination";
import { changeLayout } from "./modules/layout";
import { addStarIconToCard } from "./modules/favorite-course";

/*--
- Docs: https://developer.chrome.com/docs/extensions/reference/storage/#synchronous-response-to-storage-updates
Expand Down Expand Up @@ -47,16 +48,20 @@ const functionsToExecute = [
{ name: "classPage", func: classPage },
{ name: "courseUnitPage", func: courseUnitPage },
{ name: "injectOverrideFunctions", func: injectOverrideFunctions },
{ name: "addStarIconToCard", func: addStarIconToCard}
]

const init = async () => {

// // Watch for resize events
// addResizeListener();

// // Inject user preferences
const data = await getStorage(userPreferences);
injectAllChanges(data);

if(!(await getStorage('favorite_courses'))){
await setStorage({'favorite_courses': '{}'}) //Insert empty object
}

functionsToExecute.forEach(f => {
try {
Expand Down
129 changes: 129 additions & 0 deletions content-scripts/src/modules/favorite-course.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { getUP } from "./utilities/sigarra";
import { getStorage, setStorage } from "./utilities/storage";

const pagesWithCourseCards = [
"fest_geral.cursos_list",
"fest_geral.curso_percurso_academico_view",
"fest_geral.curso_posicao_plano_view",
"fest_geral.ucurr_inscricoes_list",
"fest_geral.estatutos_regimes_view",
"fest_geral.info_ingresso_view",
"fest_geral.info_pessoal_completa_view"
];

/**
*
* @param {Element[]} cards
* @param {string | undefined} favoriteCourse
*/
function rerenderStarIcons(cards, favoriteCourse) {
cards.forEach((val) => {
const enrollmentId = val.getAttribute('data-course-enrollment-id')
if(enrollmentId === null) {
throw Error('could not find enrollment id in card')
}

let isFavoriteCourse = enrollmentId === favoriteCourse
const i = val.querySelector('.se-course-star')
i.classList = []

i.classList.add(
isFavoriteCourse ? 'ri-star-fill' : 'ri-star-line',
'se-course-star'
)
if(isFavoriteCourse) i.classList.add('se-favorite-course')
})
}

function changeProfileLink(favoriteCourses){
const up = getUP().toString()
const favoriteCourse = favoriteCourses[up]
const profileLink = document.querySelector('.se-auth-profile')
if(favoriteCourse === undefined){
profileLink.href = `fest_geral.cursos_list?pv_num_unico=${up}`
} else {
profileLink.href = `fest_geral.curso_percurso_academico_view?pv_fest_id=${favoriteCourse}`
}
}

export async function favoriteCardListener(){
const favoriteCourses = await getStorage('favorite_courses')
changeProfileLink(JSON.parse(favoriteCourses))
chrome.storage.local.onChanged.addListener(async (changes) => {
if(!Object.keys(changes).includes('favorite_courses')){
return
}
changeProfileLink(JSON.parse(changes['favorite_courses'].newValue))
})
}

export async function addStarIconToCard() {
await favoriteCardListener();
const hasProfileRow = pagesWithCourseCards
.map((value) => document.location.href.toLowerCase().includes(value))
.reduce((prev, curr) => prev || curr);

if (!hasProfileRow){
return;
}
const up = getUP()
let favoriteCourses = JSON.parse(await getStorage('favorite_courses'))
let favoriteCourse = favoriteCourses[up.toString()]
const cards = document.querySelectorAll('.se-course-card')

cards.forEach((val) => {
const titleBar = val.querySelector('.estudante-lista-curso-nome')
const enrollmentId = val.getAttribute('data-course-enrollment-id')
if(enrollmentId === null) {
throw Error('could not find enrollment id in card')
}
if(titleBar === null){
throw Error('Could not find titlebar for the course card')
}

let isFavoriteCourse = enrollmentId === favoriteCourse
const i = document.createElement('i')
i.classList.add(
isFavoriteCourse ? 'ri-star-fill' : 'ri-star-line',
'se-course-star'
)
if(isFavoriteCourse) i.classList.add('se-favorite-course')

i.addEventListener('mouseenter', (_) => {
if(!isFavoriteCourse){
i.classList.remove('ri-star-line')
i.classList.add('ri-star-fill')
}
})

i.addEventListener('mouseleave', (_) => {
if(!isFavoriteCourse){
i.classList.remove('ri-star-fill')
i.classList.add('ri-star-line')
}
})

i.addEventListener('click', async (ev) => {
ev.preventDefault()
ev.stopPropagation()

if(favoriteCourse === enrollmentId) {
delete favoriteCourses[up.toString()]
favoriteCourse = undefined
isFavoriteCourse = false
i.classList.remove('se-favorite-course')
} else {
favoriteCourses[up.toString()] = enrollmentId
favoriteCourse = enrollmentId
isFavoriteCourse = true
i.classList.add('se-favorite-course')

}
await setStorage({'favorite_courses': JSON.stringify(favoriteCourses)})

rerenderStarIcons(cards, favoriteCourse)
})

titleBar.append(i)
})
}
12 changes: 7 additions & 5 deletions content-scripts/src/modules/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const authentication = (auth) =>
<span>${auth.number}</span>
</div>
<nav id="se-auth-profile-links">
<a href="fest_geral.cursos_list?pv_num_unico=${
<a class="se-auth-profile" href="fest_geral.cursos_list?pv_num_unico=${
auth.number
}">
<span class="se-icon ri-user-line"></span> Perfil
Expand Down Expand Up @@ -272,13 +272,15 @@ const replaceHeader = () => {

let auth = null;

if (autenticacao && autenticacao.classList.contains("autenticado"))
if (autenticacao && autenticacao.classList.contains("autenticado")){
const number = autenticacao.querySelector("img").src.slice(-9)

auth = {
name: autenticacao.querySelector(".nome").textContent,
number: autenticacao.querySelector("img").src.slice(-9),
number: number,
notifications: oldHeader.querySelector(".notificacao") !== null,
};

}
const newHeader = createNewHeader(auth);

const newAuth = newHeader.querySelector("#se-auth");
Expand Down Expand Up @@ -330,7 +332,7 @@ const removeLeftColumn = () => {
rightColumn.append(newMap);
};

export const changeLayout = () => {
export const changeLayout = async () => {
// Move all scripts and styles to head
const scripts = document.querySelectorAll("script, link, style");
document.head.append(...scripts);
Expand Down
7 changes: 7 additions & 0 deletions content-scripts/src/pages/profile_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,17 @@ export const changeCourseCards = () => {
if(detailsElement != null) {
const url = detailsElement.querySelector('a').href;
detailsElement.remove();
const parsedUrlParams = new URLSearchParams(url.split('?')[1])
let festId = parsedUrlParams.get('pv_fest_id')
if(festId === null){
festId = new URLSearchParams(location.href.split('?')[1]).get('pv_fest_id')

}

const a = document.createElement('a');
a.classList = card.classList;
a.classList.add("se-course-card-clickable");
a.setAttribute('data-course-enrollment-id', festId)
if(active || hasCardSelected == false) a.classList.add('se-course-card-active')

a.append(...card.children);
Expand Down
18 changes: 18 additions & 0 deletions css/profilePage.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@
color: inherit !important;
}

.se-course-card > .estudante-lista-curso-nome {
display: flex;
align-items: flex-start;
gap: 1rem;
}

.se-course-card > .estudante-lista-curso-nome > .se-course-star {
font-size: 1.5rem;
}

.se-course-card > .estudante-lista-curso-nome > .se-course-star.se-favorite-course:hover{
color: rgb(219, 146, 9);
}

.se-course-card > .estudante-lista-curso-nome > .se-course-star.ri-star-fill {
color: rgb(236, 156, 7);
}

.se-course-card-clickable > .estudante-lista-curso-nome > a{
display: block;
}
Expand Down

0 comments on commit 857d5ee

Please sign in to comment.