/**
* @file The saved-readings-script.js is a script that contains almost all of the
* functionality needed to store, retrieve, and delete a fortune from localStorage.
* It also contains functions to display fortunes on the page itself.
* - Last Modified: 06/11/2023
* @author Nakul Nandhakumar
* @author Ezgi Bayraktaroglu
* @author Joshua Tan
* @author Abijit Jayachandran
* @author Samuel Au
*/
/**
* Adds an event listener to window to call init function when the document
* has parsed
*/
window.addEventListener('DOMContentLoaded', init);
/**
* Function adding event listeners for the buttons on the page
* and calling the function to display fortunes.
*/
function init() {
/**
* A reference to the button to go back to the menu
* @type {HTMLElement | null}
*/
const backButton = document.querySelector(".backButton");
/**
* A reference to the button to clear the fortunes from
* local storage and from the display. Is temporary, for
* testing, but could be useful in the final product as well.
* @type {HTMLElement | null}
*/
const clearButton = document.querySelector(".clearButton");
/**
* Adds an event listener for backButton to call the function that
* sends user back to menu page.
*/
if (backButton != null)
backButton.addEventListener("click", backToMenu);
/**
* Adds a event listener for tempClearButton to call the function
* that clears fortunes from localeStorage and updates display.
*/
if (clearButton != null)
clearButton.addEventListener("click", clearFortunes);
/**
* Display fortunes when page loads
*/
displayFortunes();
/* Play sound when pressing buttons */
//playClickSound();
}
/**
* Adds event listeners to all buttons to play click sound effect.
*/
// function playClickSound() {
// let buttons = document.getElementsByTagName("button");
// for (let button of buttons) {
// button.addEventListener('click', () => {
// const sound = document.getElementById("click");
// sound.play();
// });
// }
// }
/**
* This function sends the user back to the menu page
*/
function backToMenu() {
//const sound = document.getElementById("click");
//sound.addEventListener('ended', function (){
window.location.href = "menu.html";
//});
// setTimeout(function() {
// window.location.href = "menu.html";
// }, 400);
}
/**
* This function clears the localStorage of (only) fortunes and
* calls the displayFortunes function to update the display to
* be cleared of fortunes. This function is called by the
* event listener added to tempClearButton. This is meant to be a
* temporary fuction used help test, but it could be useful for
* the actual page.
*/
function clearFortunes() {
localStorage.removeItem("fortunes");
displayFortunes();
}
/**
* Adds a event listener that fires whenever the localstorage
* changes "in the context of another document" (mozilla.org)
* and calls the displayFortunes function.
* This means that if the fortune page is open in another tab
* and the fortune bank is open in another tab and changes are
* made to local storage in that other tab, the fortune bank
* page will detect it. This means that if a fortune is saved
* in the other page, this event listener will activate.
* It will call the displayFortunes function and update
* the display to include the fortune that was saved on the
* other tab.
*/
window.addEventListener('storage', displayFortunes);
/**
* This function adds a fortune to localStorage. Does not add the fortune if it
* is a duplicate of another fortune already in localStorage.
* @param {string} - the text of the fortune
* @param {string} - the category of the fortune
* @param {Date} - a JavaScript Date object
*/
export function addFortune(fortuneText, category, date) {
// Get existing fortunes from localStorage
let savedFortunes = getFortunes();
// Convert date into weekday day month year
let modifiedDate = date.toLocaleDateString(undefined, {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});
// Check if fortune already exists, before choosing to save fortune or not
if (checkDuplicate([fortuneText,category,modifiedDate]) == -1) {
savedFortunes.push([fortuneText,category,date]);
localStorage.setItem('fortunes', JSON.stringify(savedFortunes));
}
}
/**
* Retrieves fortunes from localStorage and returns an array
* of fortunes. If nothing in local storage, it returns an empty array.
* @param {string} - the text of the fortune
* @param {string} - the category of the fortune
* @returns {Array<Object>} - an array of fortunes, each with fortune, category,
* and date elements
*/
function getFortunes() {
if(localStorage.getItem('fortunes') == null) {
return [];
}else {
let arr = [];
let list = JSON.parse(localStorage.getItem('fortunes'));
for(let i in list) {
arr.push(list[i]);
}
return arr;
}
}
/**
* Uses getFortunes and displays the fortunes it
* gets on the page with a div element for each fortune. Every
* time this function is called, it clears everything in the
* element refered to by history and re-adds each fortune to the
* page. The date values of the fortunes are displayed according to
* the locale of the browser. So if your browser uses Spanish
* for the UI, the date would be in Spanish.
*/
function displayFortunes() {
const history = document.querySelector(".historyWrapper");
if (history === null)
return;
// retrieves fortunes from local storage in an array
let arr = getFortunes();
// clears the display of fortunes
if (history !== null)
history.innerHTML = '';
// loops through each fortune and displays it
for(let i = 0; i<arr.length; i++) {
// creates div element as wrapper
let fortuneInList = document.createElement('div');
fortuneInList.classList.add("fortune");
// creates an h3 element that holds fortune text
let fortuneText = document.createElement("h3");
fortuneText.innerHTML = arr[i][0];
fortuneText.classList.add("fortuneText");
// creates an h3 element that holds fortune category
let fortuneCategory = document.createElement("h3");
fortuneCategory.innerHTML = arr[i][1];
fortuneCategory.classList.add("fortuneCategory");
// creates an h3 element that holds fortune date (specific to locale)
let fortuneDate = document.createElement("h3");
fortuneDate.innerHTML = new Date(arr[i][2]).toLocaleDateString(undefined, {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});
fortuneDate.classList.add("fortuneDate");
// Add Delete Button
let deleteButton = document.createElement('img');
deleteButton.src = "assets/saved-readings-page/trash.png";
deleteButton.style.borderRadius = '5px';
deleteButton.style.height = "100%";
// Red border on mouse over
deleteButton.addEventListener('mouseover', () => {
deleteButton.style.boxShadow = '0 0 10px 5px #ff0000';
});
// No border color when not hovering
deleteButton.addEventListener('mouseout', () => {
deleteButton.style.boxShadow = '';
});
// Delete fortune on click
deleteButton.addEventListener('click', () => {
deleteFortune(i);
displayFortunes();
});
// adds image based off category
console.log(fortuneCategory.innerHTML);
let fortuneImg = document.createElement('img');
if(fortuneCategory.innerHTML === 'Love'){
fortuneImg.src = `assets/card-page/love_back.png`;
}
else if(fortuneCategory.innerHTML === 'School'){
fortuneImg.src = `assets/card-page/school_back.png`;
}
else if(fortuneCategory.innerHTML === 'Life'){
fortuneImg.src = `assets/card-page/life_back.png`;
}
fortuneImg.style.display = 'block';
// adds elements with fortune text, category, and date to the fortune div wrapper
let fortuneDetails = document.createElement("div");
fortuneDetails.classList.add("fortuneDetails");
fortuneDetails.appendChild(fortuneImg);
fortuneDetails.appendChild(fortuneCategory);
fortuneDetails.appendChild(fortuneDate);
fortuneDetails.appendChild(deleteButton);
fortuneInList.appendChild(fortuneDetails);
fortuneInList.appendChild(fortuneText);
history.appendChild(fortuneInList);
}
}
/**
* Function that enables the individual deletion of fortunes from the saved-reading pages.
* We pass the index of the fortune that it has in the localstorage array
* and splice the array to remove that one index. Check if it the index is greater
* than -1.
* @param {number} fortuneIndex - the index of the fortune in the localstorage array
*/
function deleteFortune(fortuneIndex) {
let savedFortunes = getFortunes();
if (fortuneIndex > -1) {
savedFortunes.splice(fortuneIndex, 1);
localStorage.setItem('fortunes', JSON.stringify(savedFortunes));
}
}
/**
* Takes in a fortune array containing the fortuneText, category, and date and
* checks if there is another fortune in local storage that matches this fortune.
* Returns the index of the fortune in the localStorage array otherwise returns
* -1 if does not exist.
* @param {Array<Object>} fortune
*/
function checkDuplicate(fortune) {
// Get saved fortunes from localStorage
let savedFortunes = getFortunes();
// For each fortune in the localStorage, check if the contents are equal
// to the passed in fortune
for (let i = 0; i < savedFortunes.length; i++) {
// Convert saved date to modified date string for equal comparisons
let modifiedDate = new Date(savedFortunes[i][2]).toLocaleDateString(undefined, {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});
if (fortune[0] == savedFortunes[i][0]) {
if (fortune[1] == savedFortunes[i][1]) {
if (fortune[2] == modifiedDate) {
return i;
}
}
}
}
return -1;
}