use crate::*;
#[component]
pub(crate) fn vconsole_panel(node: VirtualNode<VconsolePanelProps>) -> VirtualNode {
let VconsolePanelProps { panel_open } = node.try_get_props().unwrap_or_default();
let console_signal: Signal<Vec<ConsoleEntry>> = get_console_signal();
let log_count: usize = console_signal.get().len();
html! {
vconsole_fab {
panel_open: panel_open
log_count: log_count
}
vconsole_drawer {
console_signal: console_signal
panel_open: panel_open
log_count: log_count
}
}
}
#[component]
pub(crate) fn vconsole_fab(node: VirtualNode<VconsoleFabProps>) -> VirtualNode {
let VconsoleFabProps {
panel_open,
log_count,
} = node.try_get_props().unwrap_or_default();
let is_open: bool = panel_open.get();
if is_open {
return html! {
div {
class: c_vconsole_fab_hidden()
}
};
}
let fab_on_click: Option<Rc<dyn Fn(Event)>> = Some(Rc::new(move |_event: Event| {
push_state_on_open();
panel_open.set(true);
}));
if log_count > 0 {
let badge_display: String = if log_count > 99 {
"99+".to_string()
} else {
log_count.to_string()
};
html! {
logo_button {
variant: LogoButtonVariant::Fab
on_click: fab_on_click
span {
class: c_vconsole_badge()
badge_display
}
}
}
} else {
html! {
logo_button {
variant: LogoButtonVariant::Fab
on_click: fab_on_click
}
}
}
}
#[component]
pub(crate) fn vconsole_drawer(node: VirtualNode<VconsoleDrawerProps>) -> VirtualNode {
let VconsoleDrawerProps {
console_signal,
panel_open,
log_count,
} = node.try_get_props().unwrap_or_default();
let filter_signal: Signal<LogFilter> = use_signal(|| LogFilter::All);
let is_open: bool = panel_open.get();
let overlay_class: String = if is_open {
c_vconsole_overlay().get_name().to_string()
} else {
format!(
"{} {}",
c_vconsole_overlay().get_name(),
c_vconsole_overlay_hidden().get_name()
)
};
let panel_class: String = if is_open {
c_vconsole_panel().get_name().to_string()
} else {
format!(
"{} {}",
c_vconsole_panel().get_name(),
c_vconsole_panel_closed().get_name()
)
};
html! {
div {
div {
class: overlay_class
onclick: move |_event: Event| {
back_on_close();
panel_open.set(false);
}
}
div {
class: panel_class
div {
class: c_vconsole_header()
h3 {
class: c_vconsole_title()
span {
class: c_vconsole_title_dot()
}
"Console"
span {
class: c_vconsole_count()
format!(" ({log_count})")
}
}
div {
class: c_vconsole_header_actions()
button {
class: c_vconsole_clear_button()
onclick: move |_event: Event| {
Console::clear();
}
"Clear"
}
button {
class: c_vconsole_close_button()
onclick: move |_event: Event| {
back_on_close();
panel_open.set(false);
}
"×"
}
}
}
div {
class: c_vconsole_filter_bar()
button {
class: if { filter_signal.get() == LogFilter::All } { c_vconsole_filter_active() } else { c_vconsole_filter_button() }
onclick: move |_event: Event| {
filter_signal.set(LogFilter::All);
}
LogFilter::All.to_string()
}
button {
class: if { filter_signal.get() == LogFilter::Log } { c_vconsole_filter_active_log() } else { c_vconsole_filter_button() }
onclick: move |_event: Event| {
filter_signal.set(LogFilter::Log);
}
LogFilter::Log.to_string()
}
button {
class: if { filter_signal.get() == LogFilter::Warn } { c_vconsole_filter_active_warn() } else { c_vconsole_filter_button() }
onclick: move |_event: Event| {
filter_signal.set(LogFilter::Warn);
}
LogFilter::Warn.to_string()
}
button {
class: if { filter_signal.get() == LogFilter::Error } { c_vconsole_filter_active_error() } else { c_vconsole_filter_button() }
onclick: move |_event: Event| {
filter_signal.set(LogFilter::Error);
}
LogFilter::Error.to_string()
}
}
div {
class: c_vconsole_body()
build_vconsole_log_nodes(console_signal, filter_signal)
}
}
}
}
}
fn build_vconsole_log_nodes(
logs: Signal<Vec<ConsoleEntry>>,
filter: Signal<LogFilter>,
) -> VirtualNode {
let filtered: Vec<(usize, ConsoleEntry)> = filter_console_entries(logs, filter);
if filtered.is_empty() {
return html! {
div {
class: c_vconsole_empty()
"No logs yet."
}
};
}
html! {
for (index, entry) in {&filtered} {
div {
key: index.to_string()
class: get_log_item_class(entry.get_level())
span {
class: get_badge_class(entry.get_level())
get_log_level_badge(entry.get_level())
}
entry.get_message().clone()
}
}
}
}