From f690c7dde14a6f9c5fbf04ed94170c7648591cb6 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Thu, 4 Apr 2013 20:58:57 +0200 Subject: store post position in database, create invisible items for unfetched --- topicmodel.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 22 deletions(-) (limited to 'topicmodel.cpp') diff --git a/topicmodel.cpp b/topicmodel.cpp index 6b4991d..d3032be 100644 --- a/topicmodel.cpp +++ b/topicmodel.cpp @@ -20,6 +20,7 @@ TopicModel::TopicModel(QObject *parent) : roles[DateTimeRole] = QByteArray("dateTime"); roles[HumanDateRole] = QByteArray("humanDate"); roles[HumanTimeRole] = QByteArray("humanTime"); + roles[UnreadRole] = QByteArray("unread"); setRoleNames(roles); } @@ -94,8 +95,23 @@ QVariant TopicModel::data(const QModelIndex &index, int role) const if (_data[row].post_id < 0) { // This post is a unfetched stub - this->fetchPost(row); - return QVariant(); // Will update the model once the post arrives + switch (role) { + case PostIdRole: + this->fetchPost(row); + return QVariant::fromValue(-1); + case TitleRole: + case ContentRole: + case UserNameRole: + case HumanDateRole: + case HumanTimeRole: + return QVariant::fromValue(QString()); + case DateTimeRole: + return QVariant::fromValue(QDateTime()); + case UnreadRole: + return QVariant::fromValue(_firstUnread >= 0 && row >= _firstUnread); + default: + return QVariant(); + } } switch (role) { // Mind the lack of break statements @@ -115,6 +131,8 @@ QVariant TopicModel::data(const QModelIndex &index, int role) const return _board->renderHumanDate(_data[row].time); case HumanTimeRole: return _board->renderHumanTime(_data[row].time); + case UnreadRole: + return _firstUnread >= 0 && row >= _firstUnread; } return QVariant(); @@ -180,6 +198,11 @@ void TopicModel::refresh() _board)); } +void TopicModel::markAsRead() +{ + _board->markTopicAsRead(_topicId); +} + QDateTime TopicModel::parseDbDateTime(const QVariant &v) { QString s = v.toString(); @@ -203,7 +226,7 @@ QDateTime TopicModel::lastTopPostUpdate() QSqlQuery query(db); query.prepare("SELECT last_update_time FROM posts " "WHERE topic_id = :topic_id " - "ORDER BY post_time ASC " + "ORDER BY position ASC " "LIMIT 1"); query.bindValue(":topic_id", _topicId); if (query.exec()) { @@ -219,19 +242,17 @@ QDateTime TopicModel::lastTopPostUpdate() QList TopicModel::loadPosts(int start, int end) { Q_ASSERT(_board); - const int rows = end - start + 1; QList posts; QSqlQuery query(_board->database()); query.prepare("SELECT post_id, post_title, post_content, post_author_id, post_author_name, post_time, last_update_time FROM posts " - "WHERE topic_id = :topic_id " - "ORDER by post_time ASC " - "LIMIT :start, :limit"); + "WHERE topic_id = :topic_id AND position BETWEEN :start AND :end " + "ORDER by position ASC "); query.bindValue(":topic_id", _topicId); query.bindValue(":start", start); - query.bindValue(":limit", rows); + query.bindValue(":end", end); if (query.exec()) { int loaded = 0; - posts.reserve(rows); + posts.reserve(end - start + 1); while (query.next()) { Post post; post.post_id = query.value(0).toInt(); @@ -254,13 +275,12 @@ void TopicModel::fetchPost(int position) const { if (_board->service()->isAccessible()) { // There are lest posts on the DB than we wanted - qDebug() << "Fetching posts because of unfetched"; + qDebug() << "Fetching post" << position << "because of unfetched"; // Always fetch one page at least. - int fetch_start = position % FORUM_PAGE_SIZE; - int fetch_end = fetch_start + FORUM_PAGE_SIZE; - _board->enqueueAction(new FetchPostsAction(_topicId, - fetch_start, fetch_end, - _board)); + int start = (position / FORUM_PAGE_SIZE) * FORUM_PAGE_SIZE; + int end = (start + FORUM_PAGE_SIZE) - 1; + qDebug() << "From" << start << "to" << end; + _board->enqueueAction(new FetchPostsAction(_topicId, start, end, _board)); } } @@ -277,6 +297,7 @@ void TopicModel::enlargeModel(int end) _data.append(post); } endInsertRows(); + Q_ASSERT(_data.size() == end + 1); } } @@ -298,17 +319,19 @@ void TopicModel::handleTopicPostsChanged(int topicId, int start, int end) _eof = false; } if (start > _data.size() + 1) { - // We are still not interested into these posts. - qDebug() << "Posts too far"; - return; + enlargeModel(start); } QList posts = loadPosts(start, end); if (posts.size() < end - start + 1) { - _eof = true; // Short read - end = start + posts.size() - 1; + // Short read + qWarning() << "Short read while handling changed posts"; + return; // This should not happen, really. } + Q_ASSERT(start <= _data.size()); + Q_ASSERT(end >= 0); + if (end >= _data.size()) { qDebug() << "Call insert rows (changed):" << _data.size() << end; beginInsertRows(QModelIndex(), _data.size(), end); @@ -324,7 +347,7 @@ void TopicModel::handleTopicPostsChanged(int topicId, int start, int end) emit dataChanged(createIndex(start, 0), createIndex(_data.size() - 1, 0)); } else { qDebug() << "Just refresh the data"; - for (int i = start; i < end; i++) { + for (int i = start; i <= end; i++) { _data[i] = posts[i - start]; } emit dataChanged(createIndex(start, 0), createIndex(end, 0)); @@ -338,6 +361,7 @@ void TopicModel::handleTopicPostsUnread(int topicId, int position) if (position != _firstUnread) { enlargeModel(position); _firstUnread = position; + qDebug() << "Changing unread post to" << position; emit firstUnreadPostChanged(); } } @@ -351,8 +375,19 @@ void TopicModel::update() QDateTime last = lastTopPostUpdate(); if (!last.isValid() || last.secsTo(QDateTime::currentDateTime()) > TOPIC_TOP_TLL) { + qDebug() << "Fetching posts because the top are old"; // Outdated or empty, refresh. - _board->enqueueAction(new FetchPostsAction(_topicId, 0, TOPIC_PAGE_SIZE - 1, _board)); + if (_board->loggedIn() && _board->getConfig("goto_unread") == "1") { + _board->enqueueAction(new FetchPostsAction(_topicId, + FetchPostsAction::FetchUnreadPosts, + TOPIC_PAGE_SIZE, + _board)); + } else { + _board->enqueueAction(new FetchPostsAction(_topicId, + 0, + TOPIC_PAGE_SIZE - 1, + _board)); + } } else { qDebug() << "Topics not outdated"; } -- cgit v1.2.3