Browse Source

app: add blockchain network status indicator

epiphany 2 months ago
parent
commit
d9c1a6b4f0

+ 10 - 0
bin/app/src/app/schema/wallet/data.rs

@@ -47,6 +47,11 @@ mod android_ui_consts {
     pub const WALLET_BTN_SIZE: f32 = 50.;
     pub const COPY_WIDTH: f32 = 200.;
     pub const COPY_SCALE: f32 = 30.;
+
+    pub const NETSTATUS_ICON_SIZE: f32 = 140.;
+    pub const SETTINGS_ICON_SIZE: f32 = 140.;
+    pub const NETLOGO_SCALE: f32 = 7.;
+    pub const EMOJI_PICKER_ICON_SIZE: f32 = 120.;
 }
 
 #[cfg(target_os = "android")]
@@ -89,6 +94,11 @@ mod ui_consts {
     pub const WALLET_BTN_SIZE: f32 = 50.;
     pub const COPY_WIDTH: f32 = 100.;
     pub const COPY_SCALE: f32 = 15.;
+
+    pub const NETSTATUS_ICON_SIZE: f32 = 60.;
+    pub const SETTINGS_ICON_SIZE: f32 = 60.;
+    pub const NETLOGO_SCALE: f32 = 3.5;
+    pub const EMOJI_PICKER_ICON_SIZE: f32 = 50.;
 }
 
 pub use ui_consts::*;

+ 4 - 4
bin/app/src/app/schema/wallet/main.rs

@@ -23,15 +23,15 @@ use crate::{
     app::{
         App,
         node::{create_button, create_layer, create_text, create_tokentable, create_vector_art},
-        schema::COLOR_SCHEME,
+        schema::{COLOR_SCHEME, wallet::netstatus},
     },
     expr,
-    gfx::{gfxtag},
+    gfx::gfxtag,
     mesh::{COLOR_CYAN, COLOR_TEAL},
     prop::{PropertyAtomicGuard, PropertyBool, PropertyFloat32, Role},
     scene::{SceneNodePtr, Slot},
     shape,
-    ui::{Button, Layer, Text, TokenTable, TokenRow, VectorArt, VectorShape},
+    ui::{Button, Layer, Text, TokenRow, TokenTable, VectorArt, VectorShape},
     util::i18n::I18nBabelFish,
 };
 
@@ -67,7 +67,7 @@ pub async fn make_main_wallet_layer(
     prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
     prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     main_layer.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
-    main_layer.set_property_u32(atom, Role::App, "z_index", 19).unwrap();
+    main_layer.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
     let main_layer = main_layer.setup(|me| Layer::new(me, app.renderer.clone())).await;
     wallet_layer.link(main_layer.clone());
 

+ 4 - 0
bin/app/src/app/schema/wallet/mod.rs

@@ -29,6 +29,7 @@ pub mod send_step2;
 pub mod send_step3;
 pub mod send_step4;
 pub mod tx_status;
+pub mod netstatus;
 
 use crate::{
     app::{App, node::create_layer},
@@ -68,6 +69,9 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     // Create main wallet layer
     let _ = make_main_wallet_layer(app, wallet_layer.clone(), i18n_fish, window_scale.clone()).await;
 
+    // Create blockchain network status indicator layer
+    let _ = netstatus::make(app, wallet_layer.clone(), i18n_fish, window_scale.clone()).await;
+
     // Create receive layer
     let _ = make_receive_layer(
         app,

+ 99 - 0
bin/app/src/app/schema/wallet/netstatus.rs

@@ -0,0 +1,99 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2026 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use crate::{
+    app::{
+        App,
+        schema::{create_vector_art, create_layer},
+        schema::wallet::data::{NETSTATUS_ICON_SIZE, NETLOGO_SCALE}
+    },
+    expr,
+    prop::{PropertyAtomicGuard, PropertyFloat32, Role},
+    shape,
+    scene::SceneNodePtr,
+    ui::{Layer, VectorArt},
+    util::i18n::I18nBabelFish
+};
+
+pub async fn make(
+    app: &App,
+    wallet_layer: SceneNodePtr,
+    i18n_fish: &I18nBabelFish,
+    window_scale: PropertyFloat32,
+) -> SceneNodePtr {
+    let atom = &mut PropertyAtomicGuard::none();
+
+    let mut cc = expr::Compiler::new();
+    cc.add_const_f32("NETSTATUS_ICON_SIZE", NETSTATUS_ICON_SIZE);
+
+    let netlayer_node = create_layer("netstatus_layer");
+    let prop = netlayer_node.get_property("rect").unwrap();
+    let code = cc.compile("w - NETSTATUS_ICON_SIZE").unwrap();
+    prop.set_expr(atom, Role::App, 0, code).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1000.).unwrap();
+    netlayer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
+    netlayer_node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
+    let netlayer_node = netlayer_node.setup(|me| Layer::new(me, app.renderer.clone())).await;
+    wallet_layer.link(netlayer_node.clone());
+
+    let node = create_vector_art("net0");
+    let prop = node.get_property("rect").unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
+    node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
+    node.set_property_f32(atom, Role::App, "scale", NETLOGO_SCALE).unwrap();
+    let mut shape = shape::create_blockchain_netlogo1([1., 0., 0.25, 1.]);
+    shape.join(shape::create_blockchain_netlogo2([0.27, 0.4, 0.4, 1.]));
+    let net0_node = node.setup(|me| VectorArt::new(me, shape, app.renderer.clone())).await;
+    netlayer_node.link(net0_node);
+
+    let node = create_vector_art("net1");
+    let prop = node.get_property("rect").unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
+    node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
+    node.set_property_f32(atom, Role::App, "scale", NETLOGO_SCALE).unwrap();
+    let mut shape = shape::create_blockchain_netlogo1([1., 0.6, 0., 1.]);
+    shape.join(shape::create_blockchain_netlogo2([0.27, 0.4, 0.4, 1.]));
+    let net1_node = node.setup(|me| VectorArt::new(me, shape, app.renderer.clone())).await;
+    netlayer_node.link(net1_node);
+
+    let node = create_vector_art("net2");
+    let prop = node.get_property("rect").unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
+    node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
+    node.set_property_f32(atom, Role::App, "scale", NETLOGO_SCALE).unwrap();
+    let mut shape = shape::create_blockchain_netlogo1([0.49, 0.57, 1., 1.]);
+    shape.join(shape::create_blockchain_netlogo2([0.49, 0.57, 1., 1.]));
+    let net2_node = node.setup(|me| VectorArt::new(me, shape, app.renderer.clone())).await;
+    netlayer_node.link(net2_node);
+
+    netlayer_node
+}

+ 46 - 0
bin/app/src/main.rs

@@ -457,6 +457,43 @@ async fn load_plugins(
         })
         .await;
 
+    let (slot, recvr) = Slot::new("connect");
+    drk.register("connect", slot).unwrap();
+    let sg_root2 = sg_root.clone();
+    let renderer2 = renderer.clone();
+    let listen_connect = ex.spawn(async move {
+        let net0 = sg_root2.lookup_node("/window/content/wallet/netstatus_layer/net0").unwrap();
+        let net1 = sg_root2.lookup_node("/window/content/wallet/netstatus_layer/net1").unwrap();
+        let net2 = sg_root2.lookup_node("/window/content/wallet/netstatus_layer/net2").unwrap();
+
+        let net0_is_visible = PropertyBool::wrap(&net0, Role::App, "is_visible", 0).unwrap();
+        let net1_is_visible = PropertyBool::wrap(&net1, Role::App, "is_visible", 0).unwrap();
+        let net2_is_visible = PropertyBool::wrap(&net2, Role::App, "is_visible", 0).unwrap();
+
+        while let Ok(data) = recvr.recv().await {
+            let status: u8 = deserialize(&data).unwrap();
+            let atom = &mut renderer2.make_guard(gfxtag!("blockchain netstatus change"));
+
+            match status {
+                1 => {
+                    net0_is_visible.set(atom, false);
+                    net1_is_visible.set(atom, true);
+                    net2_is_visible.set(atom, false);
+                },
+                2 => {
+                    net0_is_visible.set(atom, false);
+                    net1_is_visible.set(atom, false);
+                    net2_is_visible.set(atom, true);
+                },
+                _ => {
+                    net0_is_visible.set(atom, true);
+                    net1_is_visible.set(atom, false);
+                    net2_is_visible.set(atom, false);
+                }
+            }
+        }
+    });
+
     let (slot, recv) = Slot::new("balances_update");
     let _ = drk.register("balances_updated", slot);
     let sg_root2 = sg_root.clone();
@@ -680,6 +717,15 @@ pub fn create_drk(name: &str) -> SceneNode {
     t!("create_drk({name})");
     let mut node = SceneNode::new(name, SceneNodeType::Plugin);
 
+    node.add_signal(
+        "connect",
+        "Connections and disconnects",
+        vec![
+            ("connected", "Is darkfid connected", CallArgType::Bool),
+        ],
+    )
+    .unwrap();
+
     node.add_method(
         "get_default_address",
         vec![],

+ 18 - 1
bin/app/src/plugin/drk.rs

@@ -25,7 +25,7 @@ use darkfi::{
     util::parse::encode_base10,
 };
 use darkfi_money_contract::model::TokenId;
-use darkfi_serial::{Decodable, Encodable};
+use darkfi_serial::{serialize, Decodable, Encodable};
 use darkfi_sdk::crypto::{FuncId, keypair::{Address, Network, PublicKey, StandardAddress}};
 use drk::{Drk, money::BALANCE_BASE10_DECIMALS, rpc::subscribe_blocks};
 use sled_overlay::sled;
@@ -637,6 +637,7 @@ impl DrkPlugin {
         let me = Arc::downgrade(&self);
         let node = &self.node.upgrade().unwrap();
 
+        let self2 = self.clone();
         let drk = self.drk.clone();
         let (shell_sender, shell_receiver) = unbounded();
         let ex_ = ex.clone();
@@ -651,6 +652,20 @@ impl DrkPlugin {
                 let endpoint = endpoint.clone();
                 let ex = ex_.clone();
 
+                let _ = self2.node.upgrade().unwrap().trigger("connect", serialize(&1u8)).await;
+
+                if let Err(e) = drk.read().await.scan_blocks(&mut vec![], Some(&shell_sender), &false).await {
+                    e!("Failed during drk scanning: {e}");
+                    let _ = self2.node.upgrade().unwrap().trigger("connect", serialize(&0u8)).await;
+
+                    // Wait before retrying
+                    i!("Retrying connection to darkfid in {} seconds...", DARKFID_RETRY_TIME);
+                    sleep(DARKFID_RETRY_TIME).await;
+                    continue
+                }
+
+                let _ = self2.node.upgrade().unwrap().trigger("connect", serialize(&2u8)).await;
+
                 match subscribe_blocks(&drk, subscribe_rpc_task, shell_sender.clone(), endpoint, &ex).await {
                     Ok(()) => {
                         i!("darkfid subscription closed normally (detached task stopped)");
@@ -660,6 +675,8 @@ impl DrkPlugin {
                     }
                 }
 
+                let _ = self2.node.upgrade().unwrap().trigger("connect", serialize(&0u8)).await;
+
                 // Wait before retrying
                 i!("Retrying connection to darkfid in {} seconds...", DARKFID_RETRY_TIME);
                 sleep(DARKFID_RETRY_TIME).await;

File diff suppressed because it is too large
+ 3470 - 0
bin/app/src/shape/blockchain_netlogo1.rs


File diff suppressed because it is too large
+ 5270 - 0
bin/app/src/shape/blockchain_netlogo2.rs


+ 5 - 0
bin/app/src/shape/mod.rs

@@ -41,6 +41,11 @@ pub use version_block::create_version_block;
 mod copy;
 pub use copy::create_copy;
 
+mod blockchain_netlogo1;
+pub use blockchain_netlogo1::create_blockchain_netlogo1;
+mod blockchain_netlogo2;
+pub use blockchain_netlogo2::create_blockchain_netlogo2;
+
 //mod settings;
 //pub use settings::{create_right_border, create_settings};
 

Some files were not shown because too many files changed in this diff