Executes sync items sent by other device. CAVE: When changing the code to handle other sync items, take care that does not result in calls to `add_sync_item()` as otherwise we would add in a dead-loop between two devices sending message back and forth. If an error is returned, the caller shall not try over because some sync items could be already executed. Sync items are considered independent a
(&self, items: &SyncItems, timestamp_sent: i64)
| 308 | /// already executed. Sync items are considered independent and executed in the given order but |
| 309 | /// regardless of whether executing of the previous items succeeded. |
| 310 | pub(crate) async fn execute_sync_items(&self, items: &SyncItems, timestamp_sent: i64) { |
| 311 | info!(self, "executing {} sync item(s)", items.items.len()); |
| 312 | for item in &items.items { |
| 313 | // Limit the timestamp to ensure it is not in the future. |
| 314 | // |
| 315 | // `sent_timestamp` should be already corrected |
| 316 | // if the `Date` header is in the future. |
| 317 | let timestamp = std::cmp::min(item.timestamp, timestamp_sent); |
| 318 | |
| 319 | match &item.data { |
| 320 | SyncDataOrUnknown::SyncData(data) => match data { |
| 321 | AddQrToken(token) => self.add_qr_token(token, timestamp).await, |
| 322 | DeleteQrToken(token) => self.delete_qr_token(token, timestamp).await, |
| 323 | AlterChat { id, action } => self.sync_alter_chat(id, action).await, |
| 324 | SyncData::Config { key, val } => self.sync_config(key, val).await, |
| 325 | SyncData::SaveMessage { src, dest } => self.save_message(src, dest).await, |
| 326 | SyncData::DeleteMessages { msgs } => self.sync_message_deletion(msgs).await, |
| 327 | SyncData::Transports { |
| 328 | transports, |
| 329 | removed_transports, |
| 330 | } => sync_transports(self, transports, removed_transports).await, |
| 331 | }, |
| 332 | SyncDataOrUnknown::Unknown(data) => { |
| 333 | warn!(self, "Ignored unknown sync item: {data}."); |
| 334 | Ok(()) |
| 335 | } |
| 336 | } |
| 337 | .log_err(self) |
| 338 | .ok(); |
| 339 | } |
| 340 | |
| 341 | // Since there was a sync message, we know that there is a second device. |
| 342 | // Set BccSelf to true if it isn't already. |
| 343 | if !items.items.is_empty() && !self.get_config_bool(Config::BccSelf).await.unwrap_or(true) { |
| 344 | self.set_config_ex(Sync::Nosync, Config::BccSelf, Some("1")) |
| 345 | .await |
| 346 | .log_err(self) |
| 347 | .ok(); |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | async fn add_qr_token(&self, token: &QrTokenData, timestamp: i64) -> Result<()> { |
| 352 | let grpid = token.grpid.as_deref(); |