use super::{
planes::{ReconstructedPlanesInput, apply_reconstructed_planes},
shared::{catalogue_material_guess, format_optional_proportion, sides_from_angle_sequence},
};
use crate::{
AngleItem, DiagramDetailData, FileItem, LibraryModel, MainWindow, TiltModel, ViewportModel,
bridge::{library::source as library_source, render_thread::RenderContext},
gui::{
render::camera_lighting::resubmit_live_solid,
solid_preview::preview_state::SolidPreviewState,
},
settings::WorkerSettings,
};
use indicatrix_net::library::{DesignRecord, LibraryRequest, LibraryResponse};
use slint::{ComponentHandle, ModelRc, VecModel};
use std::sync::{Arc, Mutex};
use tracing::error;
pub(super) fn load_diagram_detail_remote(
ui: &MainWindow,
worker: WorkerSettings,
render_ctx: &Arc<Mutex<RenderContext>>,
entry_id: i64,
preview_state: &Arc<SolidPreviewState>,
) {
let render_ctx = render_ctx.clone();
let preview_state = Arc::clone(preview_state);
library_source::spawn_library_request(
ui.as_weak(),
worker,
LibraryRequest::FetchDesign { entry_id },
move |ui, result| match result {
Ok(LibraryResponse::Design(record)) => {
apply_design_record_to_ui(ui, &render_ctx, &record, &preview_state);
}
Ok(LibraryResponse::NotFound) => {
ui.global::<LibraryModel>()
.set_status_message("Diagram detail not found on the remote library.".into());
}
Ok(_) => {
ui.global::<LibraryModel>()
.set_status_message("Unexpected reply fetching remote diagram detail.".into());
}
Err(e) => {
error!("Remote FetchDesign failed: {e}");
ui.global::<LibraryModel>()
.set_status_message(format!("Error loading remote detail: {e}").into());
}
},
);
}
fn apply_design_record_to_ui(
ui: &MainWindow,
render_ctx: &Arc<Mutex<RenderContext>>,
record: &DesignRecord,
preview_state: &Arc<SolidPreviewState>,
) {
let is_local = record.url.starts_with("local://");
let detail_data = DiagramDetailData {
id: record.entry_id as i32,
title: record.title.clone().into(),
url: record.url.clone().into(),
designer: record.designer_info.clone().unwrap_or_default().into(),
shape: record.shape.clone().unwrap_or_default().into(),
gear: record.index_gear.clone().unwrap_or_default().into(),
facets: record.facets_count.clone().unwrap_or_default().into(),
lw_ratio: format_optional_proportion(record.lw_ratio.as_deref()).into(),
material_guess: catalogue_material_guess(record.refractive_index.as_deref()).into(),
ri: record.refractive_index.clone().unwrap_or_default().into(),
volume: format_optional_proportion(record.volume.as_deref()).into(),
competition: record
.competition_diagram
.clone()
.unwrap_or_default()
.into(),
image_name: record.diagram_image_name.clone().unwrap_or_default().into(),
has_image: record.diagram_image_data.is_some(),
is_local,
hw_ratio: format_optional_proportion(record.hw_ratio.as_deref()).into(),
cw_ratio: format_optional_proportion(record.cw_ratio.as_deref()).into(),
pw_ratio: format_optional_proportion(record.pw_ratio.as_deref()).into(),
symmetry_order: record.symmetry_order.clone().unwrap_or_default().into(),
mirror_symmetry: record.mirror_symmetry.unwrap_or(false),
};
ui.global::<LibraryModel>().set_current_detail(detail_data);
ui.global::<TiltModel>()
.set_cached_curve_material(record.preview_material.clone().unwrap_or_default().into());
let sides = sides_from_angle_sequence(record.angle_settings.iter().map(|a| a.angle.as_str()));
let angle_items: Vec<AngleItem> = record
.angle_settings
.iter()
.zip(sides)
.map(|(a, side)| AngleItem {
order_idx: a.order_index as i32,
side,
facet: a.facet.clone().into(),
angle: a.angle.clone().into(),
index_val: a.index.clone().into(),
notes: a.notes.clone().into(),
})
.collect();
ui.global::<LibraryModel>()
.set_current_angles(ModelRc::new(VecModel::from(angle_items.clone())));
let file_items: Vec<FileItem> = record
.attachments
.iter()
.map(|f| {
let size_kb = f.size as f64 / 1024.0;
FileItem {
name: f.name.clone().into(),
url: f.url.clone().into(),
size_str: format!("{size_kb:.1} KB").into(),
}
})
.collect();
ui.global::<LibraryModel>()
.set_current_files(ModelRc::new(VecModel::from(file_items)));
ui.global::<LibraryModel>()
.set_selected_entry_id(record.entry_id as i32);
apply_reconstructed_planes(
ui,
render_ctx,
record.entry_id,
ReconstructedPlanesInput {
shape: record.shape.as_deref(),
index_gear: record.index_gear.as_deref(),
angle_items: &angle_items,
refractive_index: record.refractive_index.as_deref(),
preview_material: record.preview_material.as_deref(),
real_design: None,
},
);
if ui.get_render_view_tab() == 0 && ui.global::<ViewportModel>().get_live_view_mode() == 0 {
let ctx = render_ctx
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
resubmit_live_solid(ui, &ctx, preview_state);
}
}