diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-08-05 18:43:36 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-08-05 18:43:36 +0200 |
commit | 7a632771151cc641096c786933b651ee0f57784b (patch) | |
tree | 0e9492a0fd54213a0df824c4526b8078e72f4cac /Applications | |
parent | 6311a617bed4b4f2340580846b989b0a4ea4f3aa (diff) | |
download | serenity-7a632771151cc641096c786933b651ee0f57784b.zip |
ChanViewer: Fetch the list of boards and allow switching the board
We put the list of boards in a combo box and allow the user to switch
boards that way. :^)
Diffstat (limited to 'Applications')
-rw-r--r-- | Applications/ChanViewer/BoardListModel.cpp | 90 | ||||
-rw-r--r-- | Applications/ChanViewer/BoardListModel.h | 27 | ||||
-rwxr-xr-x | Applications/ChanViewer/Makefile | 1 | ||||
-rw-r--r-- | Applications/ChanViewer/ThreadCatalogModel.cpp | 10 | ||||
-rw-r--r-- | Applications/ChanViewer/ThreadCatalogModel.h | 3 | ||||
-rw-r--r-- | Applications/ChanViewer/main.cpp | 15 |
6 files changed, 145 insertions, 1 deletions
diff --git a/Applications/ChanViewer/BoardListModel.cpp b/Applications/ChanViewer/BoardListModel.cpp new file mode 100644 index 0000000000..bb326d94db --- /dev/null +++ b/Applications/ChanViewer/BoardListModel.cpp @@ -0,0 +1,90 @@ +#include "BoardListModel.h" +#include <AK/JsonArray.h> +#include <AK/JsonObject.h> +#include <AK/JsonValue.h> +#include <LibCore/CHttpRequest.h> +#include <LibCore/CNetworkJob.h> +#include <LibCore/CNetworkResponse.h> +#include <stdio.h> + +BoardListModel::BoardListModel() +{ + update(); +} + +BoardListModel::~BoardListModel() +{ +} + +void BoardListModel::update() +{ + CHttpRequest request; + request.set_hostname("a.4cdn.org"); + request.set_path("/boards.json"); + + auto* job = request.schedule(); + + job->on_finish = [job, this](bool success) { + auto* response = job->response(); + dbg() << "Board list download finished, success=" << success << ", response=" << response; + + if (!success) + return; + + dbg() << "Board list payload size: " << response->payload().size(); + + auto json = JsonValue::from_string(response->payload()); + + if (json.is_object()) { + auto new_boards = json.as_object().get("boards"); + if (new_boards.is_array()) + m_boards = move(new_boards.as_array()); + } + + did_update(); + }; +} + +int BoardListModel::row_count(const GModelIndex&) const +{ + return m_boards.size(); +} + +String BoardListModel::column_name(int column) const +{ + switch (column) { + case Column::Board: + return "Board"; + default: + ASSERT_NOT_REACHED(); + } +} + +GModel::ColumnMetadata BoardListModel::column_metadata([[maybe_unused]] int column) const +{ + return {}; +} + +GVariant BoardListModel::data(const GModelIndex& index, Role role) const +{ + auto& board = m_boards.at(index.row()).as_object(); + if (role == Role::Display) { + switch (index.column()) { + case Column::Board: + return String::format("/%s/ - %s", + board.get("board").to_string().characters(), + board.get("title").to_string().characters()); + default: + ASSERT_NOT_REACHED(); + } + } + if (role == Role::Custom) { + switch (index.column()) { + case Column::Board: + return board.get("board").to_string(); + default: + ASSERT_NOT_REACHED(); + } + } + return {}; +} diff --git a/Applications/ChanViewer/BoardListModel.h b/Applications/ChanViewer/BoardListModel.h new file mode 100644 index 0000000000..13a997c85e --- /dev/null +++ b/Applications/ChanViewer/BoardListModel.h @@ -0,0 +1,27 @@ +#pragma once + +#include <AK/JsonArray.h> +#include <LibGUI/GModel.h> + +class BoardListModel final : public GModel { +public: + enum Column { + Board, + __Count, + }; + + static NonnullRefPtr<BoardListModel> create() { return adopt(*new BoardListModel); } + virtual ~BoardListModel() override; + + virtual int row_count(const GModelIndex& = GModelIndex()) const override; + virtual int column_count(const GModelIndex& = GModelIndex()) const override { return Column::__Count; } + virtual String column_name(int) const override; + virtual ColumnMetadata column_metadata(int) const override; + virtual GVariant data(const GModelIndex&, Role = Role::Display) const override; + virtual void update() override; + +private: + BoardListModel(); + + JsonArray m_boards; +}; diff --git a/Applications/ChanViewer/Makefile b/Applications/ChanViewer/Makefile index 65d01b6065..c31011fcf4 100755 --- a/Applications/ChanViewer/Makefile +++ b/Applications/ChanViewer/Makefile @@ -2,6 +2,7 @@ include ../../Makefile.common OBJS = \ ThreadCatalogModel.o \ + BoardListModel.o \ main.o APP = ChanViewer diff --git a/Applications/ChanViewer/ThreadCatalogModel.cpp b/Applications/ChanViewer/ThreadCatalogModel.cpp index 264ac20760..828e314410 100644 --- a/Applications/ChanViewer/ThreadCatalogModel.cpp +++ b/Applications/ChanViewer/ThreadCatalogModel.cpp @@ -16,11 +16,19 @@ ThreadCatalogModel::~ThreadCatalogModel() { } +void ThreadCatalogModel::set_board(const String& board) +{ + if (m_board == board) + return; + m_board = board; + update(); +} + void ThreadCatalogModel::update() { CHttpRequest request; request.set_hostname("a.4cdn.org"); - request.set_path("/g/catalog.json"); + request.set_path(String::format("/%s/catalog.json", m_board.characters())); auto* job = request.schedule(); diff --git a/Applications/ChanViewer/ThreadCatalogModel.h b/Applications/ChanViewer/ThreadCatalogModel.h index d39c232d06..a2b03cddde 100644 --- a/Applications/ChanViewer/ThreadCatalogModel.h +++ b/Applications/ChanViewer/ThreadCatalogModel.h @@ -25,8 +25,11 @@ public: virtual GVariant data(const GModelIndex&, Role = Role::Display) const override; virtual void update() override; + void set_board(const String&); + private: ThreadCatalogModel(); + String m_board { "g" }; JsonArray m_catalog; }; diff --git a/Applications/ChanViewer/main.cpp b/Applications/ChanViewer/main.cpp index fe4a8bf422..851903e7eb 100644 --- a/Applications/ChanViewer/main.cpp +++ b/Applications/ChanViewer/main.cpp @@ -1,7 +1,9 @@ +#include "BoardListModel.h" #include "ThreadCatalogModel.h" #include <LibDraw/PNGLoader.h> #include <LibGUI/GApplication.h> #include <LibGUI/GBoxLayout.h> +#include <LibGUI/GComboBox.h> #include <LibGUI/GTableView.h> #include <LibGUI/GWindow.h> @@ -16,11 +18,24 @@ int main(int argc, char** argv) auto* widget = new GWidget; window->set_main_widget(widget); + widget->set_fill_with_background_color(true); widget->set_layout(make<GBoxLayout>(Orientation::Vertical)); + auto* board_combo = new GComboBox(widget); + board_combo->set_only_allow_values_from_model(true); + board_combo->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); + board_combo->set_preferred_size(0, 20); + board_combo->set_model(BoardListModel::create()); + auto* catalog_view = new GTableView(widget); catalog_view->set_model(ThreadCatalogModel::create()); + board_combo->on_change = [&] (auto&, const GModelIndex& index) { + auto selected_board = board_combo->model()->data(index, GModel::Role::Custom); + ASSERT(selected_board.is_string()); + static_cast<ThreadCatalogModel*>(catalog_view->model())->set_board(selected_board.to_string()); + }; + window->show(); return app.exec(); |