add front-comments
This commit is contained in:
parent
c3ea78cab5
commit
c9f4af7e58
53 changed files with 2921 additions and 1 deletions
|
|
@ -0,0 +1,163 @@
|
|||
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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue