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(
|
2024-08-27 14:15:13 +03:00
|
|
|
const Glib::ustring & TITLE,
|
2024-08-27 14:49:09 +03:00
|
|
|
const Glib::ustring & SUBTITLE,
|
2024-08-27 14:15:13 +03:00
|
|
|
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>(
|
2024-08-27 14:15:13 +03:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2024-08-27 14:15:13 +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;
|
|
|
|
}
|
|
|
|
|
2024-08-27 14:15:13 +03:00
|
|
|
// 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
|
|
|
{
|
2024-08-16 17:56:42 +03:00
|
|
|
// Create new socket connection
|
2024-09-04 23:00:06 +03:00
|
|
|
GioSocketClient = Gio::SocketClient::create();
|
2024-08-16 17:56:42 +03:00
|
|
|
|
2024-09-04 23:00:06 +03:00
|
|
|
GioSocketClient->set_tls(
|
2024-08-16 17:56:42 +03:00
|
|
|
true
|
2024-08-16 10:00:23 +03:00
|
|
|
);
|
|
|
|
|
2024-09-04 23:00:06 +03:00
|
|
|
GioSocketClient->set_tls_validation_flags(
|
2024-08-16 17:56:42 +03:00
|
|
|
Gio::TlsCertificateFlags::NO_FLAGS
|
|
|
|
);
|
2024-08-16 10:00:23 +03:00
|
|
|
|
2024-09-04 23:00:06 +03:00
|
|
|
GioSocketClient->set_timeout(
|
2024-08-16 17:56:42 +03:00
|
|
|
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-16 17:56:42 +03:00
|
|
|
|
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
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-08-17 10:27:17 +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-08-17 10:27:17 +03:00
|
|
|
{
|
2024-09-04 23:16:43 +03:00
|
|
|
pageNavigation->set_request_text(
|
|
|
|
"gemini://" + pageNavigation->get_request_text()
|
2024-08-17 10:27:17 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2024-08-16 17:56:42 +03:00
|
|
|
else
|
2024-08-16 10:00:23 +03:00
|
|
|
{
|
2024-08-17 10:27:17 +03:00
|
|
|
// @TODO search request
|
2024-08-16 10:00:23 +03:00
|
|
|
}
|
|
|
|
}
|