szurubooru/client/js/controllers/post_list_controller.js
2023-01-24 22:19:24 +01:00

189 lines
6 KiB
JavaScript

"use strict";
const router = require("../router.js");
const api = require("../api.js");
const settings = require("../models/settings.js");
const uri = require("../util/uri.js");
const PostList = require("../models/post_list.js");
const topNavigation = require("../models/top_navigation.js");
const PageController = require("../controllers/page_controller.js");
const PostsHeaderView = require("../views/posts_header_view.js");
const PostsPageView = require("../views/posts_page_view.js");
const EmptyView = require("../views/empty_view.js");
const fields = [
"id",
"thumbnailUrl",
"type",
"safety",
"score",
"favoriteCount",
"commentCount",
"tags",
"version",
];
class PostListController {
constructor(ctx) {
this._pageController = new PageController();
if (!api.hasPrivilege("posts:list")) {
this._view = new EmptyView();
this._view.showError("You don't have privileges to view posts.");
return;
}
this._ctx = ctx;
topNavigation.activate("posts");
topNavigation.setTitle("Listing posts");
this._headerView = new PostsHeaderView({
hostNode: this._pageController.view.pageHeaderHolderNode,
parameters: ctx.parameters,
enableSafety: api.safetyEnabled(),
canBulkEditTags: api.hasPrivilege("posts:bulk-edit:tags"),
canBulkEditSafety: api.hasPrivilege("posts:bulk-edit:safety"),
canBulkDelete: api.hasPrivilege("posts:bulk-edit:delete"),
bulkEdit: {
tags: this._bulkEditTags,
},
});
this._headerView.addEventListener("navigate", (e) =>
this._evtNavigate(e)
);
if (this._headerView._bulkDeleteEditor) {
this._headerView._bulkDeleteEditor.addEventListener(
"deleteSelectedPosts",
(e) => {
this._evtDeleteSelectedPosts(e);
}
);
}
this._postsMarkedForDeletion = [];
this._syncPageController();
}
showSuccess(message) {
this._pageController.showSuccess(message);
}
get _bulkEditTags() {
return (this._ctx.parameters.tag || "").split(/\s+/).filter((s) => s);
}
_evtNavigate(e) {
router.showNoDispatch(
uri.formatClientLink("posts", e.detail.parameters)
);
Object.assign(this._ctx.parameters, e.detail.parameters);
this._syncPageController();
}
_evtTag(e) {
Promise.all(
this._bulkEditTags.map((tag) => e.detail.post.tags.addByName(tag))
)
.then(e.detail.post.save())
.catch((error) => window.alert(error.message));
}
_evtUntag(e) {
for (let tag of this._bulkEditTags) {
e.detail.post.tags.removeByName(tag);
}
e.detail.post.save().catch((error) => window.alert(error.message));
}
_evtChangeSafety(e) {
e.detail.post.safety = e.detail.safety;
e.detail.post.save().catch((error) => window.alert(error.message));
}
_evtMarkForDeletion(e) {
const postId = e.detail;
// Add or remove post from delete list
if (e.detail.delete) {
this._postsMarkedForDeletion.push(e.detail.post);
} else {
this._postsMarkedForDeletion = this._postsMarkedForDeletion.filter(
(x) => x.id != e.detail.post.id
);
}
}
_evtDeleteSelectedPosts(e) {
if (this._postsMarkedForDeletion.length == 0) return;
if (
confirm(
`Are you sure you want to delete ${this._postsMarkedForDeletion.length} posts?`
)
) {
Promise.all(
this._postsMarkedForDeletion.map((post) => post.delete())
)
.catch((error) => window.alert(error.message))
.then(() => {
this._postsMarkedForDeletion = [];
this._headerView._navigate();
});
}
}
_syncPageController() {
this._pageController.run({
parameters: this._ctx.parameters,
defaultLimit: parseInt(settings.get().postsPerPage),
getClientUrlForPage: (offset, limit) => {
const parameters = Object.assign({}, this._ctx.parameters, {
offset: offset,
limit: limit,
});
return uri.formatClientLink("posts", parameters);
},
requestPage: (offset, limit) => {
return PostList.search(
this._ctx.parameters.query,
offset,
limit,
fields
);
},
pageRenderer: (pageCtx) => {
Object.assign(pageCtx, {
canViewPosts: api.hasPrivilege("posts:view"),
canBulkEditTags: api.hasPrivilege("posts:bulk-edit:tags"),
canBulkEditSafety: api.hasPrivilege(
"posts:bulk-edit:safety"
),
canBulkDelete: api.hasPrivilege("posts:bulk-edit:delete"),
bulkEdit: {
tags: this._bulkEditTags,
markedForDeletion: this._postsMarkedForDeletion,
},
postFlow: settings.get().postFlow,
});
const view = new PostsPageView(pageCtx);
view.addEventListener("tag", (e) => this._evtTag(e));
view.addEventListener("untag", (e) => this._evtUntag(e));
view.addEventListener("changeSafety", (e) =>
this._evtChangeSafety(e)
);
view.addEventListener("markForDeletion", (e) =>
this._evtMarkForDeletion(e)
);
return view;
},
});
}
}
module.exports = (router) => {
router.enter(["posts"], (ctx, next) => {
ctx.controller = new PostListController(ctx);
});
};