mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -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/>.
|
||||
*/
|
||||
|
||||
use darkfi::system::msleep;
|
||||
use darkfi_serial::Encodable;
|
||||
use indoc::indoc;
|
||||
use sled_overlay::sled;
|
||||
@@ -23,7 +24,7 @@ use std::fs::File;
|
||||
|
||||
use crate::{
|
||||
app::{
|
||||
node::{create_layer, create_shortcut, create_vector_art, create_video},
|
||||
node::{create_button, create_layer, create_shortcut, create_vector_art, create_video},
|
||||
App,
|
||||
},
|
||||
expr::{self, Compiler},
|
||||
@@ -31,7 +32,7 @@ use crate::{
|
||||
prop::{PropertyAtomicGuard, Role},
|
||||
scene::{SceneNodePtr, Slot},
|
||||
shape,
|
||||
ui::{emoji_picker, Layer, Shortcut, VectorArt, VectorShape, Video},
|
||||
ui::{emoji_picker, Button, Layer, ShapeVertex, Shortcut, VectorArt, VectorShape, Video},
|
||||
util::{i18n::I18nBabelFish, spawn_thread},
|
||||
};
|
||||
|
||||
@@ -40,6 +41,9 @@ mod menu;
|
||||
//mod settings;
|
||||
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::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;
|
||||
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
|
||||
|
||||
/*
|
||||
|
||||
@@ -517,6 +517,33 @@ impl DarkIrc {
|
||||
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) {
|
||||
i!("Registering EventGraph P2P protocol");
|
||||
let event_graph_ = Arc::clone(&self.event_graph);
|
||||
@@ -537,6 +564,13 @@ impl DarkIrc {
|
||||
let send_method_task =
|
||||
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());
|
||||
async fn save_nick(self_: Arc<DarkIrc>, _batch: BatchGuardPtr) {
|
||||
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);
|
||||
self.tasks.set(tasks).unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user