Blocklist: Add frontend elements:

- New field in User profile edition to add/remove tags from their blocklist
- This field works as other tag fields, with auto-completion, and a proper list under the textbox
- User must have the right permissions to edit blocklist (either their own or other users')
This commit is contained in:
Soblow (Opale) Xaselgio 2024-03-03 16:53:23 +01:00 committed by Lugrim
parent f8242f8bea
commit e5f61d2c31
No known key found for this signature in database
GPG key ID: 1CF1D1FB9A327611
4 changed files with 49 additions and 0 deletions

View file

@ -68,6 +68,12 @@
</div>
</li>
<% } %>
<% if (ctx.canEditBlocklist) { %>
<li class='blocklist'>
<%= ctx.makeTextInput({text: 'Blocklist'}) %>
</li>
<% } %>
</ul>
<div class='messages'></div>

View file

@ -89,6 +89,7 @@ class UserController {
canEditAvatar: api.hasPrivilege(
`users:edit:${infix}:avatar`
),
canEditBlocklist: api.hasPrivilege(`users:edit:${infix}:blocklist`),
canEditAnything: api.hasPrivilege(`users:edit:${infix}`),
canListTokens: api.hasPrivilege(
`userTokens:list:${infix}`

View file

@ -3,11 +3,19 @@
const api = require("../api.js");
const uri = require("../util/uri.js");
const events = require("../events.js");
const misc = require("../util/misc.js");
class User extends events.EventTarget {
constructor() {
const TagList = require("./tag_list.js");
super();
this._orig = {};
for (let obj of [this, this._orig]) {
obj._blocklist = new TagList();
}
this._updateFromResponse({});
}
@ -71,6 +79,10 @@ class User extends events.EventTarget {
throw "Invalid operation";
}
get blocklist() {
return this._blocklist;
}
set name(value) {
this._name = value;
}
@ -95,6 +107,10 @@ class User extends events.EventTarget {
this._password = value;
}
set blocklist(value) {
this._blocklist = value || "";
}
static fromResponse(response) {
const ret = new User();
ret._updateFromResponse(response);
@ -121,6 +137,11 @@ class User extends events.EventTarget {
if (this._rank !== this._orig._rank) {
detail.rank = this._rank;
}
if (misc.arraysDiffer(this._blocklist, this._orig._blocklist)) {
detail.blocklist = this._blocklist.map(
(relation) => relation.names[0]
);
}
if (this._avatarStyle !== this._orig._avatarStyle) {
detail.avatarStyle = this._avatarStyle;
}
@ -187,6 +208,10 @@ class User extends events.EventTarget {
_dislikedPostCount: response.dislikedPostCount,
};
for (let obj of [this, this._orig]) {
obj._blocklist.sync(response.blocklist);
}
Object.assign(this, map);
Object.assign(this._orig, map);

View file

@ -4,6 +4,8 @@ const events = require("../events.js");
const api = require("../api.js");
const views = require("../util/views.js");
const FileDropperControl = require("../controls/file_dropper_control.js");
const TagInputControl = require("../controls/tag_input_control.js")
const misc = require("../util/misc.js");
const template = views.getTemplate("user-edit");
@ -41,6 +43,13 @@ class UserEditView extends events.EventTarget {
});
}
if (this._blocklistFieldNode) {
new TagInputControl(
this._blocklistFieldNode,
this._user.blocklist
);
}
this._formNode.addEventListener("submit", (e) => this._evtSubmit(e));
}
@ -83,6 +92,10 @@ class UserEditView extends events.EventTarget {
? this._rankInputNode.value
: undefined,
blocklist: this._blocklistFieldNode
? misc.splitByWhitespace(this._blocklistFieldNode.value)
: undefined,
avatarStyle: this._avatarStyleInputNode
? this._avatarStyleInputNode.value
: undefined,
@ -101,6 +114,10 @@ class UserEditView extends events.EventTarget {
return this._hostNode.querySelector("form");
}
get _blocklistFieldNode() {
return this._formNode.querySelector(".blocklist input");
}
get _rankInputNode() {
return this._formNode.querySelector("[name=rank]");
}