213 lines
5.1 KiB
JavaScript
213 lines
5.1 KiB
JavaScript
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;
|
|
}
|
|
|
|
clone.querySelector(".dataset").dataset.id = this.#id;
|
|
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;
|
|
}
|
|
}
|