diff --git a/CMakeLists.txt b/CMakeLists.txt index 711eddc..c9126f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,8 @@ qt_add_executable(pcomic dataitems/libraryitem.h dataitems/comicitem.cpp dataitems/comicitem.h + dataitems/folderitem.cpp + dataitems/folderitem.h ) qt_add_qml_module(pcomic diff --git a/ComicSelectionPage.qml b/ComicSelectionPage.qml index 2926aa4..a1022f3 100644 --- a/ComicSelectionPage.qml +++ b/ComicSelectionPage.qml @@ -1,42 +1,76 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import net.blumia.pineapple.comic.reader -ColumnLayout { +Item { anchors.fill: parent - Label { - text: "Comics" - font.pixelSize: 20 - } - GridView { - id: gridView - clip: true - cellHeight: cellWidth * 3 / 2 - cellWidth: width / Math.max(Math.floor(width / (65 * 2)), 1) - Layout.fillWidth: true - Layout.fillHeight: true - model: AppController.comicsModel - delegate: Button { - width: GridView.view.cellWidth - height: GridView.view.cellHeight - Column { - Image { - source: AppController.coverImageSource(model.hash) - width: gridView.cellWidth - height: gridView.cellHeight - fillMode: Image.PreserveAspectFit - retainWhileLoading: true + + Drawer { + id: drawer + width: Math.min(0.66 * parent.width, 320) + height: parent.height + + ListView { + id: listView + clip: true + anchors.fill: parent + model: AppController.foldersModel + delegate: ItemDelegate { + text: model.display + width: listView.width + onClicked: function() { + AppController.updateComicsInFolder(model.folderId) } } + } + } - onClicked: function() { - AppController.selectedComicId = model.comicId + ColumnLayout { + anchors.fill: parent + RowLayout { + ToolButton { + flat: true + icon.name: "folder-open" + onClicked: function() { + drawer.open(); + } + } + Label { + text: "Comics" + font.pixelSize: 20 } } - ScrollBar.vertical: ScrollBar { } - } + GridView { + id: gridView + clip: true + cellHeight: cellWidth * 3 / 2 + cellWidth: width / Math.max(Math.floor(width / (65 * 2)), 1) + Layout.fillWidth: true + Layout.fillHeight: true + model: AppController.comicsModel + delegate: Button { + width: GridView.view.cellWidth + height: GridView.view.cellHeight + Column { + Image { + source: AppController.coverImageSource(model.hash) + width: gridView.cellWidth + height: gridView.cellHeight + fillMode: Image.PreserveAspectFit + retainWhileLoading: true + } + } - Component.onCompleted: function() { - AppController.updateComicsInFolder() + onClicked: function() { + AppController.selectedComicId = model.comicId + } + } + ScrollBar.vertical: ScrollBar { } + } + + Component.onCompleted: function() { + AppController.updateComicsInFolder() + } } } diff --git a/appcontroller.cpp b/appcontroller.cpp index 669c32b..7ce0163 100644 --- a/appcontroller.cpp +++ b/appcontroller.cpp @@ -2,6 +2,7 @@ #include "dataitems/libraryitem.h" #include "dataitems/comicitem.h" +#include "dataitems/folderitem.h" #include #include @@ -17,20 +18,11 @@ AppController::AppController(QObject *parent) , m_restAccessManager(new QRestAccessManager(m_networkAccessManager, this)) , m_librariesModel(new QStandardItemModel(this)) , m_comicsModel(new QStandardItemModel(this)) + , m_foldersModel(new QStandardItemModel(this)) { - m_librariesModel->setItemRoleNames({ - {Qt::DisplayRole, "display"}, - {LibraryItem::IdRole, "libraryId"}, - {LibraryItem::UuidRole, "uuid"}, - }); - m_comicsModel->setItemRoleNames({ - {Qt::DisplayRole, "display"}, - {ComicItem::IdRole, "comicId"}, - {ComicItem::HashRole, "hash"}, - {ComicItem::PageCountRole, "pageCount"}, - {ComicItem::CurrentPageRole, "currentPage"}, - {ComicItem::TypeRole, "type"}, - }); + m_librariesModel->setItemRoleNames(LibraryItem::roleNames()); + m_comicsModel->setItemRoleNames(ComicItem::roleNames()); + m_foldersModel->setItemRoleNames(FolderItem::roleNames()); } void AppController::connectServer(QUrl serverBaseUrl) @@ -72,8 +64,9 @@ void AppController::updateLibraries() }); } -void AppController::updateComicsInFolder(int folderId) +void AppController::updateComicsInFolder(QString folderId) { + qDebug() << folderId; m_restAccessManager->get(apiFactory().createRequest(QString("library/%1/folder/%2/content") .arg(m_currentLibraryId).arg(folderId)), this, [=](QRestReply &reply){ @@ -83,10 +76,19 @@ void AppController::updateComicsInFolder(int folderId) if (libraries && !(*libraries).isEmpty() && (*libraries).isArray()) { const QJsonArray array = (*libraries).array(); m_comicsModel->clear(); + m_foldersModel->clear(); + // always add a top-leven folder entry...for now + QJsonObject root; + root["id"] = "1"; + m_foldersModel->appendRow(new FolderItem(root, "Root")); for (const QJsonValue & value : array) { - QJsonObject comicObj = value.toObject(); - qDebug() << comicObj; - m_comicsModel->appendRow(new ComicItem(comicObj, comicObj["file_name"].toString())); + QJsonObject obj = value.toObject(); + // qDebug() << obj; + if (obj["type"].toString() == QLatin1String("folder")) { + m_foldersModel->appendRow(new FolderItem(obj, obj["folder_name"].toString())); + } else { + m_comicsModel->appendRow(new ComicItem(obj, obj["file_name"].toString())); + } } } } diff --git a/appcontroller.h b/appcontroller.h index 6362e4e..53329a3 100644 --- a/appcontroller.h +++ b/appcontroller.h @@ -24,12 +24,13 @@ public: Q_PROPERTY(bool selectedComicOpened MEMBER m_currentComicOpened NOTIFY currentComicOpenedChanged FINAL) Q_PROPERTY(QStandardItemModel * librariesModel MEMBER m_librariesModel CONSTANT FINAL) Q_PROPERTY(QStandardItemModel * comicsModel MEMBER m_comicsModel CONSTANT FINAL) + Q_PROPERTY(QStandardItemModel * foldersModel MEMBER m_foldersModel CONSTANT FINAL) AppController(QObject *parent = nullptr); Q_INVOKABLE void connectServer(QUrl serverBaseUrl); Q_INVOKABLE void updateLibraries(); - Q_INVOKABLE void updateComicsInFolder(int folderId = 1); + Q_INVOKABLE void updateComicsInFolder(QString folderId = "1"); Q_INVOKABLE void openComic(); Q_INVOKABLE void closeComic(); Q_INVOKABLE QString coverImageSource(QString comicHash); @@ -54,4 +55,5 @@ private: QRestAccessManager * m_restAccessManager; QStandardItemModel * m_librariesModel; QStandardItemModel * m_comicsModel; + QStandardItemModel * m_foldersModel; }; diff --git a/dataitems/comicitem.cpp b/dataitems/comicitem.cpp index cd0bad3..f9c9221 100644 --- a/dataitems/comicitem.cpp +++ b/dataitems/comicitem.cpp @@ -9,3 +9,15 @@ ComicItem::ComicItem(QJsonObject jsonObj, const QString &name) setData(jsonObj["current_page"].toInt(), CurrentPageRole); setData(jsonObj["type"].toInt(), TypeRole); } + +QHash ComicItem::roleNames() +{ + return { + {Qt::DisplayRole, "display"}, + {ComicItem::IdRole, "comicId"}, + {ComicItem::HashRole, "hash"}, + {ComicItem::PageCountRole, "pageCount"}, + {ComicItem::CurrentPageRole, "currentPage"}, + {ComicItem::TypeRole, "type"}, + }; +} diff --git a/dataitems/comicitem.h b/dataitems/comicitem.h index 65907d9..4739430 100644 --- a/dataitems/comicitem.h +++ b/dataitems/comicitem.h @@ -18,4 +18,5 @@ public: Q_ENUM(Roles) explicit ComicItem(QJsonObject jsonObj, const QString &name); + static QHash roleNames(); }; diff --git a/dataitems/folderitem.cpp b/dataitems/folderitem.cpp new file mode 100644 index 0000000..1bc957f --- /dev/null +++ b/dataitems/folderitem.cpp @@ -0,0 +1,18 @@ +#include "folderitem.h" + +FolderItem::FolderItem(QJsonObject jsonObj, const QString &name) + : QStandardItem(name) +{ + setData(jsonObj["id"].toString(), IdRole); + setData(jsonObj["first_comic_hash"].toString(), FirstComicHashRole); + setData(jsonObj["path"].toString(), PathRole); +} + +QHash FolderItem::roleNames() +{ + return { + {Qt::DisplayRole, "display"}, + {FolderItem::IdRole, "folderId"}, + {FolderItem::PathRole, "path"}, + }; +} diff --git a/dataitems/folderitem.h b/dataitems/folderitem.h new file mode 100644 index 0000000..2ae8ce7 --- /dev/null +++ b/dataitems/folderitem.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +class FolderItem : public QStandardItem +{ + Q_GADGET +public: + enum Roles { + IdRole = Qt::UserRole + 1, + FirstComicHashRole, + PathRole, + }; + Q_ENUM(Roles) + + explicit FolderItem(QJsonObject jsonObj, const QString &name); + static QHash roleNames(); +}; diff --git a/dataitems/libraryitem.cpp b/dataitems/libraryitem.cpp index 06d2b85..f6eaca8 100644 --- a/dataitems/libraryitem.cpp +++ b/dataitems/libraryitem.cpp @@ -6,3 +6,12 @@ LibraryItem::LibraryItem(int id, const QString &name, const QString &uuid) setData(id, IdRole); setData(uuid, UuidRole); } + +QHash LibraryItem::roleNames() +{ + return { + {Qt::DisplayRole, "display"}, + {LibraryItem::IdRole, "libraryId"}, + {LibraryItem::UuidRole, "uuid"}, + }; +} diff --git a/dataitems/libraryitem.h b/dataitems/libraryitem.h index 59e922f..67e3d21 100644 --- a/dataitems/libraryitem.h +++ b/dataitems/libraryitem.h @@ -13,4 +13,5 @@ public: Q_ENUM(Roles) explicit LibraryItem(int id, const QString &name, const QString &uuid); + static QHash roleNames(); }; diff --git a/main.cpp b/main.cpp index 16a51d4..f29ccd5 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,7 @@ #include "dataitems/libraryitem.h" #include "dataitems/comicitem.h" +#include "dataitems/folderitem.h" class QmlNetworkAccessManager : public QNetworkAccessManager { @@ -38,6 +39,7 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableMetaObject(LibraryItem::staticMetaObject, "net.blumia.pineapple.comic.reader.libraryitem", 1, 0, "LibraryItem", "enum"); qmlRegisterUncreatableMetaObject(ComicItem::staticMetaObject, "net.blumia.pineapple.comic.reader.comicitem", 1, 0, "ComicItem", "enum"); + qmlRegisterUncreatableMetaObject(FolderItem::staticMetaObject, "net.blumia.pineapple.comic.reader.folderitem", 1, 0, "FolderItem", "enum"); QmlNetworkAccessManagerFactory namFactory;