4 Commits
Author SHA1 Message Date
Sweetbread 886f42e062 ui(credentails): loading key 2025-10-01 15:31:21 +03:00
Sweetbread f06e6f9121 wip 2025-10-01 15:04:46 +03:00
Sweetbread 6240208c17 wip 2025-10-01 15:04:46 +03:00
Sweetbread 9b1dc672a9 Update shell 2025-10-01 15:04:46 +03:00
7 changed files with 668 additions and 217 deletions
Generated
+459 -206
View File
File diff suppressed because it is too large Load Diff
+7 -4
View File
@@ -42,7 +42,9 @@ spmc = "0.3.0"
thread-priority = "1.2.0" thread-priority = "1.2.0"
# Optional dependencies regulated by features # Optional dependencies regulated by features
web-view = { git = "https://github.com/Boscop/web-view", features = [], optional = true } # web-view = { git = "https://github.com/Boscop/web-view", features = [], optional = true }
gtk = { package = "gtk4", version = "0.9.6", features = ["v4_16"], optional = true }
adw = { version = "0.7.2", package = "libadwaita", features = ["v1_5"], optional = true }
tinyfiledialogs = { version = "3.9.1", optional = true } tinyfiledialogs = { version = "3.9.1", optional = true }
open = { version = "5.3.0", optional = true } open = { version = "5.3.0", optional = true }
@@ -69,7 +71,8 @@ ProductName="ALFIS"
FileDescription="Alternative Free Identity System" FileDescription="Alternative Free Identity System"
[features] [features]
webgui = ["web-view", "tinyfiledialogs", "open"] gui = ["gtk", "adw"]
edge = ["webgui", "web-view/edge"] # webgui = ["web-view", "tinyfiledialogs", "open"]
# edge = ["webgui", "web-view/edge"]
doh = ["ureq"] doh = ["ureq"]
default = ["webgui", "doh"] default = ["gui", "doh"]
BIN
View File
Binary file not shown.
+9 -2
View File
@@ -1,6 +1,13 @@
{ pkgs ? import <nixpkgs> { } }: { pkgs ? import <nixpkgs> { } }:
pkgs.mkShell { pkgs.mkShell {
buildInputs = buildInputs = with pkgs; [
[ pkgs.cargo pkgs.rustc pkgs.webkitgtk pkgs.pkg-config pkgs.kdialog ]; cargo
rustc
rust-analyzer
pkg-config
libsForQt5.kdialog
libadwaita
gtk4
];
} }
+7 -5
View File
@@ -29,8 +29,9 @@ use alfis::{dns_utils, Block, Bytes, Chain, Context, Keystore, Miner, Network, S
#[cfg(windows)] #[cfg(windows)]
use crate::win_service::start_service; use crate::win_service::start_service;
#[cfg(feature = "webgui")] // #[cfg(feature = "webgui")]
mod web_ui; // mod web_ui;
mod ui;
#[cfg(windows)] #[cfg(windows)]
mod win_service; mod win_service;
@@ -142,7 +143,7 @@ fn main() {
}; };
let mut no_gui = opt_matches.opt_present("n"); let mut no_gui = opt_matches.opt_present("n");
if !cfg!(feature = "webgui") if !cfg!(feature = "gui")
{ {
no_gui = true; no_gui = true;
} }
@@ -250,8 +251,9 @@ fn main() {
post(Event::Error { text: String::from("Error starting DNS-server. Please, check that it&rsquo;s port is not busy.") }); post(Event::Error { text: String::from("Error starting DNS-server. Please, check that it&rsquo;s port is not busy.") });
}); });
} }
#[cfg(feature = "webgui")] // #[cfg(feature = "webgui")]
web_ui::run_interface(Arc::clone(&context), miner); // web_ui::run_interface(Arc::clone(&context), miner);
ui::run_ui(Arc::clone(&context), miner);
} }
// Without explicitly detaching the console cmd won't redraw it's prompt. // Without explicitly detaching the console cmd won't redraw it's prompt.
+107
View File
@@ -0,0 +1,107 @@
use std::{
sync::Arc,
rc::Rc, cell::RefCell
};
use alfis::Keystore;
use crate::{Mutex, Context, ui::KeyData};
use log::{error, info, warn};
use gtk::{
prelude::*,
ApplicationWindow,
Button,
Label,
Box,
Orientation,
Entry,
FileDialog
};
pub fn menu_credentials(window: &ApplicationWindow, parent: &gtk::Box, context: &Arc<Mutex<Context>>) {
let key_data = Rc::new(RefCell::from(KeyData{hash: String::new(), path: String::new(), public: String::new()}));
let keys = Box::new(Orientation::Horizontal, 8);
keys.set_hexpand(true);
parent.append(&keys);
let key_hash = Entry::builder()
.placeholder_text("No key loaded")
.editable(false)
.tooltip_text("If you load or mine a keypair the public key will be displayed here")
.hexpand(true)
.focusable(false)
.build();
keys.append(&key_hash);
let load_btn = Button::with_label("Load key");
let window = window.clone();
let context = context.clone();
load_btn.connect_clicked(move |_| {
open_file(&window, &key_hash, &context, key_data.clone());
});
keys.append(&load_btn);
let save_btn = Button::builder()
.label("Save key")
.sensitive(false)
.build();
keys.append(&save_btn);
let mine_btn = Button::with_label("Mine new key");
mine_btn.add_css_class("suggested-action");
keys.append(&mine_btn);
parent.append(&Label::new(Some("To mine domains you need a strong pair of signing keys and a pair of ecryption keys.")));
}
fn open_file(window: &ApplicationWindow, key_hash: &Entry ,context: &Arc<Mutex<Context>>, keydata: Rc<RefCell<KeyData>>) {
let filter = gtk::FileFilter::new();
filter.add_pattern("*.key");
filter.add_pattern("*.toml");
filter.set_name(Some("Key files"));
let fc = FileDialog::builder()
.title("Select key")
.default_filter(&filter)
.build();
let context = context.clone();
let key_hash = key_hash.clone();
fc.open(Some(window), None::<gtk::gio::Cancellable>.as_ref(), move |result| {
match result {
Ok(file) => {
match Keystore::from_file(file.path().unwrap().to_str().unwrap(), "") {
None => {
error!("Error loading keystore '{}'!", &file.path().unwrap().to_str().unwrap());
// show_warning(web_view, "Error loading key!<br>Key cannot be loaded or its difficulty is not enough."); # TODO: display warnings
// event_fail(web_view, &format!("Error loading key from \\'{}\\'!", &file_name));
}
Some(keystore) => {
info!("Loaded keystore with keys: {:?}, {:?}", &keystore.get_public(), &keystore.get_encryption_public());
let path = keystore.get_path().to_owned();
let public = keystore.get_public().to_string();
let hash = keystore.get_hash().to_string();
let _ = &key_hash.set_text(public.as_str());
let key_data = KeyData { path, public, hash };
*keydata.borrow_mut() = key_data;
if !context.lock().unwrap().select_key_by_public(&keystore.get_public()) {
context.lock().unwrap().add_keystore(keystore);
} else {
warn!("This key is already loaded!");
}
}
}
}
Err(e) => {
if !e.matches(gtk::gio::IOErrorEnum::Cancelled) {
error!("Error selecting file: {}", e);
}
}
}
});
}
+79
View File
@@ -0,0 +1,79 @@
#[warn(unused_imports)]
mod credentails;
use alfis::{
blockchain::{
transaction::DomainData,
types::MineResult
},
commons::*,
crypto::CryptoBox,
dns::protocol::DnsRecord,
event::Event,
eventbus::{post, register},
miner::Miner,
keystore, Block, Bytes, Context, Keystore, Transaction
};
use std::{
sync::{Arc, Mutex, MutexGuard},
thread,
time::{Duration, Instant},
rc::Rc, cell::RefCell
};
use gtk::prelude::*;
use gtk::{
glib,
ApplicationWindow,
Button,
Label,
HeaderBar,
Box,
Orientation,
Notebook,
Entry,
FileDialog
};
#[derive(Clone, Debug)]
pub struct KeyData {
pub path: String,
pub public: String,
pub hash: String,
}
#[warn(unused_variables)]
pub fn run_ui(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) -> glib::ExitCode {
let application = adw::Application::builder()
.application_id("ru.Revertron.Alfis")
.build();
let context = context.clone();
application.connect_activate(move |app| {
let window = ApplicationWindow::builder()
.application(app)
.title(format!("ALFIS {}", env!("CARGO_PKG_VERSION")))
.default_width(1023)
.default_height(720)
.resizable(false)
.build();
let ab = HeaderBar::new();
window.set_titlebar(Some(&ab));
let nb = Notebook::new();
window.set_child(Some(&nb));
let main = Box::new(Orientation::Vertical, 5);
credentails::menu_credentials(&window, &main, &context);
nb.append_page(&main, Some(&Label::new(Some("Credentials"))));
window.present();
});
application.run()
}