use std::sync::Arc;
use kimun_core::NoteVault;
use crate::app_screen::panel_set::PanelSet;
use crate::components::drawer::DrawerView;
use crate::components::events::{AppTx, AskData};
use crate::rag::RagStatus;
use crate::settings::SharedSettings;
pub struct AskCoordinator {
settings: SharedSettings,
vault: Arc<NoteVault>,
last_synced_turn: Option<u64>,
}
impl AskCoordinator {
pub fn new(settings: SharedSettings, vault: Arc<NoteVault>) -> Self {
Self {
settings,
vault,
last_synced_turn: None,
}
}
pub fn transition(&mut self, panels: &mut PanelSet, target: DrawerView, tx: &AppTx) {
let showing = panels.is_showing_ask();
if target == DrawerView::Ask && !showing {
panels.show_ask();
self.sync_sources_from_selected(panels, tx);
} else if target != DrawerView::Ask && showing {
panels.hide_ask();
}
}
pub fn hide_if_shown(&mut self, panels: &mut PanelSet) {
if panels.is_showing_ask() {
panels.hide_ask();
panels.switch_drawer_view(DrawerView::Files);
self.last_synced_turn = None;
}
}
pub async fn refresh_capability(&self, panels: &mut PanelSet, rag_status: RagStatus) {
let client = if rag_status.llm_available() {
crate::rag::rag_client(&self.settings, &self.vault)
.await
.map(Arc::new)
} else {
None
};
panels.set_ask_client(client);
}
pub fn handle_data(&self, panels: &mut PanelSet, data: AskData, tx: &AppTx) {
match &data {
AskData::AnswerReady { turn_id, .. } => {
let turn_id = *turn_id;
panels.ask_mut().handle_data(data);
if panels.is_showing_ask() {
let panel = panels.ask_mut();
let selected = panel.thread().selected().map(|t| t.id);
if selected == Some(turn_id) {
let sources = panel
.thread()
.turns()
.iter()
.find(|t| t.id == turn_id)
.map(|t| t.sources.clone())
.unwrap_or_default();
panels.ask_sources_mut().refresh(turn_id, sources, tx);
}
}
}
AskData::ReaderNote { .. } => {
panels.ask_sources_mut().handle_data(data);
}
}
}
pub fn sync_sources(&mut self, panels: &mut PanelSet, tx: &AppTx) {
if !panels.is_showing_ask() {
return;
}
let (selected, citation) = {
let panel = panels.ask_mut();
(
panel.thread().selected().map(|t| t.id),
panel.take_citation_target(),
)
};
if selected.is_some() && selected != self.last_synced_turn {
self.sync_sources_from_selected(panels, tx);
}
if let Some(ordinal) = citation {
panels.ask_sources_mut().focus_source(ordinal);
}
}
pub fn sync_sources_from_selected(&mut self, panels: &mut PanelSet, tx: &AppTx) {
let selected = panels
.ask_mut()
.thread()
.selected()
.map(|t| (t.id, t.sources.clone()));
if let Some((id, sources)) = selected {
panels.ask_sources_mut().set_turn(id, sources, tx);
self.last_synced_turn = Some(id);
}
}
}