import { DATASET_ENDPOINT, getBaseURL } from "./main.js"; export default class Dataset { static #datasets = new Map(); #abstract; #author; #categories; #date; #description; #id; #rating; #title; #type; #upvotes; #url; #votes; #elements = []; static get(id) { return this.#datasets.get(id); } constructor({ abst: shortDescription, author, categories, date, description, id, rating, title, type, upvotes, url, votes }) { this.#abstract = shortDescription; this.#author = author; this.#categories = categories; this.#date = date; this.#description = description; this.#id = id; this.#rating = rating; this.#title = title; this.#type = type; this.#upvotes = upvotes; this.#url = url; this.#votes = votes; Dataset.#datasets.set(id, this); } // Getters get abstract() { return this.#abstract; } get author() { return this.#author; } get categories() { return this.#categories; } get date() { return this.#date; } get description() { return this.#description; } get id() { return this.#id; } get rating() { return this.#rating; } get title() { return this.#title; } get type() { return this.#type; } get upvotes() { return this.#upvotes; } get url() { return this.#url; } get votes() { return this.#votes; } get mainElement() { return this.#elements[0]; } get elements() { return this.#elements; } // Main methods // Only on main page createDatasetHTMLElement() { const clone = this.#createTemplateInstance("dataset-template"); if (clone == null) { return null; } let datasetContainer = clone.querySelector(".dataset"); datasetContainer.dataset.id = this.#id; datasetContainer.addEventListener("click", event => { if (!event.target.classList.contains("btn")) { let detailsPage = new URL("/details.html", location.origin); detailsPage.searchParams.append("id", this.#id); window.location.href = detailsPage.toString(); } }) clone.querySelector(".dataset-title").innerText = this.#title; clone.querySelector(".dataset-description").innerText = this.#description; clone.querySelector(".upvote-count").innerText = this.#upvotes; this.#elements.push(clone.children[0]); this.#createUpvoteButtons(clone); return clone; } // Only on details page createUpvoteComponent() { let clone = this.#createTemplateInstance("voting-template") clone.querySelector(".upvote-count").innerText = this.#upvotes; this.#elements.push(clone.children[0]); this.#createUpvoteButtons(clone); return clone; } #createUpvoteButtons(templateInstance) { if (this.storageGetKey("is-voted", false)) { // The template instance (clone) has to be pushed before this can work this.#disableVoteBtns(); } // Event Listeners templateInstance.querySelector(".upvote-btn").addEventListener("click", () => { this.vote(); }); templateInstance.querySelector(".downvote-btn").addEventListener("click", () => { this.vote(false); }) } #createTemplateInstance(templateId) { let template = document.getElementById(templateId); if (template == null) { return null; } return template.content.cloneNode(true); } isMainElement(element) { return this.#elements.length > 0 && this.#elements[0].isEqualNode(element); } async vote(up = true) { const fetchURL = new URL( `${DATASET_ENDPOINT}/id/${this.#id}/${up ? "up" : "down"}vote`, getBaseURL(), ); const response = await fetch(fetchURL, { method: "PUT", headers: { 'Content-Type': 'application/json', } }); const data = await response.json(); this.#upvotes = data.upvotes; for (const element of this.#elements) { element.querySelector(".upvote-count").innerText = this.#upvotes; } this.storageSetKey("vote-type", up ? "upvote" : "downvote"); this.storageSetKey("is-voted", true); this.#disableVoteBtns(); } #disableVoteBtns() { if (this.#elements.length > 0) { const voteType = this.storageGetKey("vote-type", null); this.#elements.flatMap(e => Array.from(e.querySelectorAll(".upvote .btn"))) .forEach(btn => { btn.disabled = true; if (btn.classList.contains(`${voteType}-btn`)) { btn.classList.add("isVoted"); } }); } } storageGet() { const json = localStorage.getItem(this.#id); return json != null ? JSON.parse(json) : {}; } storageSetKey(key, value) { let currentStorage = this.storageGet(); currentStorage[key] = value; localStorage.setItem(this.#id, JSON.stringify(currentStorage)); } storageGetKey(key, defaultValue) { return this.storageGet()?.[key] ?? defaultValue; } }