Yoda/src/app/browser/main/tab/page.cpp

254 lines
7.7 KiB
C++
Raw Normal View History

2024-08-15 18:52:11 +03:00
#include "page.hpp"
#include "page/content.hpp"
2024-09-04 23:16:43 +03:00
#include "page/navigation.hpp"
#include "page/progress.hpp"
2024-08-13 08:07:56 +03:00
using namespace app::browser::main::tab;
2024-08-26 22:29:09 +03:00
Page::Page(
const Glib::ustring & TITLE,
2024-08-27 14:49:09 +03:00
const Glib::ustring & SUBTITLE,
const Glib::ustring & REQUEST
2024-08-26 22:29:09 +03:00
) {
2024-08-13 08:48:17 +03:00
// Init container
2024-08-13 08:07:56 +03:00
set_orientation(
Gtk::Orientation::VERTICAL
);
2024-08-14 14:59:36 +03:00
// Init components
2024-09-04 23:16:43 +03:00
pageNavigation = Gtk::make_managed<page::Navigation>(
REQUEST
2024-08-26 22:29:09 +03:00
);
2024-08-14 14:59:36 +03:00
append(
2024-09-04 23:16:43 +03:00
* pageNavigation
2024-08-14 14:59:36 +03:00
);
2024-09-04 23:16:43 +03:00
pageProgress = Gtk::make_managed<page::Progress>();
2024-08-18 23:46:27 +03:00
append(
2024-09-04 23:16:43 +03:00
* pageProgress
2024-08-18 23:46:27 +03:00
);
2024-09-02 16:25:31 +03:00
pageContent = Gtk::make_managed<page::Content>();
2024-08-14 14:59:36 +03:00
append(
2024-08-26 23:11:27 +03:00
* pageContent
2024-08-14 14:59:36 +03:00
);
2024-08-27 15:45:04 +03:00
// Init extras
2024-09-02 21:56:06 +03:00
refresh(
2024-08-27 15:45:04 +03:00
TITLE,
SUBTITLE,
0
);
2024-08-13 08:07:56 +03:00
}
// Getters
Glib::ustring Page::get_title()
{
return title;
}
2024-08-27 15:02:09 +03:00
Glib::ustring Page::get_subtitle()
{
return subtitle;
}
// Actions
2024-09-05 02:50:41 +03:00
bool Page::navigation_history_try_back()
2024-08-27 15:10:11 +03:00
{
2024-09-05 02:50:41 +03:00
return pageNavigation->history_try_back();
2024-09-01 15:21:12 +03:00
}
2024-09-05 02:50:41 +03:00
bool Page::navigation_history_try_forward()
2024-09-01 15:21:12 +03:00
{
2024-09-05 02:50:41 +03:00
return pageNavigation->history_try_forward();
2024-08-27 15:10:11 +03:00
}
2024-09-02 21:56:06 +03:00
void Page::refresh(
const Glib::ustring & TITLE,
const Glib::ustring & SUBTITLE,
const double & PROGRESS
) {
title = TITLE;
subtitle = SUBTITLE;
2024-09-04 23:16:43 +03:00
pageProgress->refresh(
2024-09-02 21:56:06 +03:00
PROGRESS
);
activate_action(
"win.refresh"
);
}
2024-09-04 21:30:35 +03:00
void Page::update(
const bool & HISTORY
) {
2024-08-29 04:02:38 +03:00
// Update navigation history
2024-09-04 21:30:35 +03:00
if (HISTORY)
{
2024-09-04 23:16:43 +03:00
pageNavigation->history_add(
pageNavigation->get_request_text()
2024-09-04 21:30:35 +03:00
);
}
2024-08-29 04:02:38 +03:00
2024-08-27 15:45:04 +03:00
// Update page extras
2024-09-02 21:56:06 +03:00
refresh(
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_host(),
2024-08-27 23:33:29 +03:00
Glib::ustring::sprintf(
_("load %s.."),
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_text()
2024-08-27 23:33:29 +03:00
), 0
2024-08-18 23:46:27 +03:00
);
// Connect scheme driver
2024-09-04 23:16:43 +03:00
if ("file" == pageNavigation->get_request_scheme())
2024-08-16 10:00:23 +03:00
{
// @TODO
}
2024-09-04 23:16:43 +03:00
else if ("gemini" == pageNavigation->get_request_scheme())
2024-08-16 10:00:23 +03:00
{
// Create new socket connection
2024-09-04 23:00:06 +03:00
GioSocketClient = Gio::SocketClient::create();
2024-09-04 23:00:06 +03:00
GioSocketClient->set_tls(
true
2024-08-16 10:00:23 +03:00
);
2024-09-04 23:00:06 +03:00
GioSocketClient->set_tls_validation_flags(
Gio::TlsCertificateFlags::NO_FLAGS
);
2024-08-16 10:00:23 +03:00
2024-09-04 23:00:06 +03:00
GioSocketClient->set_timeout(
15 // @TODO
);
2024-08-16 10:00:23 +03:00
2024-09-04 23:00:06 +03:00
GioSocketClient->connect_to_uri_async(
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_text(), 1965,
2024-08-16 10:00:23 +03:00
[this](const Glib::RefPtr<Gio::AsyncResult> & result)
{
2024-09-02 21:56:06 +03:00
refresh(
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_host(),
2024-08-27 23:33:29 +03:00
Glib::ustring::sprintf(
_("connect %s.."),
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_host()
2024-08-27 23:33:29 +03:00
), .25
2024-08-18 23:46:27 +03:00
);
2024-08-28 20:26:23 +03:00
try
{
2024-09-04 23:00:06 +03:00
GioSocketConnection = GioSocketClient->connect_to_uri_finish(
2024-08-28 20:26:23 +03:00
result
);
}
catch (const Glib::Error & EXCEPTION)
{
2024-09-02 21:56:06 +03:00
refresh(
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_host(),
2024-08-28 20:26:23 +03:00
EXCEPTION.what(), 1
);
}
// Connection established, begin request
2024-09-04 23:00:06 +03:00
if (GioSocketConnection != nullptr)
2024-08-28 20:26:23 +03:00
{
2024-09-04 23:16:43 +03:00
const Glib::ustring request = pageNavigation->get_request_text() + "\r\n";
2024-08-28 20:26:23 +03:00
2024-09-04 23:00:06 +03:00
GioSocketConnection->get_output_stream()->write_async(
2024-08-28 20:26:23 +03:00
request.data(),
request.size(),
[this](const Glib::RefPtr<Gio::AsyncResult> & result)
{
2024-09-02 21:56:06 +03:00
refresh(
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_host(),
2024-08-28 20:26:23 +03:00
Glib::ustring::sprintf(
_("request %s.."),
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_path().empty() ? pageNavigation->get_request_host()
: pageNavigation->get_request_path()
2024-08-28 20:26:23 +03:00
), .5
);
// Response
2024-09-04 23:00:06 +03:00
GioSocketConnection->get_input_stream()->read_async( // | read_all_async
2024-08-28 20:26:23 +03:00
buffer,
sizeof(buffer) - 1,
[this](const Glib::RefPtr<Gio::AsyncResult> & result)
{
2024-09-02 21:56:06 +03:00
refresh(
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_host(),
2024-08-28 20:26:23 +03:00
Glib::ustring::sprintf(
_("reading %s.."),
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_path().empty() ? pageNavigation->get_request_host()
: pageNavigation->get_request_path()
2024-08-28 20:26:23 +03:00
), .75
);
2024-08-18 23:46:27 +03:00
2024-08-28 20:26:23 +03:00
// Parse meta
auto meta = Glib::Regex::split_simple(
R"regex(^(\d+)?\s([\w]+\/[\w]+)?)regex",
buffer
);
2024-08-28 20:26:23 +03:00
// Route by status code
if (meta[1] == "20")
2024-08-18 15:19:36 +03:00
{
2024-08-28 20:26:23 +03:00
// Route by mime type or path extension
2024-09-04 23:16:43 +03:00
if (meta[2] == "text/gemini" || Glib::str_has_suffix(pageNavigation->get_request_path(), ".gmi"))
2024-08-28 20:26:23 +03:00
{
pageContent->set_text_gemini(
buffer // @TODO
);
}
else
{
pageContent->set_text_plain(
_("MIME type not supported")
);
}
2024-08-18 15:19:36 +03:00
}
else
{
2024-08-26 23:11:27 +03:00
pageContent->set_text_plain(
2024-08-28 20:26:23 +03:00
_("Could not open page")
2024-08-18 15:32:31 +03:00
);
2024-08-18 15:19:36 +03:00
}
2024-09-04 23:00:06 +03:00
GioSocketConnection->close();
2024-08-28 20:26:23 +03:00
2024-09-02 21:56:06 +03:00
refresh(
2024-09-04 23:16:43 +03:00
pageNavigation->get_request_host(), // @TODO title
pageNavigation->get_request_path().empty() ? pageNavigation->get_request_host()
: pageNavigation->get_request_path()
2024-08-28 20:26:23 +03:00
, 1
2024-08-18 15:32:31 +03:00
);
2024-08-18 15:19:36 +03:00
}
2024-08-28 20:26:23 +03:00
);
}
);
}
2024-08-16 10:00:23 +03:00
}
);
}
// Scheme not found but host provided, redirect to gemini://
2024-09-04 23:16:43 +03:00
else if (pageNavigation->get_request_scheme().empty() && !pageNavigation->get_request_host().empty())
{
2024-09-04 23:16:43 +03:00
pageNavigation->set_request_text(
"gemini://" + pageNavigation->get_request_text()
);
update();
}
else
2024-08-16 10:00:23 +03:00
{
// @TODO search request
2024-08-16 10:00:23 +03:00
}
}