szurubooru/client/js/controls/post_readonly_sidebar_control.js

223 lines
6.4 KiB
JavaScript

"use strict";
const api = require("../api.js");
const events = require("../events.js");
const views = require("../util/views.js");
const uri = require("../util/uri.js");
const misc = require("../util/misc.js");
const template = views.getTemplate("post-readonly-sidebar");
const scoreTemplate = views.getTemplate("score");
const favTemplate = views.getTemplate("fav");
class PostReadonlySidebarControl extends events.EventTarget {
constructor(hostNode, post, postContentControl) {
super();
this._hostNode = hostNode;
this._post = post;
this._postContentControl = postContentControl;
post.addEventListener("changeFavorite", (e) => this._evtChangeFav(e));
post.addEventListener("changeScore", (e) => this._evtChangeScore(e));
views.replaceContent(
this._hostNode,
template({
post: this._post,
enableSafety: api.safetyEnabled(),
canListPosts: api.hasPrivilege("posts:list"),
canEditPosts: api.hasPrivilege("posts:edit"),
canViewTags: api.hasPrivilege("tags:view"),
escapeTagName: uri.escapeTagName,
extractRootDomain: uri.extractRootDomain,
getPrettyName: misc.getPrettyName,
})
);
this._installFav();
this._installScore();
this._installFitButtons();
this._syncFitButton();
}
get _scoreContainerNode() {
return this._hostNode.querySelector(".score-container");
}
get _favContainerNode() {
return this._hostNode.querySelector(".fav-container");
}
get _upvoteButtonNode() {
return this._hostNode.querySelector(".upvote");
}
get _downvoteButtonNode() {
return this._hostNode.querySelector(".downvote");
}
get _addFavButtonNode() {
return this._hostNode.querySelector(".add-favorite");
}
get _remFavButtonNode() {
return this._hostNode.querySelector(".remove-favorite");
}
get _fitBothButtonNode() {
return this._hostNode.querySelector(".fit-both");
}
get _fitOriginalButtonNode() {
return this._hostNode.querySelector(".fit-original");
}
get _fitWidthButtonNode() {
return this._hostNode.querySelector(".fit-width");
}
get _fitHeightButtonNode() {
return this._hostNode.querySelector(".fit-height");
}
_installFitButtons() {
this._fitBothButtonNode.addEventListener(
"click",
this._eventZoomProxy(() => this._postContentControl.fitBoth())
);
this._fitOriginalButtonNode.addEventListener(
"click",
this._eventZoomProxy(() => this._postContentControl.fitOriginal())
);
this._fitWidthButtonNode.addEventListener(
"click",
this._eventZoomProxy(() => this._postContentControl.fitWidth())
);
this._fitHeightButtonNode.addEventListener(
"click",
this._eventZoomProxy(() => this._postContentControl.fitHeight())
);
}
_installFav() {
views.replaceContent(
this._favContainerNode,
favTemplate({
favoriteCount: this._post.favoriteCount,
ownFavorite: this._post.ownFavorite,
canFavorite: api.hasPrivilege("posts:favorite"),
})
);
if (this._addFavButtonNode) {
this._addFavButtonNode.addEventListener("click", (e) =>
this._evtAddToFavoritesClick(e)
);
}
if (this._remFavButtonNode) {
this._remFavButtonNode.addEventListener("click", (e) =>
this._evtRemoveFromFavoritesClick(e)
);
}
}
_installScore() {
views.replaceContent(
this._scoreContainerNode,
scoreTemplate({
score: this._post.score,
ownScore: this._post.ownScore,
canScore: api.hasPrivilege("posts:score"),
})
);
if (this._upvoteButtonNode) {
this._upvoteButtonNode.addEventListener("click", (e) =>
this._evtScoreClick(e, 1)
);
}
if (this._downvoteButtonNode) {
this._downvoteButtonNode.addEventListener("click", (e) =>
this._evtScoreClick(e, -1)
);
}
}
_eventZoomProxy(func) {
return (e) => {
e.preventDefault();
e.target.blur();
func();
this._syncFitButton();
this.dispatchEvent(
new CustomEvent("fitModeChange", {
detail: {
mode: this._getFitMode(),
},
})
);
};
}
_getFitMode() {
const funcToName = {};
funcToName[this._postContentControl.fitBoth] = "fit-both";
funcToName[this._postContentControl.fitOriginal] = "fit-original";
funcToName[this._postContentControl.fitWidth] = "fit-width";
funcToName[this._postContentControl.fitHeight] = "fit-height";
return funcToName[this._postContentControl._currentFitFunction];
}
_syncFitButton() {
const className = this._getFitMode();
const oldNode = this._hostNode.querySelector(".zoom a.active");
const newNode = this._hostNode.querySelector(`.zoom a.${className}`);
if (oldNode) {
oldNode.classList.remove("active");
}
newNode.classList.add("active");
}
_evtAddToFavoritesClick(e) {
e.preventDefault();
this.dispatchEvent(
new CustomEvent("favorite", {
detail: {
post: this._post,
},
})
);
}
_evtRemoveFromFavoritesClick(e) {
e.preventDefault();
this.dispatchEvent(
new CustomEvent("unfavorite", {
detail: {
post: this._post,
},
})
);
}
_evtScoreClick(e, score) {
e.preventDefault();
this.dispatchEvent(
new CustomEvent("score", {
detail: {
post: this._post,
score: this._post.ownScore === score ? 0 : score,
},
})
);
}
_evtChangeFav(e) {
this._installFav();
}
_evtChangeScore(e) {
this._installScore();
}
}
module.exports = PostReadonlySidebarControl;