189 lines
5.9 KiB
C++
189 lines
5.9 KiB
C++
|
#include "PostView.h"
|
||
|
#include "CommentView.h"
|
||
|
#include "model/BlogSession.h"
|
||
|
#include "model/User.h"
|
||
|
#include "model/asciidoc.h"
|
||
|
#include <Wt/WAnchor.h>
|
||
|
#include <Wt/WLineEdit.h>
|
||
|
#include <Wt/WLink.h>
|
||
|
#include <Wt/WPushButton.h>
|
||
|
#include <Wt/WText.h>
|
||
|
#include <Wt/WTextArea.h>
|
||
|
|
||
|
PostView::PostView(BlogSession &session, const std::string &basePath, Wt::Dbo::ptr<Post> post, RenderType type)
|
||
|
: session_(session), basePath_(basePath), post_(post) {
|
||
|
viewType_ = Brief;
|
||
|
render(type);
|
||
|
}
|
||
|
|
||
|
void PostView::render(RenderType type) {
|
||
|
if (type != Edit) viewType_ = type;
|
||
|
|
||
|
clear();
|
||
|
|
||
|
switch (type) {
|
||
|
case Detail: {
|
||
|
setTemplateText(tr("blog-post"));
|
||
|
|
||
|
session_.commentsChanged().connect(this, &PostView::updateCommentCount);
|
||
|
|
||
|
commentCount_ = bindWidget("comment-count", std::make_unique<Wt::WText>(post_->commentCount()));
|
||
|
bindWidget("comments", std::make_unique<CommentView>(session_, post_->rootComment()));
|
||
|
bindString("anchor", basePath_ + post_->permaLink());
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
case Brief: {
|
||
|
setTemplateText(tr("blog-post-brief"));
|
||
|
|
||
|
auto titleAnchor = std::make_unique<Wt::WAnchor>(
|
||
|
Wt::WLink(Wt::LinkType::InternalPath, basePath_ + post_->permaLink()), post_->title);
|
||
|
bindWidget("title", std::move(titleAnchor));
|
||
|
|
||
|
if (!post_->briefSrc.empty()) {
|
||
|
auto moreAnchor = std::make_unique<Wt::WAnchor>(
|
||
|
Wt::WLink(Wt::LinkType::InternalPath, basePath_ + post_->permaLink() + "/more"), tr("blog-read-more"));
|
||
|
bindWidget("read-more", std::move(moreAnchor));
|
||
|
} else {
|
||
|
bindString("read-more", Wt::WString::Empty);
|
||
|
}
|
||
|
|
||
|
auto commentsAnchor = std::make_unique<Wt::WAnchor>(
|
||
|
Wt::WLink(Wt::LinkType::InternalPath, basePath_ + post_->permaLink() + "/comments"));
|
||
|
commentCount_ = commentsAnchor->addWidget(std::make_unique<Wt::WText>("(" + post_->commentCount() + ")"));
|
||
|
bindWidget("comment-count", std::move(commentsAnchor));
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
case Edit: {
|
||
|
setTemplateText(tr("blog-post-edit"));
|
||
|
|
||
|
titleEdit_ = bindWidget("title-edit", std::make_unique<Wt::WLineEdit>(post_->title));
|
||
|
briefEdit_ = bindWidget("brief-edit", std::make_unique<Wt::WTextArea>(post_->briefSrc));
|
||
|
bodyEdit_ = bindWidget("body-edit", std::make_unique<Wt::WTextArea>(post_->bodySrc));
|
||
|
|
||
|
auto saveButton = bindWidget("save", std::make_unique<Wt::WPushButton>(tr("save")));
|
||
|
auto cancelButton = bindWidget("cancel", std::make_unique<Wt::WPushButton>(tr("cancel")));
|
||
|
|
||
|
saveButton->clicked().connect(this, &PostView::saveEdit);
|
||
|
cancelButton->clicked().connect(this, &PostView::showView);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (type == Detail || type == Brief) {
|
||
|
if (session_.user() == post_->author) {
|
||
|
std::unique_ptr<Wt::WPushButton> publishButton;
|
||
|
if (post_->state != Post::Published) {
|
||
|
publishButton = std::make_unique<Wt::WPushButton>(tr("publish"));
|
||
|
publishButton->clicked().connect(this, &PostView::publish);
|
||
|
} else {
|
||
|
publishButton = std::make_unique<Wt::WPushButton>(tr("retract"));
|
||
|
publishButton->clicked().connect(this, &PostView::retract);
|
||
|
}
|
||
|
bindWidget("publish", std::move(publishButton));
|
||
|
|
||
|
auto editButton(std::make_unique<Wt::WPushButton>(tr("edit")));
|
||
|
editButton->clicked().connect(this, &PostView::showEdit);
|
||
|
bindWidget("edit", std::move(editButton));
|
||
|
|
||
|
auto deleteButton(std::make_unique<Wt::WPushButton>(tr("delete")));
|
||
|
deleteButton->clicked().connect(this, &PostView::rm);
|
||
|
bindWidget("delete", std::move(deleteButton));
|
||
|
} else {
|
||
|
bindString("publish", Wt::WString::Empty);
|
||
|
bindString("edit", Wt::WString::Empty);
|
||
|
bindString("delete", Wt::WString::Empty);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
auto postAnchor = std::make_unique<Wt::WAnchor>(
|
||
|
Wt::WLink(Wt::LinkType::InternalPath, basePath_ + "author/" + post_->author->name.toUTF8()),
|
||
|
post_->author->name);
|
||
|
bindWidget("author", std::move(postAnchor));
|
||
|
}
|
||
|
void PostView::publish() {
|
||
|
setState(Post::Published);
|
||
|
}
|
||
|
void PostView::showEdit() {
|
||
|
Wt::Dbo::Transaction t(session_);
|
||
|
|
||
|
render(Edit);
|
||
|
|
||
|
t.commit();
|
||
|
}
|
||
|
|
||
|
void PostView::rm() {
|
||
|
Wt::Dbo::Transaction t(session_);
|
||
|
post_.remove();
|
||
|
t.commit();
|
||
|
|
||
|
this->removeFromParent();
|
||
|
}
|
||
|
void PostView::retract() {
|
||
|
setState(Post::Unpublished);
|
||
|
}
|
||
|
|
||
|
void PostView::setState(Post::State state) {
|
||
|
Wt::Dbo::Transaction t(session_);
|
||
|
|
||
|
post_.modify()->state = state;
|
||
|
if (state == Post::Published) post_.modify()->date = Wt::WDateTime::currentDateTime();
|
||
|
|
||
|
render(viewType_);
|
||
|
|
||
|
t.commit();
|
||
|
}
|
||
|
void PostView::saveEdit() {
|
||
|
Wt::Dbo::Transaction t(session_);
|
||
|
|
||
|
bool newPost = post_.id() == -1;
|
||
|
|
||
|
Post *post = post_.modify();
|
||
|
|
||
|
post->title = titleEdit_->text();
|
||
|
post->briefSrc = briefEdit_->text();
|
||
|
post->bodySrc = bodyEdit_->text();
|
||
|
|
||
|
post->briefHtml = asciidoc(post->briefSrc);
|
||
|
post->bodyHtml = asciidoc(post->bodySrc);
|
||
|
|
||
|
if (newPost) {
|
||
|
session_.add(post_);
|
||
|
|
||
|
post->date = Wt::WDateTime::currentDateTime();
|
||
|
post->state = Post::Unpublished;
|
||
|
post->author = session_.user();
|
||
|
|
||
|
Wt::Dbo::ptr<Comment> rootComment = session_.add(std::make_unique<Comment>());
|
||
|
rootComment.modify()->post = post_;
|
||
|
}
|
||
|
|
||
|
session_.flush();
|
||
|
|
||
|
render(viewType_);
|
||
|
|
||
|
t.commit();
|
||
|
}
|
||
|
|
||
|
void PostView::showView() {
|
||
|
if (post_.id() == -1)
|
||
|
this->removeFromParent();
|
||
|
else {
|
||
|
Wt::Dbo::Transaction t(session_);
|
||
|
render(viewType_);
|
||
|
t.commit();
|
||
|
}
|
||
|
}
|
||
|
void PostView::updateCommentCount(Wt::Dbo::ptr<Comment> comment) {
|
||
|
if (comment->post == post_) {
|
||
|
std::string count = comment->post->commentCount();
|
||
|
|
||
|
if (commentCount_->text().toUTF8()[0] == '(')
|
||
|
commentCount_->setText("(" + count + ")");
|
||
|
else
|
||
|
commentCount_->setText(count);
|
||
|
}
|
||
|
}
|