use super::storage::SaveSnapshot;
use super::*;
impl AppCore {
pub(super) fn debug_snapshot_path(&self) -> PathBuf {
self.data_dir.join(DEBUG_SNAPSHOT_FILENAME)
}
pub(super) fn load_persisted(&mut self) -> anyhow::Result<Option<PersistedState>> {
self.app_store.delete_expired_messages(unix_now().get())?;
self.app_store.load_state()
}
pub(super) fn persist_best_effort(&mut self) {
if self.batch_depth > 0 {
self.batch_dirty_persist = true;
return;
}
self.persist_best_effort_inner();
}
pub(super) fn persist_best_effort_inner(&mut self) {
if self.logged_in.is_none() {
if let Err(error) = self.app_store.save_preferences(&self.preferences) {
self.push_debug_log("storage.save_preferences_failed", error.to_string());
}
self.persist_debug_snapshot_best_effort();
return;
}
let authorization_state = self
.logged_in
.as_ref()
.map(|logged_in| logged_in.authorization_state.into());
let snapshot = SaveSnapshot {
active_chat_id: self.active_chat_id.as_deref(),
next_message_id: self.next_message_id,
authorization_state,
preferences: &self.preferences,
owner_profiles: &self.owner_profiles,
chat_message_ttl_seconds: &self.chat_message_ttl_seconds,
app_keys: &self.app_keys,
groups: &self.groups,
group_pictures: &self.group_pictures,
threads: &self.threads,
seen_event_order: &self.seen_event_order,
};
match self.app_store.save_state(&snapshot) {
Ok(()) => {
self.ack_pending_decrypted_deliveries_after_app_persist();
}
Err(error) => {
self.push_debug_log("storage.save_failed", error.to_string());
}
}
self.persist_debug_snapshot_best_effort();
}
pub(super) fn clear_persistence_best_effort(&mut self) {
if let Err(error) = self.app_store.clear() {
self.push_debug_log("storage.clear_failed", error.to_string());
}
let debug_path = self.debug_snapshot_path();
if debug_path.exists() {
let _ = fs::remove_file(debug_path);
}
}
pub(super) fn persist_debug_snapshot_best_effort(&mut self) {
if self.logged_in.is_none() {
return;
}
if !debug_snapshot_file_writes_enabled() {
return;
}
if self.debug_snapshot_write_inflight {
self.debug_snapshot_write_dirty = true;
return;
}
let now_ms = unix_now_ms();
if now_ms.saturating_sub(self.debug_snapshot_last_built_at_ms)
< DEBUG_SNAPSHOT_MIN_INTERVAL_MS
{
self.debug_snapshot_write_dirty = true;
return;
}
let snapshot = self.build_runtime_debug_snapshot();
self.debug_snapshot_build_count = self.debug_snapshot_build_count.saturating_add(1);
self.debug_snapshot_last_built_at_ms = now_ms;
let path = self.debug_snapshot_path();
let data_dir = self.data_dir.clone();
#[cfg(target_os = "ios")]
{
if let Ok(bytes) = serde_json::to_vec_pretty(&snapshot) {
let _ = fs::create_dir_all(&data_dir);
let _ = fs::write(path, bytes);
}
return;
}
#[cfg(not(target_os = "ios"))]
{
self.debug_snapshot_write_inflight = true;
self.debug_snapshot_write_dirty = false;
self.debug_snapshot_write_generation =
self.debug_snapshot_write_generation.wrapping_add(1);
let generation = self.debug_snapshot_write_generation;
let tx = self.core_sender.clone();
self.runtime.spawn_blocking(move || {
if let Ok(bytes) = serde_json::to_vec_pretty(&snapshot) {
let _ = fs::create_dir_all(&data_dir);
let _ = fs::write(path, bytes);
}
let _ = tx.send(CoreMsg::Internal(Box::new(
InternalEvent::DebugSnapshotWriteFinished { generation },
)));
});
}
}
pub(crate) fn debug_snapshot_build_count(&self) -> u64 {
self.debug_snapshot_build_count
}
#[cfg(not(target_os = "ios"))]
pub(super) fn handle_debug_snapshot_write_finished(&mut self, generation: u64) {
if generation != self.debug_snapshot_write_generation {
return;
}
self.debug_snapshot_write_inflight = false;
if self.debug_snapshot_write_dirty {
self.debug_snapshot_write_dirty = false;
self.persist_debug_snapshot_best_effort();
}
}
}
pub(super) fn apply_persisted_preferences(
preferences: &mut PreferencesSnapshot,
persisted: &PersistedPreferences,
) {
preferences.send_typing_indicators = persisted.send_typing_indicators;
preferences.send_read_receipts = persisted.send_read_receipts;
preferences.desktop_notifications_enabled = persisted.desktop_notifications_enabled;
preferences.invite_acceptance_notifications_enabled =
persisted.invite_acceptance_notifications_enabled;
preferences.startup_at_login_enabled = persisted.startup_at_login_enabled;
preferences.nearby_enabled = persisted.nearby_enabled;
preferences.nearby_bluetooth_enabled = persisted.nearby_bluetooth_enabled;
preferences.nearby_lan_enabled = persisted.nearby_lan_enabled;
preferences.nearby_show_in_chat_list = persisted.nearby_show_in_chat_list;
preferences.nearby_mailbag_enabled = persisted.nearby_mailbag_enabled;
preferences.nostr_relay_urls = normalize_nostr_relay_urls(&persisted.nostr_relay_urls);
preferences.image_proxy_enabled = persisted.image_proxy_enabled;
preferences.image_proxy_fallback_enabled = persisted.image_proxy_fallback_enabled;
preferences.image_proxy_url = persisted.image_proxy_url.clone();
preferences.image_proxy_key_hex = persisted.image_proxy_key_hex.clone();
preferences.image_proxy_salt_hex = persisted.image_proxy_salt_hex.clone();
preferences.mobile_push_server_url = persisted.mobile_push_server_url.clone();
preferences.debug_logging_enabled = persisted.debug_logging_enabled;
preferences.accept_unknown_direct_messages = persisted.accept_unknown_direct_messages;
preferences.muted_chat_ids = persisted.muted_chat_ids.clone();
preferences.muted_chat_ids.sort();
preferences.muted_chat_ids.dedup();
preferences.pinned_chat_ids = persisted.pinned_chat_ids.clone();
preferences.pinned_chat_ids.sort();
preferences.pinned_chat_ids.dedup();
preferences.blocked_owner_pubkeys = persisted.blocked_owner_pubkeys.clone();
preferences.blocked_owner_pubkeys.sort();
preferences.blocked_owner_pubkeys.dedup();
preferences.accepted_owner_pubkeys = persisted.accepted_owner_pubkeys.clone();
preferences.accepted_owner_pubkeys.sort();
preferences.accepted_owner_pubkeys.dedup();
}