Show remote activity on iPhone Home
This commit is contained in:
@@ -36,6 +36,7 @@ pub struct Config {
|
||||
clipboard_timeout: ClipboardTimeout,
|
||||
authentication_timeout: AuthenticationTimeout,
|
||||
mobile_tab: MobileTab,
|
||||
mobile_home_refreshed_at: Option<i64>,
|
||||
git_remotes: Vec<GitRemote>,
|
||||
}
|
||||
|
||||
@@ -125,6 +126,10 @@ impl Config {
|
||||
self.mobile_tab
|
||||
}
|
||||
|
||||
pub fn mobile_home_refreshed_at(&self) -> Option<i64> {
|
||||
self.mobile_home_refreshed_at
|
||||
}
|
||||
|
||||
pub fn git_remotes(&self) -> &[GitRemote] {
|
||||
&self.git_remotes
|
||||
}
|
||||
@@ -168,6 +173,36 @@ impl Config {
|
||||
validate_config(self.source.clone(), document, raw)?.persist()
|
||||
}
|
||||
|
||||
pub(crate) fn update_mobile_home_refresh(&self, unix_seconds: i64) -> Result<(), ConfigError> {
|
||||
if unix_seconds <= 0 {
|
||||
return Err(ConfigError::InvalidField {
|
||||
field: "ui.home_remote_refreshed_at_unix_seconds",
|
||||
});
|
||||
}
|
||||
let mut document = self.document.clone();
|
||||
let root = document
|
||||
.as_table_mut()
|
||||
.ok_or_else(|| ConfigError::Malformed {
|
||||
path: self.source.clone(),
|
||||
})?;
|
||||
let ui = root
|
||||
.entry("ui")
|
||||
.or_insert_with(|| toml::Value::Table(toml::Table::new()))
|
||||
.as_table_mut()
|
||||
.ok_or(ConfigError::InvalidField { field: "ui" })?;
|
||||
ui.insert(
|
||||
"home_remote_refreshed_at_unix_seconds".to_owned(),
|
||||
toml::Value::Integer(unix_seconds),
|
||||
);
|
||||
let raw = document
|
||||
.clone()
|
||||
.try_into::<RawConfig>()
|
||||
.map_err(|_| ConfigError::Malformed {
|
||||
path: self.source.clone(),
|
||||
})?;
|
||||
validate_config(self.source.clone(), document, raw)?.persist()
|
||||
}
|
||||
|
||||
pub(crate) fn create_mobile_clone(
|
||||
source: PathBuf,
|
||||
vault: &Path,
|
||||
@@ -806,6 +841,7 @@ struct RawSecurity {
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct RawUi {
|
||||
selected_mobile_tab: Option<String>,
|
||||
home_remote_refreshed_at_unix_seconds: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -887,6 +923,15 @@ fn validate_config(
|
||||
.map(MobileTab::from_config)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
let mobile_home_refreshed_at = match raw.ui.home_remote_refreshed_at_unix_seconds {
|
||||
Some(value) if value > 0 => Some(value),
|
||||
Some(_) => {
|
||||
return Err(ConfigError::InvalidField {
|
||||
field: "ui.home_remote_refreshed_at_unix_seconds",
|
||||
});
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
let git_remotes = validate_remotes(raw.git.remotes)?;
|
||||
|
||||
Ok(Config {
|
||||
@@ -899,6 +944,7 @@ fn validate_config(
|
||||
clipboard_timeout,
|
||||
authentication_timeout,
|
||||
mobile_tab,
|
||||
mobile_home_refreshed_at,
|
||||
git_remotes,
|
||||
})
|
||||
}
|
||||
@@ -1073,7 +1119,14 @@ fn validate_known_fields(value: &toml::Value, source: &Path) -> Result<(), Confi
|
||||
let ui = ui.as_table().ok_or_else(|| ConfigError::Malformed {
|
||||
path: source.to_owned(),
|
||||
})?;
|
||||
validate_table(ui, "ui", &["selected_mobile_tab"])?;
|
||||
validate_table(
|
||||
ui,
|
||||
"ui",
|
||||
&[
|
||||
"selected_mobile_tab",
|
||||
"home_remote_refreshed_at_unix_seconds",
|
||||
],
|
||||
)?;
|
||||
}
|
||||
let Some(git) = root.get("git") else {
|
||||
return Ok(());
|
||||
@@ -1215,6 +1268,8 @@ fn native_config_directory() -> Option<PathBuf> {
|
||||
mod tests {
|
||||
use std::fs;
|
||||
|
||||
use crate::mobile::MobileTab;
|
||||
|
||||
use super::{Config, ConfigError, GitRemote};
|
||||
|
||||
#[test]
|
||||
@@ -1234,8 +1289,16 @@ mod tests {
|
||||
"repository-example",
|
||||
)
|
||||
.expect("remote");
|
||||
Config::create_mobile_clone(source.clone(), &vault, &keys, "ALICE", &remote)
|
||||
let config = Config::create_mobile_clone(source.clone(), &vault, &keys, "ALICE", &remote)
|
||||
.expect("create config");
|
||||
assert_eq!(config.mobile_home_refreshed_at(), None);
|
||||
config
|
||||
.update_mobile_home_refresh(1_789_000_000)
|
||||
.expect("persist refresh time");
|
||||
Config::load(Some(&source))
|
||||
.expect("reload timestamped config")
|
||||
.update_mobile_tab(MobileTab::Preferences)
|
||||
.expect("persist tab after refresh time");
|
||||
let contents = fs::read_to_string(&source).expect("read config");
|
||||
assert!(!contents.contains("token ="));
|
||||
assert!(!contents.contains("password ="));
|
||||
@@ -1251,12 +1314,15 @@ mod tests {
|
||||
}
|
||||
);
|
||||
fs::rename(&original, &relocated).expect("relocate app container");
|
||||
let relocated_config =
|
||||
Config::load(Some(&relocated.join("config.toml"))).expect("reload config");
|
||||
assert_eq!(
|
||||
Config::load(Some(&relocated.join("config.toml")))
|
||||
.expect("reload config")
|
||||
.default_key()
|
||||
.as_str(),
|
||||
"ALICE"
|
||||
(
|
||||
relocated_config.default_key().as_str(),
|
||||
relocated_config.mobile_home_refreshed_at(),
|
||||
relocated_config.mobile_tab(),
|
||||
),
|
||||
("ALICE", Some(1_789_000_000), MobileTab::Preferences)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user