diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..fbc3b97e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/vendor/ +/composer.lock +/db.sqlite +/config.json \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..b4df5107 --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "yggverse/yoda", + "description": "PHP-GTK Client for Gemini Protocol", + "keywords": [ "php-gtk", "gtk", "gtk3", "gemini", "gemini-protocol", "client", "browser", "altweb" ], + "homepage": "https://github.com/YGGverse/Yoda", + "type": "project", + "require": { + "yggverse/gemini": "^0.7.0", + "yggverse/net": "^1.7" + }, + "license": "MIT", + "autoload": { + "psr-4": { + "Yggverse\\Yoda\\": "src/" + } + }, + "authors": [ + { + "name": "YGGverse" + } + ] +} diff --git a/src/Box/Main.php b/src/Box/Main.php new file mode 100644 index 00000000..bda22619 --- /dev/null +++ b/src/Box/Main.php @@ -0,0 +1,145 @@ +box = new \GtkBox( + \GtkOrientation::VERTICAL + ); + + $this->box->set_name( + $name + ); + + // Init dependencies + $this->menu = new \Yggverse\Yoda\Box\Menu(); + + $this->box->pack_start( + $this->menu->box, + false, + true, + 0 + ); + + $this->navigation = new \Yggverse\Yoda\Box\Navigation(); + + $this->box->pack_start( + $this->navigation->box, + false, + true, + 0 + ); + + $this->content = new \Yggverse\Yoda\Label\Content(); + + $scroll = new \GtkScrolledWindow(); + + $scroll->add( + $this->content->label + ); + + $this->box->pack_start( + $scroll, + true, + true, + 10 + ); + + $this->tray = new \Yggverse\Yoda\Label\Tray(); + + $this->box->pack_start( + $this->tray->label, + false, + true, + 0 + ); + + $this->navigation->address->entry->connect( + 'activate', + function ($entry) + { + global $config; + + $host = null; + + if ($config->resolver->enabled) + { + $resolve = new \Yggverse\Net\Resolve( + $config->resolver->request->record, + $config->resolver->request->host, + $config->resolver->request->timeout, + $config->resolver->result->shuffle + ); + + $address = new \Yggverse\Net\Address( + $entry->get_text() + ); + + $resolved = $resolve->address( + $address + ); + + if ($resolved) + { + $host = $resolved->getHost(); // @TODO memory cache + } + } + + $request = new \Yggverse\Gemini\Client\Request( + $entry->get_text(), + $host + ); + + $this->tray->label->set_text( + sprintf( + 'Open %s...', + $entry->get_text() + ) + ); + + $start = microtime(true); + + $raw = $request->getResponse(); + + $end = microtime(true); + + $response = new \Yggverse\Gemini\Client\Response( + $raw + ); + + $this->content->label->set_markup( + $response->getBody() + ); + + $this->tray->label->set_text( + sprintf( + '%s | %s | %d bytes | %s seconds', + date('c'), + $response->getMeta() ? $response->getMeta() : $response->getCode(), + number_format( + mb_strlen( + $raw + ) + ), + round( + $end - $start, 2 + ) + ) + ); + } + ); + } +} \ No newline at end of file diff --git a/src/Box/Menu.php b/src/Box/Menu.php new file mode 100644 index 00000000..6fa3f8d3 --- /dev/null +++ b/src/Box/Menu.php @@ -0,0 +1,30 @@ +box = new \GtkBox( + \GtkOrientation::VERTICAL + ); + + $this->box->set_name( + $name + ); + + $this->main = new \Yggverse\Yoda\Menu\Bar\Main(); + + $this->box->add( + $this->main->bar + ); + } +} \ No newline at end of file diff --git a/src/Box/Navigation.php b/src/Box/Navigation.php new file mode 100644 index 00000000..ae4e471b --- /dev/null +++ b/src/Box/Navigation.php @@ -0,0 +1,34 @@ +box = new \GtkBox( + \GtkOrientation::VERTICAL + ); + + $this->box->set_name( + $name + ); + + $this->address = new \Yggverse\Yoda\Entry\Address( + $config->homepage + ); + + $this->box->add( + $this->address->entry + ); + } +} \ No newline at end of file diff --git a/src/Entry/Address.php b/src/Entry/Address.php new file mode 100644 index 00000000..d9b5cfee --- /dev/null +++ b/src/Entry/Address.php @@ -0,0 +1,20 @@ +entry = new \GtkEntry(); + + $this->entry->set_text( + $value + ); + } +} \ No newline at end of file diff --git a/src/Label/Content.php b/src/Label/Content.php new file mode 100644 index 00000000..7fedccc8 --- /dev/null +++ b/src/Label/Content.php @@ -0,0 +1,33 @@ +label = new \GtkLabel( + $value + ); + + $this->label->set_use_markup( + true + ); + + $this->label->set_selectable( + true + ); + + $this->label->set_xalign( + 0 + ); + + $this->label->set_yalign( + 0 + ); + } +} \ No newline at end of file diff --git a/src/Label/Tray.php b/src/Label/Tray.php new file mode 100644 index 00000000..d659b756 --- /dev/null +++ b/src/Label/Tray.php @@ -0,0 +1,33 @@ +label = new \GtkLabel( + $value + ); + + $this->label->set_use_markup( + true + ); + + $this->label->set_selectable( + false + ); + + $this->label->set_xalign( + 0 + ); + + $this->label->set_yalign( + 0 + ); + } +} \ No newline at end of file diff --git a/src/Menu/Bar/Main.php b/src/Menu/Bar/Main.php new file mode 100644 index 00000000..ec7b0e8b --- /dev/null +++ b/src/Menu/Bar/Main.php @@ -0,0 +1,23 @@ +bar = new \GtkMenuBar(); + + $this->yoda = new \Yggverse\Yoda\Menu\Item\Yoda(); + + $this->bar->append( + $this->yoda->item + ); + } +} \ No newline at end of file diff --git a/src/Menu/Item/Quit.php b/src/Menu/Item/Quit.php new file mode 100644 index 00000000..9a89db32 --- /dev/null +++ b/src/Menu/Item/Quit.php @@ -0,0 +1,30 @@ +item = \GtkMenuItem::new_with_label( + $label + ); + + $this->activate(); + } + + public function activate(): void + { + $this->item->connect( + 'activate', + function () + { + \Gtk::main_quit(); + } + ); + } +} \ No newline at end of file diff --git a/src/Menu/Item/Yoda.php b/src/Menu/Item/Yoda.php new file mode 100644 index 00000000..62dec923 --- /dev/null +++ b/src/Menu/Item/Yoda.php @@ -0,0 +1,29 @@ +item = \GtkMenuItem::new_with_label( + $label + ); + + $children = new \GtkMenu(); + + $quit = new \Yggverse\Yoda\Menu\Item\Quit(); + + $children->append( + $quit->item + ); + + $this->item->set_submenu( + $children + ); + } +} \ No newline at end of file diff --git a/src/Model/Database.php b/src/Model/Database.php new file mode 100644 index 00000000..6e64cda0 --- /dev/null +++ b/src/Model/Database.php @@ -0,0 +1,11 @@ +load_from_data( + \Yggverse\Yoda\Model\File::getTheme( + $config->theme + ) +); + +$style = new \GtkStyleContext(); + +$style->add_provider_for_screen( + $css, + 600 +); + +// Init app window +$window = new \GtkWindow(); + +$window->set_size_request( + 600, + 480 +); + +$window->set_title( + 'Yoda' +); + +$window->connect( + 'destroy', + function() + { + \Gtk::main_quit(); + } +); + +$main = new \Yggverse\Yoda\Box\Main(); + +$window->add( + $main->box +); + +$window->show_all(); + +\Gtk::main(); \ No newline at end of file