diff --git a/data/hicolor/scalable/actions/folder-remote-symbolic.svg b/data/hicolor/scalable/actions/folder-remote-symbolic.svg
new file mode 100644
index 00000000..bd184b11
--- /dev/null
+++ b/data/hicolor/scalable/actions/folder-remote-symbolic.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/data/hicolor/scalable/actions/note-symbolic.svg b/data/hicolor/scalable/actions/note-symbolic.svg
new file mode 100644
index 00000000..2a5e0690
--- /dev/null
+++ b/data/hicolor/scalable/actions/note-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/data/hicolor/scalable/actions/user-home-symbolic.svg b/data/hicolor/scalable/actions/user-home-symbolic.svg
new file mode 100644
index 00000000..59203ca9
--- /dev/null
+++ b/data/hicolor/scalable/actions/user-home-symbolic.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/resources.gresource.xml b/resources.gresource.xml
index 42250054..550a3a84 100644
--- a/resources.gresource.xml
+++ b/resources.gresource.xml
@@ -17,5 +17,8 @@
ticket-special-symbolic.svg
ticket-symbolic.svg
copy-symbolic.svg
+ user-home-symbolic.svg
+ note-symbolic.svg
+ folder-remote-symbolic.svg
\ No newline at end of file
diff --git a/src/database/core.rs b/src/database/core.rs
index 1feee907..9bc49a41 100644
--- a/src/database/core.rs
+++ b/src/database/core.rs
@@ -23,12 +23,18 @@ pub struct BrowserDatabase {
impl BrowserDatabase {
pub fn new() -> miette::Result {
- Ok(Self {
+ let database = Self {
database: native_db::Builder::new()
.create(&MODELS, &*DATABASE_PATH)
.into_diagnostic()?,
history_sender: tokio::sync::watch::channel(()).0,
- })
+ };
+ if database.get_history_records()?.len() as u64
+ != HISTORY_RECORD_INDEX_READER.searcher().num_docs()
+ {
+ database.rebuild_history_record_index()?;
+ }
+ Ok(database)
}
pub fn search(
diff --git a/src/database/history_record.rs b/src/database/history_record.rs
index c4c2d5fe..223ebd07 100644
--- a/src/database/history_record.rs
+++ b/src/database/history_record.rs
@@ -147,6 +147,20 @@ impl BrowserDatabase {
.collect())
}
+ pub fn rebuild_history_record_index(&self) -> miette::Result<()> {
+ let mut index_writer = HISTORY_RECORD_INDEX_WRITER
+ .clone()
+ .try_lock_owned()
+ .into_diagnostic()?;
+ index_writer.delete_all_documents().into_diagnostic()?;
+ self.get_history_records()?
+ .into_par_iter()
+ .filter_map(|x| index_writer.add_document(x.into()).ok())
+ .collect::>();
+ index_writer.commit().into_diagnostic()?;
+ Ok(())
+ }
+
pub fn upsert_history_record(
&self,
history_record: HistoryRecord,
diff --git a/src/replica_item.rs b/src/replica_item.rs
index fee2740f..b4e5ddb4 100644
--- a/src/replica_item.rs
+++ b/src/replica_item.rs
@@ -19,6 +19,7 @@ pub mod imp {
pub struct ReplicaItem {
pub(crate) id: RefCell,
pub(crate) writable: RefCell,
+ pub(crate) home: RefCell,
}
#[glib::object_subclass]
@@ -33,6 +34,7 @@ pub mod imp {
vec![
ParamSpecString::builder("id").readwrite().build(),
ParamSpecBoolean::builder("writable").readwrite().build(),
+ ParamSpecBoolean::builder("home").readwrite().build(),
]
});
PROPERTIES.as_ref()
@@ -48,6 +50,10 @@ pub mod imp {
let writable = value.get::().unwrap();
self.writable.set(writable);
}
+ "home" => {
+ let home = value.get::().unwrap();
+ self.home.set(home);
+ }
_ => unimplemented!(),
}
}
@@ -57,6 +63,7 @@ pub mod imp {
match pspec.name() {
"id" => obj.id().to_value(),
"writable" => obj.writable().to_value(),
+ "home" => obj.home().to_value(),
_ => unimplemented!(),
}
}
@@ -74,10 +81,14 @@ impl ReplicaItem {
pub fn writable(&self) -> bool {
self.imp().writable.borrow().clone()
}
- pub fn new(id: String, writable: bool) -> Self {
+ pub fn home(&self) -> bool {
+ *self.imp().home.borrow()
+ }
+ pub fn new(id: String, writable: bool, home: bool) -> Self {
let replica_item = glib::Object::builder::()
.property("id", id)
.property("writable", writable)
+ .property("home", home)
.build();
replica_item
diff --git a/src/widgets/replica_row.rs b/src/widgets/replica_row.rs
index ce625821..2d5addec 100644
--- a/src/widgets/replica_row.rs
+++ b/src/widgets/replica_row.rs
@@ -38,7 +38,8 @@ pub mod imp {
pub struct ReplicaRow {
pub(crate) id: RefCell,
pub(crate) writable: RefCell,
- pub(crate) icon: gtk::Image,
+ pub(crate) home: RefCell,
+ pub(crate) home_button: gtk::Button,
pub(crate) open_button: gtk::Button,
pub(crate) read_ticket_button: gtk::Button,
pub(crate) write_ticket_button: gtk::Button,
@@ -80,6 +81,7 @@ pub mod imp {
vec![
ParamSpecString::builder("id").build(),
ParamSpecBoolean::builder("writable").build(),
+ ParamSpecBoolean::builder("home").build(),
]
});
PROPERTIES.as_ref()
@@ -95,6 +97,10 @@ pub mod imp {
let writable = value.get::().unwrap();
self.obj().set_writable(writable);
}
+ "home" => {
+ let home = value.get::().unwrap();
+ self.obj().set_home(home);
+ }
_ => unimplemented!(),
}
}
@@ -103,6 +109,7 @@ pub mod imp {
match pspec.name() {
"id" => self.obj().id().to_value(),
"writable" => self.obj().writable().to_value(),
+ "home" => self.obj().home().to_value(),
_ => unimplemented!(),
}
}
@@ -133,7 +140,26 @@ impl ReplicaRow {
pub fn setup(&self) {
let imp = self.imp();
- imp.icon.set_icon_name(Some("folder"));
+ imp.home_button.set_icon_name("user-home-symbolic");
+ imp.home_button.add_css_class("circular");
+ imp.home_button.set_vexpand(false);
+ imp.home_button.set_hexpand(false);
+ imp.home_button.set_valign(gtk::Align::Center);
+ imp.home_button.connect_clicked(clone!(
+ #[weak(rename_to = this)]
+ self,
+ move |_| {
+ if let Some(node) = NODE.get() {
+ let new_home_replica = match this.home() {
+ false => Some(NamespaceId::from_str(&this.id()).unwrap()),
+ true => None,
+ };
+ if let Err(e) = node.set_home_replica(new_home_replica) {
+ error!("{}", e);
+ }
+ }
+ }
+ ));
imp.open_button.set_icon_name("external-link-symbolic");
imp.open_button.add_css_class("circular");
@@ -350,7 +376,7 @@ impl ReplicaRow {
let content_box: gtk::Box = self.child().and_downcast().unwrap();
content_box.set_hexpand(true);
- self.add_prefix(&imp.icon);
+ self.add_prefix(&imp.home_button);
self.add_suffix(&imp.button_box);
self.set_title_lines(1);
self.add_css_class("caption");
@@ -365,6 +391,10 @@ impl ReplicaRow {
self.imp().writable.borrow().clone()
}
+ pub fn home(&self) -> bool {
+ self.imp().home.borrow().clone()
+ }
+
pub fn set_id(&self, id: &str) {
let imp = self.imp();
@@ -378,4 +408,16 @@ impl ReplicaRow {
imp.writable.replace(writable);
imp.write_ticket_button.set_visible(writable);
}
+
+ pub fn set_home(&self, home: bool) {
+ let imp = self.imp();
+
+ imp.home.replace(home);
+ let (old_class, new_class) = match home {
+ true => ("accent", "warning"),
+ false => ("warning", "accent"),
+ };
+ imp.home_button.remove_css_class(old_class);
+ imp.home_button.add_css_class(new_class);
+ }
}
diff --git a/src/widgets/window.rs b/src/widgets/window.rs
deleted file mode 100644
index 0ed4909f..00000000
--- a/src/widgets/window.rs
+++ /dev/null
@@ -1,3304 +0,0 @@
-use super::settings::apply_appearance_config;
-use crate::config::Palette;
-use crate::database::{HistoryRecord, DATABASE};
-use crate::history_item::HistoryItem;
-use crate::replica_item::ReplicaItem;
-use crate::suggestion_item::SuggestionItem;
-use crate::window_util::{
- connect, get_title, get_view_from_page, get_view_stack_page_by_name, get_window_from_widget,
- new_webkit_settings, update_favicon, update_nav_bar, update_title,
-};
-use crate::{CONFIG, DATA_DIR, MOUNT_DIR, NODE, VERSION};
-use chrono::Utc;
-use glib::clone;
-use gtk::prelude::GtkWindowExt;
-use gtk::subclass::prelude::*;
-use gtk::EventControllerFocus;
-use gtk::{gio, glib};
-use libadwaita::subclass::application_window::AdwApplicationWindowImpl;
-use libadwaita::{prelude::*, ResponseAppearance};
-use log::{error, info, warn};
-use oku_fs::iroh::docs::CapabilityKind;
-use std::cell::RefCell;
-use std::cell::{Cell, Ref};
-use std::hash::{Hash, Hasher};
-use std::rc::Rc;
-use uuid::Uuid;
-use webkit2gtk::functions::{
- uri_for_display, user_media_permission_is_for_audio_device,
- user_media_permission_is_for_display_device, user_media_permission_is_for_video_device,
-};
-use webkit2gtk::prelude::PermissionRequestExt;
-use webkit2gtk::prelude::WebViewExt;
-use webkit2gtk::LoadEvent;
-use webkit2gtk::{FindOptions, WebContext, WebView};
-
-pub mod imp {
- use super::*;
-
- #[derive(Debug, Default)]
- pub struct Window {
- // Window parameters
- pub(crate) is_private: Cell,
- pub(crate) style_provider: RefCell,
- // Navigation bar
- pub(crate) nav_entry: gtk::SearchEntry,
- pub(crate) nav_entry_focus: RefCell,
- pub(crate) suggestions_store: RefCell