From e166059bb04ae78e1e2d1bd1f2c08522caf9d547 Mon Sep 17 00:00:00 2001
From: neobooru <50623835+neobooru@users.noreply.github.com>
Date: Wed, 3 Feb 2021 18:33:24 +0100
Subject: [PATCH] Post description wip
---
client/css/post-main-view.styl | 10 +++++++-
client/html/post_main.tpl | 12 ++++++++++
client/js/controllers/post_main_controller.js | 3 +++
.../js/controls/post_edit_sidebar_control.js | 8 +++++++
client/js/models/post.js | 12 ++++++++++
client/js/views/post_main_view.js | 1 +
server/szurubooru/api/post_api.py | 5 ++++
server/szurubooru/func/posts.py | 15 ++++++++++++
.../58bba7e0c554_add_description_to_post.py | 24 +++++++++++++++++++
server/szurubooru/model/post.py | 1 +
10 files changed, 90 insertions(+), 1 deletion(-)
create mode 100644 server/szurubooru/migrations/versions/58bba7e0c554_add_description_to_post.py
diff --git a/client/css/post-main-view.styl b/client/css/post-main-view.styl
index 48f3c158..a8973a90 100644
--- a/client/css/post-main-view.styl
+++ b/client/css/post-main-view.styl
@@ -40,11 +40,19 @@
width: 100%
.post-container
- margin-bottom: 2em
+ margin-bottom: 0.6em
.post-content
margin: 0
+ .description-container
+ background: $top-navigation-color
+ padding: 0.6em
+
+ #post-description
+ resize: vertical
+ min-height: 200px
+
@media (max-width: 800px)
.post-view
flex-wrap: wrap
diff --git a/client/html/post_main.tpl b/client/html/post_main.tpl
index 54c57333..c0c1e9df 100644
--- a/client/html/post_main.tpl
+++ b/client/html/post_main.tpl
@@ -54,6 +54,18 @@
+ <% if (ctx.editMode) { %>
+
Description
+ <%= ctx.makeTextarea({
+ id: 'post-description',
+ value: ctx.post.description,
+ }) %>
+ <% } else if (ctx.post.description != undefined) { %>
+
+ <%= ctx.makeMarkdown(ctx.post.description) %>
+
+ <% } %>
+
<% if (ctx.canListComments) { %>
<% } %>
diff --git a/client/js/controllers/post_main_controller.js b/client/js/controllers/post_main_controller.js
index 95cfdb52..35ae7d79 100644
--- a/client/js/controllers/post_main_controller.js
+++ b/client/js/controllers/post_main_controller.js
@@ -187,6 +187,9 @@ class PostMainController extends BasePostController {
if (e.detail.source !== undefined) {
post.source = e.detail.source;
}
+ if (e.detail.description !== undefined) {
+ post.description = e.detail.description;
+ }
post.save().then(
() => {
this._view.sidebarControl.showSuccess("Post saved.");
diff --git a/client/js/controls/post_edit_sidebar_control.js b/client/js/controls/post_edit_sidebar_control.js
index b8ad9dab..f0875f0f 100644
--- a/client/js/controls/post_edit_sidebar_control.js
+++ b/client/js/controls/post_edit_sidebar_control.js
@@ -435,6 +435,10 @@ class PostEditSidebarControl extends events.EventTarget {
source: this._sourceInputNode
? this._sourceInputNode.value
: undefined,
+
+ description: this._descriptionTextareaNode
+ ? this._descriptionTextareaNode.value
+ : undefined,
},
})
);
@@ -538,6 +542,10 @@ class PostEditSidebarControl extends events.EventTarget {
return this._formNode.querySelector(".notes textarea");
}
+ get _descriptionTextareaNode() {
+ return document.querySelector("textarea#post-description");
+ }
+
enableForm() {
views.enableForm(this._formNode);
}
diff --git a/client/js/models/post.js b/client/js/models/post.js
index 2fb3d34c..24b63ecb 100644
--- a/client/js/models/post.js
+++ b/client/js/models/post.js
@@ -102,6 +102,10 @@ class Post extends events.EventTarget {
return this._flags;
}
+ get description() {
+ return this._description;
+ }
+
get tags() {
return this._tags;
}
@@ -154,6 +158,10 @@ class Post extends events.EventTarget {
this._flags = value;
}
+ set description(value) {
+ this._description = value;
+ }
+
set safety(value) {
this._safety = value;
}
@@ -277,6 +285,9 @@ class Post extends events.EventTarget {
if (this._source !== this._orig._source) {
detail.source = this._source;
}
+ if (this._description !== this._orig._description) {
+ detail.description = this._description;
+ }
let apiPromise = this._id
? api.put(uri.formatApiLink("post", this.id), detail, files)
@@ -484,6 +495,7 @@ class Post extends events.EventTarget {
_fileSize: response.fileSize,
_flags: [...(response.flags || [])],
+ _description: response.description,
_relations: [...(response.relations || [])],
_score: response.score,
diff --git a/client/js/views/post_main_view.js b/client/js/views/post_main_view.js
index c38a9337..b80b3d63 100644
--- a/client/js/views/post_main_view.js
+++ b/client/js/views/post_main_view.js
@@ -4,6 +4,7 @@ const iosCorrectedInnerHeight = require("ios-inner-height");
const router = require("../router.js");
const views = require("../util/views.js");
const uri = require("../util/uri.js");
+const misc = require("../util/misc.js");
const keyboard = require("../util/keyboard.js");
const Touch = require("../util/touch.js");
const PostContentControl = require("../controls/post_content_control.js");
diff --git a/server/szurubooru/api/post_api.py b/server/szurubooru/api/post_api.py
index daba7f7e..1b48f7bd 100644
--- a/server/szurubooru/api/post_api.py
+++ b/server/szurubooru/api/post_api.py
@@ -165,6 +165,11 @@ def update_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
if ctx.has_file("thumbnail"):
auth.verify_privilege(ctx.user, "posts:edit:thumbnail")
posts.update_post_thumbnail(post, ctx.get_file("thumbnail"))
+ if ctx.has_param("description"):
+ # auth.verify_privilege(ctx.user, "posts:edit:description")
+ posts.update_post_description(
+ post, ctx.get_param_as_string("description")
+ )
post.last_edit_time = datetime.utcnow()
ctx.session.flush()
snapshots.modify(post, ctx.user)
diff --git a/server/szurubooru/func/posts.py b/server/szurubooru/func/posts.py
index 0493681e..9ade4e8c 100644
--- a/server/szurubooru/func/posts.py
+++ b/server/szurubooru/func/posts.py
@@ -78,6 +78,10 @@ class InvalidPostFlagError(errors.ValidationError):
pass
+class InvalidPostDescriptionError(errors.ValidationError):
+ pass
+
+
SAFETY_MAP = {
model.Post.SAFETY_SAFE: "safe",
model.Post.SAFETY_SKETCHY: "sketchy",
@@ -182,6 +186,7 @@ class PostSerializer(serialization.BaseSerializer):
"thumbnailUrl": self.serialize_thumbnail_url,
"flags": self.serialize_flags,
"tags": self.serialize_tags,
+ "description": self.serialize_description,
"relations": self.serialize_relations,
"user": self.serialize_user,
"score": self.serialize_score,
@@ -259,6 +264,9 @@ class PostSerializer(serialization.BaseSerializer):
for tag in tags.sort_tags(self.post.tags)
]
+ def serialize_description(self) -> Any:
+ return self.post.description
+
def serialize_relations(self) -> Any:
return sorted(
{
@@ -791,6 +799,13 @@ def update_post_flags(post: model.Post, flags: List[str]) -> None:
post.flags = target_flags
+def update_post_description(post: model.Post, description: str) -> None:
+ assert post
+ if util.value_exceeds_column_size(description, model.Post.description):
+ raise InvalidPostDescriptionError("Description is too long.")
+ post.description = description or None
+
+
def feature_post(post: model.Post, user: Optional[model.User]) -> None:
assert post
post_feature = model.PostFeature()
diff --git a/server/szurubooru/migrations/versions/58bba7e0c554_add_description_to_post.py b/server/szurubooru/migrations/versions/58bba7e0c554_add_description_to_post.py
new file mode 100644
index 00000000..cc841408
--- /dev/null
+++ b/server/szurubooru/migrations/versions/58bba7e0c554_add_description_to_post.py
@@ -0,0 +1,24 @@
+"""
+add_description_to_post
+
+Revision ID: 58bba7e0c554
+Created at: 2021-01-30 18:06:11.511449
+"""
+
+import sqlalchemy as sa
+from alembic import op
+
+revision = "58bba7e0c554"
+down_revision = "adcd63ff76a2"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ op.add_column(
+ "post", sa.Column("description", sa.UnicodeText(), nullable=True)
+ )
+
+
+def downgrade():
+ op.drop_column("post", "description")
diff --git a/server/szurubooru/model/post.py b/server/szurubooru/model/post.py
index 49e748dc..3553a595 100644
--- a/server/szurubooru/model/post.py
+++ b/server/szurubooru/model/post.py
@@ -213,6 +213,7 @@ class Post(Base):
safety = sa.Column("safety", sa.Unicode(32), nullable=False)
source = sa.Column("source", sa.Unicode(2048))
flags_string = sa.Column("flags", sa.Unicode(32), default="")
+ description = sa.Column("description", sa.UnicodeText(), nullable=True)
# content description
type = sa.Column("type", sa.Unicode(32), nullable=False)