RelayEntry: Add relay status symbol before title and display timeout in tooltip if any [L6]

This commit is contained in:
Bu5hm4nn 2023-08-09 18:04:13 -10:00
parent 363e8b55df
commit bd4ea9fc76
4 changed files with 72 additions and 55 deletions

View File

@ -7,9 +7,8 @@ use crate::ui::widgets;
use crate::comms::ToOverlordMessage;
use eframe::egui;
use egui::{Context, Ui};
use egui_extras::{TableBuilder, Column};
use egui_winit::egui::Id;
use nostr_types::{RelayUrl, Unixtime};
use nostr_types::RelayUrl;
pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) {
let is_editing = app.relays.edit.is_some();
@ -49,45 +48,6 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
ui.label("All followed people are fully covered.".to_owned());
}
{ // penalty box
ui.add_space(10.0);
ui.heading("Penalty Box");
ui.add_space(10.0);
let now = Unixtime::now().unwrap().0;
let excluded: Vec<(String, i64)> = GLOBALS.relay_picker.excluded_relays_iter().map(|refmulti| {
(refmulti.key().as_str().to_owned(),
*refmulti.value() - now)
}).collect();
let awidth = ui.available_size_before_wrap().x - 20.0;
TableBuilder::new(ui)
.striped(true)
.column(Column::auto().at_least(awidth * 0.7))
.column(Column::auto().at_least(awidth * 0.3))
.header(20.0, |mut header| {
header.col(|ui| {
ui.heading("Relay URL");
});
header.col(|ui| {
ui.heading("Time Remaining");
});
})
.body(|body| {
body.rows(24.0, excluded.len(), |row_index, mut row| {
let data = &excluded[row_index];
row.col(|ui| {
widgets::break_anywhere_label(ui, &data.0);
});
row.col(|ui| {
ui.label(format!("{}", data.1));
});
});
});
}
ui.add_space(10.0);
ui.separator();
ui.add_space(10.0);
@ -119,12 +79,17 @@ fn get_relays(app: &mut GossipUi) -> Vec<DbRelay> {
.map(|r| r.key().clone())
.collect();
let timeout_relays: HashSet<RelayUrl> = GLOBALS.relay_picker.excluded_relays_iter()
.map(|r| r.key().clone()).collect();
let mut relays: Vec<DbRelay> = GLOBALS
.all_relays
.iter()
.map(|ri| ri.value().clone())
.filter(|ri| connected_relays.contains(&ri.url) && super::filter_relay(&app.relays, ri))
.collect();
.filter(|ri| {
(connected_relays.contains(&ri.url) || timeout_relays.contains(&ri.url))
&& super::filter_relay(&app.relays, ri)
}).collect();
relays.sort_by(|a, b| super::sort_relay(&app.relays, a, b));
relays

View File

@ -177,12 +177,17 @@ pub(super) fn relay_scroll_list(app: &mut GossipUi, ui: &mut Ui, relays: Vec<DbR
(false, "".into())
};
// get timeout if any
let timeout_until = GLOBALS.relay_picker.excluded_relays_iter()
.find(|p| p.key() == &db_url ).map(|f| *f.value());
let enabled = edit || !is_editing;
let mut widget = RelayEntry::new(db_relay, app);
widget.set_edit(edit);
widget.set_detail(app.relays.show_details);
widget.set_enabled(enabled);
widget.set_connected(is_connected);
widget.set_timeout(timeout_until);
widget.set_reasons(reasons);
if let Some(ref assignment) = GLOBALS.relay_picker.get_relay_assignment(&db_url) {
widget.set_user_count(assignment.pubkeys.len());

View File

@ -11,17 +11,17 @@ use eframe::egui::widgets::TextEdit;
use eframe::egui::{FontSelection, Ui, WidgetText};
use egui_winit::egui::{vec2, Rect, Response, Sense};
pub fn break_anywhere_label(ui: &mut Ui, text: impl Into<WidgetText>) {
let mut job = text.into().into_text_job(
ui.style(),
FontSelection::Default,
ui.layout().vertical_align(),
);
job.job.sections.first_mut().unwrap().format.color =
ui.style().visuals.widgets.noninteractive.fg_stroke.color;
job.job.wrap.break_anywhere = true;
ui.label(job.job);
}
// pub fn break_anywhere_label(ui: &mut Ui, text: impl Into<WidgetText>) {
// let mut job = text.into().into_text_job(
// ui.style(),
// FontSelection::Default,
// ui.layout().vertical_align(),
// );
// job.job.sections.first_mut().unwrap().format.color =
// ui.style().visuals.widgets.noninteractive.fg_stroke.color;
// job.job.wrap.break_anywhere = true;
// ui.label(job.job);
// }
pub fn break_anywhere_hyperlink_to(ui: &mut Ui, text: impl Into<WidgetText>, url: impl ToString) {
let mut job = text.into().into_text_job(

View File

@ -55,6 +55,10 @@ const USAGE_LINE_THICKNESS: f32 = 1.0;
const NIP11_Y_SPACING: f32 = 20.0;
/// Copy symbol for nip11 items copy button
const COPY_SYMBOL: &str = "\u{2398}";
/// Status symbol for status color indicator
const STATUS_SYMBOL: &str = "\u{25CF}";
/// Space reserved for status symbol before title
const STATUS_SYMBOL_SPACE: f32 = 18.0;
/// Max length of title string
const TITLE_MAX_LEN: usize = 50;
/// First stat column x location
@ -140,6 +144,7 @@ pub struct RelayEntry {
view: RelayEntryView,
enabled: bool,
connected: bool,
timeout_until: Option<i64>,
reasons: String,
user_count: Option<usize>,
usage: UsageBits,
@ -161,6 +166,7 @@ impl RelayEntry {
view: RelayEntryView::List,
enabled: true,
connected: false,
timeout_until: None,
reasons: "".into(),
user_count: None,
usage,
@ -205,6 +211,10 @@ impl RelayEntry {
self.connected = connected;
}
pub fn set_timeout(&mut self, timeout_until: Option<i64>) {
self.timeout_until = timeout_until;
}
pub fn set_reasons(&mut self, reasons: String) {
self.reasons = reasons;
}
@ -245,7 +255,7 @@ impl RelayEntry {
title.push('\u{2026}'); // append ellipsis
}
let text = RichText::new(title).size(16.5);
let pos = rect.min + vec2(TEXT_LEFT, TEXT_TOP);
let pos = rect.min + vec2(TEXT_LEFT + STATUS_SYMBOL_SPACE, TEXT_TOP);
let rect = draw_text_at(
ui,
pos,
@ -255,6 +265,43 @@ impl RelayEntry {
None,
);
ui.interact(rect, ui.next_auto_id(), Sense::hover()).on_hover_text(self.db_relay.url.as_str());
// paint status indicator
// green - connected
// gray - disconnected
// orange - penalty box
let text = RichText::new(STATUS_SYMBOL).size(15.0);
let color = if self.connected {
egui::Color32::from_rgb(0x63, 0xc8, 0x56) // green
} else {
if self.db_relay.rank == 0 {
egui::Color32::from_rgb(0xed, 0x6a, 0x5e) // red
} else {
if self.timeout_until.is_some() {
egui::Color32::from_rgb(0xf4, 0xbf, 0x4f) // orange
} else {
egui::Color32::GRAY
}
}
};
let pos = pos + vec2(-STATUS_SYMBOL_SPACE, 0.0);
let rect = draw_text_at(
ui,
pos,
text.into(),
Align::LEFT,
Some(color),
None
);
// show remaining time on timeout
if let Some(timeout) = self.timeout_until {
if let Ok(now) = Unixtime::now() {
let remain = timeout - now.0;
let text = format!("retry in {} seconds", remain);
ui.interact(rect, ui.next_auto_id(), Sense::hover()).on_hover_text(text);
}
}
}
fn paint_frame(&self, ui: &mut Ui, rect: &Rect) {