use super::{
dispatch::{bump_search_seq, is_current_search},
fetch::to_diagram_item,
filters::{read_range_filter, read_sort_order, read_tag_filter},
};
use crate::{
DiagramItem, LibraryModel, MainWindow, bridge::library::source as library_source,
settings::WorkerSettings,
};
use indicatrix_net::library::{
LibraryRequest, LibraryResponse, PerformanceAggregateWire, PerformanceBoundWire,
PerformanceFilterWire, PerformanceMetricWire, RangeFilterWire, SortOrderWire,
};
use indicatrix_vault::{
db::sqlite::SortOrder,
model::{
filter::RangeFilter,
performance::{
PerformanceAggregate, PerformanceBound, PerformanceFilter, PerformanceMetric,
},
},
};
use slint::{ComponentHandle, ModelRc, VecModel};
use tracing::error;
pub(in crate::gui) fn refresh_diagram_list_remote(
ui: &MainWindow,
worker: WorkerSettings,
search: &str,
shape_filter: &str,
gear_filter: &str,
) {
let seq = bump_search_seq();
let clean_shape = if shape_filter == "All Shapes" {
"All".to_string()
} else {
shape_filter.to_string()
};
let clean_gear = if gear_filter == "All Gears" {
"All".to_string()
} else {
gear_filter.to_string()
};
let range = to_range_wire(&read_range_filter(ui));
let request = LibraryRequest::Search {
query: search.to_string(),
shape_filter: clean_shape,
gear_filter: clean_gear,
range,
order: to_sort_order_wire(read_sort_order(ui)),
tag_filter: read_tag_filter(ui),
};
library_source::spawn_library_request(ui.as_weak(), worker, request, move |ui, result| {
if !is_current_search(seq) {
return;
}
match result {
Ok(LibraryResponse::SearchResults {
items,
excluded_for_missing_curves,
}) => {
let total = items.len();
let slint_items: Vec<DiagramItem> = items.iter().map(to_diagram_item).collect();
ui.global::<LibraryModel>()
.set_diagram_list(ModelRc::new(VecModel::from(slint_items)));
ui.global::<LibraryModel>().set_total_count(total as i32);
ui.global::<LibraryModel>().set_matched_count(total as i32);
ui.global::<LibraryModel>()
.set_performance_excluded_count(excluded_for_missing_curves as i32);
}
Ok(_) => {
ui.global::<LibraryModel>()
.set_status_message("Unexpected reply searching the remote library.".into());
}
Err(e) => {
error!("Remote search failed: {e}");
ui.global::<LibraryModel>()
.set_status_message(format!("Remote search failed: {e}").into());
}
}
});
}
fn to_range_wire(range: &RangeFilter) -> RangeFilterWire {
RangeFilterWire {
ri_min: range.ri_min,
ri_max: range.ri_max,
lw_min: range.lw_min,
lw_max: range.lw_max,
volume_min: range.volume_min,
volume_max: range.volume_max,
facets_min: range.facets_min,
facets_max: range.facets_max,
ri_tolerance: range.ri_tolerance,
include_ignored: range.include_ignored,
performance: range
.performance
.iter()
.map(to_performance_filter_wire)
.collect(),
}
}
const fn to_sort_order_wire(order: SortOrder) -> SortOrderWire {
match order {
SortOrder::CatalogueOrder => SortOrderWire::CatalogueOrder,
SortOrder::Title => SortOrderWire::Title,
SortOrder::Newest => SortOrderWire::Newest,
SortOrder::RecentlyEdited => SortOrderWire::RecentlyEdited,
}
}
const fn to_performance_filter_wire(filter: &PerformanceFilter) -> PerformanceFilterWire {
let metric = match filter.metric {
PerformanceMetric::Brilliance => PerformanceMetricWire::Brilliance,
PerformanceMetric::Extinction => PerformanceMetricWire::Extinction,
PerformanceMetric::Windowing => PerformanceMetricWire::Windowing,
};
let bound = match filter.bound {
PerformanceBound::AtMost(t) => PerformanceBoundWire::AtMost(t),
PerformanceBound::AtLeast(t) => PerformanceBoundWire::AtLeast(t),
};
let aggregate = match filter.aggregate {
PerformanceAggregate::Worst => PerformanceAggregateWire::Worst,
PerformanceAggregate::Mean => PerformanceAggregateWire::Mean,
};
PerformanceFilterWire {
metric,
bound,
tilt_radius_deg: filter.tilt_radius_deg,
aggregate,
}
}