-- Leo's gemini proxy

-- Connecting to typed-hole.org:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

commit 79c1ee3df272f463cbf56bde730c493dd721733e

Author: Julien Blanchard <julien@sideburns.eu>

Date: Mon Dec 23 18:16:42 2019 +0100


Add bookmarks


diff --git a/.gitignore b/.gitignore

index 53eaa21..35be495 100644

--- a/.gitignore

+++ b/.gitignore

@@ -1,2 +1,3 @@

/target

**/*.rs.bk

+/src/castor.glade~

diff --git a/Cargo.toml b/Cargo.toml

index d07e2e4..9d15c9f 100644

--- a/Cargo.toml

+++ b/Cargo.toml

@@ -24,4 +24,4 @@ lazy_static = "*"


[dependencies.gtk]

version = "0.8.0"

-features = ["v3_16"]

\ No newline at end of file

+features = ["v3_22"]

\ No newline at end of file

diff --git a/src/bookmarks.rs b/src/bookmarks.rs

new file mode 100644

index 0000000..0515e27

--- /dev/null

+++ b/src/bookmarks.rs

@@ -0,0 +1,34 @@

+extern crate dirs;

+use std::fs::File;

+use std::fs::OpenOptions;

+use std::io::{Read, Write};

+

+

+pub fn add(url: &str) {

+ let mut file = bookmarks_file();

+ let entry = format!("=> {}\n", url);

+ file.write_all(entry.as_bytes())

+ .expect("Unable to write file");

+}

+

+pub fn content() -> String {

+ let mut file = bookmarks_file();

+ let mut content = String::new();

+ file.read_to_string(&mut content)

+ .expect("Unable to read file");

+

+ content

+}

+

+fn bookmarks_file() -> File {

+ let mut bookmarks = dirs::data_local_dir().unwrap();

+ bookmarks.push("castor_bookmarks");

+ let file_path = bookmarks.into_os_string();

+

+ OpenOptions::new()

+ .create(true)

+ .append(true)

+ .read(true)

+ .open(file_path)

+ .expect("file not found")

+}

diff --git a/src/castor.glade b/src/castor.glade

index e1ef420..fd58cea 100644

--- a/src/castor.glade

+++ b/src/castor.glade

@@ -4,6 +4,23 @@

<requires lib="gtk+" version="3.16"/>

<object class="GtkTextBuffer"/>

<object class="GtkTextBuffer"/>

+ <object class="GtkImage" id="image1">

+ <property name="name">add_bookmark</property>

+ <property name="visible">True</property>

+ <property name="can_focus">False</property>

+ <property name="stock">gtk-add</property>

+ </object>

+ <object class="GtkImage" id="image2">

+ <property name="visible">True</property>

+ <property name="can_focus">False</property>

+ <property name="tooltip_text" translatable="yes">Show Bookmarks</property>

+ <property name="stock">gtk-justify-fill</property>

+ </object>

+ <object class="GtkImage" id="image3">

+ <property name="visible">True</property>

+ <property name="can_focus">False</property>

+ <property name="stock">gtk-go-back</property>

+ </object>

<object class="GtkApplicationWindow" id="window">

<property name="can_focus">False</property>

<property name="title" translatable="yes">Castor - Gemini Browser</property>

@@ -25,11 +42,12 @@

<property name="can_focus">False</property>

<child>

<object class="GtkButton" id="back_button">

- <property name="label" translatable="yes">Back</property>

<property name="name">back_button</property>

<property name="visible">True</property>

<property name="can_focus">True</property>

<property name="receives_default">True</property>

+ <property name="tooltip_text" translatable="yes">Go back</property>

+ <property name="image">image3</property>

<property name="always_show_image">True</property>

</object>

<packing>

@@ -40,12 +58,13 @@

</packing>

</child>

<child>

- <object class="GtkButton" id="forward_button">

- <property name="label" translatable="yes">Bookmarks</property>

- <property name="name">forward_button</property>

+ <object class="GtkButton" id="add_bookmark_button">

+ <property name="name">add_bookmark_button</property>

<property name="visible">True</property>

<property name="can_focus">True</property>

<property name="receives_default">True</property>

+ <property name="tooltip_text" translatable="yes">Add to Bookmarks</property>

+ <property name="image">image1</property>

<property name="always_show_image">True</property>

</object>

<packing>

@@ -56,6 +75,21 @@

</packing>

</child>

<child>

+ <object class="GtkButton" id="show_bookmarks_button">

+ <property name="name">show_bookmarks_button</property>

+ <property name="visible">True</property>

+ <property name="can_focus">True</property>

+ <property name="receives_default">True</property>

+ <property name="tooltip_text" translatable="yes">Show Bookmarks</property>

+ <property name="image">image2</property>

+ </object>

+ <packing>

+ <property name="expand">False</property>

+ <property name="fill">True</property>

+ <property name="position">2</property>

+ </packing>

+ </child>

+ <child>

<object class="GtkEntry" id="url_bar">

<property name="name">url_bar</property>

<property name="visible">True</property>

@@ -67,7 +101,7 @@

<property name="expand">True</property>

<property name="fill">True</property>

<property name="padding">1</property>

- <property name="position">2</property>

+ <property name="position">3</property>

</packing>

</child>

</object>

diff --git a/src/gui.rs b/src/gui.rs

index bbda792..8ae2f17 100644

--- a/src/gui.rs

+++ b/src/gui.rs

@@ -7,6 +7,8 @@ pub struct Gui {

url_bar: Entry,

content_view: TextView,

back_button: Button,

+ add_bookmark_button: Button,

+ show_bookmarks_button: Button,

}


impl Gui {

@@ -20,38 +22,26 @@ impl Gui {

let url_bar: Entry = builder.get_object("url_bar").expect("Couldn't get url_bar");

let content_view: TextView = builder.get_object("content_view").expect("Couldn't get content_view");

let back_button: Button = builder.get_object("back_button").expect("Couldn't get back_button");

+ let add_bookmark_button: Button = builder.get_object("add_bookmark_button").expect("Couldn't get add_bookmark_button");

+ let show_bookmarks_button: Button = builder.get_object("show_bookmarks_button").expect("Couldn't get show_bookmarks_button");


Gui {

window,

url_bar,

content_view,

back_button,

+ add_bookmark_button,

+ show_bookmarks_button,

}

}


- // Set up naming for the window and show it to the user.

pub fn start(&self) {

- glib::set_application_name("Castor");

- self.window.set_wmclass("Castor", "Castor");

+ glib::set_application_name("Castor - Gemini Browser");

+ self.window.set_role("Castor - Gemini Browser");

self.window.connect_delete_event(|_, _| { gtk::main_quit(); Inhibit(false) });

self.window.show_all();

}


- // pub fn update_from(&self, state: &State) {

- // if let Some(ref err) = state.error {

- // self.error_label.set_text(

- // &format!("The dice expression entered is not valid:\n{}", err)

- // );

- // self.popover.show_all();

- // } else {

- // // The popover will hide itself anyway when the user clicks

- // // outside of it, but we shouldn't leave an error indicator in it.

- // self.error_label.set_text("");

- // }

-

- // self.result.set_text(&format!("{}", state.value));

- // }

-

pub fn window(&self) -> &ApplicationWindow {

&self.window

}

@@ -67,4 +57,12 @@ impl Gui {

pub fn back_button(&self) -> &Button {

&self.back_button

}

+

+ pub fn add_bookmark_button(&self) -> &Button {

+ &self.add_bookmark_button

+ }

+

+ pub fn show_bookmarks_button(&self) -> &Button {

+ &self.show_bookmarks_button

+ }

}

diff --git a/src/main.rs b/src/main.rs

index 1b51095..2dde5b5 100644

--- a/src/main.rs

+++ b/src/main.rs

@@ -16,6 +16,7 @@ use url::{Position, Url};

mod gui;

use gui::Gui;

mod absolute;

+mod bookmarks;

mod content;

mod history;

mod link;

@@ -43,6 +44,24 @@ fn main() {

});

}


+ // Bind add_bookmark button

+ {

+ let button = gui.add_bookmark_button();

+ let gui = gui.clone();

+ button.connect_clicked(move |_| {

+ add_bookmark(&gui);

+ });

+ }

+

+ // Bind show_bookmarks button

+ {

+ let button = gui.show_bookmarks_button();

+ let gui = gui.clone();

+ button.connect_clicked(move |_| {

+ show_bookmarks(&gui);

+ });

+ }

+

// Bind URL bar

{

let gui_clone = gui.clone();

@@ -78,10 +97,37 @@ fn update_url_field(gui: &Arc<Gui>, url: &str) {

url_bar.get_buffer().set_text(url);

}


+fn add_bookmark(gui: &Arc<Gui>) {

+ let current_url = history::get_current_url();

+ if let Some(url) = current_url {

+ bookmarks::add(&url);

+ info_dialog(&gui, "Bookmark added.");

+ }

+}

+

+fn show_bookmarks(gui: &Arc<Gui>) {

+ let content_view = gui.content_view();

+

+ let bookmarks_list = format!("# Bookmarks\n\n{}", bookmarks::content());

+ let parsed_content = parser::parse(bookmarks_list);

+

+ clear_buffer(&content_view);

+ draw_content(&gui, parsed_content);

+

+ update_url_field(&gui, "::bookmarks");

+

+ content_view.show_all();

+}

+

fn visit_url(gui: &Arc<Gui>, url: String) {

{

let content_view = gui.content_view();


+ if url == String::from("gemini://::bookmarks") {

+ show_bookmarks(&gui);

+ return

+ }

+

match absolute::make(url.as_str()) {

Ok(url) => match content::get_data(&url) {

Ok((meta, new_content)) => {

@@ -272,6 +318,23 @@ fn insert_external_button(gui: &Arc<Gui>, url: Url, label: &str) {

buffer.insert(&mut end_iter, "\n");

}


+fn info_dialog(gui: &Arc<Gui>, message: &str) {

+ let dialog = gtk::Dialog::new_with_buttons(

+ Some("Info"),

+ Some(gui.window()),

+ gtk::DialogFlags::MODAL,

+ &[("Close", ResponseType::Close)],

+ );

+ dialog.set_default_response(ResponseType::Close);

+ dialog.connect_response(|dialog, _| dialog.destroy());

+

+ let content_area = dialog.get_content_area();

+ let message = gtk::Label::new(Some(message));

+ content_area.add(&message);

+

+ dialog.show_all();

+}

+

fn error_dialog(gui: &Arc<Gui>, message: &str) {

let dialog = gtk::Dialog::new_with_buttons(

Some("Error"),



---

Served by Pollux Gemini Server.

-- Response ended

-- Page fetched on Sun May 19 07:23:28 2024