nouveau-theatre-de-besancon/site/plugins/front-comments/src/front/classes/comments/Comment.js
2024-09-10 17:14:38 +02:00

163 lines
4.1 KiB
JavaScript

import Store from "../../store.js";
import dayjs from "dayjs";
import Helpers from "../../composables/helpers.js";
/**
* Represents a comment on a webpage.
*/
class Comment {
/**
* Create a Comment.
* @param {Object} position - The positions where the comment should be displayed.
*/
constructor(
position,
author,
message,
id,
date,
time,
windowWidth,
userAgent,
team
) {
this.position = position;
this.author = author;
this.message = message;
this.id = id;
this.date = date;
this.time = time;
this.windowWidth = windowWidth;
this.userAgent = userAgent;
this.team = team;
this.node;
}
toBubble() {
const bubble = this._injectNode(`<button
id="${this.id}"
class="fc__bubble fc__btn"
style="left: ${this.position.left}; top: ${this.position.top};">
${this.author.slice(0, 1).toUpperCase()}
</button>`);
if (this.team) {
bubble.classList.add("fc__team-icon");
bubble.classList.add(`fc__team-icon--${this.team}`);
}
bubble.addEventListener("mouseenter", () => {
setTimeout(() => {
this.expand();
}, 10);
});
this.node = bubble;
return bubble;
}
/**
* Show the comment message.
*/
expand() {
const windowWidthInfoElement = this.windowWidth
? `<li class="fc__context-item">
<b>Largeur fenêtre</b> : ${this.windowWidth}px <button class="fc__open-window" title="Ouvrir une fenêtre de cette largeur">voir</button>
</li>`
: "";
const userAgentInfoElement = this.userAgent
? `<li class="fc__context-item">
<b>Agent utilisateur</b> : <br>
${this.userAgent}
</li>`
: "";
const contextInfoElement =
this.userAgent || this.windowWidth
? `
<div class="fc__context">
<input id="collapsible" class="fc__toggle" type="checkbox">
<label for="collapsible" class="fc__label-toggle" title="État du navigateur au moment de l'ajout du commentaire">Contexte</label>
<div class="fc__collapsible-content">
<ul class="fc__content-inner">
${windowWidthInfoElement}
${userAgentInfoElement}
</ul>
</div>
</div>
`
: "";
const comment = this._injectNode(`<div
class="fc__comment"
style="left: ${this.position.left}; top: ${this.position.top};"
>
<button class="fc__btn fc__comment-delete" title="Remove comment">
<img class="fc__icon" src="${Store.filesPath}/icons/delete.svg">
</button>
<span class="fc__author">${this.author}</span><br><span class="fc__datetime">${this.date} à ${this.time}</span><br>
<p>${this.message}</p>
${contextInfoElement}
</div>`);
Helpers.fixOffscreen(comment);
const deleteBtn = comment.querySelector(".fc__comment-delete");
deleteBtn.addEventListener("click", () => {
this.remove();
});
const openWindowBtn = document.querySelector(".fc__open-window");
if (openWindowBtn) {
openWindowBtn.addEventListener("click", () => {
window.open(
window.location.href,
"",
`width=${this.windowWidth}, height=800`
);
});
}
comment.addEventListener("mouseleave", () => {
setTimeout(() => {
this.toBubble();
}, 10);
});
this.node = comment;
return comment;
}
_injectNode(htmlString) {
if (this.node) {
document.body.removeChild(this.node);
}
const div = document.createElement("div");
div.innerHTML = htmlString;
const node = div.firstChild;
document.body.appendChild(node);
return node;
}
/**
* Hide the comment message.
*/
async remove() {
const init = {
method: "PATCH",
};
fetch(`/comments/delete/${this.id}/${Store.page.uri}.json`, init)
.then((res) => res.json())
.then((json) => {
Store.comments = Store.comments.filter((item) => item.id != this.id);
document.body.removeChild(this.node);
})
.catch((error) => {
console.log(error);
});
}
}
export default Comment;