mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
app: make connect status indicator clickable- doing so will force a reconnect
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use darkfi::system::msleep;
|
||||||
use darkfi_serial::Encodable;
|
use darkfi_serial::Encodable;
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use sled_overlay::sled;
|
use sled_overlay::sled;
|
||||||
@@ -23,7 +24,7 @@ use std::fs::File;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{
|
app::{
|
||||||
node::{create_layer, create_shortcut, create_vector_art, create_video},
|
node::{create_button, create_layer, create_shortcut, create_vector_art, create_video},
|
||||||
App,
|
App,
|
||||||
},
|
},
|
||||||
expr::{self, Compiler},
|
expr::{self, Compiler},
|
||||||
@@ -31,7 +32,7 @@ use crate::{
|
|||||||
prop::{PropertyAtomicGuard, Role},
|
prop::{PropertyAtomicGuard, Role},
|
||||||
scene::{SceneNodePtr, Slot},
|
scene::{SceneNodePtr, Slot},
|
||||||
shape,
|
shape,
|
||||||
ui::{emoji_picker, Layer, Shortcut, VectorArt, VectorShape, Video},
|
ui::{emoji_picker, Button, Layer, ShapeVertex, Shortcut, VectorArt, VectorShape, Video},
|
||||||
util::{i18n::I18nBabelFish, spawn_thread},
|
util::{i18n::I18nBabelFish, spawn_thread},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,6 +41,9 @@ mod menu;
|
|||||||
//mod settings;
|
//mod settings;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
|
macro_rules! i { ($($arg:tt)*) => { info!(target: "app::schema", $($arg)*); } }
|
||||||
|
macro_rules! e { ($($arg:tt)*) => { error!(target: "app::schema", $($arg)*); } }
|
||||||
|
|
||||||
const COLOR_SCHEME: ColorScheme = ColorScheme::DarkMode;
|
const COLOR_SCHEME: ColorScheme = ColorScheme::DarkMode;
|
||||||
//const COLOR_SCHEME: ColorScheme = ColorScheme::PaperLight;
|
//const COLOR_SCHEME: ColorScheme = ColorScheme::PaperLight;
|
||||||
|
|
||||||
@@ -411,6 +415,87 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
|||||||
let net3_node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
|
let net3_node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
|
||||||
netlayer_node.link(net3_node);
|
netlayer_node.link(net3_node);
|
||||||
|
|
||||||
|
// netstat-klik icon (visual feedback when reconnect button is clicked)
|
||||||
|
let klik_color = [0., 0.5, 1., 1.]; // Blue
|
||||||
|
let node = create_vector_art("netstat_klik");
|
||||||
|
let prop = node.get_property("rect").unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 0, 0.).unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 1, 0.).unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 2, NETSTATUS_ICON_SIZE).unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 3, NETSTATUS_ICON_SIZE).unwrap();
|
||||||
|
node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
|
||||||
|
// Above other icons
|
||||||
|
node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
|
||||||
|
let mut shape = VectorShape::new();
|
||||||
|
shape.add_filled_box(
|
||||||
|
expr::const_f32(0.),
|
||||||
|
expr::const_f32(0.),
|
||||||
|
expr::const_f32(NETSTATUS_ICON_SIZE),
|
||||||
|
expr::const_f32(NETSTATUS_ICON_SIZE),
|
||||||
|
klik_color,
|
||||||
|
);
|
||||||
|
let netstat_klik_node =
|
||||||
|
node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
|
||||||
|
netlayer_node.link(netstat_klik_node.clone());
|
||||||
|
|
||||||
|
// Reconnect Button (overlaid on netstatus icons)
|
||||||
|
let node = create_button("reconnect_btn");
|
||||||
|
node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
|
||||||
|
let prop = node.get_property("rect").unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 0, 0.).unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 1, 0.).unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 2, NETSTATUS_ICON_SIZE).unwrap();
|
||||||
|
prop.set_f32(atom, Role::App, 3, NETSTATUS_ICON_SIZE).unwrap();
|
||||||
|
|
||||||
|
let sg_root = app.sg_root.clone();
|
||||||
|
let render_api = app.render_api.clone();
|
||||||
|
let (slot, recvr) = Slot::new("reconnect_clicked");
|
||||||
|
node.register("click", slot).unwrap();
|
||||||
|
let reconnect_task = app.ex.spawn(async move {
|
||||||
|
while let Ok(_) = recvr.recv().await {
|
||||||
|
i!("Reconnect button clicked");
|
||||||
|
|
||||||
|
// Show netstat-klik icon
|
||||||
|
let netstat_klik =
|
||||||
|
sg_root.lookup_node("/window/content/netstatus_layer/netstat_klik").unwrap();
|
||||||
|
|
||||||
|
{
|
||||||
|
let atom = &mut render_api.make_guard(gfxtag!("netstat_klik_show"));
|
||||||
|
if let Err(e) = netstat_klik.set_property_bool(atom, Role::App, "is_visible", true)
|
||||||
|
{
|
||||||
|
e!("Failed to show netstat_klik: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger reconnect
|
||||||
|
match sg_root.lookup_node("/plugin/darkirc") {
|
||||||
|
Some(darkirc) => {
|
||||||
|
if let Err(e) = darkirc.call_method("reconnect", vec![]).await {
|
||||||
|
e!("Failed to trigger reconnect: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
e!("DarkIrc plugin has not been loaded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msleep(200).await;
|
||||||
|
|
||||||
|
// Hide netstat-klik icon
|
||||||
|
{
|
||||||
|
let atom = &mut render_api.make_guard(gfxtag!("netstat_klik_hide"));
|
||||||
|
if let Err(e) = netstat_klik.set_property_bool(atom, Role::App, "is_visible", false)
|
||||||
|
{
|
||||||
|
e!("Failed to hide netstat_klik: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
app.tasks.lock().unwrap().push(reconnect_task);
|
||||||
|
|
||||||
|
let node = node.setup(Button::new).await;
|
||||||
|
netlayer_node.link(node);
|
||||||
|
|
||||||
// Navbar Settings Button
|
// Navbar Settings Button
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -517,6 +517,33 @@ impl DarkIrc {
|
|||||||
self_.settings.update_p2p_settings(&mut write_guard);
|
self_.settings.update_p2p_settings(&mut write_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn process_reconnect(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
|
||||||
|
let Ok(method_call) = sub.receive().await else {
|
||||||
|
d!("Reconnect method closed");
|
||||||
|
return false
|
||||||
|
};
|
||||||
|
|
||||||
|
t!("method called: reconnect({method_call:?})");
|
||||||
|
|
||||||
|
let Some(self_) = me.upgrade() else {
|
||||||
|
e!("DarkIrc destroyed before reconnect completed");
|
||||||
|
return false
|
||||||
|
};
|
||||||
|
|
||||||
|
i!("Manual P2P reconnection triggered");
|
||||||
|
self_.p2p.clone().stop().await;
|
||||||
|
|
||||||
|
while let Err(err) = self_.p2p.clone().start().await {
|
||||||
|
e!("Failed to start P2P network: {err}!");
|
||||||
|
e!("Retrying in {P2P_RETRY_TIME} secs");
|
||||||
|
sleep(P2P_RETRY_TIME).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
i!("P2P reconnection completed");
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
async fn start(self: Arc<Self>, sg_root: SceneNodePtr, ex: ExecutorPtr) {
|
async fn start(self: Arc<Self>, sg_root: SceneNodePtr, ex: ExecutorPtr) {
|
||||||
i!("Registering EventGraph P2P protocol");
|
i!("Registering EventGraph P2P protocol");
|
||||||
let event_graph_ = Arc::clone(&self.event_graph);
|
let event_graph_ = Arc::clone(&self.event_graph);
|
||||||
@@ -537,6 +564,13 @@ impl DarkIrc {
|
|||||||
let send_method_task =
|
let send_method_task =
|
||||||
ex.spawn(async move { while Self::process_send(&me2, &method_sub).await {} });
|
ex.spawn(async move { while Self::process_send(&me2, &method_sub).await {} });
|
||||||
|
|
||||||
|
let reconnect_method_sub = node.subscribe_method_call("reconnect").unwrap();
|
||||||
|
let me2 = me.clone();
|
||||||
|
let reconnect_method_task =
|
||||||
|
ex.spawn(
|
||||||
|
async move { while Self::process_reconnect(&me2, &reconnect_method_sub).await {} },
|
||||||
|
);
|
||||||
|
|
||||||
let mut on_modify = OnModify::new(ex.clone(), self.node.clone(), me.clone());
|
let mut on_modify = OnModify::new(ex.clone(), self.node.clone(), me.clone());
|
||||||
async fn save_nick(self_: Arc<DarkIrc>, _batch: BatchGuardPtr) {
|
async fn save_nick(self_: Arc<DarkIrc>, _batch: BatchGuardPtr) {
|
||||||
let _ = std::fs::write(nick_filename(), self_.nick.get());
|
let _ = std::fs::write(nick_filename(), self_.nick.get());
|
||||||
@@ -583,7 +617,8 @@ impl DarkIrc {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut tasks = vec![send_method_task, ev_task, dag_task, start_task, stop_task];
|
let mut tasks =
|
||||||
|
vec![send_method_task, reconnect_method_task, ev_task, dag_task, start_task, stop_task];
|
||||||
tasks.append(&mut on_modify.tasks);
|
tasks.append(&mut on_modify.tasks);
|
||||||
self.tasks.set(tasks).unwrap();
|
self.tasks.set(tasks).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user