szurubooru/client/js/controls/post_readonly_sidebar_control.js
2020-06-04 19:02:33 -04:00

202 lines
6.1 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'),
escapeColons: uri.escapeColons,
extractRootDomain: uri.extractRootDomain,
getPrettyTagName: misc.getPrettyTagName,
}));
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;