Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 8 additions & 24 deletions src/app/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ async fn on_input(
handle_patchset_details(app, input, terminal_handle).await?;
}
CurrentScreen::EditConfig => {
handle_edit_config(app, input)?;
handle_edit_config(app, input).await?;
}
CurrentScreen::LatestPatchsets => {
handle_latest_patchsets(app, input, loading).await?;
Expand All @@ -227,7 +227,7 @@ mod tests {
state::{AppState, ConfigUiState, LoreUiState, NavigationState, UserLoreState},
AppServices,
},
config::ConfigState,
config::{ConfigHandle, ConfigState},
infrastructure::{
env::MockEnvTrait, file_system::MockFileSystemTrait, shell::MockShellTrait,
},
Expand All @@ -253,26 +253,9 @@ mod tests {

use super::*;

struct NullConfigService;

impl crate::config::ConfigServiceApi for NullConfigService {
fn snapshot(&self) -> crate::config::ConfigSnapshot {
ConfigState::default().to_snapshot()
}

fn validate_update(
&self,
_: crate::config::ConfigUpdateDraft,
) -> Result<crate::config::ValidatedConfigUpdate, crate::config::ConfigError> {
unimplemented!()
}

fn apply_update(
&mut self,
_: crate::config::ValidatedConfigUpdate,
) -> Result<crate::config::ConfigSnapshot, crate::config::ConfigError> {
unimplemented!()
}
fn dummy_config_handle() -> ConfigHandle {
let (config_tx, _config_rx) = mpsc::channel(1);
ConfigHandle::new(config_tx)
}

fn minimal_app_with_env(env: MockEnvTrait) -> App {
Expand Down Expand Up @@ -313,7 +296,7 @@ mod tests {
shell: Box::new(MockShellTrait::new()),
fs: Box::new(MockFileSystemTrait::new()),
env: Box::new(env),
config: Box::new(NullConfigService),
config: dummy_config_handle(),
},
}
}
Expand Down Expand Up @@ -417,7 +400,8 @@ mod tests {
let ui_handle = UiActor::spawn();

let app = App::new(
Box::new(NullConfigService),
ConfigState::default().to_snapshot(),
dummy_config_handle(),
bootstrap,
Box::new(MockFileSystemTrait::new()),
Box::new(MockShellTrait::new()),
Expand Down
92 changes: 55 additions & 37 deletions src/app/flows/edit_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,68 @@ use crate::{
input::event::InputEvent,
};

pub fn handle_edit_config(app: &mut App, input: InputEvent) -> color_eyre::Result<()> {
if let Some(edit_config_state) = app.state.config_state.edit_config.as_mut() {
match edit_config_state.is_editing() {
true => match input {
InputEvent::CancelConfigEdit => {
edit_config_state.clear_edit();
edit_config_state.toggle_editing();
}
InputEvent::Backspace => {
edit_config_state.backspace_edit();
}
InputEvent::TextInput(ch) => {
edit_config_state.append_edit(ch);
}
InputEvent::StageConfigEdit => {
edit_config_state.stage_edit();
edit_config_state.clear_edit();
edit_config_state.toggle_editing();
}
_ => {}
},
false => match input {
InputEvent::OpenHelp => {
let popup = generate_help_popup();
app.state.popup = Some(popup);
}
InputEvent::SaveConfig => {
debug!("saving edited configuration");
app.consolidate_edit_config()?;
app.reset_edit_config();
app.set_current_screen(CurrentScreen::MailingListSelection);
pub async fn handle_edit_config(app: &mut App, input: InputEvent) -> color_eyre::Result<()> {
let Some(is_editing) = app
.state
.config_state
.edit_config
.as_ref()
.map(|edit_config_state| edit_config_state.is_editing())
else {
return Ok(());
};

match is_editing {
true => {
if let Some(edit_config_state) = app.state.config_state.edit_config.as_mut() {
match input {
InputEvent::CancelConfigEdit => {
edit_config_state.clear_edit();
edit_config_state.toggle_editing();
}
InputEvent::Backspace => {
edit_config_state.backspace_edit();
}
InputEvent::TextInput(ch) => {
edit_config_state.append_edit(ch);
}
InputEvent::StageConfigEdit => {
edit_config_state.stage_edit();
edit_config_state.clear_edit();
edit_config_state.toggle_editing();
}
_ => {}
}
InputEvent::EditConfigField => {
}
}
false => match input {
InputEvent::OpenHelp => {
let popup = generate_help_popup();
app.state.popup = Some(popup);
}
InputEvent::SaveConfig => {
debug!("saving edited configuration");
app.consolidate_edit_config().await?;
app.reset_edit_config();
app.set_current_screen(CurrentScreen::MailingListSelection);
}
InputEvent::EditConfigField => {
if let Some(edit_config_state) = app.state.config_state.edit_config.as_mut() {
edit_config_state.toggle_editing();
}
InputEvent::NavigateDown => {
}
InputEvent::NavigateDown => {
if let Some(edit_config_state) = app.state.config_state.edit_config.as_mut() {
edit_config_state.highlight_next();
}
InputEvent::NavigateUp => {
}
InputEvent::NavigateUp => {
if let Some(edit_config_state) = app.state.config_state.edit_config.as_mut() {
edit_config_state.highlight_prev();
}
_ => {}
},
}
}
_ => {}
},
}
Ok(())
}
Expand Down
27 changes: 16 additions & 11 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use tracing::{debug, event, info, warn, Level};
use std::path::PathBuf;

use crate::{
config::ConfigServiceApi,
config::{ConfigHandle, ConfigSnapshot},
infrastructure::{
env::EnvTrait,
file_system::FileSystemTrait,
Expand Down Expand Up @@ -62,7 +62,7 @@ pub struct AppServices {
pub shell: Box<dyn ShellTrait>,
pub fs: Box<dyn FileSystemTrait>,
pub env: Box<dyn EnvTrait>,
pub config: Box<dyn ConfigServiceApi>,
pub config: ConfigHandle,
}

/// Result type signalling whether a patchset was successfully loaded.
Expand All @@ -78,23 +78,24 @@ pub struct App {
}

impl App {
/// Creates a new instance of `App`. Configuration comes from [`ConfigServiceApi::snapshot`];
/// Lore bootstrap uses already-warmed cache from `lore_service`.
/// Creates a new instance of `App`.
///
/// Configuration starts from the already-bootstrapped snapshot owned by the
/// Config actor. Lore bootstrap uses already-warmed cache from `lore_service`.
///
/// # Returns
///
/// `App` instance with loading configurations and app data.
pub fn new(
config_service: Box<dyn ConfigServiceApi>,
config: ConfigSnapshot,
config_handle: ConfigHandle,
bootstrap: BootstrapLoreData,
fs: Box<dyn FileSystemTrait>,
shell: Box<dyn ShellTrait>,
env: Box<dyn EnvTrait>,
lore_api: LoreApiHandle,
render: RenderHandle,
) -> color_eyre::Result<Self> {
let config = config_service.snapshot();

event!(Level::INFO, "patch-hub started");
collect_garbage(&config);

Expand Down Expand Up @@ -130,7 +131,7 @@ impl App {
shell,
fs,
env,
config: config_service,
config: config_handle,
},
})
}
Expand Down Expand Up @@ -489,12 +490,16 @@ impl App {
}

/// Applies edited values from [`ConfigUiState::edit_config`] into [`AppState::config`].
pub fn consolidate_edit_config(&mut self) -> color_eyre::Result<()> {
pub async fn consolidate_edit_config(&mut self) -> color_eyre::Result<()> {
if let Some(edit_config) = &self.state.config_state.edit_config {
debug!("validating and applying config update");
let draft = edit_config.to_update_draft();
let validated = self.services.config.validate_update(draft)?;
let snapshot = self.services.config.apply_update(validated)?;
let snapshot = self
.services
.config
.validate_and_apply(draft)
.await
.map_err(|e| eyre!("{e:#?}"))?;
self.state.config = snapshot;
info!("configuration updated and persisted");
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/screens/edit_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl EditConfigState {
}
}

/// Raw form values for [`crate::config::ConfigServiceApi::validate_update`].
/// Raw form values for config validation.
pub fn to_update_draft(&self) -> ConfigUpdateDraft {
ConfigUpdateDraft {
page_size: self.config_buffer.get(&EditableConfig::PageSize).cloned(),
Expand Down
Loading
Loading