use anyhow::Result;
use super::App;
use crate::db::Session;
impl App {
pub fn activate_notification(&mut self, index: usize) -> Result<()> {
let Some(notification) = self.notifications.remove(index) else {
return Ok(());
};
self.switch_to_session_by_id(¬ification.session_id)
}
pub fn new_session(&mut self) {
self.session = None;
self.messages.clear();
self.context_total = None;
self.push_viewport_reset();
self.cleanup_incognito_images();
self.push_status("new chat — send a message to start it".to_string());
}
pub fn switch_to_session_by_id(&mut self, id: &str) -> Result<()> {
let Some(s) = self
.db
.get_session(id)?
.or_else(|| self.sessions_cache.iter().find(|s| s.id == id).cloned())
else {
self.push_status(format!("session not found: {id}"));
return Ok(());
};
self.messages = self.db.load_messages(&s.id)?;
self.unread.remove(&s.id);
self.notifications.retain(|n| n.session_id != s.id);
self.push_status(format!("switched to: {}", s.title));
self.current_model = Some(s.model.clone());
self.web_mode = s.web_mode;
self.session = Some(s);
self.backfill_compaction_row();
self.restore_survey_gate_prompt();
self.refresh_toolbox();
self.context_total = None;
self.push_viewport_reset();
self.cleanup_incognito_images();
self.maybe_compact();
Ok(())
}
}
pub fn session_score(s: &Session, needle: &str) -> Option<i32> {
use crate::app::fuzzy_score;
let mut best = fuzzy_score(&s.title, needle);
let upd = |best: &mut Option<i32>, cand: Option<i32>| {
if let Some(c) = cand {
*best = Some(best.map_or(c, |b| b.max(c)));
}
};
if let Some(slug) = &s.slug {
upd(&mut best, fuzzy_score(slug, needle).map(|v| v + 2));
}
upd(&mut best, fuzzy_score(&s.id, needle));
best
}
pub fn parse_topic(text: &str) -> Option<(String, String)> {
let start = text.find('{')?;
let end = text.rfind('}')?;
let json = text.get(start..=end)?;
let v: serde_json::Value = serde_json::from_str(json).ok()?;
let topic = v.get("topic").and_then(|t| t.as_str())?.trim();
if topic.is_empty() {
return None;
}
let raw_slug = v.get("id").and_then(|s| s.as_str()).unwrap_or(topic);
Some((topic.to_string(), slugify(raw_slug)))
}
pub fn slugify(s: &str) -> String {
let slug = s
.to_lowercase()
.split(|c: char| !c.is_ascii_alphanumeric())
.filter(|w| !w.is_empty())
.take(5)
.collect::<Vec<_>>()
.join("-");
if slug.is_empty() {
"chat".to_string()
} else {
slug
}
}