Refactored interface. Added log events to Events tab.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "alfis"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
authors = ["Revertron <alfis@revertron.com>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
+81
-4
@@ -22,6 +22,7 @@ use Cmd::*;
|
||||
use alfis::blockchain::transaction::{DomainData, ZoneData};
|
||||
use self::web_view::{WebView, Handle};
|
||||
use alfis::blockchain::enums::MineResult;
|
||||
use chrono::{DateTime, Local};
|
||||
|
||||
pub fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
||||
let file_content = include_str!("webview/index.html");
|
||||
@@ -158,6 +159,7 @@ fn action_load_key(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
|
||||
None => {
|
||||
error!("Error loading keystore '{}'!", &file_name);
|
||||
show_warning(web_view, "Error loading key!<br>Key cannot be loaded or its difficulty is not enough.");
|
||||
event_fail(web_view, &format!("Error loading key from '{}'!", &file_name));
|
||||
}
|
||||
Some(keystore) => {
|
||||
info!("Loaded keystore with key: {:?}", &keystore.get_public());
|
||||
@@ -188,13 +190,17 @@ fn action_loaded(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
|
||||
let mut status = status.lock().unwrap();
|
||||
let context = context_copy.lock().unwrap();
|
||||
let eval = match e {
|
||||
Event::KeyCreated { path, public, hash } |
|
||||
Event::KeyCreated { path, public, hash } => {
|
||||
event_handle_luck(&handle, "Key successfully created! Don\\'t forget to save it!");
|
||||
format!("keystoreChanged('{}', '{}', '{}');", &path, &public, &hash)
|
||||
}
|
||||
Event::KeyLoaded { path, public, hash } |
|
||||
Event::KeySaved { path, public, hash } => {
|
||||
format!("keystoreChanged('{}', '{}', '{}');", &path, &public, &hash)
|
||||
}
|
||||
Event::MinerStarted | Event::KeyGeneratorStarted => {
|
||||
status.mining = true;
|
||||
event_handle_info(&handle, "Mining started");
|
||||
String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);")
|
||||
}
|
||||
Event::MinerStopped {success, full} => {
|
||||
@@ -206,8 +212,14 @@ fn action_loaded(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
|
||||
};
|
||||
if full {
|
||||
match success {
|
||||
true => { s.push_str(" showSuccess('Block successfully mined!')"); }
|
||||
false => { s.push_str(" showSuccess('Mining unsuccessful, sorry.')"); }
|
||||
true => {
|
||||
event_handle_luck(&handle, "Mining is successful!");
|
||||
s.push_str(" showSuccess('Block successfully mined!')");
|
||||
}
|
||||
false => {
|
||||
event_handle_info(&handle, "Mining finished without result.");
|
||||
s.push_str(" showSuccess('Mining unsuccessful, sorry.')");
|
||||
}
|
||||
}
|
||||
}
|
||||
s
|
||||
@@ -226,6 +238,7 @@ fn action_loaded(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
|
||||
s
|
||||
}
|
||||
Event::Syncing { have, height } => {
|
||||
event_handle_info(&handle, "Syncing started...");
|
||||
status.syncing = true;
|
||||
status.synced_blocks = have;
|
||||
status.sync_height = height;
|
||||
@@ -236,6 +249,7 @@ fn action_loaded(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
|
||||
}
|
||||
}
|
||||
Event::SyncFinished => {
|
||||
event_handle_info(&handle, "Syncing finished.");
|
||||
status.syncing = false;
|
||||
if status.mining {
|
||||
String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);")
|
||||
@@ -252,6 +266,7 @@ fn action_loaded(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
|
||||
}
|
||||
Event::BlockchainChanged {index} => {
|
||||
debug!("Current blockchain height is {}", index);
|
||||
event_handle_info(&handle, &format!("Blockchain changed, current block count is {} now.", index));
|
||||
if let Ok(zones) = serde_json::to_string(&context.chain.get_zones()) {
|
||||
let _ = handle.dispatch(move |web_view|{
|
||||
web_view.eval(&format!("zonesChanged('{}');", &zones))
|
||||
@@ -279,6 +294,7 @@ fn action_loaded(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
|
||||
}
|
||||
let index = c.chain.height();
|
||||
c.bus.post(Event::BlockchainChanged { index });
|
||||
event_info(web_view, "Application loaded");
|
||||
}
|
||||
|
||||
fn action_create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, web_view: &mut WebView<()>, name: String, records: &String) {
|
||||
@@ -291,7 +307,7 @@ fn action_create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>,
|
||||
}
|
||||
let keystore = context.get_keystore().unwrap();
|
||||
let pub_key = keystore.get_public();
|
||||
match dbg!(context.chain.can_mine_domain(&name, &records, &pub_key)) {
|
||||
match context.chain.can_mine_domain(&name, &records, &pub_key) {
|
||||
MineResult::Fine => {
|
||||
let zone = get_domain_zone(&name);
|
||||
let difficulty = context.chain.get_zone_difficulty(&zone);
|
||||
@@ -301,6 +317,7 @@ fn action_create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>,
|
||||
std::mem::drop(context);
|
||||
create_domain(c, miner, &name, &data, difficulty, &keystore);
|
||||
let _ = web_view.eval("domainMiningStarted();");
|
||||
event_info(web_view, &format!("Mining of domain \\'{}\\' has started", &name));
|
||||
}
|
||||
}
|
||||
MineResult::WrongName => { show_warning(web_view, "You can't mine this domain!"); }
|
||||
@@ -309,6 +326,7 @@ fn action_create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>,
|
||||
MineResult::WrongZone => { show_warning(web_view, "You can't mine domain in this zone!"); }
|
||||
MineResult::NotOwned => { show_warning(web_view, "This domain is already taken, and it is not yours!"); }
|
||||
MineResult::Cooldown { time } => {
|
||||
event_info(web_view, &format!("You have cooldown, just {} more minutes!", time / 60));
|
||||
show_warning(web_view, &format!("You have cooldown, just {} more minutes!", time / 60));
|
||||
}
|
||||
}
|
||||
@@ -335,10 +353,12 @@ fn action_create_zone(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, we
|
||||
match transaction {
|
||||
None => {
|
||||
create_domain(Arc::clone(&context), miner.clone(), &name, &data, ZONE_DIFFICULTY, &keystore);
|
||||
event_info(web_view, &format!("Mining of zone \\'{}\\' has started", &name));
|
||||
}
|
||||
Some(transaction) => {
|
||||
if transaction.pub_key == keystore.get_public() {
|
||||
create_domain(Arc::clone(&context), miner.clone(), &name, &data, ZONE_DIFFICULTY, &keystore);
|
||||
event_info(web_view, &format!("Mining of zone \\'{}\\' has started", &name));
|
||||
} else {
|
||||
warn!("Tried to mine not owned domain!");
|
||||
show_warning(web_view, "You cannot change domain that you don't own!");
|
||||
@@ -368,6 +388,63 @@ fn show_success(web_view: &mut WebView<()>, text: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn event_info(web_view: &mut WebView<()>, message: &str) {
|
||||
let _ = web_view.eval(&format_event_now("info", message));
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn event_warn(web_view: &mut WebView<()>, message: &str) {
|
||||
let _ = web_view.eval(&format_event_now("warn", message));
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn event_fail(web_view: &mut WebView<()>, message: &str) {
|
||||
let _ = web_view.eval(&format_event_now("fail", message));
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn event_handle_info(handle: &Handle<()>, message: &str) {
|
||||
let message = message.to_owned();
|
||||
let _ = handle.dispatch(move |web_view|{
|
||||
web_view.eval(&format_event_now("info", &message))
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn event_handle_warn(handle: &Handle<()>, message: &str) {
|
||||
let message = message.to_owned();
|
||||
let _ = handle.dispatch(move |web_view|{
|
||||
web_view.eval(&format_event_now("warn", &message))
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn event_handle_fail(handle: &Handle<()>, message: &str) {
|
||||
let message = message.to_owned();
|
||||
let _ = handle.dispatch(move |web_view|{
|
||||
web_view.eval(&format_event_now("fail", &message))
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn event_handle_luck(handle: &Handle<()>, message: &str) {
|
||||
let message = message.to_owned();
|
||||
let _ = handle.dispatch(move |web_view|{
|
||||
web_view.eval(&format_event_now("luck", &message))
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn format_event(kind: &str, time: DateTime<Local>, message: &str) -> String {
|
||||
format!("addEvent('{}', '{}', '{}');", kind, time.format("%d.%m.%y %X"), message)
|
||||
}
|
||||
|
||||
fn format_event_now(kind: &str, message: &str) -> String {
|
||||
let time = Local::now();
|
||||
format!("addEvent('{}', '{}', '{}');", kind, time.format("%d.%m.%y %X"), message)
|
||||
}
|
||||
|
||||
fn create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, name: &str, data: &str, difficulty: u32, keystore: &Keystore) {
|
||||
let name = name.to_owned();
|
||||
info!("Generating domain or zone {}", &name);
|
||||
|
||||
+44
-43
@@ -9,9 +9,9 @@
|
||||
</head>
|
||||
<body onload="onLoad();">
|
||||
|
||||
<div class="container">
|
||||
<div class="main">
|
||||
<!-- Tabs -->
|
||||
<div class="tabs is-centered is-boxed">
|
||||
<div class="row header tabs is-centered is-boxed">
|
||||
<ul>
|
||||
<li class="tab is-active">
|
||||
<a onclick="openTab(this, 'tab_credentials')">
|
||||
@@ -57,7 +57,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Credentials (Key management) -->
|
||||
<div class="tab content" id="tab_credentials">
|
||||
<div class="tab row page" id="tab_credentials">
|
||||
<div class="field is-grouped">
|
||||
<div class="control is-expanded has-icons-left">
|
||||
<input class="input is-expanded" type="text" id="public_key_hash" placeholder="No key loaded" readonly>
|
||||
@@ -75,7 +75,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Domain mining -->
|
||||
<div class="tab content is-hidden" id="tab_domains">
|
||||
<div class="tab row page is-hidden" id="tab_domains">
|
||||
<div class="field is-grouped is-fullwidth">
|
||||
<div class="control field has-addons is-expanded">
|
||||
<div class="control is-expanded has-icons-left">
|
||||
@@ -113,13 +113,13 @@
|
||||
</div>
|
||||
<p class="help">Enter domain name, add some DNS-records, then hit the "Mine domain" button!</p>
|
||||
|
||||
<div id="domain_records">
|
||||
<div class="list pb-3" id="domain_records">
|
||||
<!-- Here will be our domain records, added by dialog -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zone mining -->
|
||||
<div class="tab content is-hidden" id="tab_zones">
|
||||
<div class="tab row page is-hidden" id="tab_zones">
|
||||
<div class="field is-grouped">
|
||||
<div class="control is-expanded has-icons-left">
|
||||
<input class="input" type="text" placeholder="ygg" id="new_zone" oninput="onZoneChange()">
|
||||
@@ -141,27 +141,48 @@
|
||||
</div>
|
||||
|
||||
<!-- Events and notifications -->
|
||||
<div class="tab content is-hidden" id="tab_events">
|
||||
<div class="tab row page is-hidden list" id="tab_events">
|
||||
<!-- TODO -->
|
||||
</div>
|
||||
|
||||
<!-- Help -->
|
||||
<div class="tab content is-hidden" id="tab_help">
|
||||
<h1>Welcome to ALFIS!</h1>
|
||||
<p>ALFIS stands for Alternative Free Identity System.</p>
|
||||
<p>It gives you an opportunity to create your own domains and use them in decentralized networks, store security certificates for browsers to trust without any centralized CA.</p>
|
||||
<h2>How this system works?</h2>
|
||||
<h3>If you just want to be able to resolve our domains</h3>
|
||||
<p>Carefully configure DNS section in <strong>alfis.toml</strong> and start ALFIS with <code>-n</code> command line switch.
|
||||
It will start without GUI, but will work as local DNS-resolver.</p>
|
||||
<h3>If you want to get your own domain</h3>
|
||||
<ul>
|
||||
<li>Generate a keypair in "Manage keys" part (you need just one for any number of domains)</li>
|
||||
<li>Check available zones (for now we have a test zone <code>.yy</code>). In future version a list of available zones will be somewhere here</li>
|
||||
<li>Go to "Mine domain" part and enter desired domain in first field, if it is not red - you can create it</li>
|
||||
<li>Carefully add needed DNS-records (you can add them later, but you will need to mine it again)</li>
|
||||
<li>Just click on "Mine domain" and wait for it, your domain (when properly cooked) will propagate to all blockchain nodes automatically</li>
|
||||
</ul>
|
||||
<div class="tab row page is-hidden" id="tab_help">
|
||||
<div class="content">
|
||||
<h2>Welcome to ALFIS!</h2>
|
||||
<p>ALFIS stands for Alternative Free Identity System.</p>
|
||||
<p>It gives you an opportunity to create your own domains and use them in decentralized networks, store security certificates for browsers to trust without any centralized CA.</p>
|
||||
<h3>How this system works?</h3>
|
||||
<h4>If you just want to be able to resolve our domains</h4>
|
||||
<p>Carefully configure DNS section in <strong>alfis.toml</strong> and start ALFIS with <code>-n</code> command line switch.
|
||||
It will start without GUI, but will work as local DNS-resolver.</p>
|
||||
<h4>If you want to get your own domain</h4>
|
||||
<ul>
|
||||
<li>Generate a keypair in "Manage keys" part (you need just one for any number of domains)</li>
|
||||
<li>Go to "Mine domain" part and enter desired domain in first field, choose appropriate zone from dropdown, if it is not red - you can create it</li>
|
||||
<li>Carefully add needed DNS-records (you can add them later, but you will need to mine it again)</li>
|
||||
<li>Just click on "Mine domain" and wait for it, your domain (when properly cooked) will propagate to all blockchain nodes automatically</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row status is-family-code">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item" id="indicator_parent">
|
||||
<div class="busy_indicator busy_blue" id="busy_indicator" onclick="miningIndicatorClick(this)">
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div id="status_bar_left">Connecting...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="level-right">
|
||||
<div class="level-item" id="status_bar_right">No data</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -270,25 +291,5 @@
|
||||
<p id="success_text"></p>
|
||||
</div>
|
||||
|
||||
<div class="footer is-family-code">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item" id="indicator_parent">
|
||||
<div class="busy_indicator busy_blue" id="busy_indicator" onclick="miningIndicatorClick(this)">
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div id="status_bar_left">Connecting...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="level-right">
|
||||
<div class="level-item" id="status_bar_right">No data</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+19
-3
@@ -105,9 +105,9 @@ function openTab(element, tabName) {
|
||||
var i, tabContent, tabLinks;
|
||||
|
||||
// Get all elements with class="content" and hide them
|
||||
tabContent = document.getElementsByClassName("tab content");
|
||||
tabContent = document.getElementsByClassName("tab row page");
|
||||
for (i = 0; i < tabContent.length; i++) {
|
||||
tabContent[i].className = "tab content is-hidden";
|
||||
tabContent[i].className = "tab row page is-hidden";
|
||||
}
|
||||
|
||||
// Get all elements with class="tab" and remove the class "is-active"
|
||||
@@ -117,7 +117,7 @@ function openTab(element, tabName) {
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "is-active" class to the button that opened the tab
|
||||
document.getElementById(tabName).className = "tab content";
|
||||
document.getElementById(tabName).className = "tab row page";
|
||||
element.parentElement.className = "tab is-active";
|
||||
refreshRecordsList();
|
||||
}
|
||||
@@ -315,12 +315,28 @@ function setRightStatusBarText(text) {
|
||||
bar.innerHTML = text;
|
||||
}
|
||||
|
||||
function addEvent(type, time, message) {
|
||||
var t = "";
|
||||
if (type == 'warn') {
|
||||
t = "is-warning";
|
||||
} else if (type == 'fail') {
|
||||
t = "is-danger";
|
||||
} else if (type == 'luck') {
|
||||
t = "is-success";
|
||||
}
|
||||
|
||||
var buf = "<article class=\"message mb-1 {1}\"><div class=\"message-body px-2 py-1\"><strong>{2}</strong> {3}</div></article>".replace("{1}", t).replace("{2}", time).replace("{3}", message);
|
||||
var tab_events = document.getElementById("tab_events");
|
||||
tab_events.innerHTML = tab_events.innerHTML + buf;
|
||||
}
|
||||
|
||||
function keystoreChanged(path, pub_key, hash) {
|
||||
if (path == '') {
|
||||
path = "In memory";
|
||||
}
|
||||
var public_key_hash = document.getElementById("public_key_hash");
|
||||
public_key_hash.value = hash;
|
||||
public_key_hash.title = path + "\n" + pub_key;
|
||||
|
||||
var save_key = document.getElementById("save_key");
|
||||
save_key.disabled = false;
|
||||
|
||||
+41
-9
@@ -1,8 +1,45 @@
|
||||
html {
|
||||
overflow-y: auto;
|
||||
min-width: 768px;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100%;
|
||||
padding-top: 10pt;
|
||||
}
|
||||
|
||||
.main .row {
|
||||
/*border: 1px dotted grey;*/
|
||||
}
|
||||
|
||||
.main .row.header {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.main .row.page {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
flex: 1 1 auto;
|
||||
margin-left: 10pt;
|
||||
margin-right: 10pt;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.main .row.status {
|
||||
flex: 0 1 auto;
|
||||
background-color: #f4f4f4;
|
||||
padding: 0.2rem 0.5rem 0.2rem 0.5rem;
|
||||
}
|
||||
|
||||
/* ========================================== */
|
||||
|
||||
.container {
|
||||
margin: 10pt;
|
||||
}
|
||||
@@ -25,13 +62,8 @@ html {
|
||||
right: 10pt;
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: #f4f4f4;
|
||||
padding: 0.2rem 0.5rem 0.2rem 0.5rem;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
z-index: 9;
|
||||
.list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
path {
|
||||
|
||||
Reference in New Issue
Block a user