mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-29 16:31:18 +00:00
RelayEntry: Add relay status symbol before title and display timeout in tooltip if any [L6]
This commit is contained in:
parent
363e8b55df
commit
bd4ea9fc76
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user