move Page entity out of Tab namespace

This commit is contained in:
yggverse 2024-07-08 21:01:14 +03:00
parent 46adc640e9
commit 63bc991bda
21 changed files with 111 additions and 111 deletions

View file

@ -1,416 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page;
use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content\Data;
use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content\Viewport;
class Content
{
public \GtkScrolledWindow $gtk;
// Dependencies
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page;
// Requirements
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content\Data $data;
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content\Viewport $viewport;
// Defaults
private int $_margin = 8;
public function __construct(
\Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page
) {
$this->page = $page;
// Init container
$this->gtk = new \GtkScrolledWindow;
$this->gtk->set_margin_start(
$this->_margin
);
$this->gtk->set_margin_end(
$this->_margin
);
$this->gtk->set_margin_bottom(
$this->_margin
);
// Init viewport
// to integrate scrolled window features for data label
$this->viewport = new Viewport(
$this
);
// Init data label
$this->data = new Data(
$this
);
$this->viewport->gtk->add(
$this->data->gtk
);
$this->gtk->add(
$this->viewport->gtk
);
// Render
$this->gtk->show();
}
public function refresh()
{
// @TODO
}
public function update(
bool $history = true
): void
{
// Parse address
$address = new \Yggverse\Net\Address(
$this->page->navbar->request->getValue()
);
// Init new title
$this->page->title->setValue(
$address->getHost(),
'loading...'
);
if ($history)
{
// Remember address in the navigation memory
$this->page->navbar->history->add(
$address->get()
);
// Update history in database
$this->page->tab->container->browser->database->renewHistory(
$address->get(),
// @TODO title
);
}
// Detect protocol
switch ($address->getScheme())
{
case 'file':
if (file_exists($address->getPath()) && is_readable($address->getPath()))
{
switch ($address->getPath())
{
case is_dir($address->getPath()):
// @TODO build fs listing
break;
case str_ends_with($address->getPath(), '.gmi'):
$title = null;
$this->data->setGemtext(
file_get_contents( // @TODO format relative links
$address->getPath()
),
$title
);
if ($title) // detect title by document h1
{
$this->page->title->setValue(
$title,
$this->page->title->subtitle
);
}
break;
default:
$this->page->title->setValue(
'Oops!',
'file extension not supported'
);
$this->data->setPlain(
'File extension not supported'
);
}
}
else
{
$this->page->title->setValue(
'Failure',
'resource not found or not readable'
);
$this->data->setPlain(
'Could not open file'
);
}
break;
case 'nex':
$client = new \Yggverse\Nex\Client;
if ($response = $client->request($address->get()))
{
// Detect content type
switch (true)
{
case in_array(
pathinfo(
strval(
$address->getPath()
),
PATHINFO_EXTENSION
),
[
'gmi',
'gemini'
]
):
$title = null;
$this->data->setGemtext(
$response,
$title
);
$this->page->title->setValue(
$title ? sprintf(
'%s - %s',
$title,
$address->getHost()
) : $address->getHost()
);
break;
default:
$this->data->setMono(
$response
);
$this->page->title->setValue(
$address->getHost()
);
}
}
else
{
$this->page->title->setValue(
'Failure',
'could not open resource'
);
$this->data->setPlain(
'Requested resource not available!'
);
}
break;
case 'gemini':
$request = new \Yggverse\Gemini\Client\Request(
$address->get()
);
$response = new \Yggverse\Gemini\Client\Response(
$request->getResponse()
);
// Route status code
// https://geminiprotocol.net/docs/protocol-specification.gmi#status-codes
switch ($response->getCode())
{
case 10: // response expected
case 11: // sensitive input
$this->page->title->setValue(
$address->getHost(),
$response->getMeta() ? $response->getMeta() : 'response expected'
);
$this->page->response->show(
$response->getMeta(), // placeholder
boolval(11 !== $response->getCode()) // input visibility
);
break;
case 20: // ok
// Detect content type
switch (true)
{
case str_contains(
$response->getMeta(),
'text/gemini'
):
case in_array(
pathinfo(
strval(
$address->getPath()
),
PATHINFO_EXTENSION
),
[
'gmi',
'gemini'
]
):
$title = null;
$this->data->setGemtext(
$response->getBody(),
$title
);
$this->page->title->setValue(
$title ? sprintf(
'%s - %s',
$title,
$address->getHost()
) : $address->getHost(), // detect title by document h1
$response->getMeta()
);
break;
default:
$this->data->setPlain(
$response->getBody()
);
$this->page->title->setValue(
$address->getHost()
);
}
break;
case 31: // redirect @TODO
$this->data->setGemtext(
sprintf(
'=> %s',
$response->getMeta()
)
);
$this->page->title->setValue(
$address->getHost(),
sprintf(
'redirect (code %d)',
intval(
$response->getCode()
)
)
);
break;
default:
$this->page->title->setValue(
'Failure',
sprintf(
'%s (code %d)',
$response->getMeta() ? $response->getMeta() : 'could not open resource',
intval(
$response->getCode()
)
)
);
$this->data->setPlain(
'Requested resource not available!'
);
}
break;
case null:
// Try gemini protocol
$address = new \Yggverse\Net\Address(
sprintf(
'gemini://%s',
$this->page->navbar->request->getValue()
)
);
// Is hostname request
if (filter_var(
$address->getHost(),
FILTER_VALIDATE_DOMAIN,
FILTER_FLAG_HOSTNAME
)
) {
$this->page->navbar->request->setValue(
$address->get()
);
}
// Is search request
else
{
$this->page->navbar->request->setValue(
sprintf(
'gemini://tlgs.one/search?%s', // @TODO custom provider
urlencode(
$this->page->navbar->request->getValue()
)
)
);
}
$this->update();
return;
default:
$this->page->title->setValue(
'Oops!',
'protocol not supported!'
);
$this->data->setPlain(
'Protocol not supported!'
);
}
// Render content
$this->gtk->show_all();
// Refresh page components
$this->page->refresh();
// Update window header
$this->page->tab->container->browser->header->setTitle(
$this->page->title->getValue(),
$this->page->title->getSubtitle(),
);
}
}