summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier S. Pedro <maemo@javispedro.com>2013-04-06 20:34:56 +0200
committerJavier S. Pedro <maemo@javispedro.com>2013-04-06 20:34:56 +0200
commitcb820fa02315cbf5ecc7f87435bc724460104f19 (patch)
tree19d089a0506c7da82f4e91af8e7df928d813a479
parentb04a2a981a91ed58e55a275402cb2f9f73bd85a2 (diff)
downloadtapasboard-cb820fa02315cbf5ecc7f87435bc724460104f19.tar.gz
tapasboard-cb820fa02315cbf5ecc7f87435bc724460104f19.zip
support replying to posts
-rw-r--r--board.cpp40
-rw-r--r--board.h8
-rw-r--r--newpostaction.cpp63
-rw-r--r--newpostaction.h28
-rw-r--r--qml/ForumPage.qml6
-rw-r--r--qml/NewPostSheet.qml38
-rw-r--r--qml/TopicPage.qml18
-rw-r--r--tapasboard.pro6
8 files changed, 192 insertions, 15 deletions
diff --git a/board.cpp b/board.cpp
index 5878475..7e734cb 100644
--- a/board.cpp
+++ b/board.cpp
@@ -9,6 +9,7 @@
#include "fetchconfigaction.h"
#include "fetchforumsaction.h"
#include "loginaction.h"
+#include "newpostaction.h"
#include "xmlrpcinterface.h"
#include "board.h"
@@ -150,6 +151,29 @@ void Board::logout()
// TODO
}
+int Board::getTopicForumId(int topicId)
+{
+ QSqlQuery q(_db);
+ q.prepare("SELECT forum_id FROM topics WHERE topic_id = ?");
+ q.bindValue(0, topicId);
+ if (q.exec()) {
+ if (q.next()) {
+ return q.value(0).toInt();
+ } else {
+ qWarning() << "Could not get forum of topic";
+ }
+ } else {
+ qWarning() << "Could not get forum of topic:" << q.lastError().text();
+ }
+
+ return -1;
+}
+
+void Board::replyToTopic(int topicId, const QString &text)
+{
+ enqueueAction(new NewPostAction(topicId, text, this));
+}
+
QString Board::removeHtml(QString text) const
{
static const QRegExp regexp("<[a-zA-Z\\/][^>]*>");
@@ -322,18 +346,10 @@ void Board::markTopicAsRead(int topicId)
q.bindValue(0, topicId);
if (q.exec()) {
if (q.numRowsAffected() > 0) {
- q.prepare("SELECT forum_id FROM topics WHERE topic_id = ?");
- q.bindValue(0, topicId);
- if (q.exec()) {
- if (q.next()) {
- int forum_id = q.value(0).toInt();
- notifyForumTopicChanged(forum_id, topicId);
- updateForumReadState(forum_id);
- } else {
- qWarning() << "Could not get forum of topic";
- }
- } else {
- qWarning() << "Could not get forum of topic:" << q.lastError().text();
+ int forum_id = getTopicForumId(topicId);
+ if (forum_id >= 0) {
+ notifyForumTopicChanged(forum_id, topicId);
+ updateForumReadState(forum_id);
}
}
} else {
diff --git a/board.h b/board.h
index 7e8fb97..e48dd6f 100644
--- a/board.h
+++ b/board.h
@@ -48,7 +48,13 @@ public:
void login(const QString& username, const QString& password);
void logout();
- // Some helper functions
+ // Other functions that query the database
+ int getTopicForumId(int topicId);
+
+ // Posting stuff
+ Q_INVOKABLE void replyToTopic(int topicId, const QString& text);
+
+ // BBCode-related helper functions
QString removeHtml(QString text) const;
QString removeBbcode(QString text) const;
QString bbcodeToRichText(QString text) const;
diff --git a/newpostaction.cpp b/newpostaction.cpp
new file mode 100644
index 0000000..4ad6244
--- /dev/null
+++ b/newpostaction.cpp
@@ -0,0 +1,63 @@
+#include <QtCore/QDebug>
+#include <QtSql/QSqlDatabase>
+#include <QtSql/QSqlQuery>
+
+#include "global.h"
+#include "board.h"
+#include "xmlrpcinterface.h"
+#include "xmlrpcreply.h"
+#include "newpostaction.h"
+#include "fetchpostsaction.h"
+
+NewPostAction::NewPostAction(int topicId, const QString &text, Board *board)
+ : Action(board), _topicId(topicId), _text(text)
+{
+}
+
+bool NewPostAction::isSupersetOf(Action *action) const
+{
+ return false;
+}
+
+void NewPostAction::execute()
+{
+ int forum_id = _board->getTopicForumId(_topicId);
+
+ _call = _board->service()->asyncCall("reply_post",
+ QString::number(forum_id),
+ QString::number(_topicId),
+ QByteArray(), // Empty subject
+ _text.toUtf8()
+ );
+ _call->setParent(this);
+ connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall()));
+}
+
+void NewPostAction::handleFinishedCall()
+{
+ XmlRpcReply<QVariantMap> result(_call);
+ if (result.isValid()) {
+ QVariantMap map = result;
+ bool post_ok = map["result"].toBool();
+ if (post_ok) {
+ int state = map["state"].toInt();
+ if (state == 1) {
+ // Awaiting moderation
+ // TODO
+ } else {
+ // Refresh posts
+ _board->enqueueAction(new FetchPostsAction(_topicId,
+ FetchPostsAction::FetchUnreadPosts,
+ TOPIC_PAGE_SIZE,
+ _board));
+ }
+ } else {
+ qWarning() << "Could not submit post:" << map["result_text"].toString();
+ }
+ } else {
+ qWarning() << "Could not submit post";
+ // TODO emit error ...
+ }
+ emit finished(this);
+ _call->deleteLater();
+}
diff --git a/newpostaction.h b/newpostaction.h
new file mode 100644
index 0000000..27896df
--- /dev/null
+++ b/newpostaction.h
@@ -0,0 +1,28 @@
+#ifndef NEWPOSTACTION_H
+#define NEWPOSTACTION_H
+
+#include "action.h"
+
+class XmlRpcPendingCall;
+
+class NewPostAction : public Action
+{
+ Q_OBJECT
+public:
+ explicit NewPostAction(int topicId, const QString& text, Board *board);
+
+ bool isSupersetOf(Action *action) const;
+
+ void execute();
+
+private slots:
+ void handleFinishedCall();
+
+private:
+ XmlRpcPendingCall *_call;
+ int _topicId;
+ QString _text;
+};
+
+
+#endif // NEWPOSTACTION_H
diff --git a/qml/ForumPage.qml b/qml/ForumPage.qml
index ee04e43..4f2b64f 100644
--- a/qml/ForumPage.qml
+++ b/qml/ForumPage.qml
@@ -18,6 +18,9 @@ Page {
onClicked: pageStack.pop()
}
ToolIcon {
+ platformIconId: "toolbar-add"
+ }
+ ToolIcon {
platformIconId: board.busy ? "toolbar-cancle" : "toolbar-refresh"
onClicked: {
if (board.busy) {
@@ -27,6 +30,9 @@ Page {
}
}
}
+ ToolIcon {
+ platformIconId: "toolbar-view-menu"
+ }
}
ListView {
diff --git a/qml/NewPostSheet.qml b/qml/NewPostSheet.qml
new file mode 100644
index 0000000..96de9bc
--- /dev/null
+++ b/qml/NewPostSheet.qml
@@ -0,0 +1,38 @@
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import com.nokia.extras 1.1
+import com.javispedro.tapasboard 1.0
+
+Sheet {
+ id: newPostSheet
+
+ property Board board;
+ property int topicId;
+
+ anchors.leftMargin: UiConstants.DefaultMargin
+ anchors.rightMargin: UiConstants.DefaultMargin
+
+ acceptButtonText: qsTr("Submit")
+ rejectButtonText: qsTr("Cancel")
+
+ content: TextArea {
+ id: postText
+ anchors {
+ fill: parent
+ }
+
+ platformStyle: TextAreaStyle {
+ background: "image://theme/meegotouch-sheet-inputfield-background"
+ backgroundSelected: background
+ backgroundDisabled: ""
+ }
+
+ placeholderText: qsTr("Write your reply here")
+ focus: true
+ wrapMode: TextEdit.Wrap
+ }
+
+ onAccepted: {
+ board.replyToTopic(topicId, postText.text)
+ }
+}
diff --git a/qml/TopicPage.qml b/qml/TopicPage.qml
index ebaa2c6..32a86ec 100644
--- a/qml/TopicPage.qml
+++ b/qml/TopicPage.qml
@@ -18,6 +18,19 @@ Page {
onClicked: pageStack.pop()
}
ToolIcon {
+ platformIconId: "toolbar-add"
+ onClicked: {
+ var component = Qt.createComponent("NewPostSheet.qml");
+ if (component.status === Component.Ready) {
+ var sheet = component.createObject(topicPage, {
+ "board": board,
+ "topicId": topicId
+ });
+ sheet.open();
+ }
+ }
+ }
+ ToolIcon {
platformIconId: board.busy ? "toolbar-cancle" : "toolbar-refresh"
onClicked: {
if (board.busy) {
@@ -27,6 +40,9 @@ Page {
}
}
}
+ ToolIcon {
+ platformIconId: "toolbar-view-menu"
+ }
}
ListView {
@@ -49,6 +65,8 @@ Page {
text: section
}
+ cacheBuffer: 200
+
delegate: Item {
id: postItem
diff --git a/tapasboard.pro b/tapasboard.pro
index 5d9bd08..4772169 100644
--- a/tapasboard.pro
+++ b/tapasboard.pro
@@ -51,7 +51,8 @@ SOURCES += main.cpp \
imagecache.cpp \
imagenetworkaccessmanager.cpp \
loginaction.cpp \
- markforumreadaction.cpp
+ markforumreadaction.cpp \
+ newpostaction.cpp
HEADERS += \
action.h \
@@ -72,7 +73,8 @@ HEADERS += \
imagecache.h \
imagenetworkaccessmanager.h \
loginaction.h \
- markforumreadaction.h
+ markforumreadaction.h \
+ newpostaction.h
TRANSLATIONS += i18n/en.ts i18n/es.ts