use super::*;
impl App {
pub(crate) fn main_proxy_action(&self, data: &UiData) -> Action {
let Some(current_app_routed) = data.proxy.routes_current_app_through_proxy(&self.app_type)
else {
return Action::None;
};
if data.proxy.running && !data.proxy.managed_runtime && !current_app_routed {
return Action::None;
}
Action::SetManagedProxyForCurrentApp {
app_type: self.app_type.clone(),
enabled: !current_app_routed,
}
}
pub(crate) fn on_skills_installed_key(&mut self, key: KeyEvent, data: &UiData) -> Action {
let visible = visible_skills_installed(&self.filter, data);
match key.code {
KeyCode::Up => {
self.skills_idx = self.skills_idx.saturating_sub(1);
Action::None
}
KeyCode::Down => {
if !visible.is_empty() {
self.skills_idx = (self.skills_idx + 1).min(visible.len() - 1);
}
Action::None
}
KeyCode::Enter => {
let Some(skill) = visible.get(self.skills_idx) else {
return Action::None;
};
self.push_route_and_switch(Route::SkillDetail {
directory: skill.directory.clone(),
})
}
KeyCode::Char('x') | KeyCode::Char(' ') => {
let Some(skill) = visible.get(self.skills_idx) else {
return Action::None;
};
let enabled = !skill.apps.is_enabled_for(&self.app_type);
Action::SkillsToggle {
directory: skill.directory.clone(),
enabled,
}
}
KeyCode::Char('m') => {
let Some(skill) = visible.get(self.skills_idx) else {
return Action::None;
};
self.overlay = Overlay::SkillsAppsPicker {
directory: skill.directory.clone(),
name: skill.name.clone(),
selected: four_app_picker_index(&self.app_type),
apps: skill.apps.clone(),
};
Action::None
}
KeyCode::Char('d') => {
let Some(skill) = visible.get(self.skills_idx) else {
return Action::None;
};
self.overlay = Overlay::Confirm(ConfirmOverlay {
title: texts::tui_skills_uninstall_title().to_string(),
message: texts::tui_confirm_uninstall_skill_message(
&skill.name,
&skill.directory,
),
action: ConfirmAction::SkillsUninstall {
directory: skill.directory.clone(),
},
});
Action::None
}
KeyCode::Char('i') => Action::SkillsOpenImport,
KeyCode::Char('f') => self.push_route_and_switch(Route::SkillsDiscover),
_ => Action::None,
}
}
pub(crate) fn on_skills_discover_key(&mut self, key: KeyEvent) -> Action {
match key.code {
KeyCode::Up => {
self.skills_discover_idx = self.skills_discover_idx.saturating_sub(1);
Action::None
}
KeyCode::Down => {
let visible = visible_skills_discover(&self.filter, &self.skills_discover_results);
if !visible.is_empty() {
self.skills_discover_idx =
(self.skills_discover_idx + 1).min(visible.len() - 1);
}
Action::None
}
KeyCode::Char('f') => {
self.overlay = Overlay::TextInput(TextInputState {
title: texts::tui_skills_discover_title().to_string(),
prompt: texts::tui_skills_discover_prompt().to_string(),
buffer: self.skills_discover_query.clone(),
submit: TextSubmit::SkillsDiscoverQuery,
secret: false,
});
Action::None
}
KeyCode::Enter => {
let visible = visible_skills_discover(&self.filter, &self.skills_discover_results);
let Some(skill) = visible.get(self.skills_discover_idx) else {
return Action::None;
};
if skill.installed {
self.push_toast(texts::tui_toast_skill_already_installed(), ToastKind::Info);
return Action::None;
}
Action::SkillsInstall {
spec: skill.key.clone(),
}
}
KeyCode::Char('r') => self.push_route_and_switch(Route::SkillsRepos),
_ => Action::None,
}
}
pub(crate) fn on_skills_repos_key(&mut self, key: KeyEvent, data: &UiData) -> Action {
let visible = visible_skills_repos(&self.filter, data);
match key.code {
KeyCode::Up => {
self.skills_repo_idx = self.skills_repo_idx.saturating_sub(1);
Action::None
}
KeyCode::Down => {
if !visible.is_empty() {
self.skills_repo_idx = (self.skills_repo_idx + 1).min(visible.len() - 1);
}
Action::None
}
KeyCode::Char('a') => {
self.overlay = Overlay::TextInput(TextInputState {
title: texts::tui_skills_repos_add_title().to_string(),
prompt: texts::tui_skills_repos_add_prompt().to_string(),
buffer: String::new(),
submit: TextSubmit::SkillsRepoAdd,
secret: false,
});
Action::None
}
KeyCode::Char('d') => {
let Some(repo) = visible.get(self.skills_repo_idx) else {
return Action::None;
};
self.overlay = Overlay::Confirm(ConfirmOverlay {
title: texts::tui_skills_repos_remove_title().to_string(),
message: texts::tui_confirm_remove_repo_message(&repo.owner, &repo.name),
action: ConfirmAction::SkillsRepoRemove {
owner: repo.owner.clone(),
name: repo.name.clone(),
},
});
Action::None
}
KeyCode::Char('x') | KeyCode::Char(' ') => {
let Some(repo) = visible.get(self.skills_repo_idx) else {
return Action::None;
};
Action::SkillsRepoToggleEnabled {
owner: repo.owner.clone(),
name: repo.name.clone(),
enabled: !repo.enabled,
}
}
_ => Action::None,
}
}
pub(crate) fn on_skill_detail_key(
&mut self,
key: KeyEvent,
data: &UiData,
directory: &str,
) -> Action {
let Some(skill) = data
.skills
.installed
.iter()
.find(|s| s.directory.eq_ignore_ascii_case(directory))
else {
return Action::None;
};
match key.code {
KeyCode::Char('x') | KeyCode::Char(' ') => Action::SkillsToggle {
directory: skill.directory.clone(),
enabled: !skill.apps.is_enabled_for(&self.app_type),
},
KeyCode::Char('m') => {
self.overlay = Overlay::SkillsAppsPicker {
directory: skill.directory.clone(),
name: skill.name.clone(),
selected: four_app_picker_index(&self.app_type),
apps: skill.apps.clone(),
};
Action::None
}
KeyCode::Char('d') => {
self.overlay = Overlay::Confirm(ConfirmOverlay {
title: texts::tui_skills_uninstall_title().to_string(),
message: texts::tui_confirm_uninstall_skill_message(
&skill.name,
&skill.directory,
),
action: ConfirmAction::SkillsUninstall {
directory: skill.directory.clone(),
},
});
Action::None
}
KeyCode::Char('s') => Action::SkillsSync {
app: Some(self.app_type.clone()),
},
KeyCode::Char('S') => Action::SkillsSync { app: None },
_ => Action::None,
}
}
}